diff --git a/COPYING b/COPYING index 10b86d59..08dea940 100644 --- a/COPYING +++ b/COPYING @@ -1,372 +1,176 @@ +Apache License, Version 2.0 -special clause for libxrdp and librdp, both based on rdesktop -these libraries link to openssl +Version 2.0, January 2004 - This software is released under the GNU General Public License - (reproduced below) with the additional exemption that compiling, - linking, and/or using OpenSSL together with this software is - allowed. +http://www.apache.org/licenses/ ---- +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -special clause for xrdp, that main executable -for linking with proprietary modules +1. Definitions. - Linking this library statically or dynamically with other modules - is making a combined work based on this library. Thus, the terms - and conditions of the GNU General Public License cover the whole - combination. +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. - As a special exception, the copyright holders of this library - give you permission to link this library with independent modules - to produce an executable, regardless of the license terms of - these independent modules, and to copy and distribute the resulting - executable under terms of your choice, provided that you also meet, - for each linked independent module, the terms and conditions of the - license of that module. An independent module is a module which is - not derived from or based on this library. If you modify this - library, you may extend this exception to your version of the - library, but you are not obliged to do so. If you do not wish - to do so, delete this exception statement from your version. +"Licensor" shall mean the copyright owner or entity authorized by the +copyright owner that is granting the License. ---- +"Legal Entity" shall mean the union of the acting entity and all other +entities that control, are controlled by, or are under common control +with that entity. For the purposes of this definition, "control" means +(i) the power, direct or indirect, to cause the direction or management +of such entity, whether by contract or otherwise, or (ii) ownership of +fifty percent (50%) or more of the outstanding shares, or +(iii) beneficial ownership of such entity. - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, +and configuration files. - Preamble +"Object" form shall mean any form resulting from mechanical transformation +or translation of a Source form, including but not limited to compiled +object code, generated documentation, and conversions to other media types. - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice that is +included in or attached to the work (an example is provided in the Appendix below). - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, as a +whole, an original work of authorship. For the purposes of this License, +Derivative Works shall not include works that remain separable from, or +merely link (or bind by name) to the interfaces of, the Work and +Derivative Works thereof. - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or Derivative +Works thereof, that is intentionally submitted to Licensor for inclusion in the +Work by the copyright owner or by an individual or Legal Entity authorized to +submit on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently incorporated +within the Work. - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. +2. Grant of Copyright License. Subject to the terms and conditions of this License, +each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable copyright license to reproduce, prepare +Derivative Works of, publicly display, publicly perform, sublicense, and distribute +the Work and such Derivative Works in Source or Object form. - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. +3. Grant of Patent License. Subject to the terms and conditions of this License, +each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) patent +license to make, have made, use, offer to sell, sell, import, and otherwise transfer +the Work, where such license applies only to those patent claims licensable by such +Contributor that are necessarily infringed by their Contribution(s) alone or by +combination of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution +incorporated within the Work constitutes direct or contributory patent infringement, +then any patent licenses granted to You under this License for that Work shall +terminate as of the date such litigation is filed. - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative +Works thereof in any medium, with or without modifications, and in Source or Object +form, provided that You meet the following conditions: - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +You must give any other recipients of the Work or Derivative Works a copy of this +License; and - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". +You must cause any modified files to carry prominent notices stating that You changed +the files; and -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form of the Work, +excluding those notices that do not pertain to any part of the Derivative Works; and - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the attribution +notices contained within such NOTICE file, excluding those notices that do not pertain +to any part of the Derivative Works, in at least one of the following places: within a +NOTICE text file distributed as part of the Derivative Works; within the Source form or +documentation, if provided along with the Derivative Works; or, within a display +generated by the Derivative Works, if and wherever such third-party notices normally +appear. The contents of the NOTICE file are for informational purposes only and do not +modify the License. You may add Your own attribution notices within Derivative Works +that You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as modifying +the License. You may add Your own copyright statement to Your modifications and may +provide additional or different license terms and conditions for use, reproduction, +or distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution +intentionally submitted for inclusion in the Work by You to the Licensor shall be under +the terms and conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of any +separate license agreement you may have executed with Licensor regarding such Contributions. - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: +6. Trademarks. This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for reasonable and +customary use in describing the origin of the Work and reproducing the content of +the NOTICE file. - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, +Licensor provides the Work (and each Contributor provides its Contributions) on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, +MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for +determining the appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. +8. Limitation of Liability. In no event and under no legal theory, whether in tort +(including negligence), contract, or otherwise, unless required by applicable law +(such as deliberate and grossly negligent acts) or agreed to in writing, shall any +Contributor be liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a result of this +License or out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or any +and all other commercial damages or losses), even if such Contributor has been advised +of the possibility of such damages. - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. +9. Accepting Warranty or Additional Liability. While redistributing the Work or +Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance +of support, warranty, indemnity, or other liability obligations and/or rights consistent +with this License. However, in accepting such obligations, You may act only on Your +own behalf and on Your sole responsibility, not on behalf of any other Contributor, +and only if You agree to indemnify, defend, and hold each Contributor harmless for any +liability incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. +END OF TERMS AND CONDITIONS -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. +APPENDIX: How to apply the Apache License to your work +To apply the Apache License to your work, attach the following boilerplate notice, +with the fields enclosed by brackets "[]" replaced with your own identifying +information. (Don't include the brackets!) The text should be enclosed in the +appropriate comment syntax for the file format. We also recommend that a file or class +name and description of purpose be included on the same "printed page" as the +copyright notice for easier identification within third-party archives. - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: + Copyright [yyyy] [name of copyright owner] - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, + http://www.apache.org/licenses/LICENSE-2.0 - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/Coding_Style.odt b/Coding_Style.odt new file mode 100644 index 00000000..23aeef12 Binary files /dev/null and b/Coding_Style.odt differ diff --git a/astyle_config.as b/astyle_config.as new file mode 100644 index 00000000..0a968907 --- /dev/null +++ b/astyle_config.as @@ -0,0 +1,59 @@ + +# detached brackets +--style=allman + +# 4 spaces, no tabs +--indent=spaces=4 + +# for C++ files only +--indent-classes + +# Indent 'switch' blocks so that the 'case X:' statements are indented in the switch block. +# The entire case block is indented. +--indent-switches + +# Add extra indentation to namespace blocks. This option has no effect on Java files. +--indent-namespaces + +# Converts tabs into spaces in the non-indentation part of the line. +--convert-tabs + +# requires --convert-tabs to work properly +--indent-preprocessor + +--indent-col1-comments + +--min-conditional-indent=2 + +--max-instatement-indent=40 + +# Pad empty lines around header blocks (e.g. 'if', 'for', 'while'...). +--break-blocks + +# Insert space padding around operators. +--pad-oper + +# Insert space padding after paren headers only (e.g. 'if', 'for', 'while'...). +--pad-header + + +# Add brackets to unbracketed one line conditional statements (e.g. 'if', 'for', 'while'...). +--add-brackets + +--align-pointer=name + +# Do not retain a backup of the original file. The original file is purged after it is formatted. +--suffix=none + +# For each directory in the command line, process all subdirectories recursively. +--recursive + +# Preserve the original file's date and time modified. +--preserve-date + +# Formatted files display mode. Display only the files that have been formatted. +# Do not display files that are unchanged. +--formatted + +--lineend=linux + diff --git a/common/arch.h b/common/arch.h index a380511b..b8780926 100644 --- a/common/arch.h +++ b/common/arch.h @@ -1,25 +1,20 @@ -/* - Copyright (c) 2004-2010 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #if !defined(ARCH_H) #define ARCH_H diff --git a/common/d3des.c b/common/d3des.c index 16ec35df..16ee7cde 100644 --- a/common/d3des.c +++ b/common/d3des.c @@ -38,393 +38,471 @@ static unsigned long KnL[32] = { 0L }; static unsigned long KnR[32] = { 0L }; static unsigned long Kn3[32] = { 0L }; static unsigned char Df_Key[24] = { - 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, - 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, - 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 }; + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, + 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 }; */ -static unsigned short bytebit[8] = { - 01, 02, 04, 010, 020, 040, 0100, 0200 }; +static unsigned short bytebit[8] = +{ + 01, 02, 04, 010, 020, 040, 0100, 0200 +}; -static unsigned long bigbyte[24] = { - 0x800000L, 0x400000L, 0x200000L, 0x100000L, - 0x80000L, 0x40000L, 0x20000L, 0x10000L, - 0x8000L, 0x4000L, 0x2000L, 0x1000L, - 0x800L, 0x400L, 0x200L, 0x100L, - 0x80L, 0x40L, 0x20L, 0x10L, - 0x8L, 0x4L, 0x2L, 0x1L }; +static unsigned long bigbyte[24] = +{ + 0x800000L, 0x400000L, 0x200000L, 0x100000L, + 0x80000L, 0x40000L, 0x20000L, 0x10000L, + 0x8000L, 0x4000L, 0x2000L, 0x1000L, + 0x800L, 0x400L, 0x200L, 0x100L, + 0x80L, 0x40L, 0x20L, 0x10L, + 0x8L, 0x4L, 0x2L, 0x1L +}; /* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ -static unsigned char pc1[56] = { - 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, - 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, - 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, - 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; +static unsigned char pc1[56] = +{ + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 +}; -static unsigned char totrot[16] = { - 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; +static unsigned char totrot[16] = +{ + 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 +}; -static unsigned char pc2[48] = { - 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, - 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, - 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, - 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; +static unsigned char pc2[48] = +{ + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 +}; /* Thanks to James Gillogly & Phil Karn! */ void rfbDesKey(unsigned char *key, int edf) { - register int i, j, l, m, n; - unsigned char pc1m[56], pcr[56]; - unsigned long kn[32]; + register int i, j, l, m, n; + unsigned char pc1m[56], pcr[56]; + unsigned long kn[32]; - for ( j = 0; j < 56; j++ ) { - l = pc1[j]; - m = l & 07; - pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; - } - for( i = 0; i < 16; i++ ) { - if( edf == DE1 ) m = (15 - i) << 1; - else m = i << 1; - n = m + 1; - kn[m] = kn[n] = 0L; - for( j = 0; j < 28; j++ ) { - l = j + totrot[i]; - if( l < 28 ) pcr[j] = pc1m[l]; - else pcr[j] = pc1m[l - 28]; - } - for( j = 28; j < 56; j++ ) { - l = j + totrot[i]; - if( l < 56 ) pcr[j] = pc1m[l]; - else pcr[j] = pc1m[l - 28]; - } - for( j = 0; j < 24; j++ ) { - if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; - if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; - } - } - cookey(kn); - return; - } + for ( j = 0; j < 56; j++ ) + { + l = pc1[j]; + m = l & 07; + pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; + } + + for ( i = 0; i < 16; i++ ) + { + if ( edf == DE1 ) + { + m = (15 - i) << 1; + } + else + { + m = i << 1; + } + + n = m + 1; + kn[m] = kn[n] = 0L; + + for ( j = 0; j < 28; j++ ) + { + l = j + totrot[i]; + + if ( l < 28 ) + { + pcr[j] = pc1m[l]; + } + else + { + pcr[j] = pc1m[l - 28]; + } + } + + for ( j = 28; j < 56; j++ ) + { + l = j + totrot[i]; + + if ( l < 56 ) + { + pcr[j] = pc1m[l]; + } + else + { + pcr[j] = pc1m[l - 28]; + } + } + + for ( j = 0; j < 24; j++ ) + { + if ( pcr[pc2[j]] ) + { + kn[m] |= bigbyte[j]; + } + + if ( pcr[pc2[j + 24]] ) + { + kn[n] |= bigbyte[j]; + } + } + } + + cookey(kn); + return; +} static void cookey(register unsigned long *raw1) { - register unsigned long *cook, *raw0; - unsigned long dough[32]; - register int i; + register unsigned long *cook, *raw0; + unsigned long dough[32]; + register int i; - cook = dough; - for( i = 0; i < 16; i++, raw1++ ) { - raw0 = raw1++; - *cook = (*raw0 & 0x00fc0000L) << 6; - *cook |= (*raw0 & 0x00000fc0L) << 10; - *cook |= (*raw1 & 0x00fc0000L) >> 10; - *cook++ |= (*raw1 & 0x00000fc0L) >> 6; - *cook = (*raw0 & 0x0003f000L) << 12; - *cook |= (*raw0 & 0x0000003fL) << 16; - *cook |= (*raw1 & 0x0003f000L) >> 4; - *cook++ |= (*raw1 & 0x0000003fL); - } - rfbUseKey(dough); - return; - } + cook = dough; + + for ( i = 0; i < 16; i++, raw1++ ) + { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + + rfbUseKey(dough); + return; +} void rfbCPKey(register unsigned long *into) { - register unsigned long *from, *endp; + register unsigned long *from, *endp; - from = KnL, endp = &KnL[32]; - while( from < endp ) *into++ = *from++; - return; - } + from = KnL, endp = &KnL[32]; + + while ( from < endp ) + { + *into++ = *from++; + } + + return; +} void rfbUseKey(register unsigned long *from) { - register unsigned long *to, *endp; + register unsigned long *to, *endp; - to = KnL, endp = &KnL[32]; - while( to < endp ) *to++ = *from++; - return; - } + to = KnL, endp = &KnL[32]; + + while ( to < endp ) + { + *to++ = *from++; + } + + return; +} void rfbDes(unsigned char *inblock, unsigned char *outblock) { - unsigned long work[2]; + unsigned long work[2]; - scrunch(inblock, work); - desfunc(work, KnL); - unscrun(work, outblock); - return; - } + scrunch(inblock, work); + desfunc(work, KnL); + unscrun(work, outblock); + return; +} static void scrunch(register unsigned char *outof, register unsigned long *into) { - *into = (*outof++ & 0xffL) << 24; - *into |= (*outof++ & 0xffL) << 16; - *into |= (*outof++ & 0xffL) << 8; - *into++ |= (*outof++ & 0xffL); - *into = (*outof++ & 0xffL) << 24; - *into |= (*outof++ & 0xffL) << 16; - *into |= (*outof++ & 0xffL) << 8; - *into |= (*outof & 0xffL); - return; - } + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into++ |= (*outof++ & 0xffL); + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into |= (*outof & 0xffL); + return; +} static void unscrun(register unsigned long *outof, register unsigned char *into) { - *into++ = (unsigned char)((*outof >> 24) & 0xffL); - *into++ = (unsigned char)((*outof >> 16) & 0xffL); - *into++ = (unsigned char)((*outof >> 8) & 0xffL); - *into++ = (unsigned char)( *outof++ & 0xffL); - *into++ = (unsigned char)((*outof >> 24) & 0xffL); - *into++ = (unsigned char)((*outof >> 16) & 0xffL); - *into++ = (unsigned char)((*outof >> 8) & 0xffL); - *into = (unsigned char)( *outof & 0xffL); - return; - } + *into++ = (unsigned char)((*outof >> 24) & 0xffL); + *into++ = (unsigned char)((*outof >> 16) & 0xffL); + *into++ = (unsigned char)((*outof >> 8) & 0xffL); + *into++ = (unsigned char)( *outof++ & 0xffL); + *into++ = (unsigned char)((*outof >> 24) & 0xffL); + *into++ = (unsigned char)((*outof >> 16) & 0xffL); + *into++ = (unsigned char)((*outof >> 8) & 0xffL); + *into = (unsigned char)( *outof & 0xffL); + return; +} -static unsigned long SP1[64] = { - 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, - 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, - 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, - 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, - 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, - 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, - 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, - 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, - 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, - 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, - 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, - 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, - 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, - 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, - 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, - 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; - -static unsigned long SP2[64] = { - 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, - 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, - 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, - 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, - 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, - 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, - 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, - 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, - 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, - 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, - 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, - 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, - 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, - 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, - 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, - 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; - -static unsigned long SP3[64] = { - 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, - 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, - 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, - 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, - 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, - 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, - 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, - 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, - 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, - 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, - 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, - 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, - 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, - 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, - 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, - 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; - -static unsigned long SP4[64] = { - 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, - 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, - 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, - 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, - 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, - 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, - 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, - 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, - 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, - 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, - 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, - 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, - 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, - 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, - 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, - 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; - -static unsigned long SP5[64] = { - 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, - 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, - 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, - 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, - 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, - 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, - 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, - 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, - 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, - 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, - 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, - 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, - 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, - 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, - 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, - 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; - -static unsigned long SP6[64] = { - 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, - 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, - 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, - 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, - 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, - 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, - 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, - 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, - 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, - 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, - 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, - 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, - 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, - 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, - 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, - 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; - -static unsigned long SP7[64] = { - 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, - 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, - 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, - 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, - 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, - 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, - 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, - 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, - 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, - 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, - 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, - 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, - 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, - 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, - 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, - 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; - -static unsigned long SP8[64] = { - 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, - 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, - 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, - 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, - 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, - 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, - 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, - 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, - 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, - 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, - 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, - 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, - 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, - 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, - 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, - 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; - -static void desfunc(register unsigned long* block, register unsigned long *keys) +static unsigned long SP1[64] = { - register unsigned long fval, work, right, leftt; - register int round; + 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, + 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, + 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, + 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, + 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, + 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, + 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, + 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, + 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, + 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, + 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, + 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, + 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, + 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L +}; - leftt = block[0]; - right = block[1]; - work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; - right ^= work; - leftt ^= (work << 4); - work = ((leftt >> 16) ^ right) & 0x0000ffffL; - right ^= work; - leftt ^= (work << 16); - work = ((right >> 2) ^ leftt) & 0x33333333L; - leftt ^= work; - right ^= (work << 2); - work = ((right >> 8) ^ leftt) & 0x00ff00ffL; - leftt ^= work; - right ^= (work << 8); - right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; - work = (leftt ^ right) & 0xaaaaaaaaL; - leftt ^= work; - right ^= work; - leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; +static unsigned long SP2[64] = +{ + 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, + 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, + 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, + 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, + 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, + 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, + 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, + 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, + 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, + 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, + 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, + 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, + 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, + 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, + 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, + 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L +}; - for( round = 0; round < 8; round++ ) { - work = (right << 28) | (right >> 4); - work ^= *keys++; - fval = SP7[ work & 0x3fL]; - fval |= SP5[(work >> 8) & 0x3fL]; - fval |= SP3[(work >> 16) & 0x3fL]; - fval |= SP1[(work >> 24) & 0x3fL]; - work = right ^ *keys++; - fval |= SP8[ work & 0x3fL]; - fval |= SP6[(work >> 8) & 0x3fL]; - fval |= SP4[(work >> 16) & 0x3fL]; - fval |= SP2[(work >> 24) & 0x3fL]; - leftt ^= fval; - work = (leftt << 28) | (leftt >> 4); - work ^= *keys++; - fval = SP7[ work & 0x3fL]; - fval |= SP5[(work >> 8) & 0x3fL]; - fval |= SP3[(work >> 16) & 0x3fL]; - fval |= SP1[(work >> 24) & 0x3fL]; - work = leftt ^ *keys++; - fval |= SP8[ work & 0x3fL]; - fval |= SP6[(work >> 8) & 0x3fL]; - fval |= SP4[(work >> 16) & 0x3fL]; - fval |= SP2[(work >> 24) & 0x3fL]; - right ^= fval; - } +static unsigned long SP3[64] = +{ + 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, + 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, + 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, + 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, + 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, + 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, + 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, + 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, + 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, + 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, + 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, + 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, + 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, + 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, + 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, + 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L +}; - right = (right << 31) | (right >> 1); - work = (leftt ^ right) & 0xaaaaaaaaL; - leftt ^= work; - right ^= work; - leftt = (leftt << 31) | (leftt >> 1); - work = ((leftt >> 8) ^ right) & 0x00ff00ffL; - right ^= work; - leftt ^= (work << 8); - work = ((leftt >> 2) ^ right) & 0x33333333L; - right ^= work; - leftt ^= (work << 2); - work = ((right >> 16) ^ leftt) & 0x0000ffffL; - leftt ^= work; - right ^= (work << 16); - work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; - leftt ^= work; - right ^= (work << 4); - *block++ = right; - *block = leftt; - return; - } +static unsigned long SP4[64] = +{ + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, + 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, + 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, + 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, + 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, + 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, + 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, + 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, + 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L +}; + +static unsigned long SP5[64] = +{ + 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, + 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, + 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, + 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, + 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, + 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, + 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, + 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, + 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, + 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, + 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, + 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, + 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, + 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, + 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, + 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L +}; + +static unsigned long SP6[64] = +{ + 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, + 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, + 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, + 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, + 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, + 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, + 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, + 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, + 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, + 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, + 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, + 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, + 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, + 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L +}; + +static unsigned long SP7[64] = +{ + 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, + 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, + 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, + 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, + 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, + 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, + 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, + 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, + 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, + 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, + 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, + 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, + 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, + 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, + 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, + 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L +}; + +static unsigned long SP8[64] = +{ + 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, + 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, + 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, + 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, + 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, + 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, + 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, + 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, + 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, + 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, + 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, + 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, + 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, + 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, + 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, + 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L +}; + +static void desfunc(register unsigned long *block, register unsigned long *keys) +{ + register unsigned long fval, work, right, leftt; + register int round; + + leftt = block[0]; + right = block[1]; + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; + + for ( round = 0; round < 8; round++ ) + { + work = (right << 28) | (right >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + leftt ^= fval; + work = (leftt << 28) | (leftt >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >> 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); + *block++ = right; + *block = leftt; + return; +} /* Validation sets: * * Single-length key, single-length plaintext - - * Key : 0123 4567 89ab cdef + * Key : 0123 4567 89ab cdef * Plain : 0123 4567 89ab cde7 * Cipher : c957 4425 6a5e d31d * * Double-length key, single-length plaintext - - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 * Plain : 0123 4567 89ab cde7 * Cipher : 7f1d 0a77 826b 8aff * * Double-length key, double-length plaintext - - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 * * Triple-length key, single-length plaintext - - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 * Plain : 0123 4567 89ab cde7 * Cipher : de0b 7c06 ae5e 0ed5 * * Triple-length key, double-length plaintext - - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 * diff --git a/common/defines.h b/common/defines.h index 8e2328a7..502a41e8 100644 --- a/common/defines.h +++ b/common/defines.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2009 - - main define/macro file - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * main define/macro file + */ #ifndef DEFINES_H #define DEFINES_H diff --git a/common/file.c b/common/file.c index 808d94dc..c8be7af5 100644 --- a/common/file.c +++ b/common/file.c @@ -1,26 +1,22 @@ -/* - Copyright (c) 2004-2012 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - read a config file -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * read a config file + */ #include "arch.h" #include "os_calls.h" @@ -33,250 +29,276 @@ returns 0 if everything is ok returns 1 if problem reading file */ static int APP_CC -l_file_read_sections(int fd, int max_file_size, struct list* names) +l_file_read_sections(int fd, int max_file_size, struct list *names) { - struct stream* s; - char text[256]; - char c; - int in_it; - int in_it_index; - int len; - int index; - int rv; + struct stream *s; + char text[256]; + char c; + int in_it; + int in_it_index; + int len; + int index; + int rv; - rv = 0; - g_file_seek(fd, 0); - in_it_index = 0; - in_it = 0; - g_memset(text, 0, 256); - list_clear(names); - make_stream(s); - init_stream(s, max_file_size); - len = g_file_read(fd, s->data, max_file_size); - if (len > 0) - { - s->end = s->p + len; - for (index = 0; index < len; index++) + rv = 0; + g_file_seek(fd, 0); + in_it_index = 0; + in_it = 0; + g_memset(text, 0, 256); + list_clear(names); + make_stream(s); + init_stream(s, max_file_size); + len = g_file_read(fd, s->data, max_file_size); + + if (len > 0) { - in_uint8(s, c); - if (c == '[') - { - in_it = 1; - } - else if (c == ']') - { - list_add_item(names, (tbus)g_strdup(text)); - in_it = 0; - in_it_index = 0; - g_memset(text, 0, 256); - } - else if (in_it) - { - text[in_it_index] = c; - in_it_index++; - } + s->end = s->p + len; + + for (index = 0; index < len; index++) + { + in_uint8(s, c); + + if (c == '[') + { + in_it = 1; + } + else if (c == ']') + { + list_add_item(names, (tbus)g_strdup(text)); + in_it = 0; + in_it_index = 0; + g_memset(text, 0, 256); + } + else if (in_it) + { + text[in_it_index] = c; + in_it_index++; + } + } } - } - else if (len < 0) - { - rv = 1; - } - free_stream(s); - return rv; + else if (len < 0) + { + rv = 1; + } + + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC -file_read_line(struct stream* s, char* text) +file_read_line(struct stream *s, char *text) { - int i; - int skip_to_end; - int at_end; - char c; - char* hold; + int i; + int skip_to_end; + int at_end; + char c; + char *hold; - skip_to_end = 0; - if (!s_check_rem(s, 1)) - { - return 1; - } - hold = s->p; - i = 0; - in_uint8(s, c); - while (c != 10 && c != 13) - { - if (c == '#' || c == '!' || c == ';') + skip_to_end = 0; + + if (!s_check_rem(s, 1)) { - skip_to_end = 1; + return 1; } - if (!skip_to_end) + + hold = s->p; + i = 0; + in_uint8(s, c); + + while (c != 10 && c != 13) { - text[i] = c; - i++; + if (c == '#' || c == '!' || c == ';') + { + skip_to_end = 1; + } + + if (!skip_to_end) + { + text[i] = c; + i++; + } + + if (s_check_rem(s, 1)) + { + in_uint8(s, c); + } + else + { + c = 0; + break; + } } - if (s_check_rem(s, 1)) + + if (c == 10 || c == 13) { - in_uint8(s, c); + at_end = 0; + + while (c == 10 || c == 13) + { + if (s_check_rem(s, 1)) + { + in_uint8(s, c); + } + else + { + at_end = 1; + break; + } + } + + if (!at_end) + { + s->p--; + } } - else + + text[i] = 0; + + if (text[0] == '[') { - c = 0; - break; + s->p = hold; + return 1; } - } - if (c == 10 || c == 13) - { - at_end = 0; - while (c == 10 || c == 13) - { - if (s_check_rem(s, 1)) - { - in_uint8(s, c); - } - else - { - at_end = 1; - break; - } - } - if (!at_end) - { - s->p--; - } - } - text[i] = 0; - if (text[0] == '[') - { - s->p = hold; - return 1; - } - return 0; + + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -file_split_name_value(char* text, char* name, char* value) +file_split_name_value(char *text, char *name, char *value) { - int len; - int i; - int value_index; - int name_index; - int on_to; + int len; + int i; + int value_index; + int name_index; + int on_to; - value_index = 0; - name_index = 0; - on_to = 0; - name[0] = 0; - value[0] = 0; - len = g_strlen(text); - for (i = 0; i < len; i++) - { - if (text[i] == '=') + value_index = 0; + name_index = 0; + on_to = 0; + name[0] = 0; + value[0] = 0; + len = g_strlen(text); + + for (i = 0; i < len; i++) { - on_to = 1; + if (text[i] == '=') + { + on_to = 1; + } + else if (on_to) + { + value[value_index] = text[i]; + value_index++; + value[value_index] = 0; + } + else + { + name[name_index] = text[i]; + name_index++; + name[name_index] = 0; + } } - else if (on_to) - { - value[value_index] = text[i]; - value_index++; - value[value_index] = 0; - } - else - { - name[name_index] = text[i]; - name_index++; - name[name_index] = 0; - } - } - g_strtrim(name, 3); /* trim both right and left */ - g_strtrim(value, 3); /* trim both right and left */ - return 0; + + g_strtrim(name, 3); /* trim both right and left */ + g_strtrim(value, 3); /* trim both right and left */ + return 0; } /*****************************************************************************/ /* return error */ static int APP_CC -l_file_read_section(int fd, int max_file_size, const char* section, - struct list* names, struct list* values) +l_file_read_section(int fd, int max_file_size, const char *section, + struct list *names, struct list *values) { - struct stream* s; - char text[512]; - char name[512]; - char value[512]; - char* lvalue; - char c; - int in_it; - int in_it_index; - int len; - int index; - int file_size; + struct stream *s; + char text[512]; + char name[512]; + char value[512]; + char *lvalue; + char c; + int in_it; + int in_it_index; + int len; + int index; + int file_size; - file_size = 32 * 1024; /* 32 K file size limit */ - g_file_seek(fd, 0); - in_it_index = 0; - in_it = 0; - g_memset(text, 0, 512); - list_clear(names); - list_clear(values); - make_stream(s); - init_stream(s, file_size); - len = g_file_read(fd, s->data, file_size); - if (len > 0) - { - s->end = s->p + len; - for (index = 0; index < len; index++) + file_size = 32 * 1024; /* 32 K file size limit */ + g_file_seek(fd, 0); + in_it_index = 0; + in_it = 0; + g_memset(text, 0, 512); + list_clear(names); + list_clear(values); + make_stream(s); + init_stream(s, file_size); + len = g_file_read(fd, s->data, file_size); + + if (len > 0) { - in_uint8(s, c); - if (c == '[') - { - in_it = 1; - } - else if (c == ']') - { - if (g_strcasecmp(section, text) == 0) + s->end = s->p + len; + + for (index = 0; index < len; index++) { - file_read_line(s, text); - while (file_read_line(s, text) == 0) - { - if (g_strlen(text) > 0) + in_uint8(s, c); + + if (c == '[') { - file_split_name_value(text, name, value); - list_add_item(names, (tbus)g_strdup(name)); - if (value[0] == '$') - { - lvalue = g_getenv(value + 1); - if (lvalue != 0) - { - list_add_item(values, (tbus)g_strdup(lvalue)); - } - else - { - list_add_item(values, (tbus)g_strdup("")); - } - } - else - { - list_add_item(values, (tbus)g_strdup(value)); - } + in_it = 1; + } + else if (c == ']') + { + if (g_strcasecmp(section, text) == 0) + { + file_read_line(s, text); + + while (file_read_line(s, text) == 0) + { + if (g_strlen(text) > 0) + { + file_split_name_value(text, name, value); + list_add_item(names, (tbus)g_strdup(name)); + + if (value[0] == '$') + { + lvalue = g_getenv(value + 1); + + if (lvalue != 0) + { + list_add_item(values, (tbus)g_strdup(lvalue)); + } + else + { + list_add_item(values, (tbus)g_strdup("")); + } + } + else + { + list_add_item(values, (tbus)g_strdup(value)); + } + } + } + + free_stream(s); + return 0; + } + + in_it = 0; + in_it_index = 0; + g_memset(text, 0, 512); + } + else if (in_it) + { + text[in_it_index] = c; + in_it_index++; } - } - free_stream(s); - return 0; } - in_it = 0; - in_it_index = 0; - g_memset(text, 0, 512); - } - else if (in_it) - { - text[in_it_index] = c; - in_it_index++; - } } - } - free_stream(s); - return 1; + + free_stream(s); + return 1; } /*****************************************************************************/ @@ -285,9 +307,9 @@ l_file_read_section(int fd, int max_file_size, const char* section, returns 1 if problem reading file */ /* 32 K file size limit */ int APP_CC -file_read_sections(int fd, struct list* names) +file_read_sections(int fd, struct list *names) { - return l_file_read_sections(fd, 32 * 1024, names); + return l_file_read_sections(fd, 32 * 1024, names); } /*****************************************************************************/ @@ -295,35 +317,39 @@ file_read_sections(int fd, struct list* names) /* this function should be prefered over file_read_sections because it can read any file size */ int APP_CC -file_by_name_read_sections(const char* file_name, struct list* names) +file_by_name_read_sections(const char *file_name, struct list *names) { - int fd; - int file_size; - int rv; + int fd; + int file_size; + int rv; - file_size = g_file_get_size(file_name); - if (file_size < 1) - { - return 1; - } - fd = g_file_open(file_name); - if (fd < 1) - { - return 1; - } - rv = l_file_read_sections(fd, file_size, names); - g_file_close(fd); - return rv; + file_size = g_file_get_size(file_name); + + if (file_size < 1) + { + return 1; + } + + fd = g_file_open(file_name); + + if (fd < 1) + { + return 1; + } + + rv = l_file_read_sections(fd, file_size, names); + g_file_close(fd); + return rv; } /*****************************************************************************/ /* return error */ /* 32 K file size limit */ int APP_CC -file_read_section(int fd, const char* section, - struct list* names, struct list* values) +file_read_section(int fd, const char *section, + struct list *names, struct list *values) { - return l_file_read_section(fd, 32 * 1024, section, names, values); + return l_file_read_section(fd, 32 * 1024, section, names, values); } /*****************************************************************************/ @@ -331,24 +357,28 @@ file_read_section(int fd, const char* section, /* this function should be prefered over file_read_section because it can read any file size */ int APP_CC -file_by_name_read_section(const char* file_name, const char* section, - struct list* names, struct list* values) +file_by_name_read_section(const char *file_name, const char *section, + struct list *names, struct list *values) { - int fd; - int file_size; - int rv; + int fd; + int file_size; + int rv; - file_size = g_file_get_size(file_name); - if (file_size < 1) - { - return 1; - } - fd = g_file_open(file_name); - if (fd < 1) - { - return 1; - } - rv = l_file_read_section(fd, file_size, section, names, values); - g_file_close(fd); - return rv; + file_size = g_file_get_size(file_name); + + if (file_size < 1) + { + return 1; + } + + fd = g_file_open(file_name); + + if (fd < 1) + { + return 1; + } + + rv = l_file_read_section(fd, file_size, section, names, values); + g_file_close(fd); + return rv; } diff --git a/common/file.h b/common/file.h index f5345c4c..c6ce0654 100644 --- a/common/file.h +++ b/common/file.h @@ -1,26 +1,22 @@ -/* - Copyright (c) 2004-2010 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - read a config file -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * read a config file + */ #if !defined(FILE_H) #define FILE_H diff --git a/common/file_loc.h b/common/file_loc.h index acbdd2fc..db312fb4 100644 --- a/common/file_loc.h +++ b/common/file_loc.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - default file locations for log, config, etc - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * default file locations for log, config, etc + */ #if !defined(FILE_LOC_H) #define FILE_LOC_H diff --git a/common/list.c b/common/list.c index f67a08ab..0c27d596 100644 --- a/common/list.c +++ b/common/list.c @@ -1,217 +1,226 @@ -/* - Copyright (c) 2004-2010 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - simple list -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * simple list + */ #include "arch.h" #include "os_calls.h" #include "list.h" /*****************************************************************************/ -struct list* APP_CC +struct list *APP_CC list_create(void) { - struct list* self; + struct list *self; - self = (struct list*)g_malloc(sizeof(struct list), 1); - self->grow_by = 10; - self->alloc_size = 10; - self->items = (tbus*)g_malloc(sizeof(tbus) * 10, 1); - return self; + self = (struct list *)g_malloc(sizeof(struct list), 1); + self->grow_by = 10; + self->alloc_size = 10; + self->items = (tbus *)g_malloc(sizeof(tbus) * 10, 1); + return self; } /*****************************************************************************/ void APP_CC -list_delete(struct list* self) +list_delete(struct list *self) { - int i; + int i; - if (self == 0) - { - return; - } - if (self->auto_free) - { - for (i = 0; i < self->count; i++) + if (self == 0) { - g_free((void*)self->items[i]); - self->items[i] = 0; + return; } - } - g_free(self->items); - g_free(self); + + if (self->auto_free) + { + for (i = 0; i < self->count; i++) + { + g_free((void *)self->items[i]); + self->items[i] = 0; + } + } + + g_free(self->items); + g_free(self); } /*****************************************************************************/ void APP_CC -list_add_item(struct list* self, tbus item) +list_add_item(struct list *self, tbus item) { - tbus* p; - int i; + tbus *p; + int i; - if (self->count >= self->alloc_size) - { - i = self->alloc_size; - self->alloc_size += self->grow_by; - p = (tbus*)g_malloc(sizeof(tbus) * self->alloc_size, 1); - g_memcpy(p, self->items, sizeof(tbus) * i); - g_free(self->items); - self->items = p; - } - self->items[self->count] = item; - self->count++; + if (self->count >= self->alloc_size) + { + i = self->alloc_size; + self->alloc_size += self->grow_by; + p = (tbus *)g_malloc(sizeof(tbus) * self->alloc_size, 1); + g_memcpy(p, self->items, sizeof(tbus) * i); + g_free(self->items); + self->items = p; + } + + self->items[self->count] = item; + self->count++; } /*****************************************************************************/ tbus APP_CC -list_get_item(struct list* self, int index) +list_get_item(struct list *self, int index) { - if (index < 0 || index >= self->count) - { - return 0; - } - return self->items[index]; + if (index < 0 || index >= self->count) + { + return 0; + } + + return self->items[index]; } /*****************************************************************************/ void APP_CC -list_clear(struct list* self) +list_clear(struct list *self) { - int i; + int i; - if (self->auto_free) - { - for (i = 0; i < self->count; i++) + if (self->auto_free) { - g_free((void*)self->items[i]); - self->items[i] = 0; + for (i = 0; i < self->count; i++) + { + g_free((void *)self->items[i]); + self->items[i] = 0; + } } - } - g_free(self->items); - self->count = 0; - self->grow_by = 10; - self->alloc_size = 10; - self->items = (tbus*)g_malloc(sizeof(tbus) * 10, 1); + + g_free(self->items); + self->count = 0; + self->grow_by = 10; + self->alloc_size = 10; + self->items = (tbus *)g_malloc(sizeof(tbus) * 10, 1); } /*****************************************************************************/ int APP_CC -list_index_of(struct list* self, tbus item) +list_index_of(struct list *self, tbus item) { - int i; + int i; - for (i = 0; i < self->count; i++) - { - if (self->items[i] == item) + for (i = 0; i < self->count; i++) { - return i; + if (self->items[i] == item) + { + return i; + } } - } - return -1; + + return -1; } /*****************************************************************************/ void APP_CC -list_remove_item(struct list* self, int index) +list_remove_item(struct list *self, int index) { - int i; + int i; - if (index >= 0 && index < self->count) - { - if (self->auto_free) + if (index >= 0 && index < self->count) { - g_free((void*)self->items[index]); - self->items[index] = 0; + if (self->auto_free) + { + g_free((void *)self->items[index]); + self->items[index] = 0; + } + + for (i = index; i < (self->count - 1); i++) + { + self->items[i] = self->items[i + 1]; + } + + self->count--; } - for (i = index; i < (self->count - 1); i++) - { - self->items[i] = self->items[i + 1]; - } - self->count--; - } } /*****************************************************************************/ void APP_CC -list_insert_item(struct list* self, int index, tbus item) +list_insert_item(struct list *self, int index, tbus item) { - tbus* p; - int i; + tbus *p; + int i; - if (index == self->count) - { - list_add_item(self, item); - return; - } - if (index >= 0 && index < self->count) - { - self->count++; - if (self->count > self->alloc_size) + if (index == self->count) { - i = self->alloc_size; - self->alloc_size += self->grow_by; - p = (tbus*)g_malloc(sizeof(tbus) * self->alloc_size, 1); - g_memcpy(p, self->items, sizeof(tbus) * i); - g_free(self->items); - self->items = p; + list_add_item(self, item); + return; } - for (i = (self->count - 2); i >= index; i--) + + if (index >= 0 && index < self->count) { - self->items[i + 1] = self->items[i]; + self->count++; + + if (self->count > self->alloc_size) + { + i = self->alloc_size; + self->alloc_size += self->grow_by; + p = (tbus *)g_malloc(sizeof(tbus) * self->alloc_size, 1); + g_memcpy(p, self->items, sizeof(tbus) * i); + g_free(self->items); + self->items = p; + } + + for (i = (self->count - 2); i >= index; i--) + { + self->items[i + 1] = self->items[i]; + } + + self->items[index] = item; } - self->items[index] = item; - } } /*****************************************************************************/ /* append one list to another using strdup for each item in the list */ /* begins copy at start_index, a zero based index on the soure list */ void APP_CC -list_append_list_strdup(struct list* self, struct list* dest, int start_index) +list_append_list_strdup(struct list *self, struct list *dest, int start_index) { - int index; - tbus item; - char* dup; + int index; + tbus item; + char *dup; - for (index = start_index; index < self->count; index++) - { - item = list_get_item(self, index); - dup = g_strdup((char*)item); - list_add_item(dest, (tbus)dup); - } + for (index = start_index; index < self->count; index++) + { + item = list_get_item(self, index); + dup = g_strdup((char *)item); + list_add_item(dest, (tbus)dup); + } } /*****************************************************************************/ void APP_CC -list_dump_items(struct list* self) +list_dump_items(struct list *self) { - int index; + int index; - if (self->count == 0) - { - g_writeln("List is empty"); - } - for (index = 0; index < self->count; index++) - { - g_writeln("%d: %s", index, list_get_item(self, index)); - } + if (self->count == 0) + { + g_writeln("List is empty"); + } + + for (index = 0; index < self->count; index++) + { + g_writeln("%d: %s", index, list_get_item(self, index)); + } } diff --git a/common/list.h b/common/list.h index b7cd10b4..2c0f9339 100644 --- a/common/list.h +++ b/common/list.h @@ -1,26 +1,22 @@ -/* - Copyright (c) 2004-2010 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - simple list -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * simple list + */ #if !defined(LIST_H) #define LIST_H diff --git a/common/log.c b/common/log.c index 390b2bff..9b2e9289 100644 --- a/common/log.c +++ b/common/log.c @@ -1,25 +1,20 @@ -/* - Copyright (c) 2005-2012 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #include @@ -41,7 +36,7 @@ #include "log.h" /* Here we store the current state and configuration of the log */ -static struct log_config* staticLogConfig = NULL; +static struct log_config *staticLogConfig = NULL; /* This file first start with all private functions. In the end of the file the public functions is defined */ @@ -54,15 +49,17 @@ static struct log_config* staticLogConfig = NULL; * */ int DEFAULT_CC -internal_log_file_open(const char* fname) +internal_log_file_open(const char *fname) { - int ret = -1; - if (fname != NULL) - { - ret = open(fname, O_WRONLY | O_CREAT | O_APPEND | O_SYNC, - S_IRUSR | S_IWUSR); - } - return ret; + int ret = -1; + + if (fname != NULL) + { + ret = open(fname, O_WRONLY | O_CREAT | O_APPEND | O_SYNC, + S_IRUSR | S_IWUSR); + } + + return ret; } /** @@ -75,22 +72,22 @@ internal_log_file_open(const char* fname) int DEFAULT_CC internal_log_xrdp2syslog(const enum logLevels lvl) { - switch (lvl) - { - case LOG_LEVEL_ALWAYS: - return LOG_CRIT; - case LOG_LEVEL_ERROR: - return LOG_ERR; - case LOG_LEVEL_WARNING: - return LOG_WARNING; - case LOG_LEVEL_INFO: - return LOG_INFO; - case LOG_LEVEL_DEBUG: - return LOG_DEBUG; - default: - g_writeln("Undefined log level - programming error"); - return LOG_DEBUG; - } + switch (lvl) + { + case LOG_LEVEL_ALWAYS: + return LOG_CRIT; + case LOG_LEVEL_ERROR: + return LOG_ERR; + case LOG_LEVEL_WARNING: + return LOG_WARNING; + case LOG_LEVEL_INFO: + return LOG_INFO; + case LOG_LEVEL_DEBUG: + return LOG_DEBUG; + default: + g_writeln("Undefined log level - programming error"); + return LOG_DEBUG; + } } /** @@ -101,117 +98,121 @@ internal_log_xrdp2syslog(const enum logLevels lvl) * */ void DEFAULT_CC -internal_log_lvl2str(const enum logLevels lvl, char* str) +internal_log_lvl2str(const enum logLevels lvl, char *str) { - switch (lvl) - { - case LOG_LEVEL_ALWAYS: - snprintf(str, 9, "%s", "[CORE ] "); - break; - case LOG_LEVEL_ERROR: - snprintf(str, 9, "%s", "[ERROR] "); - break; - case LOG_LEVEL_WARNING: - snprintf(str, 9, "%s", "[WARN ] "); - break; - case LOG_LEVEL_INFO: - snprintf(str, 9, "%s", "[INFO ] "); - break; - case LOG_LEVEL_DEBUG: - snprintf(str, 9, "%s", "[DEBUG] "); - break; - default: - snprintf(str, 9, "%s", "PRG ERR!"); - g_writeln("Programming error - undefined log level!!!"); - } + switch (lvl) + { + case LOG_LEVEL_ALWAYS: + snprintf(str, 9, "%s", "[CORE ] "); + break; + case LOG_LEVEL_ERROR: + snprintf(str, 9, "%s", "[ERROR] "); + break; + case LOG_LEVEL_WARNING: + snprintf(str, 9, "%s", "[WARN ] "); + break; + case LOG_LEVEL_INFO: + snprintf(str, 9, "%s", "[INFO ] "); + break; + case LOG_LEVEL_DEBUG: + snprintf(str, 9, "%s", "[DEBUG] "); + break; + default: + snprintf(str, 9, "%s", "PRG ERR!"); + g_writeln("Programming error - undefined log level!!!"); + } } /******************************************************************************/ enum logReturns DEFAULT_CC -internal_log_start(struct log_config* l_cfg) +internal_log_start(struct log_config *l_cfg) { - enum logReturns ret = LOG_GENERAL_ERROR; - if (0 == l_cfg) - { - ret = LOG_ERROR_MALLOC; - return ret; - } + enum logReturns ret = LOG_GENERAL_ERROR; - /* if logfile is NULL, we return error */ - if (0 == l_cfg->log_file) - { - g_writeln("log_file not properly assigned"); - return ret; - } + if (0 == l_cfg) + { + ret = LOG_ERROR_MALLOC; + return ret; + } - /* if progname is NULL, we ureturn error */ - if (0 == l_cfg->program_name) - { - g_writeln("program_name not properly assigned"); - return ret; - } + /* if logfile is NULL, we return error */ + if (0 == l_cfg->log_file) + { + g_writeln("log_file not properly assigned"); + return ret; + } - /* open file */ - l_cfg->fd = internal_log_file_open(l_cfg->log_file); + /* if progname is NULL, we ureturn error */ + if (0 == l_cfg->program_name) + { + g_writeln("program_name not properly assigned"); + return ret; + } - if (-1 == l_cfg->fd) - { - return LOG_ERROR_FILE_OPEN; - } + /* open file */ + l_cfg->fd = internal_log_file_open(l_cfg->log_file); - /* if syslog is enabled, open it */ - if (l_cfg->enable_syslog) - { - openlog(l_cfg->program_name, LOG_CONS | LOG_PID, LOG_DAEMON); - } + if (-1 == l_cfg->fd) + { + return LOG_ERROR_FILE_OPEN; + } + + /* if syslog is enabled, open it */ + if (l_cfg->enable_syslog) + { + openlog(l_cfg->program_name, LOG_CONS | LOG_PID, LOG_DAEMON); + } #ifdef LOG_ENABLE_THREAD - pthread_mutexattr_init(&(l_cfg->log_lock_attr)); - pthread_mutex_init(&(l_cfg->log_lock), &(l_cfg->log_lock_attr)); + pthread_mutexattr_init(&(l_cfg->log_lock_attr)); + pthread_mutex_init(&(l_cfg->log_lock), &(l_cfg->log_lock_attr)); #endif - return LOG_STARTUP_OK; + return LOG_STARTUP_OK; } /******************************************************************************/ enum logReturns DEFAULT_CC -internal_log_end(struct log_config* l_cfg) +internal_log_end(struct log_config *l_cfg) { - enum logReturns ret = LOG_GENERAL_ERROR; - /* if log is closed, quit silently */ - if (0 == l_cfg) - { + enum logReturns ret = LOG_GENERAL_ERROR; + + /* if log is closed, quit silently */ + if (0 == l_cfg) + { + return ret; + } + + /* closing log file */ + log_message(LOG_LEVEL_ALWAYS, "shutting down log subsystem..."); + + if (0 > l_cfg->fd) + { + /* closing logfile... */ + g_file_close(l_cfg->fd); + } + + /* if syslog is enabled, close it */ + if (l_cfg->enable_syslog) + { + closelog(); + } + + /* freeing allocated memory */ + if (0 != l_cfg->log_file) + { + g_free(l_cfg->log_file); + l_cfg->log_file = 0; + } + + if (0 != l_cfg->program_name) + { + g_free(l_cfg->program_name); + l_cfg->program_name = 0; + } + + ret = LOG_STARTUP_OK; return ret; - } - - /* closing log file */ - log_message(LOG_LEVEL_ALWAYS, "shutting down log subsystem..."); - - if (0 > l_cfg->fd) - { - /* closing logfile... */ - g_file_close(l_cfg->fd); - } - - /* if syslog is enabled, close it */ - if (l_cfg->enable_syslog) - { - closelog(); - } - - /* freeing allocated memory */ - if (0 != l_cfg->log_file) - { - g_free(l_cfg->log_file); - l_cfg->log_file = 0; - } - if (0 != l_cfg->program_name) - { - g_free(l_cfg->program_name); - l_cfg->program_name = 0; - } - ret = LOG_STARTUP_OK; - return ret; } /** @@ -220,177 +221,192 @@ internal_log_end(struct log_config* l_cfg) * @return */ enum logLevels DEFAULT_CC -internal_log_text2level(char* buf) +internal_log_text2level(char *buf) { - if (0 == g_strcasecmp(buf, "0") || - 0 == g_strcasecmp(buf, "core")) - { - return LOG_LEVEL_ALWAYS; - } - else if (0 == g_strcasecmp(buf, "1") || - 0 == g_strcasecmp(buf, "error")) - { - return LOG_LEVEL_ERROR; - } - else if (0 == g_strcasecmp(buf, "2") || - 0 == g_strcasecmp(buf, "warn") || - 0 == g_strcasecmp(buf, "warning")) - { - return LOG_LEVEL_WARNING; - } - else if (0 == g_strcasecmp(buf, "3") || - 0 == g_strcasecmp(buf, "info")) - { - return LOG_LEVEL_INFO; - } - else if (0 == g_strcasecmp(buf, "4") || - 0 == g_strcasecmp(buf, "debug")) - { + if (0 == g_strcasecmp(buf, "0") || + 0 == g_strcasecmp(buf, "core")) + { + return LOG_LEVEL_ALWAYS; + } + else if (0 == g_strcasecmp(buf, "1") || + 0 == g_strcasecmp(buf, "error")) + { + return LOG_LEVEL_ERROR; + } + else if (0 == g_strcasecmp(buf, "2") || + 0 == g_strcasecmp(buf, "warn") || + 0 == g_strcasecmp(buf, "warning")) + { + return LOG_LEVEL_WARNING; + } + else if (0 == g_strcasecmp(buf, "3") || + 0 == g_strcasecmp(buf, "info")) + { + return LOG_LEVEL_INFO; + } + else if (0 == g_strcasecmp(buf, "4") || + 0 == g_strcasecmp(buf, "debug")) + { + return LOG_LEVEL_DEBUG; + } + + g_writeln("Your configured log level is corrupt - we use debug log level"); return LOG_LEVEL_DEBUG; - } - g_writeln("Your configured log level is corrupt - we use debug log level"); - return LOG_LEVEL_DEBUG; } enum logReturns DEFAULT_CC -internalReadConfiguration(const char* inFilename, const char* applicationName) +internalReadConfiguration(const char *inFilename, const char *applicationName) { - int fd; - enum logReturns ret = LOG_GENERAL_ERROR; - struct list* sec; - struct list* param_n; - struct list* param_v; + int fd; + enum logReturns ret = LOG_GENERAL_ERROR; + struct list *sec; + struct list *param_n; + struct list *param_v; - if (inFilename == NULL) - { - g_writeln("The inifile is null to readConfiguration!"); - return ret; - } - fd = g_file_open(inFilename); - if (-1 == fd) - { - ret = LOG_ERROR_NO_CFG; - g_writeln("We could not open the configuration file to read log parameters"); - return ret; - } - /* we initialize the memory for the configuration and set all content - to zero. */ - ret = internalInitAndAllocStruct(); - if (ret != LOG_STARTUP_OK) - { - return ret; - } + if (inFilename == NULL) + { + g_writeln("The inifile is null to readConfiguration!"); + return ret; + } - sec = list_create(); - sec->auto_free = 1; - file_read_sections(fd, sec); - param_n = list_create(); - param_n->auto_free = 1; - param_v = list_create(); - param_v->auto_free = 1; + fd = g_file_open(inFilename); - /* read logging config */ - ret = internal_config_read_logging(fd, staticLogConfig, param_n, - param_v, applicationName); - if (ret != LOG_STARTUP_OK) - { + if (-1 == fd) + { + ret = LOG_ERROR_NO_CFG; + g_writeln("We could not open the configuration file to read log parameters"); + return ret; + } + + /* we initialize the memory for the configuration and set all content + to zero. */ + ret = internalInitAndAllocStruct(); + + if (ret != LOG_STARTUP_OK) + { + return ret; + } + + sec = list_create(); + sec->auto_free = 1; + file_read_sections(fd, sec); + param_n = list_create(); + param_n->auto_free = 1; + param_v = list_create(); + param_v->auto_free = 1; + + /* read logging config */ + ret = internal_config_read_logging(fd, staticLogConfig, param_n, + param_v, applicationName); + + if (ret != LOG_STARTUP_OK) + { + return ret; + } + + /* cleanup */ + list_delete(sec); + list_delete(param_v); + list_delete(param_n); + g_file_close(fd); return ret; - } - /* cleanup */ - list_delete(sec); - list_delete(param_v); - list_delete(param_n); - g_file_close(fd); - return ret; } /******************************************************************************/ enum logReturns DEFAULT_CC -internal_config_read_logging(int file, struct log_config* lc, - struct list* param_n, - struct list* param_v, - const char* applicationName) +internal_config_read_logging(int file, struct log_config *lc, + struct list *param_n, + struct list *param_v, + const char *applicationName) { - int i; - char* buf; - char* temp_buf; + int i; + char *buf; + char *temp_buf; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - /* setting defaults */ - lc->program_name = g_strdup(applicationName); - lc->log_file = 0; - lc->fd = 0; - lc->log_level = LOG_LEVEL_DEBUG; - lc->enable_syslog = 0; - lc->syslog_level = LOG_LEVEL_DEBUG; + /* setting defaults */ + lc->program_name = g_strdup(applicationName); + lc->log_file = 0; + lc->fd = 0; + lc->log_level = LOG_LEVEL_DEBUG; + lc->enable_syslog = 0; + lc->syslog_level = LOG_LEVEL_DEBUG; - file_read_section(file, SESMAN_CFG_LOGGING, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - buf = (char*)list_get_item(param_n, i); - if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_FILE)) + file_read_section(file, SESMAN_CFG_LOGGING, param_n, param_v); + + for (i = 0; i < param_n->count; i++) { - lc->log_file = g_strdup((char*)list_get_item(param_v, i)); - if (lc->log_file != NULL) - { - if (lc->log_file[0] != '/') + buf = (char *)list_get_item(param_n, i); + + if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_FILE)) { - temp_buf = (char*)g_malloc(512, 0); - g_snprintf(temp_buf, 511, "%s/%s", XRDP_LOG_PATH, lc->log_file); - g_free(lc->log_file); - lc->log_file = temp_buf; + lc->log_file = g_strdup((char *)list_get_item(param_v, i)); + + if (lc->log_file != NULL) + { + if (lc->log_file[0] != '/') + { + temp_buf = (char *)g_malloc(512, 0); + g_snprintf(temp_buf, 511, "%s/%s", XRDP_LOG_PATH, lc->log_file); + g_free(lc->log_file); + lc->log_file = temp_buf; + } + } } - } - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_LEVEL)) - { - lc->log_level = internal_log_text2level((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_SYSLOG)) - { - lc->enable_syslog = text2bool((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_SYSLOG_LEVEL)) - { - lc->syslog_level = internal_log_text2level((char*)list_get_item(param_v, i)); - } - } - if (0 == lc->log_file) - { - lc->log_file = g_strdup("./sesman.log"); - } + if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_LEVEL)) + { + lc->log_level = internal_log_text2level((char *)list_get_item(param_v, i)); + } - /* try to create path if not exist */ - g_create_path(lc->log_file); + if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_SYSLOG)) + { + lc->enable_syslog = text2bool((char *)list_get_item(param_v, i)); + } - g_printf("logging configuration:\r\n"); - g_printf("\tLogFile: %s\r\n", lc->log_file); - g_printf("\tLogLevel: %i\r\n", lc->log_level); - g_printf("\tEnableSyslog: %i\r\n", lc->enable_syslog); - g_printf("\tSyslogLevel: %i\r\n", lc->syslog_level); - return LOG_STARTUP_OK; + if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_SYSLOG_LEVEL)) + { + lc->syslog_level = internal_log_text2level((char *)list_get_item(param_v, i)); + } + } + + if (0 == lc->log_file) + { + lc->log_file = g_strdup("./sesman.log"); + } + + /* try to create path if not exist */ + g_create_path(lc->log_file); + + g_printf("logging configuration:\r\n"); + g_printf("\tLogFile: %s\r\n", lc->log_file); + g_printf("\tLogLevel: %i\r\n", lc->log_level); + g_printf("\tEnableSyslog: %i\r\n", lc->enable_syslog); + g_printf("\tSyslogLevel: %i\r\n", lc->syslog_level); + return LOG_STARTUP_OK; } enum logReturns DEFAULT_CC internalInitAndAllocStruct(void) { - enum logReturns ret = LOG_GENERAL_ERROR; - staticLogConfig = g_malloc(sizeof(struct log_config), 1); - if (staticLogConfig != NULL) - { - staticLogConfig->fd = -1; - staticLogConfig->enable_syslog = 0; - ret = LOG_STARTUP_OK; - } - else - { - g_writeln("could not allocate memory for log struct"); - ret = LOG_ERROR_MALLOC; - } - return ret; + enum logReturns ret = LOG_GENERAL_ERROR; + staticLogConfig = g_malloc(sizeof(struct log_config), 1); + + if (staticLogConfig != NULL) + { + staticLogConfig->fd = -1; + staticLogConfig->enable_syslog = 0; + ret = LOG_STARTUP_OK; + } + else + { + g_writeln("could not allocate memory for log struct"); + ret = LOG_ERROR_MALLOC; + } + + return ret; } /* @@ -406,60 +422,68 @@ internalInitAndAllocStruct(void) * */ int APP_CC -text2bool(char* s) +text2bool(char *s) { - if (0 == g_strcasecmp(s, "1") || - 0 == g_strcasecmp(s, "true") || - 0 == g_strcasecmp(s, "yes")) - { - return 1; - } - return 0; + if (0 == g_strcasecmp(s, "1") || + 0 == g_strcasecmp(s, "true") || + 0 == g_strcasecmp(s, "yes")) + { + return 1; + } + + return 0; } enum logReturns DEFAULT_CC -log_start_from_param(const struct log_config* iniParams) +log_start_from_param(const struct log_config *iniParams) { - enum logReturns ret = LOG_GENERAL_ERROR; - if (staticLogConfig != NULL) - { - log_message(LOG_LEVEL_ALWAYS, "Log already initialized"); - return ret; - } - if (iniParams == NULL) - { - g_writeln("inparam to log_start_from_param is NULL"); - return ret; - } - else - { - /*Copy the struct information*/ - ret = internalInitAndAllocStruct(); - if (ret != LOG_STARTUP_OK) + enum logReturns ret = LOG_GENERAL_ERROR; + + if (staticLogConfig != NULL) { - g_writeln("internalInitAndAllocStruct failed"); - return ret; + log_message(LOG_LEVEL_ALWAYS, "Log already initialized"); + return ret; } - staticLogConfig->enable_syslog = iniParams->enable_syslog; - staticLogConfig->fd = iniParams->fd; - staticLogConfig->log_file = g_strdup(iniParams->log_file); - staticLogConfig->log_level = iniParams->log_level; - staticLogConfig->log_lock = iniParams->log_lock; - staticLogConfig->log_lock_attr = iniParams->log_lock_attr; - staticLogConfig->program_name = g_strdup(iniParams->program_name); - staticLogConfig->syslog_level = iniParams->syslog_level; - ret = internal_log_start(staticLogConfig); - if (ret != LOG_STARTUP_OK) + + if (iniParams == NULL) { - g_writeln("Could not start log"); - if (staticLogConfig != NULL) - { - g_free(staticLogConfig); - staticLogConfig = NULL; - } + g_writeln("inparam to log_start_from_param is NULL"); + return ret; } - } - return ret; + else + { + /*Copy the struct information*/ + ret = internalInitAndAllocStruct(); + + if (ret != LOG_STARTUP_OK) + { + g_writeln("internalInitAndAllocStruct failed"); + return ret; + } + + staticLogConfig->enable_syslog = iniParams->enable_syslog; + staticLogConfig->fd = iniParams->fd; + staticLogConfig->log_file = g_strdup(iniParams->log_file); + staticLogConfig->log_level = iniParams->log_level; + staticLogConfig->log_lock = iniParams->log_lock; + staticLogConfig->log_lock_attr = iniParams->log_lock_attr; + staticLogConfig->program_name = g_strdup(iniParams->program_name); + staticLogConfig->syslog_level = iniParams->syslog_level; + ret = internal_log_start(staticLogConfig); + + if (ret != LOG_STARTUP_OK) + { + g_writeln("Could not start log"); + + if (staticLogConfig != NULL) + { + g_free(staticLogConfig); + staticLogConfig = NULL; + } + } + } + + return ret; } /** @@ -470,34 +494,40 @@ log_start_from_param(const struct log_config* iniParams) * @return 0 on success */ enum logReturns DEFAULT_CC -log_start(const char* iniFile, const char* applicationName) +log_start(const char *iniFile, const char *applicationName) { - enum logReturns ret = LOG_GENERAL_ERROR; - if (applicationName == NULL) - { - g_writeln("Programming error your application name cannot be null"); - return ret; - } - ret = internalReadConfiguration(iniFile, applicationName); - if (ret == LOG_STARTUP_OK) - { - ret = internal_log_start(staticLogConfig); - if (ret != LOG_STARTUP_OK) + enum logReturns ret = LOG_GENERAL_ERROR; + + if (applicationName == NULL) { - g_writeln("Could not start log"); - if (staticLogConfig != NULL) - { - g_free(staticLogConfig); - staticLogConfig = NULL; - } + g_writeln("Programming error your application name cannot be null"); + return ret; } - } - else - { - g_writeln("Error reading configuration for log based on config: %s", - iniFile); - } - return ret; + + ret = internalReadConfiguration(iniFile, applicationName); + + if (ret == LOG_STARTUP_OK) + { + ret = internal_log_start(staticLogConfig); + + if (ret != LOG_STARTUP_OK) + { + g_writeln("Could not start log"); + + if (staticLogConfig != NULL) + { + g_free(staticLogConfig); + staticLogConfig = NULL; + } + } + } + else + { + g_writeln("Error reading configuration for log based on config: %s", + iniFile); + } + + return ret; } /** @@ -507,123 +537,132 @@ log_start(const char* iniFile, const char* applicationName) enum logReturns DEFAULT_CC log_end(void) { - enum logReturns ret = LOG_GENERAL_ERROR; - ret = internal_log_end(staticLogConfig); - if (staticLogConfig != NULL) - { - g_free(staticLogConfig); - staticLogConfig = NULL; - } - return ret; + enum logReturns ret = LOG_GENERAL_ERROR; + ret = internal_log_end(staticLogConfig); + + if (staticLogConfig != NULL) + { + g_free(staticLogConfig); + staticLogConfig = NULL; + } + + return ret; } enum logReturns DEFAULT_CC -log_message(const enum logLevels lvl, const char* msg, ...) +log_message(const enum logLevels lvl, const char *msg, ...) { - char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */ - va_list ap; - int len = 0; - enum logReturns rv = LOG_STARTUP_OK; - int writereply = 0; - time_t now_t; - struct tm* now; - if (staticLogConfig == NULL) - { - g_writeln("The log reference is NULL - log not initialized properly"); - return LOG_ERROR_NO_CFG; - } - if (0 > staticLogConfig->fd && staticLogConfig->enable_syslog == 0) - { - return LOG_ERROR_FILE_NOT_OPEN; - } + char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */ + va_list ap; + int len = 0; + enum logReturns rv = LOG_STARTUP_OK; + int writereply = 0; + time_t now_t; + struct tm *now; - now_t = time(&now_t); - now = localtime(&now_t); + if (staticLogConfig == NULL) + { + g_writeln("The log reference is NULL - log not initialized properly"); + return LOG_ERROR_NO_CFG; + } - snprintf(buff, 21, "[%.4d%.2d%.2d-%.2d:%.2d:%.2d] ", now->tm_year + 1900, - now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, - now->tm_sec); + if (0 > staticLogConfig->fd && staticLogConfig->enable_syslog == 0) + { + return LOG_ERROR_FILE_NOT_OPEN; + } - internal_log_lvl2str(lvl, buff + 20); + now_t = time(&now_t); + now = localtime(&now_t); - va_start(ap, msg); - len = vsnprintf(buff + 28, LOG_BUFFER_SIZE, msg, ap); - va_end(ap); + snprintf(buff, 21, "[%.4d%.2d%.2d-%.2d:%.2d:%.2d] ", now->tm_year + 1900, + now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, + now->tm_sec); - /* checking for truncated messages */ - if (len > LOG_BUFFER_SIZE) - { - log_message(LOG_LEVEL_WARNING, "next message will be truncated"); - } + internal_log_lvl2str(lvl, buff + 20); - /* forcing the end of message string */ + va_start(ap, msg); + len = vsnprintf(buff + 28, LOG_BUFFER_SIZE, msg, ap); + va_end(ap); + + /* checking for truncated messages */ + if (len > LOG_BUFFER_SIZE) + { + log_message(LOG_LEVEL_WARNING, "next message will be truncated"); + } + + /* forcing the end of message string */ #ifdef _WIN32 - buff[len + 28] = '\r'; - buff[len + 29] = '\n'; - buff[len + 30] = '\0'; + buff[len + 28] = '\r'; + buff[len + 29] = '\n'; + buff[len + 30] = '\0'; #else #ifdef _MACOS - buff[len + 28] = '\r'; - buff[len + 29] = '\0'; + buff[len + 28] = '\r'; + buff[len + 29] = '\0'; #else - buff[len + 28] = '\n'; - buff[len + 29] = '\0'; + buff[len + 28] = '\n'; + buff[len + 29] = '\0'; #endif #endif - if (staticLogConfig->enable_syslog && (lvl <= staticLogConfig->syslog_level)) - { - /* log to syslog*/ - /* %s fix compiler warning 'not a string literal' */ - syslog(internal_log_xrdp2syslog(lvl), "(%d)(%ld)%s", g_getpid(), - tc_get_threadid(), buff + 20); - } - - if (lvl <= staticLogConfig->log_level) - { - /* log to console */ - g_printf(buff); - - /* log to application logfile */ -#ifdef LOG_ENABLE_THREAD - pthread_mutex_lock(&(staticLogConfig->log_lock)); -#endif - if (staticLogConfig->fd > 0) + if (staticLogConfig->enable_syslog && (lvl <= staticLogConfig->syslog_level)) { - writereply = g_file_write(staticLogConfig->fd, buff, g_strlen(buff)); - if (writereply <= 0) - { - rv = LOG_ERROR_NULL_FILE; - } + /* log to syslog*/ + /* %s fix compiler warning 'not a string literal' */ + syslog(internal_log_xrdp2syslog(lvl), "(%d)(%ld)%s", g_getpid(), + tc_get_threadid(), buff + 20); } + + if (lvl <= staticLogConfig->log_level) + { + /* log to console */ + g_printf(buff); + + /* log to application logfile */ #ifdef LOG_ENABLE_THREAD - pthread_mutex_unlock(&(staticLogConfig->log_lock)); + pthread_mutex_lock(&(staticLogConfig->log_lock)); #endif - } - return rv; + + if (staticLogConfig->fd > 0) + { + writereply = g_file_write(staticLogConfig->fd, buff, g_strlen(buff)); + + if (writereply <= 0) + { + rv = LOG_ERROR_NULL_FILE; + } + } + +#ifdef LOG_ENABLE_THREAD + pthread_mutex_unlock(&(staticLogConfig->log_lock)); +#endif + } + + return rv; } /** * Return the configured log file name * @return */ -char* DEFAULT_CC -getLogFile(char* replybuf, int bufsize) +char *DEFAULT_CC +getLogFile(char *replybuf, int bufsize) { - if (staticLogConfig) - { - if (staticLogConfig->log_file) + if (staticLogConfig) { - g_strncpy(replybuf, staticLogConfig->log_file, bufsize); + if (staticLogConfig->log_file) + { + g_strncpy(replybuf, staticLogConfig->log_file, bufsize); + } + else + { + g_sprintf(replybuf, "The log_file name is NULL"); + } } else { - g_sprintf(replybuf, "The log_file name is NULL"); + g_snprintf(replybuf, bufsize, "The log is not properly started"); } - } - else - { - g_snprintf(replybuf, bufsize, "The log is not properly started"); - } - return replybuf; + + return replybuf; } diff --git a/common/log.h b/common/log.h index cc355b18..c83a34d3 100644 --- a/common/log.h +++ b/common/log.h @@ -1,25 +1,20 @@ -/* - Copyright (c) 2005-2012 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef LOG_H #define LOG_H diff --git a/common/os_calls.c b/common/os_calls.c index 6b55f2f7..20c84f3e 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -1,28 +1,24 @@ -/* - Copyright (c) 2004-2012 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - generic operating system calls - - put all the os / arch define in here you want -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * generic operating system calls + * + * put all the os / arch define in here you want + */ #if defined(HAVE_CONFIG_H) #include "config_ac.h" @@ -68,7 +64,7 @@ /* for clearenv() */ #if defined(_WIN32) #else -extern char** environ; +extern char **environ; #endif #if defined(__linux__) @@ -90,77 +86,85 @@ static char g_temp_base_org[128] = ""; int APP_CC g_rm_temp_dir(void) { - if (g_temp_base[0] != 0) - { - if (!g_remove_dir(g_temp_base)) + if (g_temp_base[0] != 0) { - printf("g_rm_temp_dir: removing temp directory [%s] failed\n", g_temp_base); + if (!g_remove_dir(g_temp_base)) + { + printf("g_rm_temp_dir: removing temp directory [%s] failed\n", g_temp_base); + } + + g_temp_base[0] = 0; } - g_temp_base[0] = 0; - } - return 0; + + return 0; } /*****************************************************************************/ int APP_CC -g_mk_temp_dir(const char* app_name) +g_mk_temp_dir(const char *app_name) { - if (app_name != 0) - { - if (app_name[0] != 0) + if (app_name != 0) { - if (!g_directory_exist("/tmp/.xrdp")) - { - if (!g_create_dir("/tmp/.xrdp")) + if (app_name[0] != 0) { - printf("g_mk_temp_dir: g_create_dir failed\n"); - return 1; + if (!g_directory_exist("/tmp/.xrdp")) + { + if (!g_create_dir("/tmp/.xrdp")) + { + printf("g_mk_temp_dir: g_create_dir failed\n"); + return 1; + } + + g_chmod_hex("/tmp/.xrdp", 0x1777); + } + + snprintf(g_temp_base, sizeof(g_temp_base), + "/tmp/.xrdp/%s-XXXXXX", app_name); + snprintf(g_temp_base_org, sizeof(g_temp_base_org), + "/tmp/.xrdp/%s-XXXXXX", app_name); + + if (mkdtemp(g_temp_base) == 0) + { + printf("g_mk_temp_dir: mkdtemp failed [%s]\n", g_temp_base); + return 1; + } + } + else + { + printf("g_mk_temp_dir: bad app name\n"); + return 1; } - g_chmod_hex("/tmp/.xrdp", 0x1777); - } - snprintf(g_temp_base, sizeof(g_temp_base), - "/tmp/.xrdp/%s-XXXXXX", app_name); - snprintf(g_temp_base_org, sizeof(g_temp_base_org), - "/tmp/.xrdp/%s-XXXXXX", app_name); - if (mkdtemp(g_temp_base) == 0) - { - printf("g_mk_temp_dir: mkdtemp failed [%s]\n", g_temp_base); - return 1; - } } else { - printf("g_mk_temp_dir: bad app name\n"); - return 1; + if (g_temp_base_org[0] == 0) + { + printf("g_mk_temp_dir: g_temp_base_org not set\n"); + return 1; + } + + g_strncpy(g_temp_base, g_temp_base_org, 127); + + if (mkdtemp(g_temp_base) == 0) + { + printf("g_mk_temp_dir: mkdtemp failed [%s]\n", g_temp_base); + } } - } - else - { - if (g_temp_base_org[0] == 0) - { - printf("g_mk_temp_dir: g_temp_base_org not set\n"); - return 1; - } - g_strncpy(g_temp_base, g_temp_base_org, 127); - if (mkdtemp(g_temp_base) == 0) - { - printf("g_mk_temp_dir: mkdtemp failed [%s]\n", g_temp_base); - } - } - return 0; + + return 0; } /*****************************************************************************/ void APP_CC -g_init(const char* app_name) +g_init(const char *app_name) { #if defined(_WIN32) - WSADATA wsadata; + WSADATA wsadata; - WSAStartup(2, &wsadata); + WSAStartup(2, &wsadata); #endif - setlocale(LC_CTYPE, ""); - g_mk_temp_dir(app_name); + setlocale(LC_CTYPE, ""); + g_mk_temp_dir(app_name); } /*****************************************************************************/ @@ -168,160 +172,168 @@ void APP_CC g_deinit(void) { #if defined(_WIN32) - WSACleanup(); + WSACleanup(); #endif - g_rm_temp_dir(); + g_rm_temp_dir(); } /*****************************************************************************/ /* allocate memory, returns a pointer to it, size bytes are allocated, if zero is non zero, each byte will be set to zero */ -void* APP_CC +void *APP_CC g_malloc(int size, int zero) { - char* rv; + char *rv; - rv = (char*)malloc(size); - if (zero) - { - if (rv != 0) + rv = (char *)malloc(size); + + if (zero) { - memset(rv, 0, size); + if (rv != 0) + { + memset(rv, 0, size); + } } - } - return rv; + + return rv; } /*****************************************************************************/ /* free the memory pointed to by ptr, ptr can be zero */ void APP_CC -g_free(void* ptr) +g_free(void *ptr) { - if (ptr != 0) - { - free(ptr); - } + if (ptr != 0) + { + free(ptr); + } } /*****************************************************************************/ /* output text to stdout, try to use g_write / g_writeln instead to avoid linux / windows EOL problems */ void DEFAULT_CC -g_printf(const char* format, ...) +g_printf(const char *format, ...) { - va_list ap; + va_list ap; - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); } /*****************************************************************************/ void DEFAULT_CC -g_sprintf(char* dest, const char* format, ...) +g_sprintf(char *dest, const char *format, ...) { - va_list ap; + va_list ap; - va_start(ap, format); - vsprintf(dest, format, ap); - va_end(ap); + va_start(ap, format); + vsprintf(dest, format, ap); + va_end(ap); } /*****************************************************************************/ void DEFAULT_CC -g_snprintf(char* dest, int len, const char* format, ...) +g_snprintf(char *dest, int len, const char *format, ...) { - va_list ap; + va_list ap; - va_start(ap, format); - vsnprintf(dest, len, format, ap); - va_end(ap); + va_start(ap, format); + vsnprintf(dest, len, format, ap); + va_end(ap); } /*****************************************************************************/ void DEFAULT_CC -g_writeln(const char* format, ...) +g_writeln(const char *format, ...) { - va_list ap; + va_list ap; - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); #if defined(_WIN32) - g_printf("\r\n"); + g_printf("\r\n"); #else - g_printf("\n"); + g_printf("\n"); #endif } /*****************************************************************************/ void DEFAULT_CC -g_write(const char* format, ...) +g_write(const char *format, ...) { - va_list ap; + va_list ap; - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); } /*****************************************************************************/ /* produce a hex dump */ void APP_CC -g_hexdump(char* p, int len) +g_hexdump(char *p, int len) { - unsigned char* line; - int i; - int thisline; - int offset; + unsigned char *line; + int i; + int thisline; + int offset; - line = (unsigned char*)p; - offset = 0; - while (offset < len) - { - g_printf("%04x ", offset); - thisline = len - offset; - if (thisline > 16) + line = (unsigned char *)p; + offset = 0; + + while (offset < len) { - thisline = 16; + g_printf("%04x ", offset); + thisline = len - offset; + + if (thisline > 16) + { + thisline = 16; + } + + for (i = 0; i < thisline; i++) + { + g_printf("%02x ", line[i]); + } + + for (; i < 16; i++) + { + g_printf(" "); + } + + for (i = 0; i < thisline; i++) + { + g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); + } + + g_writeln(""); + offset += thisline; + line += thisline; } - for (i = 0; i < thisline; i++) - { - g_printf("%02x ", line[i]); - } - for (; i < 16; i++) - { - g_printf(" "); - } - for (i = 0; i < thisline; i++) - { - g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); - } - g_writeln(""); - offset += thisline; - line += thisline; - } } /*****************************************************************************/ void APP_CC -g_memset(void* ptr, int val, int size) +g_memset(void *ptr, int val, int size) { - memset(ptr, val, size); + memset(ptr, val, size); } /*****************************************************************************/ void APP_CC -g_memcpy(void* d_ptr, const void* s_ptr, int size) +g_memcpy(void *d_ptr, const void *s_ptr, int size) { - memcpy(d_ptr, s_ptr, size); + memcpy(d_ptr, s_ptr, size); } /*****************************************************************************/ int APP_CC g_getchar(void) { - return getchar(); + return getchar(); } /*****************************************************************************/ @@ -329,40 +341,43 @@ g_getchar(void) int APP_CC g_tcp_set_no_delay(int sck) { - int ret = 1; /* error */ + int ret = 1; /* error */ #if defined(_WIN32) - int option_value; - int option_len; + int option_value; + int option_len; #else - int option_value; - unsigned int option_len; + int option_value; + unsigned int option_len; #endif - option_len = sizeof(option_value); - /* SOL_TCP IPPROTO_TCP */ - if (getsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value, - &option_len) == 0) - { - if (option_value == 0) + option_len = sizeof(option_value); + + /* SOL_TCP IPPROTO_TCP */ + if (getsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char *)&option_value, + &option_len) == 0) { - option_value = 1; - option_len = sizeof(option_value); - if (setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value, - option_len) == 0) - { - ret = 0; /* success */ - } - else - { - g_writeln("Error setting tcp_nodelay"); - } + if (option_value == 0) + { + option_value = 1; + option_len = sizeof(option_value); + + if (setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char *)&option_value, + option_len) == 0) + { + ret = 0; /* success */ + } + else + { + g_writeln("Error setting tcp_nodelay"); + } + } } - } - else - { - g_writeln("Error getting tcp_nodelay"); - } - return ret; + else + { + g_writeln("Error getting tcp_nodelay"); + } + + return ret; } /*****************************************************************************/ @@ -370,40 +385,43 @@ g_tcp_set_no_delay(int sck) int APP_CC g_tcp_set_keepalive(int sck) { - int ret = 1; /* error */ + int ret = 1; /* error */ #if defined(_WIN32) - int option_value; - int option_len; + int option_value; + int option_len; #else - int option_value; - unsigned int option_len; + int option_value; + unsigned int option_len; #endif - option_len = sizeof(option_value); - /* SOL_TCP IPPROTO_TCP */ - if (getsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char*)&option_value, - &option_len) == 0) - { - if (option_value == 0) + option_len = sizeof(option_value); + + /* SOL_TCP IPPROTO_TCP */ + if (getsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char *)&option_value, + &option_len) == 0) { - option_value = 1; - option_len = sizeof(option_value); - if (setsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char*)&option_value, - option_len) == 0) - { - ret = 0; /* success */ - } - else - { - g_writeln("Error setting tcp_keepalive"); - } + if (option_value == 0) + { + option_value = 1; + option_len = sizeof(option_value); + + if (setsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char *)&option_value, + option_len) == 0) + { + ret = 0; /* success */ + } + else + { + g_writeln("Error setting tcp_keepalive"); + } + } } - } - else - { - g_writeln("Error getting tcp_keepalive"); - } - return ret; + else + { + g_writeln("Error getting tcp_keepalive"); + } + + return ret; } /*****************************************************************************/ @@ -412,46 +430,52 @@ int APP_CC g_tcp_socket(void) { #if defined(_WIN32) - int rv; - int option_value; - int option_len; + int rv; + int option_value; + int option_len; #else - int rv; - int option_value; - unsigned int option_len; + int rv; + int option_value; + unsigned int option_len; #endif - /* in win32 a socket is an unsigned int, in linux, its an int */ - rv = (int)socket(PF_INET, SOCK_STREAM, 0); - if (rv < 0) - { - return -1; - } - option_len = sizeof(option_value); - if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char*)&option_value, - &option_len) == 0) - { - if (option_value == 0) + /* in win32 a socket is an unsigned int, in linux, its an int */ + rv = (int)socket(PF_INET, SOCK_STREAM, 0); + + if (rv < 0) { - option_value = 1; - option_len = sizeof(option_value); - setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char*)&option_value, - option_len); + return -1; } - } - option_len = sizeof(option_value); - if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char*)&option_value, - &option_len) == 0) - { - if (option_value < (1024 * 32)) + + option_len = sizeof(option_value); + + if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value, + &option_len) == 0) { - option_value = 1024 * 32; - option_len = sizeof(option_value); - setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char*)&option_value, - option_len); + if (option_value == 0) + { + option_value = 1; + option_len = sizeof(option_value); + setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value, + option_len); + } } - } - return rv; + + option_len = sizeof(option_value); + + if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, + &option_len) == 0) + { + if (option_value < (1024 * 32)) + { + option_value = 1024 * 32; + option_len = sizeof(option_value); + setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, + option_len); + } + } + + return rv; } /*****************************************************************************/ @@ -459,9 +483,9 @@ int APP_CC g_tcp_local_socket(void) { #if defined(_WIN32) - return 0; + return 0; #else - return socket(PF_LOCAL, SOCK_STREAM, 0); + return socket(PF_LOCAL, SOCK_STREAM, 0); #endif } @@ -469,63 +493,67 @@ g_tcp_local_socket(void) void APP_CC g_tcp_close(int sck) { - if (sck == 0) - { - return; - } + if (sck == 0) + { + return; + } + #if defined(_WIN32) - closesocket(sck); + closesocket(sck); #else - close(sck); + close(sck); #endif } /*****************************************************************************/ /* returns error, zero is good */ int APP_CC -g_tcp_connect(int sck, const char* address, const char* port) +g_tcp_connect(int sck, const char *address, const char *port) { - struct sockaddr_in s; - struct hostent* h; + struct sockaddr_in s; + struct hostent *h; - g_memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons((tui16)atoi(port)); - s.sin_addr.s_addr = inet_addr(address); - if (s.sin_addr.s_addr == INADDR_NONE) - { - h = gethostbyname(address); - if (h != 0) + g_memset(&s, 0, sizeof(struct sockaddr_in)); + s.sin_family = AF_INET; + s.sin_port = htons((tui16)atoi(port)); + s.sin_addr.s_addr = inet_addr(address); + + if (s.sin_addr.s_addr == INADDR_NONE) { - if (h->h_name != 0) - { - if (h->h_addr_list != 0) + h = gethostbyname(address); + + if (h != 0) { - if ((*(h->h_addr_list)) != 0) - { - s.sin_addr.s_addr = *((int*)(*(h->h_addr_list))); - } + if (h->h_name != 0) + { + if (h->h_addr_list != 0) + { + if ((*(h->h_addr_list)) != 0) + { + s.sin_addr.s_addr = *((int *)(*(h->h_addr_list))); + } + } + } } - } } - } - return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); + + return connect(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_in)); } /*****************************************************************************/ /* returns error, zero is good */ int APP_CC -g_tcp_local_connect(int sck, const char* port) +g_tcp_local_connect(int sck, const char *port) { #if defined(_WIN32) - return -1; + return -1; #else - struct sockaddr_un s; + struct sockaddr_un s; - memset(&s, 0, sizeof(struct sockaddr_un)); - s.sun_family = AF_UNIX; - strcpy(s.sun_path, port); - return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_un)); + memset(&s, 0, sizeof(struct sockaddr_un)); + s.sun_family = AF_UNIX; + strcpy(s.sun_path, port); + return connect(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_un)); #endif } @@ -533,65 +561,67 @@ g_tcp_local_connect(int sck, const char* port) int APP_CC g_tcp_set_non_blocking(int sck) { - unsigned long i; + unsigned long i; #if defined(_WIN32) - i = 1; - ioctlsocket(sck, FIONBIO, &i); + i = 1; + ioctlsocket(sck, FIONBIO, &i); #else - i = fcntl(sck, F_GETFL); - i = i | O_NONBLOCK; - fcntl(sck, F_SETFL, i); + i = fcntl(sck, F_GETFL); + i = i | O_NONBLOCK; + fcntl(sck, F_SETFL, i); #endif - return 0; + return 0; } /*****************************************************************************/ /* returns error, zero is good */ int APP_CC -g_tcp_bind(int sck, char* port) +g_tcp_bind(int sck, char *port) { - struct sockaddr_in s; + struct sockaddr_in s; - memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons((tui16)atoi(port)); - s.sin_addr.s_addr = INADDR_ANY; - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); + memset(&s, 0, sizeof(struct sockaddr_in)); + s.sin_family = AF_INET; + s.sin_port = htons((tui16)atoi(port)); + s.sin_addr.s_addr = INADDR_ANY; + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_in)); } /*****************************************************************************/ int APP_CC -g_tcp_local_bind(int sck, char* port) +g_tcp_local_bind(int sck, char *port) { #if defined(_WIN32) - return -1; + return -1; #else - struct sockaddr_un s; + struct sockaddr_un s; - memset(&s, 0, sizeof(struct sockaddr_un)); - s.sun_family = AF_UNIX; - strcpy(s.sun_path, port); - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_un)); + memset(&s, 0, sizeof(struct sockaddr_un)); + s.sun_family = AF_UNIX; + strcpy(s.sun_path, port); + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_un)); #endif } /*****************************************************************************/ /* returns error, zero is good */ int APP_CC -g_tcp_bind_address(int sck, char* port, const char* address) +g_tcp_bind_address(int sck, char *port, const char *address) { - struct sockaddr_in s; + struct sockaddr_in s; - memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons((tui16)atoi(port)); - s.sin_addr.s_addr = INADDR_ANY; - if (inet_aton(address, &s.sin_addr) < 0) - { - return -1; /* bad address */ - } - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); + memset(&s, 0, sizeof(struct sockaddr_in)); + s.sin_family = AF_INET; + s.sin_port = htons((tui16)atoi(port)); + s.sin_addr.s_addr = INADDR_ANY; + + if (inet_aton(address, &s.sin_addr) < 0) + { + return -1; /* bad address */ + } + + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_in)); } /*****************************************************************************/ @@ -599,58 +629,61 @@ g_tcp_bind_address(int sck, char* port, const char* address) int APP_CC g_tcp_listen(int sck) { - return listen(sck, 2); + return listen(sck, 2); } /*****************************************************************************/ int APP_CC g_tcp_accept(int sck) { - struct sockaddr_in s; + struct sockaddr_in s; #if defined(_WIN32) - signed int i; + signed int i; #else - unsigned int i; + unsigned int i; #endif - i = sizeof(struct sockaddr_in); - memset(&s, 0, i); - return accept(sck, (struct sockaddr*)&s, &i); + i = sizeof(struct sockaddr_in); + memset(&s, 0, i); + return accept(sck, (struct sockaddr *)&s, &i); } /*****************************************************************************/ void APP_CC -g_write_ip_address(int rcv_sck, char* ip_address, int bytes) +g_write_ip_address(int rcv_sck, char *ip_address, int bytes) { - struct sockaddr_in s; - struct in_addr in; + struct sockaddr_in s; + struct in_addr in; #if defined(_WIN32) - int len; + int len; #else - unsigned int len; + unsigned int len; #endif - int ip_port; - int ok; + int ip_port; + int ok; - ok = 0; - memset(&s, 0, sizeof(s)); - len = sizeof(s); - if (getpeername(rcv_sck,(struct sockaddr*)&s, &len) == 0) - { - memset(&in, 0, sizeof(in)); - in.s_addr = s.sin_addr.s_addr; - ip_port = ntohs(s.sin_port); - if (ip_port != 0) + ok = 0; + memset(&s, 0, sizeof(s)); + len = sizeof(s); + + if (getpeername(rcv_sck, (struct sockaddr *)&s, &len) == 0) { - ok = 1; - snprintf(ip_address, bytes, "%s:%d - socket: %d", inet_ntoa(in), - ip_port, rcv_sck); + memset(&in, 0, sizeof(in)); + in.s_addr = s.sin_addr.s_addr; + ip_port = ntohs(s.sin_port); + + if (ip_port != 0) + { + ok = 1; + snprintf(ip_address, bytes, "%s:%d - socket: %d", inet_ntoa(in), + ip_port, rcv_sck); + } + } + + if (!ok) + { + snprintf(ip_address, bytes, "NULL:NULL - socket: %d", rcv_sck); } - } - if (!ok) - { - snprintf(ip_address, bytes, "NULL:NULL - socket: %d", rcv_sck); - } } /*****************************************************************************/ @@ -658,9 +691,9 @@ void APP_CC g_sleep(int msecs) { #if defined(_WIN32) - Sleep(msecs); + Sleep(msecs); #else - usleep(msecs * 1000); + usleep(msecs * 1000); #endif } @@ -669,31 +702,31 @@ int APP_CC g_tcp_last_error_would_block(int sck) { #if defined(_WIN32) - return WSAGetLastError() == WSAEWOULDBLOCK; + return WSAGetLastError() == WSAEWOULDBLOCK; #else - return (errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINPROGRESS); + return (errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINPROGRESS); #endif } /*****************************************************************************/ int APP_CC -g_tcp_recv(int sck, void* ptr, int len, int flags) +g_tcp_recv(int sck, void *ptr, int len, int flags) { #if defined(_WIN32) - return recv(sck, (char*)ptr, len, flags); + return recv(sck, (char *)ptr, len, flags); #else - return recv(sck, ptr, len, flags); + return recv(sck, ptr, len, flags); #endif } /*****************************************************************************/ int APP_CC -g_tcp_send(int sck, const void* ptr, int len, int flags) +g_tcp_send(int sck, const void *ptr, int len, int flags) { #if defined(_WIN32) - return send(sck, (const char*)ptr, len, flags); + return send(sck, (const char *)ptr, len, flags); #else - return send(sck, ptr, len, flags); + return send(sck, ptr, len, flags); #endif } @@ -703,22 +736,24 @@ int APP_CC g_tcp_socket_ok(int sck) { #if defined(_WIN32) - int opt; - int opt_len; + int opt; + int opt_len; #else - int opt; - unsigned int opt_len; + int opt; + unsigned int opt_len; #endif - opt_len = sizeof(opt); - if (getsockopt(sck, SOL_SOCKET, SO_ERROR, (char*)(&opt), &opt_len) == 0) - { - if (opt == 0) + opt_len = sizeof(opt); + + if (getsockopt(sck, SOL_SOCKET, SO_ERROR, (char *)(&opt), &opt_len) == 0) { - return 1; + if (opt == 0) + { + return 1; + } } - } - return 0; + + return 0; } /*****************************************************************************/ @@ -727,23 +762,26 @@ g_tcp_socket_ok(int sck) int APP_CC g_tcp_can_send(int sck, int millis) { - fd_set wfds; - struct timeval time; - int rv; + fd_set wfds; + struct timeval time; + int rv; - time.tv_sec = millis / 1000; - time.tv_usec = (millis * 1000) % 1000000; - FD_ZERO(&wfds); - if (sck > 0) - { - FD_SET(((unsigned int)sck), &wfds); - rv = select(sck + 1, 0, &wfds, 0, &time); - if (rv > 0) + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + FD_ZERO(&wfds); + + if (sck > 0) { - return g_tcp_socket_ok(sck); + FD_SET(((unsigned int)sck), &wfds); + rv = select(sck + 1, 0, &wfds, 0, &time); + + if (rv > 0) + { + return g_tcp_socket_ok(sck); + } } - } - return 0; + + return 0; } /*****************************************************************************/ @@ -752,144 +790,166 @@ g_tcp_can_send(int sck, int millis) int APP_CC g_tcp_can_recv(int sck, int millis) { - fd_set rfds; - struct timeval time; - int rv; + fd_set rfds; + struct timeval time; + int rv; - time.tv_sec = millis / 1000; - time.tv_usec = (millis * 1000) % 1000000; - FD_ZERO(&rfds); - if (sck > 0) - { - FD_SET(((unsigned int)sck), &rfds); - rv = select(sck + 1, &rfds, 0, 0, &time); - if (rv > 0) + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + FD_ZERO(&rfds); + + if (sck > 0) { - return g_tcp_socket_ok(sck); + FD_SET(((unsigned int)sck), &rfds); + rv = select(sck + 1, &rfds, 0, 0, &time); + + if (rv > 0) + { + return g_tcp_socket_ok(sck); + } } - } - return 0; + + return 0; } /*****************************************************************************/ int APP_CC g_tcp_select(int sck1, int sck2) { - fd_set rfds; - struct timeval time; - int max = 0; - int rv = 0; + fd_set rfds; + struct timeval time; + int max = 0; + int rv = 0; - g_memset(&rfds,0,sizeof(fd_set)); - g_memset(&time,0,sizeof(struct timeval)); + g_memset(&rfds, 0, sizeof(fd_set)); + g_memset(&time, 0, sizeof(struct timeval)); - time.tv_sec = 0; - time.tv_usec = 0; - FD_ZERO(&rfds); - if (sck1 > 0) - { - FD_SET(((unsigned int)sck1), &rfds); - } - if (sck2 > 0) - { - FD_SET(((unsigned int)sck2), &rfds); - } - max = sck1; - if (sck2 > max) - { - max = sck2; - } - rv = select(max + 1, &rfds, 0, 0, &time); - if (rv > 0) - { - rv = 0; - if (FD_ISSET(((unsigned int)sck1), &rfds)) + time.tv_sec = 0; + time.tv_usec = 0; + FD_ZERO(&rfds); + + if (sck1 > 0) { - rv = rv | 1; + FD_SET(((unsigned int)sck1), &rfds); } - if (FD_ISSET(((unsigned int)sck2), &rfds)) + + if (sck2 > 0) { - rv = rv | 2; + FD_SET(((unsigned int)sck2), &rfds); } - } - else - { - rv = 0; - } - return rv; + + max = sck1; + + if (sck2 > max) + { + max = sck2; + } + + rv = select(max + 1, &rfds, 0, 0, &time); + + if (rv > 0) + { + rv = 0; + + if (FD_ISSET(((unsigned int)sck1), &rfds)) + { + rv = rv | 1; + } + + if (FD_ISSET(((unsigned int)sck2), &rfds)) + { + rv = rv | 2; + } + } + else + { + rv = 0; + } + + return rv; } /*****************************************************************************/ /* returns 0 on error */ tbus APP_CC -g_create_wait_obj(char* name) +g_create_wait_obj(char *name) { #ifdef _WIN32 - tbus obj; + tbus obj; - obj = (tbus)CreateEvent(0, 1, 0, name); - return obj; + obj = (tbus)CreateEvent(0, 1, 0, name); + return obj; #else - tbus obj; - struct sockaddr_un sa; - size_t len; - tbus sck; - int i; - int safety; - int unnamed; + tbus obj; + struct sockaddr_un sa; + size_t len; + tbus sck; + int i; + int safety; + int unnamed; - if (g_temp_base[0] == 0) - { - return 0; - } - sck = socket(PF_UNIX, SOCK_DGRAM, 0); - if (sck < 0) - { - return 0; - } - safety = 0; - g_memset(&sa, 0, sizeof(sa)); - sa.sun_family = AF_UNIX; - unnamed = 1; - if (name != 0) - { - if (name[0] != 0) + if (g_temp_base[0] == 0) { - unnamed = 0; + return 0; } - } - if (unnamed) - { - do + + sck = socket(PF_UNIX, SOCK_DGRAM, 0); + + if (sck < 0) { - if (safety > 100) - { - break; - } - safety++; - g_random((char*)&i, sizeof(i)); - len = sizeof(sa.sun_path); - g_snprintf(sa.sun_path, len, "%s/auto_%8.8x", g_temp_base, i); - len = sizeof(sa); - } while (bind(sck, (struct sockaddr*)&sa, len) < 0); - } - else - { - do + return 0; + } + + safety = 0; + g_memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + unnamed = 1; + + if (name != 0) { - if (safety > 100) - { - break; - } - safety++; - g_random((char*)&i, sizeof(i)); - len = sizeof(sa.sun_path); - g_snprintf(sa.sun_path, len, "%s/%s_%8.8x", g_temp_base, name, i); - len = sizeof(sa); - } while (bind(sck, (struct sockaddr*)&sa, len) < 0); - } - obj = (tbus)sck; - return obj; + if (name[0] != 0) + { + unnamed = 0; + } + } + + if (unnamed) + { + do + { + if (safety > 100) + { + break; + } + + safety++; + g_random((char *)&i, sizeof(i)); + len = sizeof(sa.sun_path); + g_snprintf(sa.sun_path, len, "%s/auto_%8.8x", g_temp_base, i); + len = sizeof(sa); + } + while (bind(sck, (struct sockaddr *)&sa, len) < 0); + } + else + { + do + { + if (safety > 100) + { + break; + } + + safety++; + g_random((char *)&i, sizeof(i)); + len = sizeof(sa.sun_path); + g_snprintf(sa.sun_path, len, "%s/%s_%8.8x", g_temp_base, name, i); + len = sizeof(sa); + } + while (bind(sck, (struct sockaddr *)&sa, len) < 0); + } + + obj = (tbus)sck; + return obj; #endif } @@ -899,24 +959,26 @@ tbus APP_CC g_create_wait_obj_from_socket(tbus socket, int write) { #ifdef _WIN32 - /* Create and return corresponding event handle for WaitForMultipleObjets */ - WSAEVENT event; - long lnetevent = 0; + /* Create and return corresponding event handle for WaitForMultipleObjets */ + WSAEVENT event; + long lnetevent = 0; - g_memset(&event,0,sizeof(WSAEVENT)); + g_memset(&event, 0, sizeof(WSAEVENT)); + + event = WSACreateEvent(); + lnetevent = (write ? FD_WRITE : FD_READ) | FD_CLOSE; + + if (WSAEventSelect(socket, event, lnetevent) == 0) + { + return (tbus)event; + } + else + { + return 0; + } - event = WSACreateEvent(); - lnetevent = (write ? FD_WRITE : FD_READ) | FD_CLOSE; - if (WSAEventSelect(socket, event, lnetevent) == 0) - { - return (tbus)event; - } - else - { - return 0; - } #else - return socket; + return socket; #endif } @@ -925,11 +987,13 @@ void APP_CC g_delete_wait_obj_from_socket(tbus wait_obj) { #ifdef _WIN32 - if (wait_obj == 0) - { - return; - } - WSACloseEvent((HANDLE)wait_obj); + + if (wait_obj == 0) + { + return; + } + + WSACloseEvent((HANDLE)wait_obj); #else #endif } @@ -940,39 +1004,47 @@ int APP_CC g_set_wait_obj(tbus obj) { #ifdef _WIN32 - if (obj == 0) - { - return 0; - } - SetEvent((HANDLE)obj); - return 0; -#else - socklen_t sa_size; - int s; - struct sockaddr_un sa; - if (obj == 0) - { + if (obj == 0) + { + return 0; + } + + SetEvent((HANDLE)obj); return 0; - } - if (g_tcp_can_recv((int)obj, 0)) - { - /* already signalled */ +#else + socklen_t sa_size; + int s; + struct sockaddr_un sa; + + if (obj == 0) + { + return 0; + } + + if (g_tcp_can_recv((int)obj, 0)) + { + /* already signalled */ + return 0; + } + + sa_size = sizeof(sa); + + if (getsockname((int)obj, (struct sockaddr *)&sa, &sa_size) < 0) + { + return 1; + } + + s = socket(PF_UNIX, SOCK_DGRAM, 0); + + if (s < 0) + { + return 1; + } + + sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size); + close(s); return 0; - } - sa_size = sizeof(sa); - if (getsockname((int)obj, (struct sockaddr*)&sa, &sa_size) < 0) - { - return 1; - } - s = socket(PF_UNIX, SOCK_DGRAM, 0); - if (s < 0) - { - return 1; - } - sendto(s, "sig", 4, 0, (struct sockaddr*)&sa, sa_size); - close(s); - return 0; #endif } @@ -982,24 +1054,28 @@ int APP_CC g_reset_wait_obj(tbus obj) { #ifdef _WIN32 - if (obj == 0) - { - return 0; - } - ResetEvent((HANDLE)obj); - return 0; -#else - char buf[64]; - if (obj == 0) - { + if (obj == 0) + { + return 0; + } + + ResetEvent((HANDLE)obj); + return 0; +#else + char buf[64]; + + if (obj == 0) + { + return 0; + } + + while (g_tcp_can_recv((int)obj, 0)) + { + recvfrom((int)obj, &buf, 64, 0, 0, 0); + } + return 0; - } - while (g_tcp_can_recv((int)obj, 0)) - { - recvfrom((int)obj, &buf, 64, 0, 0, 0); - } - return 0; #endif } @@ -1009,21 +1085,26 @@ int APP_CC g_is_wait_obj_set(tbus obj) { #ifdef _WIN32 - if (obj == 0) - { + + if (obj == 0) + { + return 0; + } + + if (WaitForSingleObject((HANDLE)obj, 0) == WAIT_OBJECT_0) + { + return 1; + } + return 0; - } - if (WaitForSingleObject((HANDLE)obj, 0) == WAIT_OBJECT_0) - { - return 1; - } - return 0; #else - if (obj == 0) - { - return 0; - } - return g_tcp_can_recv((int)obj, 0); + + if (obj == 0) + { + return 0; + } + + return g_tcp_can_recv((int)obj, 0); #endif } @@ -1033,29 +1114,34 @@ int APP_CC g_delete_wait_obj(tbus obj) { #ifdef _WIN32 - if (obj == 0) - { - return 0; - } - /* Close event handle */ - CloseHandle((HANDLE)obj); - return 0; -#else - socklen_t sa_size; - struct sockaddr_un sa; - if (obj == 0) - { + if (obj == 0) + { + return 0; + } + + /* Close event handle */ + CloseHandle((HANDLE)obj); + return 0; +#else + socklen_t sa_size; + struct sockaddr_un sa; + + if (obj == 0) + { + return 0; + } + + sa_size = sizeof(sa); + + if (getsockname((int)obj, (struct sockaddr *)&sa, &sa_size) < 0) + { + return 1; + } + + close((int)obj); + unlink(sa.sun_path); return 0; - } - sa_size = sizeof(sa); - if (getsockname((int)obj, (struct sockaddr*)&sa, &sa_size) < 0) - { - return 1; - } - close((int)obj); - unlink(sa.sun_path); - return 0; #endif } @@ -1067,158 +1153,182 @@ g_close_wait_obj(tbus obj) { #ifdef _WIN32 #else - close((int)obj); + close((int)obj); #endif - return 0; + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount, +g_obj_wait(tbus *read_objs, int rcount, tbus *write_objs, int wcount, int mstimeout) { #ifdef _WIN32 - HANDLE handles[256]; - DWORD count; - DWORD error; - int j; - int i; + HANDLE handles[256]; + DWORD count; + DWORD error; + int j; + int i; - j = 0; - count = rcount + wcount; - for (i = 0; i < rcount; i++) - { - handles[j++] = (HANDLE)(read_objs[i]); - } - for (i = 0; i < wcount; i++) - { - handles[j++] = (HANDLE)(write_objs[i]); - } - if (mstimeout < 1) - { - mstimeout = INFINITE; - } - error = WaitForMultipleObjects(count, handles, FALSE, mstimeout); - if (error == WAIT_FAILED) - { - return 1; - } - return 0; -#else - fd_set rfds; - fd_set wfds; - struct timeval time; - struct timeval* ptime = (struct timeval *)NULL; - int i = 0; - int res = 0; - int max = 0; - int sck = 0; + j = 0; + count = rcount + wcount; - g_memset(&rfds,0,sizeof(fd_set)); - g_memset(&wfds,0,sizeof(fd_set)); - g_memset(&time,0,sizeof(struct timeval)); - - max = 0; - if (mstimeout < 1) - { - ptime = (struct timeval *)NULL; - } - else - { - time.tv_sec = mstimeout / 1000; - time.tv_usec = (mstimeout % 1000) * 1000; - ptime = &time; - } - FD_ZERO(&rfds); - FD_ZERO(&wfds); - /* Find the highest descriptor number in read_obj */ - if (read_objs!=NULL) - { for (i = 0; i < rcount; i++) { - sck = (int)(read_objs[i]); - if (sck > 0) - { - FD_SET(sck, &rfds); - if (sck > max) - { - max = sck; /* max holds the highest socket/descriptor number */ - } - } + handles[j++] = (HANDLE)(read_objs[i]); } - } - else if (rcount>0) - { - g_writeln("Programming error read_objs is null"); - return 1; /* error */ - } - if (write_objs!=NULL) - { + for (i = 0; i < wcount; i++) { - sck = (int)(write_objs[i]); - if (sck > 0) - { - FD_SET(sck, &wfds); - if (sck > max) - { - max = sck; /* max holds the highest socket/descriptor number */ - } - } + handles[j++] = (HANDLE)(write_objs[i]); } - } - else if (wcount > 0) - { - g_writeln("Programming error write_objs is null"); - return 1; /* error */ - } - res = select(max + 1, &rfds, &wfds, 0, ptime); - if (res < 0) - { - /* these are not really errors */ - if ((errno == EAGAIN) || - (errno == EWOULDBLOCK) || - (errno == EINPROGRESS) || - (errno == EINTR)) /* signal occurred */ + + if (mstimeout < 1) { - return 0; + mstimeout = INFINITE; } - return 1; /* error */ - } - return 0; + + error = WaitForMultipleObjects(count, handles, FALSE, mstimeout); + + if (error == WAIT_FAILED) + { + return 1; + } + + return 0; +#else + fd_set rfds; + fd_set wfds; + struct timeval time; + struct timeval *ptime = (struct timeval *)NULL; + int i = 0; + int res = 0; + int max = 0; + int sck = 0; + + g_memset(&rfds, 0, sizeof(fd_set)); + g_memset(&wfds, 0, sizeof(fd_set)); + g_memset(&time, 0, sizeof(struct timeval)); + + max = 0; + + if (mstimeout < 1) + { + ptime = (struct timeval *)NULL; + } + else + { + time.tv_sec = mstimeout / 1000; + time.tv_usec = (mstimeout % 1000) * 1000; + ptime = &time; + } + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + /* Find the highest descriptor number in read_obj */ + if (read_objs != NULL) + { + for (i = 0; i < rcount; i++) + { + sck = (int)(read_objs[i]); + + if (sck > 0) + { + FD_SET(sck, &rfds); + + if (sck > max) + { + max = sck; /* max holds the highest socket/descriptor number */ + } + } + } + } + else if (rcount > 0) + { + g_writeln("Programming error read_objs is null"); + return 1; /* error */ + } + + if (write_objs != NULL) + { + for (i = 0; i < wcount; i++) + { + sck = (int)(write_objs[i]); + + if (sck > 0) + { + FD_SET(sck, &wfds); + + if (sck > max) + { + max = sck; /* max holds the highest socket/descriptor number */ + } + } + } + } + else if (wcount > 0) + { + g_writeln("Programming error write_objs is null"); + return 1; /* error */ + } + + res = select(max + 1, &rfds, &wfds, 0, ptime); + + if (res < 0) + { + /* these are not really errors */ + if ((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR)) /* signal occurred */ + { + return 0; + } + + return 1; /* error */ + } + + return 0; #endif } /*****************************************************************************/ void APP_CC -g_random(char* data, int len) +g_random(char *data, int len) { #if defined(_WIN32) - int index; + int index; - srand(g_time1()); - for (index = 0; index < len; index++) - { - data[index] = (char)rand(); /* rand returns a number between 0 and - RAND_MAX */ - } -#else - int fd; + srand(g_time1()); - memset(data, 0x44, len); - fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) - { - fd = open("/dev/random", O_RDONLY); - } - if (fd != -1) - { - if (read(fd, data, len) != len) + for (index = 0; index < len; index++) { + data[index] = (char)rand(); /* rand returns a number between 0 and + RAND_MAX */ } - close(fd); - } + +#else + int fd; + + memset(data, 0x44, len); + fd = open("/dev/urandom", O_RDONLY); + + if (fd == -1) + { + fd = open("/dev/random", O_RDONLY); + } + + if (fd != -1) + { + if (read(fd, data, len) != len) + { + } + + close(fd); + } + #endif } @@ -1226,35 +1336,37 @@ g_random(char* data, int len) int APP_CC g_abs(int i) { - return abs(i); + return abs(i); } /*****************************************************************************/ int APP_CC -g_memcmp(const void* s1, const void* s2, int len) +g_memcmp(const void *s1, const void *s2, int len) { - return memcmp(s1, s2, len); + return memcmp(s1, s2, len); } /*****************************************************************************/ /* returns -1 on error, else return handle or file descriptor */ int APP_CC -g_file_open(const char* file_name) +g_file_open(const char *file_name) { #if defined(_WIN32) - return (int)CreateFileA(file_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + return (int)CreateFileA(file_name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); #else - int rv; + int rv; - rv = open(file_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (rv == -1) - { - /* can't open read / write, try to open read only */ - rv = open(file_name, O_RDONLY); - } - return rv; + rv = open(file_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + if (rv == -1) + { + /* can't open read / write, try to open read only */ + rv = open(file_name, O_RDONLY); + } + + return rv; #endif } @@ -1264,48 +1376,52 @@ int APP_CC g_file_close(int fd) { #if defined(_WIN32) - CloseHandle((HANDLE)fd); + CloseHandle((HANDLE)fd); #else - close(fd); + close(fd); #endif - return 0; + return 0; } /*****************************************************************************/ /* read from file, returns the number of bytes read or -1 on error */ int APP_CC -g_file_read(int fd, char* ptr, int len) +g_file_read(int fd, char *ptr, int len) { #if defined(_WIN32) - if (ReadFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0)) - { - return len; - } - else - { - return -1; - } + + if (ReadFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0)) + { + return len; + } + else + { + return -1; + } + #else - return read(fd, ptr, len); + return read(fd, ptr, len); #endif } /*****************************************************************************/ /* write to file, returns the number of bytes writen or -1 on error */ int APP_CC -g_file_write(int fd, char* ptr, int len) +g_file_write(int fd, char *ptr, int len) { #if defined(_WIN32) - if (WriteFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0)) - { - return len; - } - else - { - return -1; - } + + if (WriteFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0)) + { + return len; + } + else + { + return -1; + } + #else - return write(fd, ptr, len); + return write(fd, ptr, len); #endif } @@ -1315,19 +1431,21 @@ int APP_CC g_file_seek(int fd, int offset) { #if defined(_WIN32) - int rv; + int rv; + + rv = (int)SetFilePointer((HANDLE)fd, offset, 0, FILE_BEGIN); + + if (rv == (int)INVALID_SET_FILE_POINTER) + { + return -1; + } + else + { + return rv; + } - rv = (int)SetFilePointer((HANDLE)fd, offset, 0, FILE_BEGIN); - if (rv == (int)INVALID_SET_FILE_POINTER) - { - return -1; - } - else - { - return rv; - } #else - return (int)lseek(fd, offset, SEEK_SET); + return (int)lseek(fd, offset, SEEK_SET); #endif } @@ -1338,67 +1456,69 @@ int APP_CC g_file_lock(int fd, int start, int len) { #if defined(_WIN32) - return LockFile((HANDLE)fd, start, 0, len, 0); + return LockFile((HANDLE)fd, start, 0, len, 0); #else - struct flock lock; + struct flock lock; - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = start; - lock.l_len = len; - if (fcntl(fd, F_SETLK, &lock) == -1) - { - return 0; - } - return 1; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = start; + lock.l_len = len; + + if (fcntl(fd, F_SETLK, &lock) == -1) + { + return 0; + } + + return 1; #endif } /*****************************************************************************/ /* returns error */ int APP_CC -g_chmod_hex(const char* filename, int flags) +g_chmod_hex(const char *filename, int flags) { #if defined(_WIN32) - return 0; + return 0; #else - int fl; + int fl; - fl = 0; - fl |= (flags & 0x4000) ? S_ISUID : 0; - fl |= (flags & 0x2000) ? S_ISGID : 0; - fl |= (flags & 0x1000) ? S_ISVTX : 0; - fl |= (flags & 0x0400) ? S_IRUSR : 0; - fl |= (flags & 0x0200) ? S_IWUSR : 0; - fl |= (flags & 0x0100) ? S_IXUSR : 0; - fl |= (flags & 0x0040) ? S_IRGRP : 0; - fl |= (flags & 0x0020) ? S_IWGRP : 0; - fl |= (flags & 0x0010) ? S_IXGRP : 0; - fl |= (flags & 0x0004) ? S_IROTH : 0; - fl |= (flags & 0x0002) ? S_IWOTH : 0; - fl |= (flags & 0x0001) ? S_IXOTH : 0; - return chmod(filename, fl); + fl = 0; + fl |= (flags & 0x4000) ? S_ISUID : 0; + fl |= (flags & 0x2000) ? S_ISGID : 0; + fl |= (flags & 0x1000) ? S_ISVTX : 0; + fl |= (flags & 0x0400) ? S_IRUSR : 0; + fl |= (flags & 0x0200) ? S_IWUSR : 0; + fl |= (flags & 0x0100) ? S_IXUSR : 0; + fl |= (flags & 0x0040) ? S_IRGRP : 0; + fl |= (flags & 0x0020) ? S_IWGRP : 0; + fl |= (flags & 0x0010) ? S_IXGRP : 0; + fl |= (flags & 0x0004) ? S_IROTH : 0; + fl |= (flags & 0x0002) ? S_IWOTH : 0; + fl |= (flags & 0x0001) ? S_IXOTH : 0; + return chmod(filename, fl); #endif } /*****************************************************************************/ /* returns error, zero is ok */ int APP_CC -g_chown(const char* name, int uid, int gid) +g_chown(const char *name, int uid, int gid) { - return chown(name, uid, gid); + return chown(name, uid, gid); } /*****************************************************************************/ /* returns error, always zero */ int APP_CC -g_mkdir(const char* dirname) +g_mkdir(const char *dirname) { #if defined(_WIN32) - return 0; + return 0; #else - mkdir(dirname, S_IRWXU); - return 0; + mkdir(dirname, S_IRWXU); + return 0; #endif } @@ -1406,82 +1526,87 @@ g_mkdir(const char* dirname) /* gets the current working directory and puts up to maxlen chars in dirname always returns 0 */ -char* APP_CC -g_get_current_dir(char* dirname, int maxlen) +char *APP_CC +g_get_current_dir(char *dirname, int maxlen) { #if defined(_WIN32) - GetCurrentDirectoryA(maxlen, dirname); - return 0; + GetCurrentDirectoryA(maxlen, dirname); + return 0; #else - if (getcwd(dirname, maxlen) == 0) - { - } - return 0; + + if (getcwd(dirname, maxlen) == 0) + { + } + + return 0; #endif } /*****************************************************************************/ /* returns error, zero on success and -1 on failure */ int APP_CC -g_set_current_dir(char* dirname) +g_set_current_dir(char *dirname) { #if defined(_WIN32) - if (SetCurrentDirectoryA(dirname)) - { - return 0; - } - else - { - return -1; - } + + if (SetCurrentDirectoryA(dirname)) + { + return 0; + } + else + { + return -1; + } + #else - return chdir(dirname); + return chdir(dirname); #endif } /*****************************************************************************/ /* returns boolean, non zero if the file exists */ int APP_CC -g_file_exist(const char* filename) +g_file_exist(const char *filename) { #if defined(_WIN32) - return 0; // use FileAge(filename) <> -1 + return 0; // use FileAge(filename) <> -1 #else - return access(filename, F_OK) == 0; + return access(filename, F_OK) == 0; #endif } /*****************************************************************************/ /* returns boolean, non zero if the directory exists */ int APP_CC -g_directory_exist(const char* dirname) +g_directory_exist(const char *dirname) { #if defined(_WIN32) - return 0; // use GetFileAttributes and check return value - // is not -1 and FILE_ATTRIBUT_DIRECTORY bit is set + return 0; // use GetFileAttributes and check return value + // is not -1 and FILE_ATTRIBUT_DIRECTORY bit is set #else - struct stat st; + struct stat st; + + if (stat(dirname, &st) == 0) + { + return S_ISDIR(st.st_mode); + } + else + { + return 0; + } - if (stat(dirname, &st) == 0) - { - return S_ISDIR(st.st_mode); - } - else - { - return 0; - } #endif } /*****************************************************************************/ /* returns boolean */ int APP_CC -g_create_dir(const char* dirname) +g_create_dir(const char *dirname) { #if defined(_WIN32) - return CreateDirectoryA(dirname, 0); // test this + return CreateDirectoryA(dirname, 0); // test this #else - return mkdir(dirname, (mode_t)-1) == 0; + return mkdir(dirname, (mode_t) - 1) == 0; #endif } @@ -1490,353 +1615,380 @@ g_create_dir(const char* dirname) example /tmp/a/b/c/readme.txt will try to create /tmp/a/b/c returns boolean */ int APP_CC -g_create_path(const char* path) +g_create_path(const char *path) { - char* pp; - char* sp; - char* copypath; - int status; + char *pp; + char *sp; + char *copypath; + int status; - status = 1; - copypath = g_strdup(path); - pp = copypath; - sp = strchr(pp, '/'); - while (sp != 0) - { - if (sp != pp) - { - *sp = 0; - if (!g_directory_exist(copypath)) - { - if (!g_create_dir(copypath)) - { - status = 0; - break; - } - } - *sp = '/'; - } - pp = sp + 1; + status = 1; + copypath = g_strdup(path); + pp = copypath; sp = strchr(pp, '/'); - } - g_free(copypath); - return status; + + while (sp != 0) + { + if (sp != pp) + { + *sp = 0; + + if (!g_directory_exist(copypath)) + { + if (!g_create_dir(copypath)) + { + status = 0; + break; + } + } + + *sp = '/'; + } + + pp = sp + 1; + sp = strchr(pp, '/'); + } + + g_free(copypath); + return status; } /*****************************************************************************/ /* returns boolean */ int APP_CC -g_remove_dir(const char* dirname) +g_remove_dir(const char *dirname) { #if defined(_WIN32) - return RemoveDirectoryA(dirname); // test this + return RemoveDirectoryA(dirname); // test this #else - return rmdir(dirname) == 0; + return rmdir(dirname) == 0; #endif } /*****************************************************************************/ /* returns non zero if the file was deleted */ int APP_CC -g_file_delete(const char* filename) +g_file_delete(const char *filename) { #if defined(_WIN32) - return DeleteFileA(filename); + return DeleteFileA(filename); #else - return unlink(filename) != -1; + return unlink(filename) != -1; #endif } /*****************************************************************************/ /* returns file size, -1 on error */ int APP_CC -g_file_get_size(const char* filename) +g_file_get_size(const char *filename) { #if defined(_WIN32) - return -1; -#else - struct stat st; - - if (stat(filename, &st) == 0) - { - return (int)(st.st_size); - } - else - { return -1; - } +#else + struct stat st; + + if (stat(filename, &st) == 0) + { + return (int)(st.st_size); + } + else + { + return -1; + } + #endif } /*****************************************************************************/ /* returns length of text */ int APP_CC -g_strlen(const char* text) +g_strlen(const char *text) { - if (text == NULL) - { - return 0; - } - return strlen(text); + if (text == NULL) + { + return 0; + } + + return strlen(text); } /*****************************************************************************/ /* returns dest */ -char* APP_CC -g_strcpy(char* dest, const char* src) +char *APP_CC +g_strcpy(char *dest, const char *src) { - if (src == 0 && dest != 0) - { - dest[0] = 0; - return dest; - } - if (dest == 0 || src == 0) - { - return 0; - } - return strcpy(dest, src); + if (src == 0 && dest != 0) + { + dest[0] = 0; + return dest; + } + + if (dest == 0 || src == 0) + { + return 0; + } + + return strcpy(dest, src); } /*****************************************************************************/ /* returns dest */ -char* APP_CC -g_strncpy(char* dest, const char* src, int len) +char *APP_CC +g_strncpy(char *dest, const char *src, int len) { - char* rv; + char *rv; - if (src == 0 && dest != 0) - { - dest[0] = 0; - return dest; - } - if (dest == 0 || src == 0) - { - return 0; - } - rv = strncpy(dest, src, len); - dest[len] = 0; - return rv; + if (src == 0 && dest != 0) + { + dest[0] = 0; + return dest; + } + + if (dest == 0 || src == 0) + { + return 0; + } + + rv = strncpy(dest, src, len); + dest[len] = 0; + return rv; } /*****************************************************************************/ /* returns dest */ -char* APP_CC -g_strcat(char* dest, const char* src) +char *APP_CC +g_strcat(char *dest, const char *src) { - if (dest == 0 || src == 0) - { - return dest; - } - return strcat(dest, src); + if (dest == 0 || src == 0) + { + return dest; + } + + return strcat(dest, src); } /*****************************************************************************/ /* if in = 0, return 0 else return newly alloced copy of in */ -char* APP_CC -g_strdup(const char* in) +char *APP_CC +g_strdup(const char *in) { - int len; - char* p; + int len; + char *p; - if (in == 0) - { - return 0; - } - len = g_strlen(in); - p = (char*)g_malloc(len + 1, 0); - if (p != NULL) - { - g_strcpy(p, in); - } - return p; + if (in == 0) + { + return 0; + } + + len = g_strlen(in); + p = (char *)g_malloc(len + 1, 0); + + if (p != NULL) + { + g_strcpy(p, in); + } + + return p; } /*****************************************************************************/ /* if in = 0, return 0 else return newly alloced copy of input string * if the input string is larger than maxlen the returned string will be * truncated. All strings returned will include null termination*/ -char* APP_CC -g_strndup(const char* in, const unsigned int maxlen) +char *APP_CC +g_strndup(const char *in, const unsigned int maxlen) { - int len; - char* p; + int len; + char *p; - if (in == 0) - { - return 0; - } - len = g_strlen(in); - if (len>maxlen) - { - len = maxlen - 1; - } - p = (char*)g_malloc(len + 2, 0); - if (p != NULL) - { - g_strncpy(p, in,len+1); - } - return p; -} -/*****************************************************************************/ -int APP_CC -g_strcmp(const char* c1, const char* c2) -{ - return strcmp(c1, c2); -} - -/*****************************************************************************/ -int APP_CC -g_strncmp(const char* c1, const char* c2, int len) -{ - return strncmp(c1, c2, len); -} - -/*****************************************************************************/ -int APP_CC -g_strcasecmp(const char* c1, const char* c2) -{ -#if defined(_WIN32) - return stricmp(c1, c2); -#else - return strcasecmp(c1, c2); -#endif -} - -/*****************************************************************************/ -int APP_CC -g_strncasecmp(const char* c1, const char* c2, int len) -{ -#if defined(_WIN32) - return strnicmp(c1, c2, len); -#else - return strncasecmp(c1, c2, len); -#endif -} - -/*****************************************************************************/ -int APP_CC -g_atoi(const char* str) -{ - if (str == 0) - { - return 0; - } - return atoi(str); -} - -/*****************************************************************************/ -int APP_CC -g_htoi(char* str) -{ - int len; - int index; - int rv; - int val; - int shift; - - rv = 0; - len = strlen(str); - index = len - 1; - shift = 0; - while (index >= 0) - { - val = 0; - switch (str[index]) + if (in == 0) { - case '1': - val = 1; - break; - case '2': - val = 2; - break; - case '3': - val = 3; - break; - case '4': - val = 4; - break; - case '5': - val = 5; - break; - case '6': - val = 6; - break; - case '7': - val = 7; - break; - case '8': - val = 8; - break; - case '9': - val = 9; - break; - case 'a': - case 'A': - val = 10; - break; - case 'b': - case 'B': - val = 11; - break; - case 'c': - case 'C': - val = 12; - break; - case 'd': - case 'D': - val = 13; - break; - case 'e': - case 'E': - val = 14; - break; - case 'f': - case 'F': - val = 15; - break; + return 0; } - rv = rv | (val << shift); - index--; - shift += 4; - } - return rv; + + len = g_strlen(in); + + if (len > maxlen) + { + len = maxlen - 1; + } + + p = (char *)g_malloc(len + 2, 0); + + if (p != NULL) + { + g_strncpy(p, in, len + 1); + } + + return p; +} +/*****************************************************************************/ +int APP_CC +g_strcmp(const char *c1, const char *c2) +{ + return strcmp(c1, c2); } /*****************************************************************************/ int APP_CC -g_pos(char* str, const char* to_find) +g_strncmp(const char *c1, const char *c2, int len) { - char* pp; - - pp = strstr(str, to_find); - if (pp == 0) - { - return -1; - } - return (pp - str); + return strncmp(c1, c2, len); } /*****************************************************************************/ int APP_CC -g_mbstowcs(twchar* dest, const char* src, int n) +g_strcasecmp(const char *c1, const char *c2) { - wchar_t* ldest; - int rv; - - ldest = (wchar_t*)dest; - rv = mbstowcs(ldest, src, n); - return rv; +#if defined(_WIN32) + return stricmp(c1, c2); +#else + return strcasecmp(c1, c2); +#endif } /*****************************************************************************/ int APP_CC -g_wcstombs(char* dest, const twchar* src, int n) +g_strncasecmp(const char *c1, const char *c2, int len) { - const wchar_t* lsrc; - int rv; +#if defined(_WIN32) + return strnicmp(c1, c2, len); +#else + return strncasecmp(c1, c2, len); +#endif +} - lsrc = (const wchar_t*)src; - rv = wcstombs(dest, lsrc, n); - return rv; +/*****************************************************************************/ +int APP_CC +g_atoi(const char *str) +{ + if (str == 0) + { + return 0; + } + + return atoi(str); +} + +/*****************************************************************************/ +int APP_CC +g_htoi(char *str) +{ + int len; + int index; + int rv; + int val; + int shift; + + rv = 0; + len = strlen(str); + index = len - 1; + shift = 0; + + while (index >= 0) + { + val = 0; + + switch (str[index]) + { + case '1': + val = 1; + break; + case '2': + val = 2; + break; + case '3': + val = 3; + break; + case '4': + val = 4; + break; + case '5': + val = 5; + break; + case '6': + val = 6; + break; + case '7': + val = 7; + break; + case '8': + val = 8; + break; + case '9': + val = 9; + break; + case 'a': + case 'A': + val = 10; + break; + case 'b': + case 'B': + val = 11; + break; + case 'c': + case 'C': + val = 12; + break; + case 'd': + case 'D': + val = 13; + break; + case 'e': + case 'E': + val = 14; + break; + case 'f': + case 'F': + val = 15; + break; + } + + rv = rv | (val << shift); + index--; + shift += 4; + } + + return rv; +} + +/*****************************************************************************/ +int APP_CC +g_pos(char *str, const char *to_find) +{ + char *pp; + + pp = strstr(str, to_find); + + if (pp == 0) + { + return -1; + } + + return (pp - str); +} + +/*****************************************************************************/ +int APP_CC +g_mbstowcs(twchar *dest, const char *src, int n) +{ + wchar_t *ldest; + int rv; + + ldest = (wchar_t *)dest; + rv = mbstowcs(ldest, src, n); + return rv; +} + +/*****************************************************************************/ +int APP_CC +g_wcstombs(char *dest, const twchar *src, int n) +{ + const wchar_t *lsrc; + int rv; + + lsrc = (const wchar_t *)src; + rv = wcstombs(dest, lsrc, n); + return rv; } /*****************************************************************************/ @@ -1845,127 +1997,143 @@ g_wcstombs(char* dest, const twchar* src, int n) /* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */ /* this will always shorten the string or not change it */ int APP_CC -g_strtrim(char* str, int trim_flags) +g_strtrim(char *str, int trim_flags) { - int index; - int len; - int text1_index; - int got_char; - wchar_t* text; - wchar_t* text1; + int index; + int len; + int text1_index; + int got_char; + wchar_t *text; + wchar_t *text1; - len = mbstowcs(0, str, 0); - if (len < 1) - { + len = mbstowcs(0, str, 0); + + if (len < 1) + { + return 0; + } + + if ((trim_flags < 1) || (trim_flags > 4)) + { + return 1; + } + + text = (wchar_t *)malloc(len * sizeof(wchar_t) + 8); + text1 = (wchar_t *)malloc(len * sizeof(wchar_t) + 8); + text1_index = 0; + mbstowcs(text, str, len + 1); + + switch (trim_flags) + { + case 4: /* trim through */ + + for (index = 0; index < len; index++) + { + if (text[index] > 32) + { + text1[text1_index] = text[index]; + text1_index++; + } + } + + text1[text1_index] = 0; + break; + case 3: /* trim both */ + got_char = 0; + + for (index = 0; index < len; index++) + { + if (got_char) + { + text1[text1_index] = text[index]; + text1_index++; + } + else + { + if (text[index] > 32) + { + text1[text1_index] = text[index]; + text1_index++; + got_char = 1; + } + } + } + + text1[text1_index] = 0; + len = text1_index; + + /* trim right */ + for (index = len - 1; index >= 0; index--) + { + if (text1[index] > 32) + { + break; + } + } + + text1_index = index + 1; + text1[text1_index] = 0; + break; + case 2: /* trim right */ + + /* copy it */ + for (index = 0; index < len; index++) + { + text1[text1_index] = text[index]; + text1_index++; + } + + /* trim right */ + for (index = len - 1; index >= 0; index--) + { + if (text1[index] > 32) + { + break; + } + } + + text1_index = index + 1; + text1[text1_index] = 0; + break; + case 1: /* trim left */ + got_char = 0; + + for (index = 0; index < len; index++) + { + if (got_char) + { + text1[text1_index] = text[index]; + text1_index++; + } + else + { + if (text[index] > 32) + { + text1[text1_index] = text[index]; + text1_index++; + got_char = 1; + } + } + } + + text1[text1_index] = 0; + break; + } + + wcstombs(str, text1, text1_index + 1); + free(text); + free(text1); return 0; - } - if ((trim_flags < 1) || (trim_flags > 4)) - { - return 1; - } - text = (wchar_t*)malloc(len * sizeof(wchar_t) + 8); - text1 = (wchar_t*)malloc(len * sizeof(wchar_t) + 8); - text1_index = 0; - mbstowcs(text, str, len + 1); - switch (trim_flags) - { - case 4: /* trim through */ - for (index = 0; index < len; index++) - { - if (text[index] > 32) - { - text1[text1_index] = text[index]; - text1_index++; - } - } - text1[text1_index] = 0; - break; - case 3: /* trim both */ - got_char = 0; - for (index = 0; index < len; index++) - { - if (got_char) - { - text1[text1_index] = text[index]; - text1_index++; - } - else - { - if (text[index] > 32) - { - text1[text1_index] = text[index]; - text1_index++; - got_char = 1; - } - } - } - text1[text1_index] = 0; - len = text1_index; - /* trim right */ - for (index = len - 1; index >= 0; index--) - { - if (text1[index] > 32) - { - break; - } - } - text1_index = index + 1; - text1[text1_index] = 0; - break; - case 2: /* trim right */ - /* copy it */ - for (index = 0; index < len; index++) - { - text1[text1_index] = text[index]; - text1_index++; - } - /* trim right */ - for (index = len - 1; index >= 0; index--) - { - if (text1[index] > 32) - { - break; - } - } - text1_index = index + 1; - text1[text1_index] = 0; - break; - case 1: /* trim left */ - got_char = 0; - for (index = 0; index < len; index++) - { - if (got_char) - { - text1[text1_index] = text[index]; - text1_index++; - } - else - { - if (text[index] > 32) - { - text1[text1_index] = text[index]; - text1_index++; - got_char = 1; - } - } - } - text1[text1_index] = 0; - break; - } - wcstombs(str, text1, text1_index + 1); - free(text); - free(text1); - return 0; } /*****************************************************************************/ long APP_CC -g_load_library(char* in) +g_load_library(char *in) { #if defined(_WIN32) - return (long)LoadLibraryA(in); + return (long)LoadLibraryA(in); #else - return (long)dlopen(in, RTLD_LOCAL | RTLD_LAZY); + return (long)dlopen(in, RTLD_LOCAL | RTLD_LAZY); #endif } @@ -1973,54 +2141,56 @@ g_load_library(char* in) int APP_CC g_free_library(long lib) { - if (lib == 0) - { - return 0; - } + if (lib == 0) + { + return 0; + } + #if defined(_WIN32) - return FreeLibrary((HMODULE)lib); + return FreeLibrary((HMODULE)lib); #else - return dlclose((void*)lib); + return dlclose((void *)lib); #endif } /*****************************************************************************/ /* returns NULL if not found */ -void* APP_CC -g_get_proc_address(long lib, const char* name) +void *APP_CC +g_get_proc_address(long lib, const char *name) { - if (lib == 0) - { - return 0; - } + if (lib == 0) + { + return 0; + } + #if defined(_WIN32) - return GetProcAddress((HMODULE)lib, name); + return GetProcAddress((HMODULE)lib, name); #else - return dlsym((void*)lib, name); + return dlsym((void *)lib, name); #endif } /*****************************************************************************/ /* does not work in win32 */ int APP_CC -g_system(char* aexec) +g_system(char *aexec) { #if defined(_WIN32) - return 0; + return 0; #else - return system(aexec); + return system(aexec); #endif } /*****************************************************************************/ /* does not work in win32 */ -char* APP_CC +char *APP_CC g_get_strerror(void) { #if defined(_WIN32) - return 0; + return 0; #else - return strerror(errno); + return strerror(errno); #endif } @@ -2029,43 +2199,43 @@ int APP_CC g_get_errno(void) { #if defined(_WIN32) - return GetLastError(); + return GetLastError(); #else - return errno; + return errno; #endif } /*****************************************************************************/ /* does not work in win32 */ int APP_CC -g_execvp(const char* p1, char* args[]) +g_execvp(const char *p1, char *args[]) { #if defined(_WIN32) - return 0; + return 0; #else - int rv; + int rv; - g_rm_temp_dir(); - rv = execvp(p1, args); - g_mk_temp_dir(0); - return rv; + g_rm_temp_dir(); + rv = execvp(p1, args); + g_mk_temp_dir(0); + return rv; #endif } /*****************************************************************************/ /* does not work in win32 */ int APP_CC -g_execlp3(const char* a1, const char* a2, const char* a3) +g_execlp3(const char *a1, const char *a2, const char *a3) { #if defined(_WIN32) - return 0; + return 0; #else - int rv; + int rv; - g_rm_temp_dir(); - rv = execlp(a1, a2, a3, (void*)0); - g_mk_temp_dir(0); - return rv; + g_rm_temp_dir(); + rv = execlp(a1, a2, a3, (void *)0); + g_mk_temp_dir(0); + return rv; #endif } @@ -2076,7 +2246,7 @@ g_signal_child_stop(void (*func)(int)) { #if defined(_WIN32) #else - signal(SIGCHLD, func); + signal(SIGCHLD, func); #endif } @@ -2087,7 +2257,7 @@ g_signal_hang_up(void (*func)(int)) { #if defined(_WIN32) #else - signal(SIGHUP, func); + signal(SIGHUP, func); #endif } @@ -2098,7 +2268,7 @@ g_signal_user_interrupt(void (*func)(int)) { #if defined(_WIN32) #else - signal(SIGINT, func); + signal(SIGINT, func); #endif } @@ -2109,7 +2279,7 @@ g_signal_kill(void (*func)(int)) { #if defined(_WIN32) #else - signal(SIGKILL, func); + signal(SIGKILL, func); #endif } @@ -2120,7 +2290,7 @@ g_signal_terminate(void (*func)(int)) { #if defined(_WIN32) #else - signal(SIGTERM, func); + signal(SIGTERM, func); #endif } @@ -2131,7 +2301,7 @@ g_signal_pipe(void (*func)(int)) { #if defined(_WIN32) #else - signal(SIGPIPE, func); + signal(SIGPIPE, func); #endif } @@ -2142,7 +2312,7 @@ g_signal_usr1(void (*func)(int)) { #if defined(_WIN32) #else - signal(SIGUSR1, func); + signal(SIGUSR1, func); #endif } @@ -2152,16 +2322,18 @@ int APP_CC g_fork(void) { #if defined(_WIN32) - return 0; + return 0; #else - int rv; + int rv; - rv = fork(); - if (rv == 0) /* child */ - { - g_mk_temp_dir(0); - } - return rv; + rv = fork(); + + if (rv == 0) /* child */ + { + g_mk_temp_dir(0); + } + + return rv; #endif } @@ -2171,9 +2343,9 @@ int APP_CC g_setgid(int pid) { #if defined(_WIN32) - return 0; + return 0; #else - return setgid(pid); + return setgid(pid); #endif } @@ -2181,12 +2353,12 @@ g_setgid(int pid) /* returns error, zero is success, non zero is error */ /* does not work in win32 */ int APP_CC -g_initgroups(const char* user, int gid) +g_initgroups(const char *user, int gid) { #if defined(_WIN32) - return 0; + return 0; #else - return initgroups(user, gid); + return initgroups(user, gid); #endif } @@ -2197,9 +2369,9 @@ int APP_CC g_getuid(void) { #if defined(_WIN32) - return 0; + return 0; #else - return getuid(); + return getuid(); #endif } @@ -2210,9 +2382,9 @@ int APP_CC g_setuid(int pid) { #if defined(_WIN32) - return 0; + return 0; #else - return setuid(pid); + return setuid(pid); #endif } @@ -2223,20 +2395,22 @@ int APP_CC g_waitchild(void) { #if defined(_WIN32) - return 0; + return 0; #else - int wstat; - int rv; + int wstat; + int rv; - rv = waitpid(0, &wstat, WNOHANG); - if (rv == -1) - { - if (errno == EINTR) /* signal occurred */ + rv = waitpid(0, &wstat, WNOHANG); + + if (rv == -1) { - rv = 0; + if (errno == EINTR) /* signal occurred */ + { + rv = 0; + } } - } - return rv; + + return rv; #endif } @@ -2247,23 +2421,28 @@ int APP_CC g_waitpid(int pid) { #if defined(_WIN32) - return 0; + return 0; #else - int rv = 0; - if (pid < 0) { - rv = -1; - } - else { - rv = waitpid(pid, 0, 0); - if (rv == -1) + int rv = 0; + + if (pid < 0) { - if (errno == EINTR) /* signal occurred */ - { - rv = 0; - } + rv = -1; } - } - return rv; + else + { + rv = waitpid(pid, 0, 0); + + if (rv == -1) + { + if (errno == EINTR) /* signal occurred */ + { + rv = 0; + } + } + } + + return rv; #endif } @@ -2274,31 +2453,31 @@ g_clearenv(void) { #if defined(_WIN32) #else - environ = 0; + environ = 0; #endif } /*****************************************************************************/ /* does not work in win32 */ int APP_CC -g_setenv(const char* name, const char* value, int rewrite) +g_setenv(const char *name, const char *value, int rewrite) { #if defined(_WIN32) - return 0; + return 0; #else - return setenv(name, value, rewrite); + return setenv(name, value, rewrite); #endif } /*****************************************************************************/ /* does not work in win32 */ -char* APP_CC -g_getenv(const char* name) +char *APP_CC +g_getenv(const char *name) { #if defined(_WIN32) - return 0; + return 0; #else - return getenv(name); + return getenv(name); #endif } @@ -2306,8 +2485,8 @@ g_getenv(const char* name) int APP_CC g_exit(int exit_code) { - _exit(exit_code); - return 0; + _exit(exit_code); + return 0; } /*****************************************************************************/ @@ -2315,9 +2494,9 @@ int APP_CC g_getpid(void) { #if defined(_WIN32) - return (int)GetCurrentProcessId(); + return (int)GetCurrentProcessId(); #else - return (int)getpid(); + return (int)getpid(); #endif } @@ -2327,9 +2506,9 @@ int APP_CC g_sigterm(int pid) { #if defined(_WIN32) - return 0; + return 0; #else - return kill(pid, SIGTERM); + return kill(pid, SIGTERM); #endif } @@ -2337,40 +2516,47 @@ g_sigterm(int pid) /* returns 0 if ok */ /* does not work in win32 */ int APP_CC -g_getuser_info(const char* username, int* gid, int* uid, char* shell, - char* dir, char* gecos) +g_getuser_info(const char *username, int *gid, int *uid, char *shell, + char *dir, char *gecos) { #if defined(_WIN32) - return 1; + return 1; #else - struct passwd* pwd_1; + struct passwd *pwd_1; - pwd_1 = getpwnam(username); - if (pwd_1 != 0) - { - if (gid != 0) + pwd_1 = getpwnam(username); + + if (pwd_1 != 0) { - *gid = pwd_1->pw_gid; + if (gid != 0) + { + *gid = pwd_1->pw_gid; + } + + if (uid != 0) + { + *uid = pwd_1->pw_uid; + } + + if (dir != 0) + { + g_strcpy(dir, pwd_1->pw_dir); + } + + if (shell != 0) + { + g_strcpy(shell, pwd_1->pw_shell); + } + + if (gecos != 0) + { + g_strcpy(gecos, pwd_1->pw_gecos); + } + + return 0; } - if (uid != 0) - { - *uid = pwd_1->pw_uid; - } - if (dir != 0) - { - g_strcpy(dir, pwd_1->pw_dir); - } - if (shell != 0) - { - g_strcpy(shell, pwd_1->pw_shell); - } - if (gecos != 0) - { - g_strcpy(gecos, pwd_1->pw_gecos); - } - return 0; - } - return 1; + + return 1; #endif } @@ -2378,23 +2564,26 @@ g_getuser_info(const char* username, int* gid, int* uid, char* shell, /* returns 0 if ok */ /* does not work in win32 */ int APP_CC -g_getgroup_info(const char* groupname, int* gid) +g_getgroup_info(const char *groupname, int *gid) { #if defined(_WIN32) - return 1; + return 1; #else - struct group* g; + struct group *g; - g = getgrnam(groupname); - if (g != 0) - { - if (gid != 0) + g = getgrnam(groupname); + + if (g != 0) { - *gid = g->gr_gid; + if (gid != 0) + { + *gid = g->gr_gid; + } + + return 0; } - return 0; - } - return 1; + + return 1; #endif } @@ -2403,31 +2592,36 @@ g_getgroup_info(const char* groupname, int* gid) /* if zero is returned, then ok is set */ /* does not work in win32 */ int APP_CC -g_check_user_in_group(const char* username, int gid, int* ok) +g_check_user_in_group(const char *username, int gid, int *ok) { #if defined(_WIN32) - return 1; -#else - struct group* groups; - int i; - - groups = getgrgid(gid); - if (groups == 0) - { return 1; - } - *ok = 0; - i = 0; - while (0 != groups->gr_mem[i]) - { - if (0 == g_strcmp(groups->gr_mem[i], username)) +#else + struct group *groups; + int i; + + groups = getgrgid(gid); + + if (groups == 0) { - *ok = 1; - break; + return 1; } - i++; - } - return 0; + + *ok = 0; + i = 0; + + while (0 != groups->gr_mem[i]) + { + if (0 == g_strcmp(groups->gr_mem[i], username)) + { + *ok = 1; + break; + } + + i++; + } + + return 0; #endif } @@ -2440,9 +2634,9 @@ int APP_CC g_time1(void) { #if defined(_WIN32) - return GetTickCount() / 1000; + return GetTickCount() / 1000; #else - return time(0); + return time(0); #endif } @@ -2453,13 +2647,13 @@ int APP_CC g_time2(void) { #if defined(_WIN32) - return (int)GetTickCount(); + return (int)GetTickCount(); #else - struct tms tm; - clock_t num_ticks = 0; - g_memset(&tm,0,sizeof(struct tms)); - num_ticks = times(&tm); - return (int)(num_ticks * 10); + struct tms tm; + clock_t num_ticks = 0; + g_memset(&tm, 0, sizeof(struct tms)); + num_ticks = times(&tm); + return (int)(num_ticks * 10); #endif } @@ -2470,11 +2664,11 @@ int APP_CC g_time3(void) { #if defined(_WIN32) - return 0; + return 0; #else - struct timeval tp; + struct timeval tp; - gettimeofday(&tp, 0); - return (tp.tv_sec * 1000) + (tp.tv_usec / 1000); + gettimeofday(&tp, 0); + return (tp.tv_sec * 1000) + (tp.tv_usec / 1000); #endif } diff --git a/common/os_calls.h b/common/os_calls.h index 41b221bf..c734c9fe 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -1,26 +1,22 @@ -/* - Copyright (c) 2004-2012 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - generic operating system calls -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * generic operating system calls + */ #if !defined(OS_CALLS_H) #define OS_CALLS_H diff --git a/common/parse.h b/common/parse.h index 9bd6850c..deee7845 100644 --- a/common/parse.h +++ b/common/parse.h @@ -1,30 +1,26 @@ -/* - Copyright (c) 2004-2010 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - Parsing structs and macros - - based on parse.h from rdesktop - this is a super fast stream method, you bet - needed functions g_malloc, g_free, g_memset, g_memcpy -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Parsing structs and macros + * + * based on parse.h from rdesktop + * this is a super fast stream method, you bet + * needed functions g_malloc, g_free, g_memset, g_memcpy + */ #if !defined(PARSE_H) #define PARSE_H diff --git a/common/ssl_calls.c b/common/ssl_calls.c index 3d37ed6d..4cb706f3 100644 --- a/common/ssl_calls.c +++ b/common/ssl_calls.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - ssl calls - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ssl calls + */ #include /* needed for openssl headers */ #include @@ -43,197 +41,200 @@ int ssl_init(void) { - SSL_load_error_strings(); - SSL_library_init(); - return 0; + SSL_load_error_strings(); + SSL_library_init(); + return 0; } /*****************************************************************************/ int ssl_finish(void) { - return 0; + return 0; } /* rc4 stuff */ /*****************************************************************************/ -void* APP_CC +void *APP_CC ssl_rc4_info_create(void) { - return g_malloc(sizeof(RC4_KEY), 1); + return g_malloc(sizeof(RC4_KEY), 1); } /*****************************************************************************/ void APP_CC -ssl_rc4_info_delete(void* rc4_info) +ssl_rc4_info_delete(void *rc4_info) { - g_free(rc4_info); + g_free(rc4_info); } /*****************************************************************************/ void APP_CC -ssl_rc4_set_key(void* rc4_info, char* key, int len) +ssl_rc4_set_key(void *rc4_info, char *key, int len) { - RC4_set_key((RC4_KEY*)rc4_info, len, (tui8*)key); + RC4_set_key((RC4_KEY *)rc4_info, len, (tui8 *)key); } /*****************************************************************************/ void APP_CC -ssl_rc4_crypt(void* rc4_info, char* data, int len) +ssl_rc4_crypt(void *rc4_info, char *data, int len) { - RC4((RC4_KEY*)rc4_info, len, (tui8*)data, (tui8*)data); + RC4((RC4_KEY *)rc4_info, len, (tui8 *)data, (tui8 *)data); } /* sha1 stuff */ /*****************************************************************************/ -void* APP_CC +void *APP_CC ssl_sha1_info_create(void) { - return g_malloc(sizeof(SHA_CTX), 1); + return g_malloc(sizeof(SHA_CTX), 1); } /*****************************************************************************/ void APP_CC -ssl_sha1_info_delete(void* sha1_info) +ssl_sha1_info_delete(void *sha1_info) { - g_free(sha1_info); + g_free(sha1_info); } /*****************************************************************************/ void APP_CC -ssl_sha1_clear(void* sha1_info) +ssl_sha1_clear(void *sha1_info) { - SHA1_Init((SHA_CTX*)sha1_info); + SHA1_Init((SHA_CTX *)sha1_info); } /*****************************************************************************/ void APP_CC -ssl_sha1_transform(void* sha1_info, char* data, int len) +ssl_sha1_transform(void *sha1_info, char *data, int len) { - SHA1_Update((SHA_CTX*)sha1_info, data, len); + SHA1_Update((SHA_CTX *)sha1_info, data, len); } /*****************************************************************************/ void APP_CC -ssl_sha1_complete(void* sha1_info, char* data) +ssl_sha1_complete(void *sha1_info, char *data) { - SHA1_Final((tui8*)data, (SHA_CTX*)sha1_info); + SHA1_Final((tui8 *)data, (SHA_CTX *)sha1_info); } /* md5 stuff */ /*****************************************************************************/ -void* APP_CC +void *APP_CC ssl_md5_info_create(void) { - return g_malloc(sizeof(MD5_CTX), 1); + return g_malloc(sizeof(MD5_CTX), 1); } /*****************************************************************************/ void APP_CC -ssl_md5_info_delete(void* md5_info) +ssl_md5_info_delete(void *md5_info) { - g_free(md5_info); + g_free(md5_info); } /*****************************************************************************/ void APP_CC -ssl_md5_clear(void* md5_info) +ssl_md5_clear(void *md5_info) { - MD5_Init((MD5_CTX*)md5_info); + MD5_Init((MD5_CTX *)md5_info); } /*****************************************************************************/ void APP_CC -ssl_md5_transform(void* md5_info, char* data, int len) +ssl_md5_transform(void *md5_info, char *data, int len) { - MD5_Update((MD5_CTX*)md5_info, data, len); + MD5_Update((MD5_CTX *)md5_info, data, len); } /*****************************************************************************/ void APP_CC -ssl_md5_complete(void* md5_info, char* data) +ssl_md5_complete(void *md5_info, char *data) { - MD5_Final((tui8*)data, (MD5_CTX*)md5_info); + MD5_Final((tui8 *)data, (MD5_CTX *)md5_info); } /*****************************************************************************/ static void APP_CC -ssl_reverse_it(char* p, int len) +ssl_reverse_it(char *p, int len) { - int i; - int j; - char temp; + int i; + int j; + char temp; - i = 0; - j = len - 1; - while (i < j) - { - temp = p[i]; - p[i] = p[j]; - p[j] = temp; - i++; - j--; - } + i = 0; + j = len - 1; + + while (i < j) + { + temp = p[i]; + p[i] = p[j]; + p[j] = temp; + i++; + j--; + } } /*****************************************************************************/ int APP_CC -ssl_mod_exp(char* out, int out_len, char* in, int in_len, - char* mod, int mod_len, char* exp, int exp_len) +ssl_mod_exp(char *out, int out_len, char *in, int in_len, + char *mod, int mod_len, char *exp, int exp_len) { - BN_CTX* ctx; - BIGNUM lmod; - BIGNUM lexp; - BIGNUM lin; - BIGNUM lout; - int rv; - char* l_out; - char* l_in; - char* l_mod; - char* l_exp; + BN_CTX *ctx; + BIGNUM lmod; + BIGNUM lexp; + BIGNUM lin; + BIGNUM lout; + int rv; + char *l_out; + char *l_in; + char *l_mod; + char *l_exp; - l_out = (char*)g_malloc(out_len, 1); - l_in = (char*)g_malloc(in_len, 1); - l_mod = (char*)g_malloc(mod_len, 1); - l_exp = (char*)g_malloc(exp_len, 1); - g_memcpy(l_in, in, in_len); - g_memcpy(l_mod, mod, mod_len); - g_memcpy(l_exp, exp, exp_len); - ssl_reverse_it(l_in, in_len); - ssl_reverse_it(l_mod, mod_len); - ssl_reverse_it(l_exp, exp_len); - ctx = BN_CTX_new(); - BN_init(&lmod); - BN_init(&lexp); - BN_init(&lin); - BN_init(&lout); - BN_bin2bn((tui8*)l_mod, mod_len, &lmod); - BN_bin2bn((tui8*)l_exp, exp_len, &lexp); - BN_bin2bn((tui8*)l_in, in_len, &lin); - BN_mod_exp(&lout, &lin, &lexp, &lmod, ctx); - rv = BN_bn2bin(&lout, (tui8*)l_out); - if (rv <= out_len) - { - ssl_reverse_it(l_out, rv); - g_memcpy(out, l_out, out_len); - } - else - { - rv = 0; - } - BN_free(&lin); - BN_free(&lout); - BN_free(&lexp); - BN_free(&lmod); - BN_CTX_free(ctx); - g_free(l_out); - g_free(l_in); - g_free(l_mod); - g_free(l_exp); - return rv; + l_out = (char *)g_malloc(out_len, 1); + l_in = (char *)g_malloc(in_len, 1); + l_mod = (char *)g_malloc(mod_len, 1); + l_exp = (char *)g_malloc(exp_len, 1); + g_memcpy(l_in, in, in_len); + g_memcpy(l_mod, mod, mod_len); + g_memcpy(l_exp, exp, exp_len); + ssl_reverse_it(l_in, in_len); + ssl_reverse_it(l_mod, mod_len); + ssl_reverse_it(l_exp, exp_len); + ctx = BN_CTX_new(); + BN_init(&lmod); + BN_init(&lexp); + BN_init(&lin); + BN_init(&lout); + BN_bin2bn((tui8 *)l_mod, mod_len, &lmod); + BN_bin2bn((tui8 *)l_exp, exp_len, &lexp); + BN_bin2bn((tui8 *)l_in, in_len, &lin); + BN_mod_exp(&lout, &lin, &lexp, &lmod, ctx); + rv = BN_bn2bin(&lout, (tui8 *)l_out); + + if (rv <= out_len) + { + ssl_reverse_it(l_out, rv); + g_memcpy(out, l_out, out_len); + } + else + { + rv = 0; + } + + BN_free(&lin); + BN_free(&lout); + BN_free(&lexp); + BN_free(&lmod); + BN_CTX_free(ctx); + g_free(l_out); + g_free(l_in); + g_free(l_mod); + g_free(l_exp); + return rv; } #if defined(OLD_RSA_GEN1) @@ -242,61 +243,68 @@ ssl_mod_exp(char* out, int out_len, char* in, int in_len, generates a new rsa key exp is passed in and mod and pri are passed out */ int APP_CC -ssl_gen_key_xrdp1(int key_size_in_bits, char* exp, int exp_len, - char* mod, int mod_len, char* pri, int pri_len) +ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len, + char *mod, int mod_len, char *pri, int pri_len) { - int my_e; - RSA* my_key; - char* lmod; - char* lpri; - tui8* lexp; - int error; - int len; + int my_e; + RSA *my_key; + char *lmod; + char *lpri; + tui8 *lexp; + int error; + int len; - if ((exp_len != 4) || (mod_len != 64) || (pri_len != 64)) - { - return 1; - } - lmod = (char*)g_malloc(mod_len, 0); - lpri = (char*)g_malloc(pri_len, 0); - lexp = (tui8*)exp; - my_e = lexp[0]; - my_e |= lexp[1] << 8; - my_e |= lexp[2] << 16; - my_e |= lexp[3] << 24; - /* srand is in stdlib.h */ - srand(g_time1()); - my_key = RSA_generate_key(key_size_in_bits, my_e, 0, 0); - error = my_key == 0; - if (error == 0) - { - len = BN_num_bytes(my_key->n); - error = len != mod_len; - } - if (error == 0) - { - BN_bn2bin(my_key->n, (tui8*)lmod); - ssl_reverse_it(lmod, mod_len); - } - if (error == 0) - { - len = BN_num_bytes(my_key->d); - error = len != pri_len; - } - if (error == 0) - { - BN_bn2bin(my_key->d, (tui8*)lpri); - ssl_reverse_it(lpri, pri_len); - } - if (error == 0) - { - g_memcpy(mod, lmod, mod_len); - g_memcpy(pri, lpri, pri_len); - } - RSA_free(my_key); - g_free(lmod); - g_free(lpri); - return error; + if ((exp_len != 4) || (mod_len != 64) || (pri_len != 64)) + { + return 1; + } + + lmod = (char *)g_malloc(mod_len, 0); + lpri = (char *)g_malloc(pri_len, 0); + lexp = (tui8 *)exp; + my_e = lexp[0]; + my_e |= lexp[1] << 8; + my_e |= lexp[2] << 16; + my_e |= lexp[3] << 24; + /* srand is in stdlib.h */ + srand(g_time1()); + my_key = RSA_generate_key(key_size_in_bits, my_e, 0, 0); + error = my_key == 0; + + if (error == 0) + { + len = BN_num_bytes(my_key->n); + error = len != mod_len; + } + + if (error == 0) + { + BN_bn2bin(my_key->n, (tui8 *)lmod); + ssl_reverse_it(lmod, mod_len); + } + + if (error == 0) + { + len = BN_num_bytes(my_key->d); + error = len != pri_len; + } + + if (error == 0) + { + BN_bn2bin(my_key->d, (tui8 *)lpri); + ssl_reverse_it(lpri, pri_len); + } + + if (error == 0) + { + g_memcpy(mod, lmod, mod_len); + g_memcpy(pri, lpri, pri_len); + } + + RSA_free(my_key); + g_free(lmod); + g_free(lpri); + return error; } #else /*****************************************************************************/ @@ -304,60 +312,67 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char* exp, int exp_len, generates a new rsa key exp is passed in and mod and pri are passed out */ int APP_CC -ssl_gen_key_xrdp1(int key_size_in_bits, char* exp, int exp_len, - char* mod, int mod_len, char* pri, int pri_len) +ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len, + char *mod, int mod_len, char *pri, int pri_len) { - BIGNUM* my_e; - RSA* my_key; - char* lexp; - char* lmod; - char* lpri; - int error; - int len; + BIGNUM *my_e; + RSA *my_key; + char *lexp; + char *lmod; + char *lpri; + int error; + int len; - if ((exp_len != 4) || (mod_len != 64) || (pri_len != 64)) - { - return 1; - } - lexp = (char*)g_malloc(exp_len, 0); - lmod = (char*)g_malloc(mod_len, 0); - lpri = (char*)g_malloc(pri_len, 0); - g_memcpy(lexp, exp, exp_len); - ssl_reverse_it(lexp, exp_len); - my_e = BN_new(); - BN_bin2bn((tui8*)lexp, exp_len, my_e); - my_key = RSA_new(); - error = RSA_generate_key_ex(my_key, key_size_in_bits, my_e, 0) == 0; - if (error == 0) - { - len = BN_num_bytes(my_key->n); - error = len != mod_len; - } - if (error == 0) - { - BN_bn2bin(my_key->n, (tui8*)lmod); - ssl_reverse_it(lmod, mod_len); - } - if (error == 0) - { - len = BN_num_bytes(my_key->d); - error = len != pri_len; - } - if (error == 0) - { - BN_bn2bin(my_key->d, (tui8*)lpri); - ssl_reverse_it(lpri, pri_len); - } - if (error == 0) - { - g_memcpy(mod, lmod, mod_len); - g_memcpy(pri, lpri, pri_len); - } - BN_free(my_e); - RSA_free(my_key); - g_free(lexp); - g_free(lmod); - g_free(lpri); - return error; + if ((exp_len != 4) || (mod_len != 64) || (pri_len != 64)) + { + return 1; + } + + lexp = (char *)g_malloc(exp_len, 0); + lmod = (char *)g_malloc(mod_len, 0); + lpri = (char *)g_malloc(pri_len, 0); + g_memcpy(lexp, exp, exp_len); + ssl_reverse_it(lexp, exp_len); + my_e = BN_new(); + BN_bin2bn((tui8 *)lexp, exp_len, my_e); + my_key = RSA_new(); + error = RSA_generate_key_ex(my_key, key_size_in_bits, my_e, 0) == 0; + + if (error == 0) + { + len = BN_num_bytes(my_key->n); + error = len != mod_len; + } + + if (error == 0) + { + BN_bn2bin(my_key->n, (tui8 *)lmod); + ssl_reverse_it(lmod, mod_len); + } + + if (error == 0) + { + len = BN_num_bytes(my_key->d); + error = len != pri_len; + } + + if (error == 0) + { + BN_bn2bin(my_key->d, (tui8 *)lpri); + ssl_reverse_it(lpri, pri_len); + } + + if (error == 0) + { + g_memcpy(mod, lmod, mod_len); + g_memcpy(pri, lpri, pri_len); + } + + BN_free(my_e); + RSA_free(my_key); + g_free(lexp); + g_free(lmod); + g_free(lpri); + return error; } #endif diff --git a/common/ssl_calls.h b/common/ssl_calls.h index d78bdb0b..f4a63155 100644 --- a/common/ssl_calls.h +++ b/common/ssl_calls.h @@ -1,22 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #if !defined(SSL_CALLS_H) #define SSL_CALLS_H diff --git a/common/thread_calls.c b/common/thread_calls.c index 80856fd8..ad944d02 100644 --- a/common/thread_calls.c +++ b/common/thread_calls.c @@ -1,27 +1,22 @@ -/* - Copyright (c) 2004-2010 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - thread calls - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * thread calls + */ #if defined(_WIN32) #include @@ -38,33 +33,36 @@ /* returns error */ #if defined(_WIN32) int APP_CC -tc_thread_create(unsigned long (__stdcall * start_routine)(void*), void* arg) +tc_thread_create(unsigned long (__stdcall *start_routine)(void *), void *arg) { - int rv = 0; - DWORD thread_id = 0; - HANDLE thread = (HANDLE)0; + int rv = 0; + DWORD thread_id = 0; + HANDLE thread = (HANDLE)0; - /* CreateThread returns handle or zero on error */ - thread = CreateThread(0, 0, start_routine, arg, 0, &thread_id); - rv = !thread; - CloseHandle(thread); - return rv; + /* CreateThread returns handle or zero on error */ + thread = CreateThread(0, 0, start_routine, arg, 0, &thread_id); + rv = !thread; + CloseHandle(thread); + return rv; } #else int APP_CC -tc_thread_create(void* (* start_routine)(void *), void* arg) +tc_thread_create(void * (* start_routine)(void *), void *arg) { - int rv = 0; - pthread_t thread = (pthread_t)0; + int rv = 0; + pthread_t thread = (pthread_t)0; - g_memset(&thread, 0x00, sizeof(pthread_t)); + g_memset(&thread, 0x00, sizeof(pthread_t)); - /* pthread_create returns error */ - rv = pthread_create(&thread, 0, start_routine, arg); - if (!rv) { - rv = pthread_detach(thread); - } - return rv; + /* pthread_create returns error */ + rv = pthread_create(&thread, 0, start_routine, arg); + + if (!rv) + { + rv = pthread_detach(thread); + } + + return rv; } #endif @@ -73,9 +71,9 @@ tbus APP_CC tc_get_threadid(void) { #if defined(_WIN32) - return (tbus)GetCurrentThreadId(); + return (tbus)GetCurrentThreadId(); #else - return (tbus)pthread_self(); + return (tbus)pthread_self(); #endif } @@ -85,9 +83,9 @@ int APP_CC tc_threadid_equal(tbus tid1, tbus tid2) { #if defined(_WIN32) - return tid1 == tid2; + return tid1 == tid2; #else - return pthread_equal((pthread_t)tid1, (pthread_t)tid2); + return pthread_equal((pthread_t)tid1, (pthread_t)tid2); #endif } @@ -96,13 +94,13 @@ tbus APP_CC tc_mutex_create(void) { #if defined(_WIN32) - return (tbus)CreateMutex(0, 0, 0); + return (tbus)CreateMutex(0, 0, 0); #else - pthread_mutex_t* lmutex; + pthread_mutex_t *lmutex; - lmutex = (pthread_mutex_t*)g_malloc(sizeof(pthread_mutex_t), 0); - pthread_mutex_init(lmutex, 0); - return (tbus)lmutex; + lmutex = (pthread_mutex_t *)g_malloc(sizeof(pthread_mutex_t), 0); + pthread_mutex_init(lmutex, 0); + return (tbus)lmutex; #endif } @@ -111,13 +109,13 @@ void APP_CC tc_mutex_delete(tbus mutex) { #if defined(_WIN32) - CloseHandle((HANDLE)mutex); + CloseHandle((HANDLE)mutex); #else - pthread_mutex_t* lmutex; + pthread_mutex_t *lmutex; - lmutex = (pthread_mutex_t*)mutex; - pthread_mutex_destroy(lmutex); - g_free(lmutex); + lmutex = (pthread_mutex_t *)mutex; + pthread_mutex_destroy(lmutex); + g_free(lmutex); #endif } @@ -126,11 +124,11 @@ int APP_CC tc_mutex_lock(tbus mutex) { #if defined(_WIN32) - WaitForSingleObject((HANDLE)mutex, INFINITE); - return 0; + WaitForSingleObject((HANDLE)mutex, INFINITE); + return 0; #else - pthread_mutex_lock((pthread_mutex_t*)mutex); - return 0; + pthread_mutex_lock((pthread_mutex_t *)mutex); + return 0; #endif } @@ -138,15 +136,18 @@ tc_mutex_lock(tbus mutex) int APP_CC tc_mutex_unlock(tbus mutex) { - int rv = 0; + int rv = 0; #if defined(_WIN32) - ReleaseMutex((HANDLE)mutex); + ReleaseMutex((HANDLE)mutex); #else - if (mutex != 0) { - rv = pthread_mutex_unlock((pthread_mutex_t *)mutex); - } + + if (mutex != 0) + { + rv = pthread_mutex_unlock((pthread_mutex_t *)mutex); + } + #endif - return rv; + return rv; } /*****************************************************************************/ @@ -154,16 +155,16 @@ tbus APP_CC tc_sem_create(int init_count) { #if defined(_WIN32) - HANDLE sem; + HANDLE sem; - sem = CreateSemaphore(0, init_count, init_count + 10, 0); - return (tbus)sem; + sem = CreateSemaphore(0, init_count, init_count + 10, 0); + return (tbus)sem; #else - sem_t * sem = (sem_t *)NULL; + sem_t *sem = (sem_t *)NULL; - sem = (sem_t *)g_malloc(sizeof(sem_t), 0); - sem_init(sem, 0, init_count); - return (tbus)sem; + sem = (sem_t *)g_malloc(sizeof(sem_t), 0); + sem_init(sem, 0, init_count); + return (tbus)sem; #endif } @@ -172,13 +173,13 @@ void APP_CC tc_sem_delete(tbus sem) { #if defined(_WIN32) - CloseHandle((HANDLE)sem); + CloseHandle((HANDLE)sem); #else - sem_t* lsem; + sem_t *lsem; - lsem = (sem_t*)sem; - sem_destroy(lsem); - g_free(lsem); + lsem = (sem_t *)sem; + sem_destroy(lsem); + g_free(lsem); #endif } @@ -187,11 +188,11 @@ int APP_CC tc_sem_dec(tbus sem) { #if defined(_WIN32) - WaitForSingleObject((HANDLE)sem, INFINITE); - return 0; + WaitForSingleObject((HANDLE)sem, INFINITE); + return 0; #else - sem_wait((sem_t*)sem); - return 0; + sem_wait((sem_t *)sem); + return 0; #endif } @@ -200,10 +201,10 @@ int APP_CC tc_sem_inc(tbus sem) { #if defined(_WIN32) - ReleaseSemaphore((HANDLE)sem, 1, 0); - return 0; + ReleaseSemaphore((HANDLE)sem, 1, 0); + return 0; #else - sem_post((sem_t*)sem); - return 0; + sem_post((sem_t *)sem); + return 0; #endif } diff --git a/common/thread_calls.h b/common/thread_calls.h index cc40a7d9..0c853d22 100644 --- a/common/thread_calls.h +++ b/common/thread_calls.h @@ -1,27 +1,22 @@ -/* - Copyright (c) 2004-2010 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - thread calls - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * thread calls + */ #if !defined(THREAD_CALLS_H) #define THREAD_CALLS_H diff --git a/common/trans.c b/common/trans.c index 6b762d00..c287d310 100644 --- a/common/trans.c +++ b/common/trans.c @@ -1,27 +1,22 @@ -/* - Copyright (c) 2008-2010 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - generic transport - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * generic transport + */ #include "os_calls.h" #include "trans.h" @@ -29,394 +24,440 @@ #include "parse.h" /*****************************************************************************/ -struct trans* APP_CC +struct trans *APP_CC trans_create(int mode, int in_size, int out_size) { - struct trans* self = (struct trans *)NULL; + struct trans *self = (struct trans *)NULL; - self = (struct trans*)g_malloc(sizeof(struct trans), 1); - if (self != NULL) { - make_stream(self->in_s); - init_stream(self->in_s, in_size); - make_stream(self->out_s); - init_stream(self->out_s, out_size); - self->mode = mode; - } - return self; + self = (struct trans *)g_malloc(sizeof(struct trans), 1); + + if (self != NULL) + { + make_stream(self->in_s); + init_stream(self->in_s, in_size); + make_stream(self->out_s); + init_stream(self->out_s, out_size); + self->mode = mode; + } + + return self; } /*****************************************************************************/ void APP_CC -trans_delete(struct trans* self) +trans_delete(struct trans *self) { - if (self == 0) - { - return; - } - free_stream(self->in_s); - free_stream(self->out_s); - if (self->sck > 0) { - g_tcp_close(self->sck); - } - self->sck = 0; - if (self->listen_filename != 0) - { - g_file_delete(self->listen_filename); - g_free(self->listen_filename); - } - g_free(self); -} - -/*****************************************************************************/ -int APP_CC -trans_get_wait_objs(struct trans* self, tbus* objs, int* count) -{ - if (self == 0) - { - return 1; - } - if (self->status != TRANS_STATUS_UP) - { - return 1; - } - objs[*count] = self->sck; - (*count)++; - return 0; -} - -/*****************************************************************************/ -int APP_CC -trans_check_wait_objs(struct trans* self) -{ - tbus in_sck = (tbus)0; - struct trans* in_trans = (struct trans *)NULL; - int read_bytes = 0; - int to_read = 0; - int read_so_far = 0; - int rv = 0; - - if (self == 0) - { - return 1; - } - if (self->status != TRANS_STATUS_UP) - { - return 1; - } - rv = 0; - if (self->type1 == TRANS_TYPE_LISTENER) /* listening */ - { - if (g_tcp_can_recv(self->sck, 0)) + if (self == 0) { - in_sck = g_tcp_accept(self->sck); - if (in_sck == -1) - { - if (g_tcp_last_error_would_block(self->sck)) - { - /* ok, but shouldn't happen */ - } - else - { - /* error */ - self->status = TRANS_STATUS_DOWN; - return 1; - } - } - if (in_sck != -1) - { - if (self->trans_conn_in != 0) /* is function assigned */ - { - in_trans = trans_create(self->mode, self->in_s->size, - self->out_s->size); - in_trans->sck = in_sck; - in_trans->type1 = TRANS_TYPE_SERVER; - in_trans->status = TRANS_STATUS_UP; - if (self->trans_conn_in(self, in_trans) != 0) - { - trans_delete(in_trans); - } - } - else - { - g_tcp_close(in_sck); - } - } + return; } - } - else /* connected server or client (2 or 3) */ - { - if (g_tcp_can_recv(self->sck, 0)) + + free_stream(self->in_s); + free_stream(self->out_s); + + if (self->sck > 0) { - read_so_far = (int)(self->in_s->end - self->in_s->data); - to_read = self->header_size - read_so_far; - if (to_read > 0) - { - read_bytes = g_tcp_recv(self->sck, self->in_s->end, to_read, 0); - if (read_bytes == -1) + g_tcp_close(self->sck); + } + + self->sck = 0; + + if (self->listen_filename != 0) + { + g_file_delete(self->listen_filename); + g_free(self->listen_filename); + } + + g_free(self); +} + +/*****************************************************************************/ +int APP_CC +trans_get_wait_objs(struct trans *self, tbus *objs, int *count) +{ + if (self == 0) + { + return 1; + } + + if (self->status != TRANS_STATUS_UP) + { + return 1; + } + + objs[*count] = self->sck; + (*count)++; + return 0; +} + +/*****************************************************************************/ +int APP_CC +trans_check_wait_objs(struct trans *self) +{ + tbus in_sck = (tbus)0; + struct trans *in_trans = (struct trans *)NULL; + int read_bytes = 0; + int to_read = 0; + int read_so_far = 0; + int rv = 0; + + if (self == 0) + { + return 1; + } + + if (self->status != TRANS_STATUS_UP) + { + return 1; + } + + rv = 0; + + if (self->type1 == TRANS_TYPE_LISTENER) /* listening */ + { + if (g_tcp_can_recv(self->sck, 0)) + { + in_sck = g_tcp_accept(self->sck); + + if (in_sck == -1) + { + if (g_tcp_last_error_would_block(self->sck)) + { + /* ok, but shouldn't happen */ + } + else + { + /* error */ + self->status = TRANS_STATUS_DOWN; + return 1; + } + } + + if (in_sck != -1) + { + if (self->trans_conn_in != 0) /* is function assigned */ + { + in_trans = trans_create(self->mode, self->in_s->size, + self->out_s->size); + in_trans->sck = in_sck; + in_trans->type1 = TRANS_TYPE_SERVER; + in_trans->status = TRANS_STATUS_UP; + + if (self->trans_conn_in(self, in_trans) != 0) + { + trans_delete(in_trans); + } + } + else + { + g_tcp_close(in_sck); + } + } + } + } + else /* connected server or client (2 or 3) */ + { + if (g_tcp_can_recv(self->sck, 0)) + { + read_so_far = (int)(self->in_s->end - self->in_s->data); + to_read = self->header_size - read_so_far; + + if (to_read > 0) + { + read_bytes = g_tcp_recv(self->sck, self->in_s->end, to_read, 0); + + if (read_bytes == -1) + { + if (g_tcp_last_error_would_block(self->sck)) + { + /* ok, but shouldn't happen */ + } + else + { + /* error */ + self->status = TRANS_STATUS_DOWN; + return 1; + } + } + else if (read_bytes == 0) + { + /* error */ + self->status = TRANS_STATUS_DOWN; + return 1; + } + else + { + self->in_s->end += read_bytes; + } + } + + read_so_far = (int)(self->in_s->end - self->in_s->data); + + if (read_so_far == self->header_size) + { + if (self->trans_data_in != 0) + { + rv = self->trans_data_in(self); + init_stream(self->in_s, 0); + } + } + } + } + + return rv; +} + +/*****************************************************************************/ +int APP_CC +trans_force_read_s(struct trans *self, struct stream *in_s, int size) +{ + int rcvd; + + if (self->status != TRANS_STATUS_UP) + { + return 1; + } + + while (size > 0) + { + rcvd = g_tcp_recv(self->sck, in_s->end, size, 0); + + if (rcvd == -1) + { + if (g_tcp_last_error_would_block(self->sck)) + { + if (!g_tcp_can_recv(self->sck, 10)) + { + /* check for term here */ + } + } + else + { + /* error */ + self->status = TRANS_STATUS_DOWN; + return 1; + } + } + else if (rcvd == 0) { - if (g_tcp_last_error_would_block(self->sck)) - { - /* ok, but shouldn't happen */ - } - else - { /* error */ self->status = TRANS_STATUS_DOWN; return 1; - } - } - else if (read_bytes == 0) - { - /* error */ - self->status = TRANS_STATUS_DOWN; - return 1; } else { - self->in_s->end += read_bytes; + in_s->end += rcvd; + size -= rcvd; } - } - read_so_far = (int)(self->in_s->end - self->in_s->data); - if (read_so_far == self->header_size) - { - if (self->trans_data_in != 0) - { - rv = self->trans_data_in(self); - init_stream(self->in_s, 0); - } - } } - } - return rv; + + return 0; } /*****************************************************************************/ int APP_CC -trans_force_read_s(struct trans* self, struct stream* in_s, int size) +trans_force_read(struct trans *self, int size) { - int rcvd; + return trans_force_read_s(self, self->in_s, size); +} - if (self->status != TRANS_STATUS_UP) - { - return 1; - } - while (size > 0) - { - rcvd = g_tcp_recv(self->sck, in_s->end, size, 0); - if (rcvd == -1) +/*****************************************************************************/ +int APP_CC +trans_force_write_s(struct trans *self, struct stream *out_s) +{ + int size; + int total; + int sent; + + if (self->status != TRANS_STATUS_UP) { - if (g_tcp_last_error_would_block(self->sck)) - { - if (!g_tcp_can_recv(self->sck, 10)) - { - /* check for term here */ - } - } - else - { - /* error */ - self->status = TRANS_STATUS_DOWN; return 1; - } } - else if (rcvd == 0) - { - /* error */ - self->status = TRANS_STATUS_DOWN; - return 1; - } - else - { - in_s->end += rcvd; - size -= rcvd; - } - } - return 0; -} -/*****************************************************************************/ -int APP_CC -trans_force_read(struct trans* self, int size) -{ - return trans_force_read_s(self, self->in_s, size); -} + size = (int)(out_s->end - out_s->data); + total = 0; -/*****************************************************************************/ -int APP_CC -trans_force_write_s(struct trans* self, struct stream* out_s) -{ - int size; - int total; - int sent; - - if (self->status != TRANS_STATUS_UP) - { - return 1; - } - size = (int)(out_s->end - out_s->data); - total = 0; - while (total < size) - { - sent = g_tcp_send(self->sck, out_s->data + total, size - total, 0); - if (sent == -1) + while (total < size) { - if (g_tcp_last_error_would_block(self->sck)) - { - if (!g_tcp_can_send(self->sck, 10)) + sent = g_tcp_send(self->sck, out_s->data + total, size - total, 0); + + if (sent == -1) { - /* check for term here */ + if (g_tcp_last_error_would_block(self->sck)) + { + if (!g_tcp_can_send(self->sck, 10)) + { + /* check for term here */ + } + } + else + { + /* error */ + self->status = TRANS_STATUS_DOWN; + return 1; + } + } + else if (sent == 0) + { + /* error */ + self->status = TRANS_STATUS_DOWN; + return 1; + } + else + { + total = total + sent; } - } - else - { - /* error */ - self->status = TRANS_STATUS_DOWN; - return 1; - } } - else if (sent == 0) - { - /* error */ - self->status = TRANS_STATUS_DOWN; - return 1; - } - else - { - total = total + sent; - } - } - return 0; + + return 0; } /*****************************************************************************/ int APP_CC -trans_force_write(struct trans* self) +trans_force_write(struct trans *self) { - return trans_force_write_s(self, self->out_s); + return trans_force_write_s(self, self->out_s); } /*****************************************************************************/ int APP_CC -trans_connect(struct trans* self, const char* server, const char* port, +trans_connect(struct trans *self, const char *server, const char *port, int timeout) { - int error; + int error; - if (self->sck != 0) - { - g_tcp_close(self->sck); - } - if (self->mode == TRANS_MODE_TCP) /* tcp */ - { - self->sck = g_tcp_socket(); - g_tcp_set_non_blocking(self->sck); - error = g_tcp_connect(self->sck, server, port); - } - else if (self->mode == TRANS_MODE_UNIX) /* unix socket */ - { - self->sck = g_tcp_local_socket(); - g_tcp_set_non_blocking(self->sck); - error = g_tcp_local_connect(self->sck, port); - } - else - { - self->status = TRANS_STATUS_DOWN; - return 1; - } - if (error == -1) - { - if (g_tcp_last_error_would_block(self->sck)) + if (self->sck != 0) { - if (g_tcp_can_send(self->sck, timeout)) - { - self->status = TRANS_STATUS_UP; /* ok */ - self->type1 = TRANS_TYPE_CLIENT; /* client */ - return 0; - } + g_tcp_close(self->sck); } - return 1; - } - self->status = TRANS_STATUS_UP; /* ok */ - self->type1 = TRANS_TYPE_CLIENT; /* client */ - return 0; + + if (self->mode == TRANS_MODE_TCP) /* tcp */ + { + self->sck = g_tcp_socket(); + g_tcp_set_non_blocking(self->sck); + error = g_tcp_connect(self->sck, server, port); + } + else if (self->mode == TRANS_MODE_UNIX) /* unix socket */ + { + self->sck = g_tcp_local_socket(); + g_tcp_set_non_blocking(self->sck); + error = g_tcp_local_connect(self->sck, port); + } + else + { + self->status = TRANS_STATUS_DOWN; + return 1; + } + + if (error == -1) + { + if (g_tcp_last_error_would_block(self->sck)) + { + if (g_tcp_can_send(self->sck, timeout)) + { + self->status = TRANS_STATUS_UP; /* ok */ + self->type1 = TRANS_TYPE_CLIENT; /* client */ + return 0; + } + } + + return 1; + } + + self->status = TRANS_STATUS_UP; /* ok */ + self->type1 = TRANS_TYPE_CLIENT; /* client */ + return 0; } /*****************************************************************************/ int APP_CC -trans_listen_address(struct trans* self, char* port, const char* address) +trans_listen_address(struct trans *self, char *port, const char *address) { - if (self->sck != 0) - { - g_tcp_close(self->sck); - } - if (self->mode == TRANS_MODE_TCP) /* tcp */ - { - self->sck = g_tcp_socket(); - g_tcp_set_non_blocking(self->sck); - if (g_tcp_bind_address(self->sck, port, address) == 0) + if (self->sck != 0) { - if (g_tcp_listen(self->sck) == 0) - { - self->status = TRANS_STATUS_UP; /* ok */ - self->type1 = TRANS_TYPE_LISTENER; /* listener */ - return 0; - } + g_tcp_close(self->sck); } - } - else if (self->mode == TRANS_MODE_UNIX) /* unix socket */ - { - g_free(self->listen_filename); - self->listen_filename = 0; - g_file_delete(port); - self->sck = g_tcp_local_socket(); - g_tcp_set_non_blocking(self->sck); - if (g_tcp_local_bind(self->sck, port) == 0) + + if (self->mode == TRANS_MODE_TCP) /* tcp */ { - self->listen_filename = g_strdup(port); - if (g_tcp_listen(self->sck) == 0) - { - g_chmod_hex(port, 0xffff); - self->status = TRANS_STATUS_UP; /* ok */ - self->type1 = TRANS_TYPE_LISTENER; /* listener */ - return 0; - } + self->sck = g_tcp_socket(); + g_tcp_set_non_blocking(self->sck); + + if (g_tcp_bind_address(self->sck, port, address) == 0) + { + if (g_tcp_listen(self->sck) == 0) + { + self->status = TRANS_STATUS_UP; /* ok */ + self->type1 = TRANS_TYPE_LISTENER; /* listener */ + return 0; + } + } } - } - return 1; + else if (self->mode == TRANS_MODE_UNIX) /* unix socket */ + { + g_free(self->listen_filename); + self->listen_filename = 0; + g_file_delete(port); + self->sck = g_tcp_local_socket(); + g_tcp_set_non_blocking(self->sck); + + if (g_tcp_local_bind(self->sck, port) == 0) + { + self->listen_filename = g_strdup(port); + + if (g_tcp_listen(self->sck) == 0) + { + g_chmod_hex(port, 0xffff); + self->status = TRANS_STATUS_UP; /* ok */ + self->type1 = TRANS_TYPE_LISTENER; /* listener */ + return 0; + } + } + } + + return 1; } /*****************************************************************************/ int APP_CC -trans_listen(struct trans* self, char* port) +trans_listen(struct trans *self, char *port) { - return trans_listen_address(self, port, "0.0.0.0"); + return trans_listen_address(self, port, "0.0.0.0"); } /*****************************************************************************/ -struct stream* APP_CC -trans_get_in_s(struct trans* self) +struct stream *APP_CC +trans_get_in_s(struct trans *self) { - struct stream * rv = (struct stream *)NULL; - if (self == NULL) { - rv = (struct stream *)NULL; - } - else { - rv = self->in_s; - } - return rv; + struct stream *rv = (struct stream *)NULL; + + if (self == NULL) + { + rv = (struct stream *)NULL; + } + else + { + rv = self->in_s; + } + + return rv; } /*****************************************************************************/ -struct stream* APP_CC -trans_get_out_s(struct trans* self, int size) +struct stream *APP_CC +trans_get_out_s(struct trans *self, int size) { - struct stream * rv = (struct stream *)NULL; - if (self == NULL) { - rv = (struct stream *)NULL; - } - else { - init_stream(self->out_s, size); - rv = self->out_s; - } - return rv; + struct stream *rv = (struct stream *)NULL; + + if (self == NULL) + { + rv = (struct stream *)NULL; + } + else + { + init_stream(self->out_s, size); + rv = self->out_s; + } + + return rv; } diff --git a/common/trans.h b/common/trans.h index 8e8d942a..36d08a7c 100644 --- a/common/trans.h +++ b/common/trans.h @@ -1,27 +1,22 @@ -/* - Copyright (c) 2008-2010 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - generic transport - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * generic transport + */ #if !defined(TRANS_H) #define TRANS_H diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index f95543a3..596177c4 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -1,27 +1,22 @@ -/* - Copyright (c) 2012 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - xrdp / xserver info / caps - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * xrdp / xserver info / caps + */ #if !defined(XRDP_CLIENT_INFO_H) #define XRDP_CLIENT_INFO_H diff --git a/fontdump/fontdump.c b/fontdump/fontdump.c index 34bdffdc..03609cf0 100755 --- a/fontdump/fontdump.c +++ b/fontdump/fontdump.c @@ -1,3 +1,20 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #include @@ -25,426 +42,485 @@ static int g_running = 0; int check_messages(void) { - MSG msg; + MSG msg; - while (PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) - { - GetMessage(&msg, NULL, 0, 0); - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return 0; + while (PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) + { + GetMessage(&msg, NULL, 0, 0); + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 0; } /*****************************************************************************/ static int -msg(char* msg1, ...) +msg(char *msg1, ...) { - va_list ap; - char text1[512]; + va_list ap; + char text1[512]; - va_start(ap, msg1); - vsnprintf(text1, 511, msg1, ap); - SendMessageA(g_lb, LB_ADDSTRING, 0, (LPARAM)text1); - va_end(ap); - return 0; + va_start(ap, msg1); + vsnprintf(text1, 511, msg1, ap); + SendMessageA(g_lb, LB_ADDSTRING, 0, (LPARAM)text1); + va_end(ap); + return 0; } /*****************************************************************************/ static int show_last_error(void) { - LPVOID lpMsgBuf; - - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&lpMsgBuf, 0, NULL); - msg("GetLastError - %s", lpMsgBuf); - LocalFree(lpMsgBuf); - return 0; + LPVOID lpMsgBuf; + + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&lpMsgBuf, 0, NULL); + msg("GetLastError - %s", lpMsgBuf); + LocalFree(lpMsgBuf); + return 0; } /*****************************************************************************/ static int font_dump(void) { - HDC dc; - HDC dc1; - RECT rect; - HBRUSH brush; - HGDIOBJ saved; - HBITMAP bitmap; - BITMAPINFO bi; - char* bits; - ABC abc; - SIZE sz; - char filename[256]; - TCHAR text[256]; - char zero1; - char* bmtext; - int bmtextindex; - int fd; - int x1; - int strlen1; - int index1; - int index2; - int len; - int pixel; - int red; - int green; - int blue; - int width; - int height; - int roller; - int outlen; - tui8 b1; - short x2; + HDC dc; + HDC dc1; + RECT rect; + HBRUSH brush; + HGDIOBJ saved; + HBITMAP bitmap; + BITMAPINFO bi; + char *bits; + ABC abc; + SIZE sz; + char filename[256]; + TCHAR text[256]; + char zero1; + char *bmtext; + int bmtextindex; + int fd; + int x1; + int strlen1; + int index1; + int index2; + int len; + int pixel; + int red; + int green; + int blue; + int width; + int height; + int roller; + int outlen; + tui8 b1; + short x2; - if (g_running) - { - return 0; - } - g_running = 1; - msg("starting"); - g_font_name[0] = 0; - SendMessageA(g_font_list, WM_GETTEXT, 255, (LPARAM)g_font_name); - if (g_strlen(g_font_name) == 0) - { - msg("error font not set"); - g_running = 0; - return 1; - } - dc = GetDC(g_wnd); - height = -MulDiv(g_font_size, GetDeviceCaps(dc, LOGPIXELSY), 72); - g_font = CreateFontA(height, 0, 0, 0, FW_DONTCARE, 0, 0, 0, 0, 0, 0, - 0, 0, g_font_name); - ReleaseDC(g_wnd, dc); - if (g_font == 0) - { - msg("error - Font creation failed"); - } - zero1 = 0; - g_snprintf(filename, 255, "%s-%d.fv1", g_font_name, g_font_size); - msg("creating file %s", filename); - g_file_delete(filename); - fd = g_file_open(filename); - g_file_write(fd, "FNT1", 4); - strlen1 = g_strlen(g_font_name); - g_file_write(fd, g_font_name, strlen1); - x1 = strlen1; - while (x1 < 32) - { - g_file_write(fd, &zero1, 1); - x1++; - } - x2 = g_font_size; /* font size */ - g_file_write(fd, (char*)&x2, 2); - x2 = 1; /* style */ - g_file_write(fd, (char*)&x2, 2); - /* pad */ - index1 = 0; - while (index1 < 8) - { - g_file_write(fd, &zero1, 1); - index1++; - } - for (x1 = 32; x1 < 0x4e00; x1++) - { - check_messages(); - dc = GetWindowDC(g_wnd); - saved = SelectObject(dc, g_font); - if (!GetCharABCWidths(dc, x1, x1, &abc)) + if (g_running) { - show_last_error(); + return 0; } - text[0] = (TCHAR)x1; - text[1] = 0; - if (!GetTextExtentPoint32(dc, text, 1, &sz)) + + g_running = 1; + msg("starting"); + g_font_name[0] = 0; + SendMessageA(g_font_list, WM_GETTEXT, 255, (LPARAM)g_font_name); + + if (g_strlen(g_font_name) == 0) { - show_last_error(); + msg("error font not set"); + g_running = 0; + return 1; } - SelectObject(dc, saved); + + dc = GetDC(g_wnd); + height = -MulDiv(g_font_size, GetDeviceCaps(dc, LOGPIXELSY), 72); + g_font = CreateFontA(height, 0, 0, 0, FW_DONTCARE, 0, 0, 0, 0, 0, 0, + 0, 0, g_font_name); ReleaseDC(g_wnd, dc); - if ((sz.cx > 0) && (sz.cy > 0)) + + if (g_font == 0) + { + msg("error - Font creation failed"); + } + + zero1 = 0; + g_snprintf(filename, 255, "%s-%d.fv1", g_font_name, g_font_size); + msg("creating file %s", filename); + g_file_delete(filename); + fd = g_file_open(filename); + g_file_write(fd, "FNT1", 4); + strlen1 = g_strlen(g_font_name); + g_file_write(fd, g_font_name, strlen1); + x1 = strlen1; + + while (x1 < 32) + { + g_file_write(fd, &zero1, 1); + x1++; + } + + x2 = g_font_size; /* font size */ + g_file_write(fd, (char *)&x2, 2); + x2 = 1; /* style */ + g_file_write(fd, (char *)&x2, 2); + /* pad */ + index1 = 0; + + while (index1 < 8) { - dc = GetWindowDC(g_wnd); - saved = SelectObject(dc, g_font); - SetBkColor(dc, RGB(255, 255, 255)); - if (!ExtTextOut(dc, 50, 50, ETO_OPAQUE, 0, text, 1, 0)) - { - show_last_error(); - } - SelectObject(dc, saved); - ReleaseDC(g_wnd, dc); - Sleep(10); - /* width */ - x2 = abc.abcB; - g_file_write(fd, (char*)&x2, 2); - /* height */ - x2 = sz.cy; - g_file_write(fd, (char*)&x2, 2); - /* baseline */ - x2 = -sz.cy; - g_file_write(fd, (char*)&x2, 2); - /* offset */ - x2 = abc.abcA; - g_file_write(fd, (char*)&x2, 2); - /* incby */ - x2 = sz.cx; - g_file_write(fd, (char*)&x2, 2); - /* pad */ - index1 = 0; - while (index1 < 6) - { g_file_write(fd, &zero1, 1); index1++; - } - dc = GetWindowDC(g_wnd); - rect.left = 50 + abc.abcA; - rect.top = 50; - rect.right = rect.left + abc.abcB; - rect.bottom = rect.top + sz.cy; - memset(&bi, 0, sizeof(bi)); - width = (abc.abcB + 7) & (~7); - height = sz.cy; - bi.bmiHeader.biSize = sizeof(bi.bmiHeader); - bi.bmiHeader.biWidth = width; - bi.bmiHeader.biHeight = height; - bi.bmiHeader.biPlanes = 1; - bi.bmiHeader.biBitCount = 32; - bitmap = CreateDIBSection(dc, &bi, DIB_RGB_COLORS, (void*)&bits, 0, 0); - if (bitmap == 0) - { - msg("error - CreateDIBSection failed"); - } - else - { - memset(bits, 0, width * height * 4); - dc1 = CreateCompatibleDC(dc); - SelectObject(dc1, bitmap); - if (!BitBlt(dc1, 0, 0, width, height, dc, rect.left, rect.top, SRCCOPY)) + } + + for (x1 = 32; x1 < 0x4e00; x1++) + { + check_messages(); + dc = GetWindowDC(g_wnd); + saved = SelectObject(dc, g_font); + + if (!GetCharABCWidths(dc, x1, x1, &abc)) { - show_last_error(); + show_last_error(); } - bmtext = (char*)g_malloc(width * height + 16, 1); - bmtextindex = 0; - for (index1 = (height - 1); index1 >= 0; index1--) + + text[0] = (TCHAR)x1; + text[1] = 0; + + if (!GetTextExtentPoint32(dc, text, 1, &sz)) { - for (index2 = 0; index2 < width; index2++) - { - pixel = ((int*)bits)[index1 * width + index2]; - red = (pixel >> 16) & 0xff; - green = (pixel >> 8) & 0xff; - blue = (pixel >> 0) & 0xff; - if (red == 0 && green == 0 && blue == 0) + show_last_error(); + } + + SelectObject(dc, saved); + ReleaseDC(g_wnd, dc); + + if ((sz.cx > 0) && (sz.cy > 0)) + { + dc = GetWindowDC(g_wnd); + saved = SelectObject(dc, g_font); + SetBkColor(dc, RGB(255, 255, 255)); + + if (!ExtTextOut(dc, 50, 50, ETO_OPAQUE, 0, text, 1, 0)) { - bmtext[bmtextindex] = '1'; - bmtextindex++; + show_last_error(); + } + + SelectObject(dc, saved); + ReleaseDC(g_wnd, dc); + Sleep(10); + /* width */ + x2 = abc.abcB; + g_file_write(fd, (char *)&x2, 2); + /* height */ + x2 = sz.cy; + g_file_write(fd, (char *)&x2, 2); + /* baseline */ + x2 = -sz.cy; + g_file_write(fd, (char *)&x2, 2); + /* offset */ + x2 = abc.abcA; + g_file_write(fd, (char *)&x2, 2); + /* incby */ + x2 = sz.cx; + g_file_write(fd, (char *)&x2, 2); + /* pad */ + index1 = 0; + + while (index1 < 6) + { + g_file_write(fd, &zero1, 1); + index1++; + } + + dc = GetWindowDC(g_wnd); + rect.left = 50 + abc.abcA; + rect.top = 50; + rect.right = rect.left + abc.abcB; + rect.bottom = rect.top + sz.cy; + memset(&bi, 0, sizeof(bi)); + width = (abc.abcB + 7) & (~7); + height = sz.cy; + bi.bmiHeader.biSize = sizeof(bi.bmiHeader); + bi.bmiHeader.biWidth = width; + bi.bmiHeader.biHeight = height; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 32; + bitmap = CreateDIBSection(dc, &bi, DIB_RGB_COLORS, (void *)&bits, 0, 0); + + if (bitmap == 0) + { + msg("error - CreateDIBSection failed"); } else { - bmtext[bmtextindex] = '0'; - bmtextindex++; + memset(bits, 0, width * height * 4); + dc1 = CreateCompatibleDC(dc); + SelectObject(dc1, bitmap); + + if (!BitBlt(dc1, 0, 0, width, height, dc, rect.left, rect.top, SRCCOPY)) + { + show_last_error(); + } + + bmtext = (char *)g_malloc(width * height + 16, 1); + bmtextindex = 0; + + for (index1 = (height - 1); index1 >= 0; index1--) + { + for (index2 = 0; index2 < width; index2++) + { + pixel = ((int *)bits)[index1 * width + index2]; + red = (pixel >> 16) & 0xff; + green = (pixel >> 8) & 0xff; + blue = (pixel >> 0) & 0xff; + + if (red == 0 && green == 0 && blue == 0) + { + bmtext[bmtextindex] = '1'; + bmtextindex++; + } + else + { + bmtext[bmtextindex] = '0'; + bmtextindex++; + } + } + } + + outlen = 0; + b1 = 0; + roller = 0; + len = g_strlen(bmtext); + + for (index2 = 0; index2 < len; index2++) + { + if (bmtext[index2] == '1') + { + switch (roller) + { + case 0: + b1 = b1 | 0x80; + break; + case 1: + b1 = b1 | 0x40; + break; + case 2: + b1 = b1 | 0x20; + break; + case 3: + b1 = b1 | 0x10; + break; + case 4: + b1 = b1 | 0x08; + break; + case 5: + b1 = b1 | 0x04; + break; + case 6: + b1 = b1 | 0x02; + break; + case 7: + b1 = b1 | 0x01; + break; + } + } + + roller++; + + if (roller == 8) + { + roller = 0; + g_file_write(fd, &b1, 1); + outlen++; + b1 = 0; + } + } + + while ((outlen % 4) != 0) + { + g_file_write(fd, &zero1, 1); + outlen++; + } + + free(bmtext); + DeleteDC(dc1); + DeleteObject(bitmap); } - } - } - outlen = 0; - b1 = 0; - roller = 0; - len = g_strlen(bmtext); - for (index2 = 0; index2 < len; index2++) - { - if (bmtext[index2] == '1') - { - switch (roller) + + if (sz.cx != (long)(abc.abcA + abc.abcB + abc.abcC)) { - case 0: b1 = b1 | 0x80; break; - case 1: b1 = b1 | 0x40; break; - case 2: b1 = b1 | 0x20; break; - case 3: b1 = b1 | 0x10; break; - case 4: b1 = b1 | 0x08; break; - case 5: b1 = b1 | 0x04; break; - case 6: b1 = b1 | 0x02; break; - case 7: b1 = b1 | 0x01; break; + msg("error - width not right 1"); } - } - roller++; - if (roller == 8) - { - roller = 0; - g_file_write(fd, &b1, 1); - outlen++; - b1 = 0; - } + + brush = CreateSolidBrush(RGB(255, 255, 255)); + FillRect(dc, &rect, brush); + DeleteObject(brush); + ReleaseDC(g_wnd, dc); } - while ((outlen % 4) != 0) + else { - g_file_write(fd, &zero1, 1); - outlen++; + /* write out a blank glyph here */ + /* width */ + x2 = 1; + g_file_write(fd, (char *)&x2, 2); + /* height */ + x2 = 1; + g_file_write(fd, (char *)&x2, 2); + /* baseline */ + x2 = 0; + g_file_write(fd, (char *)&x2, 2); + /* offset */ + x2 = 0; + g_file_write(fd, (char *)&x2, 2); + /* incby */ + x2 = 1; + g_file_write(fd, (char *)&x2, 2); + /* pad */ + index1 = 0; + + while (index1 < 6) + { + g_file_write(fd, &zero1, 1); + index1++; + } + + /* blank bitmap */ + index1 = 0; + + while (index1 < 4) + { + g_file_write(fd, &zero1, 1); + index1++; + } } - free(bmtext); - DeleteDC(dc1); - DeleteObject(bitmap); - } - if (sz.cx != (long)(abc.abcA + abc.abcB + abc.abcC)) - { - msg("error - width not right 1"); - } - brush = CreateSolidBrush(RGB(255, 255, 255)); - FillRect(dc, &rect, brush); - DeleteObject(brush); - ReleaseDC(g_wnd, dc); } - else - { - /* write out a blank glyph here */ - /* width */ - x2 = 1; - g_file_write(fd, (char*)&x2, 2); - /* height */ - x2 = 1; - g_file_write(fd, (char*)&x2, 2); - /* baseline */ - x2 = 0; - g_file_write(fd, (char*)&x2, 2); - /* offset */ - x2 = 0; - g_file_write(fd, (char*)&x2, 2); - /* incby */ - x2 = 1; - g_file_write(fd, (char*)&x2, 2); - /* pad */ - index1 = 0; - while (index1 < 6) - { - g_file_write(fd, &zero1, 1); - index1++; - } - /* blank bitmap */ - index1 = 0; - while (index1 < 4) - { - g_file_write(fd, &zero1, 1); - index1++; - } - } - } - g_file_close(fd); - msg("done"); - g_running = 0; - return 0; + + g_file_close(fd); + msg("done"); + g_running = 0; + return 0; } /*****************************************************************************/ static LRESULT CALLBACK wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - PAINTSTRUCT ps; - HBRUSH brush; - RECT rect; + PAINTSTRUCT ps; + HBRUSH brush; + RECT rect; - switch (message) - { - case WM_PAINT: - BeginPaint(hWnd, &ps); - brush = CreateSolidBrush(RGB(255, 255, 255)); - rect = ps.rcPaint; - FillRect(ps.hdc, &rect, brush); - DeleteObject(brush); - EndPaint(hWnd, &ps); - break; - case WM_CLOSE: - DestroyWindow(g_wnd); - g_wnd = 0; - break; - case WM_DESTROY: - PostQuitMessage(0); - break; - case WM_TIMER: - KillTimer(g_wnd, 1); - font_dump(); - break; - case WM_COMMAND: - if ((HWND)lParam == g_exit_button) - { - PostMessage(g_wnd, WM_CLOSE, 0, 0); - } - else if ((HWND)lParam == g_go_button) - { - while (SendMessage(g_lb, LB_GETCOUNT, 0, 0) > 0) - { - SendMessage(g_lb, LB_DELETESTRING, 0, 0); - } - SetTimer(g_wnd, 1, 1000, 0); - } - break; - } - return DefWindowProc(hWnd, message, wParam, lParam); + switch (message) + { + case WM_PAINT: + BeginPaint(hWnd, &ps); + brush = CreateSolidBrush(RGB(255, 255, 255)); + rect = ps.rcPaint; + FillRect(ps.hdc, &rect, brush); + DeleteObject(brush); + EndPaint(hWnd, &ps); + break; + case WM_CLOSE: + DestroyWindow(g_wnd); + g_wnd = 0; + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + case WM_TIMER: + KillTimer(g_wnd, 1); + font_dump(); + break; + case WM_COMMAND: + + if ((HWND)lParam == g_exit_button) + { + PostMessage(g_wnd, WM_CLOSE, 0, 0); + } + else if ((HWND)lParam == g_go_button) + { + while (SendMessage(g_lb, LB_GETCOUNT, 0, 0) > 0) + { + SendMessage(g_lb, LB_DELETESTRING, 0, 0); + } + + SetTimer(g_wnd, 1, 1000, 0); + } + + break; + } + + return DefWindowProc(hWnd, message, wParam, lParam); } /*****************************************************************************/ static int create_window(void) { - WNDCLASS wc; - DWORD style; - HDC dc; - int height; - int left; - int top; + WNDCLASS wc; + DWORD style; + HDC dc; + int height; + int left; + int top; - ZeroMemory(&wc, sizeof(wc)); - wc.lpfnWndProc = wnd_proc; /* points to window procedure */ - /* name of window class */ - wc.lpszClassName = _T("fontdump"); - wc.hCursor = LoadCursor(0, IDC_ARROW); - /* Register the window class. */ - if (!RegisterClass(&wc)) - { - return 0; /* Failed to register window class */ - } - style = WS_OVERLAPPED | WS_CAPTION | WS_POPUP | WS_MINIMIZEBOX | - WS_SYSMENU | WS_SIZEBOX | WS_MAXIMIZEBOX; - left = GetSystemMetrics(SM_CXSCREEN) / 2 - 640 / 2; - top = GetSystemMetrics(SM_CYSCREEN) / 2 - 480 / 2; - g_wnd = CreateWindow(wc.lpszClassName, _T("fontdump"), - style, left, top, 640, 480, - (HWND) NULL, (HMENU) NULL, g_instance, - (LPVOID) NULL); - style = WS_CHILD | WS_VISIBLE | WS_BORDER; - g_lb = CreateWindow(_T("LISTBOX"), _T("LISTBOX1"), style, - 200, 10, 400, 400, g_wnd, 0, g_instance, 0); - style = WS_CHILD | WS_VISIBLE; - g_exit_button = CreateWindow(_T("BUTTON"), _T("Exit"), style, - 540, 410, 75, 25, g_wnd, 0, g_instance, 0); - g_go_button = CreateWindow(_T("BUTTON"), _T("Go"), style, - 440, 410, 75, 25, g_wnd, 0, g_instance, 0); - style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN; - g_font_list = CreateWindow(_T("COMBOBOX"), _T("COMBOBOX1"), style, - 50, 250, 125, 125, g_wnd, 0, g_instance, 0); - ShowWindow(g_wnd, SW_SHOWNORMAL); - PostMessage(g_wnd, WM_SETFONT, (WPARAM)g_font, 0); - SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Tahoma"); - SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"DejaVu Serif"); - SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"DejaVu Sans"); - SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Arial"); - SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Comic Sans MS"); - return 0; + ZeroMemory(&wc, sizeof(wc)); + wc.lpfnWndProc = wnd_proc; /* points to window procedure */ + /* name of window class */ + wc.lpszClassName = _T("fontdump"); + wc.hCursor = LoadCursor(0, IDC_ARROW); + + /* Register the window class. */ + if (!RegisterClass(&wc)) + { + return 0; /* Failed to register window class */ + } + + style = WS_OVERLAPPED | WS_CAPTION | WS_POPUP | WS_MINIMIZEBOX | + WS_SYSMENU | WS_SIZEBOX | WS_MAXIMIZEBOX; + left = GetSystemMetrics(SM_CXSCREEN) / 2 - 640 / 2; + top = GetSystemMetrics(SM_CYSCREEN) / 2 - 480 / 2; + g_wnd = CreateWindow(wc.lpszClassName, _T("fontdump"), + style, left, top, 640, 480, + (HWND) NULL, (HMENU) NULL, g_instance, + (LPVOID) NULL); + style = WS_CHILD | WS_VISIBLE | WS_BORDER; + g_lb = CreateWindow(_T("LISTBOX"), _T("LISTBOX1"), style, + 200, 10, 400, 400, g_wnd, 0, g_instance, 0); + style = WS_CHILD | WS_VISIBLE; + g_exit_button = CreateWindow(_T("BUTTON"), _T("Exit"), style, + 540, 410, 75, 25, g_wnd, 0, g_instance, 0); + g_go_button = CreateWindow(_T("BUTTON"), _T("Go"), style, + 440, 410, 75, 25, g_wnd, 0, g_instance, 0); + style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN; + g_font_list = CreateWindow(_T("COMBOBOX"), _T("COMBOBOX1"), style, + 50, 250, 125, 125, g_wnd, 0, g_instance, 0); + ShowWindow(g_wnd, SW_SHOWNORMAL); + PostMessage(g_wnd, WM_SETFONT, (WPARAM)g_font, 0); + SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Tahoma"); + SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"DejaVu Serif"); + SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"DejaVu Sans"); + SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Arial"); + SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Comic Sans MS"); + return 0; } /*****************************************************************************/ static int main_loop(void) { - MSG msg; + MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return (int)(msg.wParam); + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return (int)(msg.wParam); } /*****************************************************************************/ @@ -452,7 +528,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - g_instance = hInstance; - create_window(); - return main_loop(); + g_instance = hInstance; + create_window(); + return main_loop(); } diff --git a/freerdp/xrdp-color.c b/freerdp/xrdp-color.c index 1bbdef43..0ecf4dbf 100644 --- a/freerdp/xrdp-color.c +++ b/freerdp/xrdp-color.c @@ -1,279 +1,314 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2010 - - freerdp wrapper - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * freerdp wrapper + */ #include "xrdp-freerdp.h" -char* APP_CC -convert_bitmap(int in_bpp, int out_bpp, char* bmpdata, - int width, int height, int* palette) +char *APP_CC +convert_bitmap(int in_bpp, int out_bpp, char *bmpdata, + int width, int height, int *palette) { - char* out; - char* src; - char* dst; - int i; - int j; - int red; - int green; - int blue; - int pixel; + char *out; + char *src; + char *dst; + int i; + int j; + int red; + int green; + int blue; + int pixel; - if ((in_bpp == 8) && (out_bpp == 8)) - { - out = (char*)g_malloc(width * height, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + if ((in_bpp == 8) && (out_bpp == 8)) { - for (j = 0; j < width; j++) - { - pixel = *((tui8*)src); - pixel = palette[pixel]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR8(red, green, blue); - *dst = pixel; - src++; - dst++; - } + out = (char *)g_malloc(width * height, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui8 *)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + *dst = pixel; + src++; + dst++; + } + } + + return out; } - return out; - } - if ((in_bpp == 8) && (out_bpp == 16)) - { - out = (char*)g_malloc(width * height * 2, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 8) && (out_bpp == 16)) { - for (j = 0; j < width; j++) - { - pixel = *((tui8*)src); - pixel = palette[pixel]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - *((tui16*)dst) = pixel; - src++; - dst += 2; - } + out = (char *)g_malloc(width * height * 2, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui8 *)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + *((tui16 *)dst) = pixel; + src++; + dst += 2; + } + } + + return out; } - return out; - } - if ((in_bpp == 8) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 8) && (out_bpp == 24)) { - for (j = 0; j < width; j++) - { - pixel = *((tui8*)src); - pixel = palette[pixel]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - src++; - dst += 4; - } + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui8 *)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + src++; + dst += 4; + } + } + + return out; } - return out; - } - if ((in_bpp == 15) && (out_bpp == 16)) - { - out = (char*)g_malloc(width * height * 2, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 15) && (out_bpp == 16)) { - for (j = 0; j < width; j++) - { - pixel = *((tui16*)src); - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - *((tui16*)dst) = pixel; - src += 2; - dst += 2; - } + out = (char *)g_malloc(width * height * 2, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui16 *)src); + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + *((tui16 *)dst) = pixel; + src += 2; + dst += 2; + } + } + + return out; } - return out; - } - if ((in_bpp == 15) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 15) && (out_bpp == 24)) { - for (j = 0; j < width; j++) - { - pixel = *((tui16*)src); - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - src += 2; - dst += 4; - } + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui16 *)src); + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + src += 2; + dst += 4; + } + } + + return out; } - return out; - } - if ((in_bpp == 16) && (out_bpp == 16)) - { - return bmpdata; - } - if ((in_bpp == 16) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 16) && (out_bpp == 16)) { - for (j = 0; j < width; j++) - { - pixel = *((tui16*)src); - SPLITCOLOR16(red, green, blue, pixel); - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - src += 2; - dst += 4; - } + return bmpdata; } - return out; - } - if ((in_bpp == 24) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 16) && (out_bpp == 24)) { - for (j = 0; j < width; j++) - { - blue = *((tui8*)src); - src++; - green = *((tui8*)src); - src++; - red = *((tui8*)src); - src++; - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - dst += 4; - } + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui16 *)src); + SPLITCOLOR16(red, green, blue, pixel); + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + src += 2; + dst += 4; + } + } + + return out; } - return out; - } - if ((in_bpp == 32) && (out_bpp == 24)) - { - return bmpdata; - } - if ((in_bpp == 32) && (out_bpp == 32)) - { - return bmpdata; - } - if ((in_bpp == 15) && (out_bpp == 15)) - { - return bmpdata; - } - g_writeln("convert_bitmap: error unknown conversion from %d to %d", - in_bpp, out_bpp); - return 0; + + if ((in_bpp == 24) && (out_bpp == 24)) + { + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + blue = *((tui8 *)src); + src++; + green = *((tui8 *)src); + src++; + red = *((tui8 *)src); + src++; + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + dst += 4; + } + } + + return out; + } + + if ((in_bpp == 32) && (out_bpp == 24)) + { + return bmpdata; + } + + if ((in_bpp == 32) && (out_bpp == 32)) + { + return bmpdata; + } + + if ((in_bpp == 15) && (out_bpp == 15)) + { + return bmpdata; + } + + g_writeln("convert_bitmap: error unknown conversion from %d to %d", + in_bpp, out_bpp); + return 0; } /*****************************************************************************/ /* returns color or 0 */ int APP_CC -convert_color(int in_bpp, int out_bpp, int in_color, int* palette) +convert_color(int in_bpp, int out_bpp, int in_color, int *palette) { - int pixel; - int red; - int green; - int blue; + int pixel; + int red; + int green; + int blue; - if ((in_bpp == 1) && (out_bpp == 24)) - { - pixel = in_color == 0 ? 0 : 0xffffff; - return pixel; - } - if ((in_bpp == 8) && (out_bpp == 8)) - { - pixel = palette[in_color]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR8(red, green, blue); - return pixel; - } - if ((in_bpp == 8) && (out_bpp == 16)) - { - pixel = palette[in_color]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - return pixel; - } - if ((in_bpp == 8) && (out_bpp == 24)) - { - pixel = palette[in_color]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR24BGR(red, green, blue); - return pixel; - } - if ((in_bpp == 15) && (out_bpp == 16)) - { - pixel = in_color; - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - return pixel; - } - if ((in_bpp == 15) && (out_bpp == 24)) - { - pixel = in_color; - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR24BGR(red, green, blue); - return pixel; - } - if ((in_bpp == 16) && (out_bpp == 16)) - { - return in_color; - } - if ((in_bpp == 16) && (out_bpp == 24)) - { - pixel = in_color; - SPLITCOLOR16(red, green, blue, pixel); - pixel = COLOR24BGR(red, green, blue); - return pixel; - } - if ((in_bpp == 24) && (out_bpp == 24)) - { - return in_color; - } - if ((in_bpp == 32) && (out_bpp == 24)) - { - return in_color; - } - if ((in_bpp == 32) && (out_bpp == 32)) - { - return in_color; - } - if ((in_bpp == 15) && (out_bpp == 15)) - { - return in_color; - } - g_writeln("convert_color: error unknown conversion from %d to %d", - in_bpp, out_bpp); - return 0; + if ((in_bpp == 1) && (out_bpp == 24)) + { + pixel = in_color == 0 ? 0 : 0xffffff; + return pixel; + } + + if ((in_bpp == 8) && (out_bpp == 8)) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + return pixel; + } + + if ((in_bpp == 8) && (out_bpp == 16)) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + return pixel; + } + + if ((in_bpp == 8) && (out_bpp == 24)) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR24BGR(red, green, blue); + return pixel; + } + + if ((in_bpp == 15) && (out_bpp == 16)) + { + pixel = in_color; + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + return pixel; + } + + if ((in_bpp == 15) && (out_bpp == 24)) + { + pixel = in_color; + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR24BGR(red, green, blue); + return pixel; + } + + if ((in_bpp == 16) && (out_bpp == 16)) + { + return in_color; + } + + if ((in_bpp == 16) && (out_bpp == 24)) + { + pixel = in_color; + SPLITCOLOR16(red, green, blue, pixel); + pixel = COLOR24BGR(red, green, blue); + return pixel; + } + + if ((in_bpp == 24) && (out_bpp == 24)) + { + return in_color; + } + + if ((in_bpp == 32) && (out_bpp == 24)) + { + return in_color; + } + + if ((in_bpp == 32) && (out_bpp == 32)) + { + return in_color; + } + + if ((in_bpp == 15) && (out_bpp == 15)) + { + return in_color; + } + + g_writeln("convert_color: error unknown conversion from %d to %d", + in_bpp, out_bpp); + return 0; } diff --git a/freerdp/xrdp-color.h b/freerdp/xrdp-color.h index c9375b53..3c58c032 100644 --- a/freerdp/xrdp-color.h +++ b/freerdp/xrdp-color.h @@ -1,22 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2010 - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef __XRDP_COLOR_H #define __XRDP_COLOR_H diff --git a/freerdp/xrdp-freerdp.c b/freerdp/xrdp-freerdp.c index f7e7fd5e..5ee58800 100644 --- a/freerdp/xrdp-freerdp.c +++ b/freerdp/xrdp-freerdp.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2010 - - freerdp wrapper - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * freerdp wrapper + */ #include "xrdp-freerdp.h" #include "xrdp-color.h" @@ -28,723 +26,744 @@ struct my_bitmap { - char* data; - int width; - int height; - int bpp; + char *data; + int width; + int height; + int bpp; }; struct my_cursor { - char* andmask; - int andbpp; - char* xormask; - int xorbpp; - int width; - int height; - int hotx; - int hoty; + char *andmask; + int andbpp; + char *xormask; + int xorbpp; + int width; + int height; + int hotx; + int hoty; }; /*****************************************************************************/ /* return error */ static int DEFAULT_CC -lib_mod_start(struct mod* mod, int w, int h, int bpp) +lib_mod_start(struct mod *mod, int w, int h, int bpp) { - LIB_DEBUG(mod, "in lib_mod_start"); - g_writeln("lib_mod_start: w %d h %d bpp %d", w, h, bpp); - mod->width = w; - mod->height = h; - mod->bpp = bpp; - if (bpp == 24) - { - mod->settings->server_depth = 32; - } - else - { - mod->settings->server_depth = mod->bpp; - } - mod->settings->width = mod->width; - mod->settings->height = mod->height; - LIB_DEBUG(mod, "out lib_mod_start"); - return 0; + LIB_DEBUG(mod, "in lib_mod_start"); + g_writeln("lib_mod_start: w %d h %d bpp %d", w, h, bpp); + mod->width = w; + mod->height = h; + mod->bpp = bpp; + + if (bpp == 24) + { + mod->settings->server_depth = 32; + } + else + { + mod->settings->server_depth = mod->bpp; + } + + mod->settings->width = mod->width; + mod->settings->height = mod->height; + LIB_DEBUG(mod, "out lib_mod_start"); + return 0; } /******************************************************************************/ /* return error */ static int DEFAULT_CC -lib_mod_connect(struct mod* mod) +lib_mod_connect(struct mod *mod) { - int code; + int code; - LIB_DEBUG(mod, "in lib_mod_connect"); - code = mod->inst->rdp_connect(mod->inst); - g_writeln("lib_mod_connect: code %d", code); - LIB_DEBUG(mod, "out lib_mod_connect"); - return code; + LIB_DEBUG(mod, "in lib_mod_connect"); + code = mod->inst->rdp_connect(mod->inst); + g_writeln("lib_mod_connect: code %d", code); + LIB_DEBUG(mod, "out lib_mod_connect"); + return code; } /******************************************************************************/ /* return error */ static int DEFAULT_CC -lib_mod_event(struct mod* mod, int msg, long param1, long param2, +lib_mod_event(struct mod *mod, int msg, long param1, long param2, long param3, long param4) { - LIB_DEBUG(mod, "in lib_mod_event"); - int ext; + LIB_DEBUG(mod, "in lib_mod_event"); + int ext; - //g_writeln("%d %d %d %d %d", msg, param1, param2, param3, param4); - switch (msg) - { - case 15: - ext = param4 & 0x100 ? 1 : 0; - mod->inst->rdp_send_input_scancode(mod->inst, 0, ext, param3); - break; - case 16: - ext = param4 & 0x100 ? 1 : 0; - mod->inst->rdp_send_input_scancode(mod->inst, 1, ext, param3); - break; - case 17: - mod->inst->rdp_sync_input(mod->inst, param4); - break; - case 100: - mod->inst->rdp_send_input_mouse(mod->inst, PTRFLAGS_MOVE, - param1, param2); - break; - case 101: - mod->inst->rdp_send_input_mouse(mod->inst, PTRFLAGS_BUTTON1, - param1, param2); - break; - case 102: - mod->inst->rdp_send_input_mouse(mod->inst, - PTRFLAGS_BUTTON1 | PTRFLAGS_DOWN, - param1, param2); - break; - case 103: - mod->inst->rdp_send_input_mouse(mod->inst, - PTRFLAGS_BUTTON2, param1, param2); - break; - case 104: - mod->inst->rdp_send_input_mouse(mod->inst, - PTRFLAGS_BUTTON2 | PTRFLAGS_DOWN, - param1, param2); - break; - case 105: - mod->inst->rdp_send_input_mouse(mod->inst, - PTRFLAGS_BUTTON3, param1, param2); - break; - case 106: - mod->inst->rdp_send_input_mouse(mod->inst, - PTRFLAGS_BUTTON3 | PTRFLAGS_DOWN, - param1, param2); - break; - case 107: - mod->inst->rdp_send_input_mouse(mod->inst, - PTRFLAGS_WHEEL | 0x0078, 0, 0); - break; - case 108: - break; - case 109: - mod->inst->rdp_send_input_mouse(mod->inst, - PTRFLAGS_WHEEL | - PTRFLAGS_WHEEL_NEGATIVE | 0x0088, 0, 0); - break; - case 110: - break; - } - LIB_DEBUG(mod, "out lib_mod_event"); - return 0; + //g_writeln("%d %d %d %d %d", msg, param1, param2, param3, param4); + switch (msg) + { + case 15: + ext = param4 & 0x100 ? 1 : 0; + mod->inst->rdp_send_input_scancode(mod->inst, 0, ext, param3); + break; + case 16: + ext = param4 & 0x100 ? 1 : 0; + mod->inst->rdp_send_input_scancode(mod->inst, 1, ext, param3); + break; + case 17: + mod->inst->rdp_sync_input(mod->inst, param4); + break; + case 100: + mod->inst->rdp_send_input_mouse(mod->inst, PTRFLAGS_MOVE, + param1, param2); + break; + case 101: + mod->inst->rdp_send_input_mouse(mod->inst, PTRFLAGS_BUTTON1, + param1, param2); + break; + case 102: + mod->inst->rdp_send_input_mouse(mod->inst, + PTRFLAGS_BUTTON1 | PTRFLAGS_DOWN, + param1, param2); + break; + case 103: + mod->inst->rdp_send_input_mouse(mod->inst, + PTRFLAGS_BUTTON2, param1, param2); + break; + case 104: + mod->inst->rdp_send_input_mouse(mod->inst, + PTRFLAGS_BUTTON2 | PTRFLAGS_DOWN, + param1, param2); + break; + case 105: + mod->inst->rdp_send_input_mouse(mod->inst, + PTRFLAGS_BUTTON3, param1, param2); + break; + case 106: + mod->inst->rdp_send_input_mouse(mod->inst, + PTRFLAGS_BUTTON3 | PTRFLAGS_DOWN, + param1, param2); + break; + case 107: + mod->inst->rdp_send_input_mouse(mod->inst, + PTRFLAGS_WHEEL | 0x0078, 0, 0); + break; + case 108: + break; + case 109: + mod->inst->rdp_send_input_mouse(mod->inst, + PTRFLAGS_WHEEL | + PTRFLAGS_WHEEL_NEGATIVE | 0x0088, 0, 0); + break; + case 110: + break; + } + + LIB_DEBUG(mod, "out lib_mod_event"); + return 0; } /******************************************************************************/ /* return error */ static int DEFAULT_CC -lib_mod_signal(struct mod* mod) +lib_mod_signal(struct mod *mod) { - LIB_DEBUG(mod, "in lib_mod_signal"); - g_writeln("lib_mod_signal:"); - LIB_DEBUG(mod, "out lib_mod_signal"); - return 0; + LIB_DEBUG(mod, "in lib_mod_signal"); + g_writeln("lib_mod_signal:"); + LIB_DEBUG(mod, "out lib_mod_signal"); + return 0; } /******************************************************************************/ /* return error */ static int DEFAULT_CC -lib_mod_end(struct mod* mod) +lib_mod_end(struct mod *mod) { - g_writeln("lib_mod_end:"); - return 0; + g_writeln("lib_mod_end:"); + return 0; } /******************************************************************************/ /* return error */ static int DEFAULT_CC -lib_mod_set_param(struct mod* mod, char* name, char* value) +lib_mod_set_param(struct mod *mod, char *name, char *value) { - g_writeln("lib_mod_set_param: name [%s] value [%s]", name, value); - if (g_strcmp(name, "hostname") == 0) - { - g_strncpy(mod->settings->hostname, value, sizeof(mod->settings->hostname)); - } - else if (g_strcmp(name, "ip") == 0) - { - g_strncpy(mod->settings->server, value, sizeof(mod->settings->server)); - } - else if (g_strcmp(name, "port") == 0) - { - mod->settings->tcp_port_rdp = g_atoi(value); - } - else if (g_strcmp(name, "keylayout") == 0) - { - mod->settings->keyboard_layout = g_atoi(value); - } - else if (g_strcmp(name, "name") == 0) - { - } - else if (g_strcmp(name, "lib") == 0) - { - } - else - { - g_writeln("lib_mod_set_param: unknown name [%s] value [%s]", name, value); - } - return 0; + g_writeln("lib_mod_set_param: name [%s] value [%s]", name, value); + + if (g_strcmp(name, "hostname") == 0) + { + g_strncpy(mod->settings->hostname, value, sizeof(mod->settings->hostname)); + } + else if (g_strcmp(name, "ip") == 0) + { + g_strncpy(mod->settings->server, value, sizeof(mod->settings->server)); + } + else if (g_strcmp(name, "port") == 0) + { + mod->settings->tcp_port_rdp = g_atoi(value); + } + else if (g_strcmp(name, "keylayout") == 0) + { + mod->settings->keyboard_layout = g_atoi(value); + } + else if (g_strcmp(name, "name") == 0) + { + } + else if (g_strcmp(name, "lib") == 0) + { + } + else + { + g_writeln("lib_mod_set_param: unknown name [%s] value [%s]", name, value); + } + + return 0; } /******************************************************************************/ static int DEFAULT_CC -mod_session_change(struct mod* v, int a, int b) +mod_session_change(struct mod *v, int a, int b) { - g_writeln("mod_session_change:"); - return 0; + g_writeln("mod_session_change:"); + return 0; } /******************************************************************************/ static int DEFAULT_CC -mod_get_wait_objs(struct mod* v, tbus* read_objs, int* rcount, - tbus* write_objs, int* wcount, int* timeout) +mod_get_wait_objs(struct mod *v, tbus *read_objs, int *rcount, + tbus *write_objs, int *wcount, int *timeout) { - void** rfds; - void** wfds; + void **rfds; + void **wfds; - rfds = (void**)read_objs; - wfds = (void**)write_objs; - return v->inst->rdp_get_fds(v->inst, rfds, rcount, wfds, wcount); + rfds = (void **)read_objs; + wfds = (void **)write_objs; + return v->inst->rdp_get_fds(v->inst, rfds, rcount, wfds, wcount); } /******************************************************************************/ static int DEFAULT_CC -mod_check_wait_objs(struct mod* v) +mod_check_wait_objs(struct mod *v) { - return v->inst->rdp_check_fds(v->inst); + return v->inst->rdp_check_fds(v->inst); } /******************************************************************************/ static void DEFAULT_CC -ui_error(rdpInst* inst, const char* text) +ui_error(rdpInst *inst, const char *text) { - g_writeln("ui_error: %s", text); + g_writeln("ui_error: %s", text); } /******************************************************************************/ static void DEFAULT_CC -ui_warning(rdpInst* inst, const char* text) +ui_warning(rdpInst *inst, const char *text) { - g_writeln("ui_warning: %s", text); + g_writeln("ui_warning: %s", text); } /******************************************************************************/ static void DEFAULT_CC -ui_unimpl(rdpInst* inst, const char* text) +ui_unimpl(rdpInst *inst, const char *text) { - g_writeln("ui_unimpl: %s", text); + g_writeln("ui_unimpl: %s", text); } /******************************************************************************/ static void DEFAULT_CC -ui_begin_update(rdpInst* inst) +ui_begin_update(rdpInst *inst) { - struct mod* mod; + struct mod *mod; - mod = GET_MOD(inst); - mod->server_begin_update(mod); + mod = GET_MOD(inst); + mod->server_begin_update(mod); } /******************************************************************************/ static void DEFAULT_CC -ui_end_update(rdpInst* inst) +ui_end_update(rdpInst *inst) { - struct mod* mod; + struct mod *mod; - mod = GET_MOD(inst); - mod->server_end_update(mod); + mod = GET_MOD(inst); + mod->server_end_update(mod); } /******************************************************************************/ static void DEFAULT_CC -ui_desktop_save(rdpInst* inst, int offset, int x, int y, +ui_desktop_save(rdpInst *inst, int offset, int x, int y, int cx, int cy) { - g_writeln("ui_desktop_save:"); + g_writeln("ui_desktop_save:"); } /******************************************************************************/ static void DEFAULT_CC -ui_desktop_restore(rdpInst* inst, int offset, int x, int y, - int cx, int cy) +ui_desktop_restore(rdpInst *inst, int offset, int x, int y, + int cx, int cy) { - g_writeln("ui_desktop_restore:"); + g_writeln("ui_desktop_restore:"); } /******************************************************************************/ static RD_HBITMAP DEFAULT_CC -ui_create_bitmap(rdpInst* inst, int width, int height, uint8* data) +ui_create_bitmap(rdpInst *inst, int width, int height, uint8 *data) { - struct my_bitmap* bm; - struct mod* mod; - int size; - int bpp; - char* bmpdata; + struct my_bitmap *bm; + struct mod *mod; + int size; + int bpp; + char *bmpdata; - mod = GET_MOD(inst); - bpp = mod->bpp == 24 ? 32 : mod->bpp; - bm = (struct my_bitmap*)g_malloc(sizeof(struct my_bitmap), 1); - bm->width = width; - bm->height = height; - bm->bpp = bpp; - bmpdata = convert_bitmap(mod->settings->server_depth, bpp, - data, width, height, mod->cmap); - if (bmpdata == (char*)data) - { - size = width * height * ((bpp + 7) / 8); - bm->data = (char*)g_malloc(size, 0); - g_memcpy(bm->data, bmpdata, size); - } - else - { - bm->data = bmpdata; - } - return bm; + mod = GET_MOD(inst); + bpp = mod->bpp == 24 ? 32 : mod->bpp; + bm = (struct my_bitmap *)g_malloc(sizeof(struct my_bitmap), 1); + bm->width = width; + bm->height = height; + bm->bpp = bpp; + bmpdata = convert_bitmap(mod->settings->server_depth, bpp, + data, width, height, mod->cmap); + + if (bmpdata == (char *)data) + { + size = width * height * ((bpp + 7) / 8); + bm->data = (char *)g_malloc(size, 0); + g_memcpy(bm->data, bmpdata, size); + } + else + { + bm->data = bmpdata; + } + + return bm; } /******************************************************************************/ static void DEFAULT_CC -ui_paint_bitmap(rdpInst* inst, int x, int y, int cx, int cy, int width, - int height, uint8* data) +ui_paint_bitmap(rdpInst *inst, int x, int y, int cx, int cy, int width, + int height, uint8 *data) { - struct mod* mod; - char* bmpdata; + struct mod *mod; + char *bmpdata; - mod = GET_MOD(inst); - bmpdata = convert_bitmap(mod->settings->server_depth, mod->bpp, - data, width, height, mod->cmap); - if (bmpdata != 0) - { - mod->server_paint_rect(mod, x, y, cx, cy, bmpdata, width, height, 0, 0); - } - if (bmpdata != (char*)data) - { - g_free(bmpdata); - } + mod = GET_MOD(inst); + bmpdata = convert_bitmap(mod->settings->server_depth, mod->bpp, + data, width, height, mod->cmap); + + if (bmpdata != 0) + { + mod->server_paint_rect(mod, x, y, cx, cy, bmpdata, width, height, 0, 0); + } + + if (bmpdata != (char *)data) + { + g_free(bmpdata); + } } /******************************************************************************/ static void DEFAULT_CC -ui_destroy_bitmap(rdpInst* inst, RD_HBITMAP bmp) +ui_destroy_bitmap(rdpInst *inst, RD_HBITMAP bmp) { - struct my_bitmap* bm; + struct my_bitmap *bm; - bm = (struct my_bitmap*)bmp; - g_free(bm->data); - g_free(bm); + bm = (struct my_bitmap *)bmp; + g_free(bm->data); + g_free(bm); } /******************************************************************************/ static void DEFAULT_CC -ui_line(rdpInst* inst, uint8 opcode, int startx, int starty, int endx, - int endy, RD_PEN* pen) +ui_line(rdpInst *inst, uint8 opcode, int startx, int starty, int endx, + int endy, RD_PEN *pen) { - g_writeln("ui_line:"); + g_writeln("ui_line:"); } /******************************************************************************/ static void DEFAULT_CC -ui_rect(rdpInst* inst, int x, int y, int cx, int cy, uint32 color) +ui_rect(rdpInst *inst, int x, int y, int cx, int cy, uint32 color) { - struct mod* mod; + struct mod *mod; - mod = GET_MOD(inst); - color = convert_color(mod->settings->server_depth, mod->bpp, - color, mod->cmap); - mod->server_set_fgcolor(mod, color); - mod->server_fill_rect(mod, x, y, cx, cy); + mod = GET_MOD(inst); + color = convert_color(mod->settings->server_depth, mod->bpp, + color, mod->cmap); + mod->server_set_fgcolor(mod, color); + mod->server_fill_rect(mod, x, y, cx, cy); } /******************************************************************************/ static void DEFAULT_CC -ui_polygon(rdpInst* inst, uint8 opcode, uint8 fillmode, RD_POINT* point, - int npoints, RD_BRUSH* brush, uint32 bgcolor, uint32 fgcolor) +ui_polygon(rdpInst *inst, uint8 opcode, uint8 fillmode, RD_POINT *point, + int npoints, RD_BRUSH *brush, uint32 bgcolor, uint32 fgcolor) { - g_writeln("ui_polygon:"); + g_writeln("ui_polygon:"); } /******************************************************************************/ static void DEFAULT_CC -ui_polyline(rdpInst* inst, uint8 opcode, RD_POINT* points, int npoints, - RD_PEN* pen) +ui_polyline(rdpInst *inst, uint8 opcode, RD_POINT *points, int npoints, + RD_PEN *pen) { - g_writeln("ui_polyline:"); + g_writeln("ui_polyline:"); } /******************************************************************************/ static void DEFAULT_CC -ui_ellipse(rdpInst* inst, uint8 opcode, uint8 fillmode, int x, int y, - int cx, int cy, RD_BRUSH* brush, uint32 bgcolor, uint32 fgcolor) +ui_ellipse(rdpInst *inst, uint8 opcode, uint8 fillmode, int x, int y, + int cx, int cy, RD_BRUSH *brush, uint32 bgcolor, uint32 fgcolor) { - g_writeln("ui_ellipse:"); + g_writeln("ui_ellipse:"); } /******************************************************************************/ static void DEFAULT_CC -ui_add_char(rdpInst * inst, uint8 font, uint16 character, sint16 offset, - sint16 baseline, uint16 width, uint16 height, uint8 * data) +ui_add_char(rdpInst *inst, uint8 font, uint16 character, sint16 offset, + sint16 baseline, uint16 width, uint16 height, uint8 *data) { - struct mod* mod; + struct mod *mod; - //g_writeln("ui_add_char:"); - mod = GET_MOD(inst); - mod->server_add_char(mod, font, character, offset, baseline, - width, height, (char*)data); + //g_writeln("ui_add_char:"); + mod = GET_MOD(inst); + mod->server_add_char(mod, font, character, offset, baseline, + width, height, (char *)data); } /******************************************************************************/ static void DEFAULT_CC -ui_draw_text(rdpInst* inst, uint8 font, uint8 flags, +ui_draw_text(rdpInst *inst, uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y, int clipx, int clipy, int clipcx, int clipcy, - int boxx, int boxy, int boxcx, int boxcy, RD_BRUSH * brush, - uint32 bgcolor, uint32 fgcolor, uint8 * text, uint8 length) + int boxx, int boxy, int boxcx, int boxcy, RD_BRUSH *brush, + uint32 bgcolor, uint32 fgcolor, uint8 *text, uint8 length) { - struct mod* mod; + struct mod *mod; - //g_writeln("ui_draw_text: flags %d mixmode %d x %d y %d", flags, mixmode, x, y); - //g_writeln("%d %d %d %d %d %d %d %d", clipx, clipy, clipcx, clipcy, boxx, boxy, boxcx, boxcy); - mod = GET_MOD(inst); - fgcolor = convert_color(mod->settings->server_depth, mod->bpp, - fgcolor, mod->cmap); - mod->server_set_fgcolor(mod, fgcolor); - bgcolor = convert_color(mod->settings->server_depth, mod->bpp, - bgcolor, mod->cmap); - mod->server_set_bgcolor(mod, bgcolor); - mod->server_draw_text(mod, font, flags, mixmode, - clipx, clipy, clipx + clipcx, clipy + clipcy, - boxx, boxy, boxx + boxcx, boxy + boxcy, x, y, - (char*)text, length); + //g_writeln("ui_draw_text: flags %d mixmode %d x %d y %d", flags, mixmode, x, y); + //g_writeln("%d %d %d %d %d %d %d %d", clipx, clipy, clipcx, clipcy, boxx, boxy, boxcx, boxcy); + mod = GET_MOD(inst); + fgcolor = convert_color(mod->settings->server_depth, mod->bpp, + fgcolor, mod->cmap); + mod->server_set_fgcolor(mod, fgcolor); + bgcolor = convert_color(mod->settings->server_depth, mod->bpp, + bgcolor, mod->cmap); + mod->server_set_bgcolor(mod, bgcolor); + mod->server_draw_text(mod, font, flags, mixmode, + clipx, clipy, clipx + clipcx, clipy + clipcy, + boxx, boxy, boxx + boxcx, boxy + boxcy, x, y, + (char *)text, length); } /******************************************************************************/ static void DEFAULT_CC -ui_start_draw_glyphs(rdpInst* inst, uint32 bgcolor, uint32 fgcolor) +ui_start_draw_glyphs(rdpInst *inst, uint32 bgcolor, uint32 fgcolor) { - g_writeln("ui_start_draw_glyphs:"); + g_writeln("ui_start_draw_glyphs:"); } /******************************************************************************/ static void DEFAULT_CC -ui_draw_glyph(rdpInst* inst, int x, int y, int cx, int cy, - RD_HGLYPH glyph) +ui_draw_glyph(rdpInst *inst, int x, int y, int cx, int cy, + RD_HGLYPH glyph) { - g_writeln("ui_draw_glyph:"); + g_writeln("ui_draw_glyph:"); } /******************************************************************************/ static void DEFAULT_CC -ui_end_draw_glyphs(rdpInst* inst, int x, int y, int cx, int cy) +ui_end_draw_glyphs(rdpInst *inst, int x, int y, int cx, int cy) { - g_writeln("ui_end_draw_glyphs:"); + g_writeln("ui_end_draw_glyphs:"); } /******************************************************************************/ static uint32 DEFAULT_CC -ui_get_toggle_keys_state(rdpInst* inst) +ui_get_toggle_keys_state(rdpInst *inst) { - g_writeln("ui_get_toggle_keys_state:"); - return 0; + g_writeln("ui_get_toggle_keys_state:"); + return 0; } /******************************************************************************/ static void DEFAULT_CC -ui_bell(rdpInst* inst) +ui_bell(rdpInst *inst) { - g_writeln("ui_bell:"); + g_writeln("ui_bell:"); } /******************************************************************************/ static void DEFAULT_CC -ui_destblt(rdpInst* inst, uint8 opcode, int x, int y, int cx, int cy) +ui_destblt(rdpInst *inst, uint8 opcode, int x, int y, int cx, int cy) { - struct mod* mod; + struct mod *mod; - g_writeln("ui_destblt:"); - mod = GET_MOD(inst); - mod->server_set_opcode(mod, opcode); - mod->server_fill_rect(mod, x, y, cx, cy); - mod->server_set_opcode(mod, 0xcc); + g_writeln("ui_destblt:"); + mod = GET_MOD(inst); + mod->server_set_opcode(mod, opcode); + mod->server_fill_rect(mod, x, y, cx, cy); + mod->server_set_opcode(mod, 0xcc); } /******************************************************************************/ static void DEFAULT_CC -ui_patblt(rdpInst* inst, uint8 opcode, int x, int y, int cx, int cy, - RD_BRUSH* brush, uint32 bgcolor, uint32 fgcolor) +ui_patblt(rdpInst *inst, uint8 opcode, int x, int y, int cx, int cy, + RD_BRUSH *brush, uint32 bgcolor, uint32 fgcolor) { - struct mod* mod; - uint8 idata[8]; - int index; + struct mod *mod; + uint8 idata[8]; + int index; - mod = GET_MOD(inst); - mod->server_set_opcode(mod, opcode); - fgcolor = convert_color(mod->settings->server_depth, mod->bpp, - fgcolor, mod->cmap); - mod->server_set_fgcolor(mod, fgcolor); - bgcolor = convert_color(mod->settings->server_depth, mod->bpp, - bgcolor, mod->cmap); - mod->server_set_bgcolor(mod, bgcolor); - mod->server_set_mixmode(mod, 1); - if (brush->bd != 0) - { - if (brush->bd->color_code == 1) /* 8x8 1 bpp */ + mod = GET_MOD(inst); + mod->server_set_opcode(mod, opcode); + fgcolor = convert_color(mod->settings->server_depth, mod->bpp, + fgcolor, mod->cmap); + mod->server_set_fgcolor(mod, fgcolor); + bgcolor = convert_color(mod->settings->server_depth, mod->bpp, + bgcolor, mod->cmap); + mod->server_set_bgcolor(mod, bgcolor); + mod->server_set_mixmode(mod, 1); + + if (brush->bd != 0) { - for (index = 0; index < 8; index++) - { - idata[index] = ~(brush->bd->data[index]); - } - mod->server_set_brush(mod, brush->xorigin, brush->yorigin, - brush->style, idata); + if (brush->bd->color_code == 1) /* 8x8 1 bpp */ + { + for (index = 0; index < 8; index++) + { + idata[index] = ~(brush->bd->data[index]); + } + + mod->server_set_brush(mod, brush->xorigin, brush->yorigin, + brush->style, idata); + } + else + { + g_writeln("ui_patblt: error color_code %d", brush->bd->color_code); + } } else { - g_writeln("ui_patblt: error color_code %d", brush->bd->color_code); + for (index = 0; index < 8; index++) + { + idata[index] = ~(brush->pattern[index]); + } + + mod->server_set_brush(mod, brush->xorigin, brush->yorigin, + brush->style, idata); } - } - else - { - for (index = 0; index < 8; index++) - { - idata[index] = ~(brush->pattern[index]); - } - mod->server_set_brush(mod, brush->xorigin, brush->yorigin, - brush->style, idata); - } - mod->server_fill_rect(mod, x, y, cx, cy); - mod->server_set_opcode(mod, 0xcc); - mod->server_set_mixmode(mod, 0); + + mod->server_fill_rect(mod, x, y, cx, cy); + mod->server_set_opcode(mod, 0xcc); + mod->server_set_mixmode(mod, 0); } /******************************************************************************/ static void DEFAULT_CC -ui_screenblt(rdpInst* inst, uint8 opcode, int x, int y, int cx, int cy, +ui_screenblt(rdpInst *inst, uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy) { - struct mod* mod; + struct mod *mod; - mod = GET_MOD(inst); - mod->server_set_opcode(mod, opcode); - mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy); - mod->server_set_opcode(mod, 0xcc); + mod = GET_MOD(inst); + mod->server_set_opcode(mod, opcode); + mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy); + mod->server_set_opcode(mod, 0xcc); } /******************************************************************************/ static void DEFAULT_CC -ui_memblt(rdpInst* inst, uint8 opcode, int x, int y, int cx, int cy, +ui_memblt(rdpInst *inst, uint8 opcode, int x, int y, int cx, int cy, RD_HBITMAP src, int srcx, int srcy) { - struct my_bitmap* bitmap; - struct mod* mod; - char* bmpdata; + struct my_bitmap *bitmap; + struct mod *mod; + char *bmpdata; - mod = GET_MOD(inst); - bitmap = (struct my_bitmap*)src; - mod->server_set_opcode(mod, opcode); - mod->server_paint_rect(mod, x, y, cx, cy, bitmap->data, - bitmap->width, bitmap->height, srcx, srcy); - mod->server_set_opcode(mod, 0xcc); + mod = GET_MOD(inst); + bitmap = (struct my_bitmap *)src; + mod->server_set_opcode(mod, opcode); + mod->server_paint_rect(mod, x, y, cx, cy, bitmap->data, + bitmap->width, bitmap->height, srcx, srcy); + mod->server_set_opcode(mod, 0xcc); } /******************************************************************************/ static void DEFAULT_CC -ui_triblt(rdpInst* inst, uint8 opcode, int x, int y, int cx, int cy, - RD_HBITMAP src, int srcx, int srcy, RD_BRUSH* brush, +ui_triblt(rdpInst *inst, uint8 opcode, int x, int y, int cx, int cy, + RD_HBITMAP src, int srcx, int srcy, RD_BRUSH *brush, uint32 bgcolor, uint32 fgcolor) { - g_writeln("ui_triblt:"); + g_writeln("ui_triblt:"); } /******************************************************************************/ static RD_HGLYPH DEFAULT_CC -ui_create_glyph(rdpInst* inst, int width, int height, uint8* data) +ui_create_glyph(rdpInst *inst, int width, int height, uint8 *data) { - g_writeln("ui_create_glyph:"); - return 0; + g_writeln("ui_create_glyph:"); + return 0; } /******************************************************************************/ static void DEFAULT_CC -ui_destroy_glyph(rdpInst* inst, RD_HGLYPH glyph) +ui_destroy_glyph(rdpInst *inst, RD_HGLYPH glyph) { - g_writeln("ui_destroy_glyph:"); + g_writeln("ui_destroy_glyph:"); } /******************************************************************************/ static int DEFAULT_CC -ui_select(rdpInst* inst, int rdp_socket) +ui_select(rdpInst *inst, int rdp_socket) { - return 1; + return 1; } /******************************************************************************/ static void DEFAULT_CC -ui_set_clip(rdpInst* inst, int x, int y, int cx, int cy) +ui_set_clip(rdpInst *inst, int x, int y, int cx, int cy) { - struct mod* mod; + struct mod *mod; - mod = GET_MOD(inst); - mod->server_set_clip(mod, x, y, cx, cy); + mod = GET_MOD(inst); + mod->server_set_clip(mod, x, y, cx, cy); } /******************************************************************************/ static void DEFAULT_CC -ui_reset_clip(rdpInst* inst) +ui_reset_clip(rdpInst *inst) { - struct mod* mod; + struct mod *mod; - mod = GET_MOD(inst); - mod->server_reset_clip(mod); + mod = GET_MOD(inst); + mod->server_reset_clip(mod); } /******************************************************************************/ static void DEFAULT_CC -ui_resize_window(rdpInst* inst) +ui_resize_window(rdpInst *inst) { - g_writeln("ui_resize_window:"); + g_writeln("ui_resize_window:"); } /******************************************************************************/ static void DEFAULT_CC -ui_set_cursor(rdpInst* inst, RD_HCURSOR cursor) +ui_set_cursor(rdpInst *inst, RD_HCURSOR cursor) { - struct mod* mod; - struct my_cursor* cur; + struct mod *mod; + struct my_cursor *cur; - //g_writeln("ui_set_cursor:"); - mod = GET_MOD(inst); - cur = (struct my_cursor*)cursor; - if (cur != 0) - { - mod->server_set_cursor(mod, cur->hotx, cur->hoty, - cur->xormask, cur->andmask); - } - else - { - g_writeln("ui_set_cursor: nil cursor"); - } + //g_writeln("ui_set_cursor:"); + mod = GET_MOD(inst); + cur = (struct my_cursor *)cursor; + + if (cur != 0) + { + mod->server_set_cursor(mod, cur->hotx, cur->hoty, + cur->xormask, cur->andmask); + } + else + { + g_writeln("ui_set_cursor: nil cursor"); + } } /******************************************************************************/ static void DEFAULT_CC -ui_destroy_cursor(rdpInst* inst, RD_HCURSOR cursor) +ui_destroy_cursor(rdpInst *inst, RD_HCURSOR cursor) { - struct my_cursor* cur; + struct my_cursor *cur; - //g_writeln("ui_destroy_cursor:"); - cur = (struct my_cursor*)cursor; - if (cur != 0) - { - g_free(cur->andmask); - g_free(cur->xormask); - } - g_free(cur); + //g_writeln("ui_destroy_cursor:"); + cur = (struct my_cursor *)cursor; + + if (cur != 0) + { + g_free(cur->andmask); + g_free(cur->xormask); + } + + g_free(cur); } #define RGB24(_r, _g, _b) \ - (_r << 16) | (_g << 8) | _b; + (_r << 16) | (_g << 8) | _b; /******************************************************************************/ static int -l_get_pixel(tui8* data, int x, int y, int width, int height, int bpp) +l_get_pixel(tui8 *data, int x, int y, int width, int height, int bpp) { - int start; - int shift; - tui16* src16; - tui32* src32; - int red, green, blue; + int start; + int shift; + tui16 *src16; + tui32 *src32; + int red, green, blue; - switch (bpp) - { - case 1: - width = (width + 7) / 8; - start = (y * width) + x / 8; - shift = x % 8; - return (data[start] & (0x80 >> shift)) != 0; - case 8: - return data[y * width + x]; - case 15: - case 16: - src16 = (uint16*) data; - return src16[y * width + x]; - case 24: - data += y * width * 3; - data += x * 3; - red = data[0]; - green = data[1]; - blue = data[2]; - return RGB24(red, green, blue); - case 32: - src32 = (uint32*) data; - return src32[y * width + x]; - default: - g_writeln("l_get_pixel: unknown bpp %d", bpp); - break; - } + switch (bpp) + { + case 1: + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + return (data[start] & (0x80 >> shift)) != 0; + case 8: + return data[y * width + x]; + case 15: + case 16: + src16 = (uint16 *) data; + return src16[y * width + x]; + case 24: + data += y * width * 3; + data += x * 3; + red = data[0]; + green = data[1]; + blue = data[2]; + return RGB24(red, green, blue); + case 32: + src32 = (uint32 *) data; + return src32[y * width + x]; + default: + g_writeln("l_get_pixel: unknown bpp %d", bpp); + break; + } - return 0; + return 0; } /******************************************************************************/ static void -l_set_pixel(tui8* data, int x, int y, int width, int height, +l_set_pixel(tui8 *data, int x, int y, int width, int height, int bpp, int pixel) { - int start; - int shift; - int* dst32; - tui8* dst8; + int start; + int shift; + int *dst32; + tui8 *dst8; - if (bpp == 1) - { - width = (width + 7) / 8; - start = (y * width) + x / 8; - shift = x % 8; - if (pixel) - data[start] = data[start] | (0x80 >> shift); + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + + if (pixel) + { + data[start] = data[start] | (0x80 >> shift); + } + else + { + data[start] = data[start] & ~(0x80 >> shift); + } + } + else if (bpp == 24) + { + dst8 = data + (y * width + x) * 3; + *(dst8++) = (pixel >> 16) & 0xff; + *(dst8++) = (pixel >> 8) & 0xff; + *(dst8++) = (pixel >> 0) & 0xff; + } + else if (bpp == 32) + { + dst32 = (int *) data; + dst32[y * width + x] = pixel; + } else - data[start] = data[start] & ~(0x80 >> shift); - } - else if (bpp == 24) - { - dst8 = data + (y * width + x) * 3; - *(dst8++) = (pixel >> 16) & 0xff; - *(dst8++) = (pixel >> 8) & 0xff; - *(dst8++) = (pixel >> 0) & 0xff; - } - else if (bpp == 32) - { - dst32 = (int*) data; - dst32[y * width + x] = pixel; - } - else - { - g_writeln("l_set_pixel: unknown bpp %d", bpp); - } + { + g_writeln("l_set_pixel: unknown bpp %d", bpp); + } } @@ -752,269 +771,279 @@ l_set_pixel(tui8* data, int x, int y, int width, int height, /* andmask = mask = 32 * 32 / 8 xormask = data = 32 * 32 * 3 */ static RD_HCURSOR DEFAULT_CC -ui_create_cursor(rdpInst* inst, unsigned int x, unsigned int y, - int width, int height, uint8* andmask, - uint8* xormask, int bpp) +ui_create_cursor(rdpInst *inst, unsigned int x, unsigned int y, + int width, int height, uint8 *andmask, + uint8 *xormask, int bpp) { - struct mod* mod; - struct my_cursor* cur; - int i; - int j; - int jj; - int apixel; - int xpixel; - char* dst; + struct mod *mod; + struct my_cursor *cur; + int i; + int j; + int jj; + int apixel; + int xpixel; + char *dst; - mod = GET_MOD(inst); - g_writeln("ui_create_cursor: x %d y %d width %d height %d bpp %d", - x, y, width, height, bpp); - cur = (struct my_cursor*)g_malloc(sizeof(struct my_cursor), 1); - cur->width = width; - cur->height = height; - cur->hotx = x; - cur->hoty = y; - cur->andmask = g_malloc(32 * 32 * 4, 1); - cur->xormask = g_malloc(32 * 32 * 4, 1); - for (j = 0; j < height; j++) - { - jj = (bpp != 1) ? j : (height - 1) - j; - for (i = 0; i < width; i++) + mod = GET_MOD(inst); + g_writeln("ui_create_cursor: x %d y %d width %d height %d bpp %d", + x, y, width, height, bpp); + cur = (struct my_cursor *)g_malloc(sizeof(struct my_cursor), 1); + cur->width = width; + cur->height = height; + cur->hotx = x; + cur->hoty = y; + cur->andmask = g_malloc(32 * 32 * 4, 1); + cur->xormask = g_malloc(32 * 32 * 4, 1); + + for (j = 0; j < height; j++) { - apixel = l_get_pixel(andmask, i, jj, width, height, 1); - xpixel = l_get_pixel(xormask, i, jj, width, height, bpp); - xpixel = convert_color(bpp, 24, xpixel, mod->cmap); - l_set_pixel(cur->andmask, i, j, width, height, 1, apixel); - l_set_pixel(cur->xormask, i, j, width, height, 24, xpixel); + jj = (bpp != 1) ? j : (height - 1) - j; + + for (i = 0; i < width; i++) + { + apixel = l_get_pixel(andmask, i, jj, width, height, 1); + xpixel = l_get_pixel(xormask, i, jj, width, height, bpp); + xpixel = convert_color(bpp, 24, xpixel, mod->cmap); + l_set_pixel(cur->andmask, i, j, width, height, 1, apixel); + l_set_pixel(cur->xormask, i, j, width, height, 24, xpixel); + } } - } - return (RD_HCURSOR)cur; + + return (RD_HCURSOR)cur; } /******************************************************************************/ static void DEFAULT_CC -ui_set_null_cursor(rdpInst* inst) +ui_set_null_cursor(rdpInst *inst) { - g_writeln("ui_set_null_cursor:"); + g_writeln("ui_set_null_cursor:"); } /******************************************************************************/ static void DEFAULT_CC -ui_set_default_cursor(rdpInst* inst) +ui_set_default_cursor(rdpInst *inst) { - g_writeln("ui_set_default_cursor:"); + g_writeln("ui_set_default_cursor:"); } /******************************************************************************/ static RD_HPALETTE DEFAULT_CC -ui_create_palette(rdpInst* inst, RD_PALETTE* colors) +ui_create_palette(rdpInst *inst, RD_PALETTE *colors) { - struct mod* mod; - int index; - int red; - int green; - int blue; - int pixel; - int count; - int* cmap; + struct mod *mod; + int index; + int red; + int green; + int blue; + int pixel; + int count; + int *cmap; - mod = GET_MOD(inst); - g_writeln("ui_create_palette:"); - count = 256; - if (count > colors->count) - { - count = colors->count; - } - cmap = (int*)g_malloc(256 * 4, 1); - for (index = 0; index < count; index++) - { - red = colors->entries[index].red; - green = colors->entries[index].green; - blue = colors->entries[index].blue; - pixel = COLOR24RGB(red, green, blue); - cmap[index] = pixel; - } - return (RD_HPALETTE)cmap; + mod = GET_MOD(inst); + g_writeln("ui_create_palette:"); + count = 256; + + if (count > colors->count) + { + count = colors->count; + } + + cmap = (int *)g_malloc(256 * 4, 1); + + for (index = 0; index < count; index++) + { + red = colors->entries[index].red; + green = colors->entries[index].green; + blue = colors->entries[index].blue; + pixel = COLOR24RGB(red, green, blue); + cmap[index] = pixel; + } + + return (RD_HPALETTE)cmap; } /******************************************************************************/ static void DEFAULT_CC -ui_move_pointer(rdpInst* inst, int x, int y) +ui_move_pointer(rdpInst *inst, int x, int y) { - g_writeln("ui_move_pointer:"); + g_writeln("ui_move_pointer:"); } /******************************************************************************/ static void DEFAULT_CC -ui_set_palette(rdpInst* inst, RD_HPALETTE map) +ui_set_palette(rdpInst *inst, RD_HPALETTE map) { - struct mod* mod; + struct mod *mod; - mod = GET_MOD(inst); - g_writeln("ui_set_palette:"); - g_memcpy(mod->cmap, map, 256 * 4); - g_free(map); + mod = GET_MOD(inst); + g_writeln("ui_set_palette:"); + g_memcpy(mod->cmap, map, 256 * 4); + g_free(map); } /******************************************************************************/ static RD_HBITMAP DEFAULT_CC -ui_create_surface(rdpInst* inst, int width, int height, RD_HBITMAP old) +ui_create_surface(rdpInst *inst, int width, int height, RD_HBITMAP old) { - g_writeln("ui_create_surface:"); - return 0; + g_writeln("ui_create_surface:"); + return 0; } /******************************************************************************/ static void DEFAULT_CC -ui_set_surface(rdpInst* inst, RD_HBITMAP surface) +ui_set_surface(rdpInst *inst, RD_HBITMAP surface) { - g_writeln("ui_set_surface:"); + g_writeln("ui_set_surface:"); } /******************************************************************************/ static void DEFAULT_CC -ui_destroy_surface(rdpInst* inst, RD_HBITMAP surface) +ui_destroy_surface(rdpInst *inst, RD_HBITMAP surface) { - g_writeln("ui_destroy_surface:"); + g_writeln("ui_destroy_surface:"); } /******************************************************************************/ static void DEFAULT_CC -ui_channel_data(rdpInst* inst, int chan_id, char* data, int data_size, - int flags, int total_size) +ui_channel_data(rdpInst *inst, int chan_id, char *data, int data_size, + int flags, int total_size) { - g_writeln("ui_channel_data:"); + g_writeln("ui_channel_data:"); } /******************************************************************************/ static RD_BOOL DEFAULT_CC -ui_authenticate(rdpInst * inst) +ui_authenticate(rdpInst *inst) { - return 1; + return 1; } /******************************************************************************/ static int DEFAULT_CC -ui_decode(rdpInst * inst, uint8 * data, int data_size) +ui_decode(rdpInst *inst, uint8 *data, int data_size) { - return 0; + return 0; } /******************************************************************************/ static RD_BOOL DEFAULT_CC -ui_check_certificate(rdpInst * inst, const char * fingerprint, - const char * subject, const char * issuer, RD_BOOL verified) +ui_check_certificate(rdpInst *inst, const char *fingerprint, + const char *subject, const char *issuer, RD_BOOL verified) { - return 1; + return 1; } /******************************************************************************/ -struct mod* EXPORT_CC +struct mod *EXPORT_CC mod_init(void) { - struct mod* mod; + struct mod *mod; - //g_writeln("1"); - //freerdp_global_init(); - //g_writeln("2"); - mod = (struct mod*)g_malloc(sizeof(struct mod), 1); - mod->size = sizeof(struct mod); - mod->version = CURRENT_MOD_VER; - mod->handle = (tbus)mod; - mod->mod_connect = lib_mod_connect; - mod->mod_start = lib_mod_start; - mod->mod_event = lib_mod_event; - mod->mod_signal = lib_mod_signal; - mod->mod_end = lib_mod_end; - mod->mod_set_param = lib_mod_set_param; - mod->mod_session_change = mod_session_change; - mod->mod_get_wait_objs = mod_get_wait_objs; - mod->mod_check_wait_objs = mod_check_wait_objs; - mod->settings = (struct rdp_set*)g_malloc(sizeof(struct rdp_set), 1); + //g_writeln("1"); + //freerdp_global_init(); + //g_writeln("2"); + mod = (struct mod *)g_malloc(sizeof(struct mod), 1); + mod->size = sizeof(struct mod); + mod->version = CURRENT_MOD_VER; + mod->handle = (tbus)mod; + mod->mod_connect = lib_mod_connect; + mod->mod_start = lib_mod_start; + mod->mod_event = lib_mod_event; + mod->mod_signal = lib_mod_signal; + mod->mod_end = lib_mod_end; + mod->mod_set_param = lib_mod_set_param; + mod->mod_session_change = mod_session_change; + mod->mod_get_wait_objs = mod_get_wait_objs; + mod->mod_check_wait_objs = mod_check_wait_objs; + mod->settings = (struct rdp_set *)g_malloc(sizeof(struct rdp_set), 1); - mod->settings->width = 1280; - mod->settings->height = 1024; - mod->settings->encryption = 1; - mod->settings->rdp_security = 1; - mod->settings->tls_security = 1; - mod->settings->server_depth = 16; - mod->settings->bitmap_cache = 1; - mod->settings->bitmap_compression = 1; - mod->settings->performanceflags = - PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS; - mod->settings->new_cursors = 1; - mod->settings->rdp_version = 5; - mod->settings->text_flags = 1; + mod->settings->width = 1280; + mod->settings->height = 1024; + mod->settings->encryption = 1; + mod->settings->rdp_security = 1; + mod->settings->tls_security = 1; + mod->settings->server_depth = 16; + mod->settings->bitmap_cache = 1; + mod->settings->bitmap_compression = 1; + mod->settings->performanceflags = + PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS; + mod->settings->new_cursors = 1; + mod->settings->rdp_version = 5; + mod->settings->text_flags = 1; - mod->inst = freerdp_new(mod->settings); - if (mod->inst == 0) - { - return 0; - } - SET_MOD(mod->inst, mod); - mod->inst->ui_error = ui_error; - mod->inst->ui_warning = ui_warning; - mod->inst->ui_unimpl = ui_unimpl; - mod->inst->ui_begin_update = ui_begin_update; - mod->inst->ui_end_update = ui_end_update; - mod->inst->ui_desktop_save = ui_desktop_save; - mod->inst->ui_desktop_restore = ui_desktop_restore; - mod->inst->ui_create_bitmap = ui_create_bitmap; - mod->inst->ui_paint_bitmap = ui_paint_bitmap; - mod->inst->ui_destroy_bitmap = ui_destroy_bitmap; - mod->inst->ui_line = ui_line; - mod->inst->ui_rect = ui_rect; - mod->inst->ui_polygon = ui_polygon; - mod->inst->ui_polyline = ui_polyline; - mod->inst->ui_ellipse = ui_ellipse; - mod->inst->ui_add_char = ui_add_char; - mod->inst->ui_draw_text = ui_draw_text; - mod->inst->ui_start_draw_glyphs = ui_start_draw_glyphs; - mod->inst->ui_draw_glyph = ui_draw_glyph; - mod->inst->ui_end_draw_glyphs = ui_end_draw_glyphs; - mod->inst->ui_get_toggle_keys_state = ui_get_toggle_keys_state; - mod->inst->ui_bell = ui_bell; - mod->inst->ui_destblt = ui_destblt; - mod->inst->ui_patblt = ui_patblt; - mod->inst->ui_screenblt = ui_screenblt; - mod->inst->ui_memblt = ui_memblt; - mod->inst->ui_triblt = ui_triblt; - mod->inst->ui_create_glyph = ui_create_glyph; - mod->inst->ui_destroy_glyph = ui_destroy_glyph; - mod->inst->ui_select = ui_select; - mod->inst->ui_set_clip = ui_set_clip; - mod->inst->ui_reset_clip = ui_reset_clip; - mod->inst->ui_resize_window = ui_resize_window; - mod->inst->ui_set_cursor = ui_set_cursor; - mod->inst->ui_destroy_cursor = ui_destroy_cursor; - mod->inst->ui_create_cursor = ui_create_cursor; - mod->inst->ui_set_null_cursor = ui_set_null_cursor; - mod->inst->ui_set_default_cursor = ui_set_default_cursor; - mod->inst->ui_create_palette = ui_create_palette; - mod->inst->ui_move_pointer = ui_move_pointer; - mod->inst->ui_set_palette = ui_set_palette; - mod->inst->ui_create_surface = ui_create_surface; - mod->inst->ui_set_surface = ui_set_surface; - mod->inst->ui_destroy_surface = ui_destroy_surface; - mod->inst->ui_channel_data = ui_channel_data; + mod->inst = freerdp_new(mod->settings); - mod->inst->ui_authenticate = ui_authenticate; - mod->inst->ui_decode = ui_decode; - mod->inst->ui_check_certificate = ui_check_certificate; + if (mod->inst == 0) + { + return 0; + } - return mod; + SET_MOD(mod->inst, mod); + mod->inst->ui_error = ui_error; + mod->inst->ui_warning = ui_warning; + mod->inst->ui_unimpl = ui_unimpl; + mod->inst->ui_begin_update = ui_begin_update; + mod->inst->ui_end_update = ui_end_update; + mod->inst->ui_desktop_save = ui_desktop_save; + mod->inst->ui_desktop_restore = ui_desktop_restore; + mod->inst->ui_create_bitmap = ui_create_bitmap; + mod->inst->ui_paint_bitmap = ui_paint_bitmap; + mod->inst->ui_destroy_bitmap = ui_destroy_bitmap; + mod->inst->ui_line = ui_line; + mod->inst->ui_rect = ui_rect; + mod->inst->ui_polygon = ui_polygon; + mod->inst->ui_polyline = ui_polyline; + mod->inst->ui_ellipse = ui_ellipse; + mod->inst->ui_add_char = ui_add_char; + mod->inst->ui_draw_text = ui_draw_text; + mod->inst->ui_start_draw_glyphs = ui_start_draw_glyphs; + mod->inst->ui_draw_glyph = ui_draw_glyph; + mod->inst->ui_end_draw_glyphs = ui_end_draw_glyphs; + mod->inst->ui_get_toggle_keys_state = ui_get_toggle_keys_state; + mod->inst->ui_bell = ui_bell; + mod->inst->ui_destblt = ui_destblt; + mod->inst->ui_patblt = ui_patblt; + mod->inst->ui_screenblt = ui_screenblt; + mod->inst->ui_memblt = ui_memblt; + mod->inst->ui_triblt = ui_triblt; + mod->inst->ui_create_glyph = ui_create_glyph; + mod->inst->ui_destroy_glyph = ui_destroy_glyph; + mod->inst->ui_select = ui_select; + mod->inst->ui_set_clip = ui_set_clip; + mod->inst->ui_reset_clip = ui_reset_clip; + mod->inst->ui_resize_window = ui_resize_window; + mod->inst->ui_set_cursor = ui_set_cursor; + mod->inst->ui_destroy_cursor = ui_destroy_cursor; + mod->inst->ui_create_cursor = ui_create_cursor; + mod->inst->ui_set_null_cursor = ui_set_null_cursor; + mod->inst->ui_set_default_cursor = ui_set_default_cursor; + mod->inst->ui_create_palette = ui_create_palette; + mod->inst->ui_move_pointer = ui_move_pointer; + mod->inst->ui_set_palette = ui_set_palette; + mod->inst->ui_create_surface = ui_create_surface; + mod->inst->ui_set_surface = ui_set_surface; + mod->inst->ui_destroy_surface = ui_destroy_surface; + mod->inst->ui_channel_data = ui_channel_data; + + mod->inst->ui_authenticate = ui_authenticate; + mod->inst->ui_decode = ui_decode; + mod->inst->ui_check_certificate = ui_check_certificate; + + return mod; } /******************************************************************************/ int EXPORT_CC -mod_exit(struct mod* mod) +mod_exit(struct mod *mod) { - if (mod == 0) - { + if (mod == 0) + { + return 0; + } + + freerdp_free(mod->inst); + g_free(mod->settings); + g_free(mod); + //freerdp_global_finish(); return 0; - } - freerdp_free(mod->inst); - g_free(mod->settings); - g_free(mod); - //freerdp_global_finish(); - return 0; } diff --git a/freerdp/xrdp-freerdp.h b/freerdp/xrdp-freerdp.h index cd931003..b62c8206 100644 --- a/freerdp/xrdp-freerdp.h +++ b/freerdp/xrdp-freerdp.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2010 - - freerdp wrapper - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * freerdp wrapper + */ /* include other h files */ #include "arch.h" diff --git a/freerdp1/xrdp-color.c b/freerdp1/xrdp-color.c index ef74d1c5..6b99140a 100644 --- a/freerdp1/xrdp-color.c +++ b/freerdp1/xrdp-color.c @@ -19,258 +19,295 @@ #include "xrdp-freerdp.h" -char* APP_CC -convert_bitmap(int in_bpp, int out_bpp, char* bmpdata, - int width, int height, int* palette) +char *APP_CC +convert_bitmap(int in_bpp, int out_bpp, char *bmpdata, + int width, int height, int *palette) { - char* out; - char* src; - char* dst; - int i; - int j; - int red; - int green; - int blue; - int pixel; + char *out; + char *src; + char *dst; + int i; + int j; + int red; + int green; + int blue; + int pixel; - if ((in_bpp == 8) && (out_bpp == 8)) - { - out = (char*)g_malloc(width * height, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + if ((in_bpp == 8) && (out_bpp == 8)) { - for (j = 0; j < width; j++) - { - pixel = *((tui8*)src); - pixel = palette[pixel]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR8(red, green, blue); - *dst = pixel; - src++; - dst++; - } + out = (char *)g_malloc(width * height, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui8 *)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + *dst = pixel; + src++; + dst++; + } + } + + return out; } - return out; - } - if ((in_bpp == 8) && (out_bpp == 16)) - { - out = (char*)g_malloc(width * height * 2, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 8) && (out_bpp == 16)) { - for (j = 0; j < width; j++) - { - pixel = *((tui8*)src); - pixel = palette[pixel]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - *((tui16*)dst) = pixel; - src++; - dst += 2; - } + out = (char *)g_malloc(width * height * 2, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui8 *)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + *((tui16 *)dst) = pixel; + src++; + dst += 2; + } + } + + return out; } - return out; - } - if ((in_bpp == 8) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 8) && (out_bpp == 24)) { - for (j = 0; j < width; j++) - { - pixel = *((tui8*)src); - pixel = palette[pixel]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - src++; - dst += 4; - } + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui8 *)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + src++; + dst += 4; + } + } + + return out; } - return out; - } - if ((in_bpp == 15) && (out_bpp == 16)) - { - out = (char*)g_malloc(width * height * 2, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 15) && (out_bpp == 16)) { - for (j = 0; j < width; j++) - { - pixel = *((tui16*)src); - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - *((tui16*)dst) = pixel; - src += 2; - dst += 2; - } + out = (char *)g_malloc(width * height * 2, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui16 *)src); + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + *((tui16 *)dst) = pixel; + src += 2; + dst += 2; + } + } + + return out; } - return out; - } - if ((in_bpp == 15) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 15) && (out_bpp == 24)) { - for (j = 0; j < width; j++) - { - pixel = *((tui16*)src); - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - src += 2; - dst += 4; - } + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui16 *)src); + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + src += 2; + dst += 4; + } + } + + return out; } - return out; - } - if ((in_bpp == 15) && (out_bpp == 15)) - { - return bmpdata; - } - if ((in_bpp == 16) && (out_bpp == 16)) - { - return bmpdata; - } - if ((in_bpp == 16) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 15) && (out_bpp == 15)) { - for (j = 0; j < width; j++) - { - pixel = *((tui16*)src); - SPLITCOLOR16(red, green, blue, pixel); - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - src += 2; - dst += 4; - } + return bmpdata; } - return out; - } - if ((in_bpp == 24) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 16) && (out_bpp == 16)) { - for (j = 0; j < width; j++) - { - blue = *((tui8*)src); - src++; - green = *((tui8*)src); - src++; - red = *((tui8*)src); - src++; - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - dst += 4; - } + return bmpdata; } - return out; - } - if ((in_bpp == 32) && (out_bpp == 24)) - { - return bmpdata; - } - if ((in_bpp == 32) && (out_bpp == 32)) - { - return bmpdata; - } - g_writeln("convert_bitmap: error unknown conversion from %d to %d", - in_bpp, out_bpp); - return 0; + + if ((in_bpp == 16) && (out_bpp == 24)) + { + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui16 *)src); + SPLITCOLOR16(red, green, blue, pixel); + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + src += 2; + dst += 4; + } + } + + return out; + } + + if ((in_bpp == 24) && (out_bpp == 24)) + { + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + blue = *((tui8 *)src); + src++; + green = *((tui8 *)src); + src++; + red = *((tui8 *)src); + src++; + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + dst += 4; + } + } + + return out; + } + + if ((in_bpp == 32) && (out_bpp == 24)) + { + return bmpdata; + } + + if ((in_bpp == 32) && (out_bpp == 32)) + { + return bmpdata; + } + + g_writeln("convert_bitmap: error unknown conversion from %d to %d", + in_bpp, out_bpp); + return 0; } /*****************************************************************************/ /* returns color or 0 */ int APP_CC -convert_color(int in_bpp, int out_bpp, int in_color, int* palette) +convert_color(int in_bpp, int out_bpp, int in_color, int *palette) { - int pixel; - int red; - int green; - int blue; + int pixel; + int red; + int green; + int blue; - if ((in_bpp == 1) && (out_bpp == 24)) - { - pixel = in_color == 0 ? 0 : 0xffffff; - return pixel; - } - if ((in_bpp == 8) && (out_bpp == 8)) - { - pixel = palette[in_color]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR8(red, green, blue); - return pixel; - } - if ((in_bpp == 8) && (out_bpp == 16)) - { - pixel = palette[in_color]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - return pixel; - } - if ((in_bpp == 8) && (out_bpp == 24)) - { - pixel = palette[in_color]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR24BGR(red, green, blue); - return pixel; - } - if ((in_bpp == 15) && (out_bpp == 16)) - { - pixel = in_color; - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - return pixel; - } - if ((in_bpp == 15) && (out_bpp == 24)) - { - pixel = in_color; - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR24BGR(red, green, blue); - return pixel; - } - if ((in_bpp == 15) && (out_bpp == 15)) - { - return in_color; - } - if ((in_bpp == 16) && (out_bpp == 16)) - { - return in_color; - } - if ((in_bpp == 16) && (out_bpp == 24)) - { - pixel = in_color; - SPLITCOLOR16(red, green, blue, pixel); - pixel = COLOR24BGR(red, green, blue); - return pixel; - } - if ((in_bpp == 24) && (out_bpp == 24)) - { - return in_color; - } - if ((in_bpp == 32) && (out_bpp == 24)) - { - return in_color; - } - if ((in_bpp == 32) && (out_bpp == 32)) - { - return in_color; - } - g_writeln("convert_color: error unknown conversion from %d to %d", - in_bpp, out_bpp); - return 0; + if ((in_bpp == 1) && (out_bpp == 24)) + { + pixel = in_color == 0 ? 0 : 0xffffff; + return pixel; + } + + if ((in_bpp == 8) && (out_bpp == 8)) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + return pixel; + } + + if ((in_bpp == 8) && (out_bpp == 16)) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + return pixel; + } + + if ((in_bpp == 8) && (out_bpp == 24)) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR24BGR(red, green, blue); + return pixel; + } + + if ((in_bpp == 15) && (out_bpp == 16)) + { + pixel = in_color; + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + return pixel; + } + + if ((in_bpp == 15) && (out_bpp == 24)) + { + pixel = in_color; + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR24BGR(red, green, blue); + return pixel; + } + + if ((in_bpp == 15) && (out_bpp == 15)) + { + return in_color; + } + + if ((in_bpp == 16) && (out_bpp == 16)) + { + return in_color; + } + + if ((in_bpp == 16) && (out_bpp == 24)) + { + pixel = in_color; + SPLITCOLOR16(red, green, blue, pixel); + pixel = COLOR24BGR(red, green, blue); + return pixel; + } + + if ((in_bpp == 24) && (out_bpp == 24)) + { + return in_color; + } + + if ((in_bpp == 32) && (out_bpp == 24)) + { + return in_color; + } + + if ((in_bpp == 32) && (out_bpp == 32)) + { + return in_color; + } + + g_writeln("convert_color: error unknown conversion from %d to %d", + in_bpp, out_bpp); + return 0; } diff --git a/freerdp1/xrdp-freerdp.c b/freerdp1/xrdp-freerdp.c index 524dcf2e..25206f8e 100644 --- a/freerdp1/xrdp-freerdp.c +++ b/freerdp1/xrdp-freerdp.c @@ -23,1659 +23,1735 @@ #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0) + do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0) + do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0) struct mod_context { - rdpContext _p; - struct mod* modi; + rdpContext _p; + struct mod *modi; }; typedef struct mod_context modContext; /*****************************************************************************/ /* return error */ static int DEFAULT_CC -lxrdp_start(struct mod* mod, int w, int h, int bpp) +lxrdp_start(struct mod *mod, int w, int h, int bpp) { - rdpSettings* settings; + rdpSettings *settings; - LLOGLN(10, ("lxrdp_start: w %d h %d bpp %d", w, h, bpp)); - settings = mod->inst->settings; - settings->width = w; - settings->height = h; - settings->color_depth = bpp; - mod->bpp = bpp; + LLOGLN(10, ("lxrdp_start: w %d h %d bpp %d", w, h, bpp)); + settings = mod->inst->settings; + settings->width = w; + settings->height = h; + settings->color_depth = bpp; + mod->bpp = bpp; - settings->encryption = 1; - settings->tls_security = 1; - settings->nla_security = 0; - settings->rdp_security = 1; + settings->encryption = 1; + settings->tls_security = 1; + settings->nla_security = 0; + settings->rdp_security = 1; - return 0; + return 0; } /******************************************************************************/ /* return error */ static int DEFAULT_CC -lxrdp_connect(struct mod* mod) +lxrdp_connect(struct mod *mod) { - boolean ok; + boolean ok; - LLOGLN(10, ("lxrdp_connect:")); + LLOGLN(10, ("lxrdp_connect:")); - ok = freerdp_connect(mod->inst); - LLOGLN(0, ("lxrdp_connect: freerdp_connect returned %d", ok)); + ok = freerdp_connect(mod->inst); + LLOGLN(0, ("lxrdp_connect: freerdp_connect returned %d", ok)); - if (!ok) - { - LLOGLN(0, ("Failure to connect")); -#ifdef ERRORSTART - if (connectErrorCode != 0) + if (!ok) { - char buf[128]; + LLOGLN(0, ("Failure to connect")); +#ifdef ERRORSTART - if (connectErrorCode < ERRORSTART) - { - if (strerror_r(connectErrorCode, buf, 128) != 0) + if (connectErrorCode != 0) { - snprintf(buf, 128, "Errorcode from connect : %d", connectErrorCode); - } - } - else - { - switch (connectErrorCode) - { - case PREECONNECTERROR: - snprintf(buf, 128, "The error code from connect is " - "PREECONNECTERROR"); - break; - case UNDEFINEDCONNECTERROR: - snprintf(buf, 128, "The error code from connect is " - "UNDEFINEDCONNECTERROR"); - break; - case POSTCONNECTERROR: - snprintf(buf, 128, "The error code from connect is " - "POSTCONNECTERROR"); - break; - case DNSERROR: - snprintf(buf, 128, "The DNS system generated an error"); - break; - case DNSNAMENOTFOUND: - snprintf(buf, 128, "The DNS system could not find the " - "specified name"); - break; - case CONNECTERROR: - snprintf(buf, 128, "A general connect error was returned"); - break; - case MCSCONNECTINITIALERROR: - snprintf(buf, 128, "The error code from connect is " - "MCSCONNECTINITIALERROR"); - break; - case TLSCONNECTERROR: - snprintf(buf, 128, "Error in TLS handshake"); - break; - case AUTHENTICATIONERROR: - snprintf(buf, 128, "Authentication error check your password " - "and username"); - break; - default: - snprintf(buf, 128, "Unhandled Errorcode from connect : %d", - connectErrorCode); - break; - } - } - mod->server_msg(mod, buf, 0); - } -#endif - return 1; - } - return 0; -} + char buf[128]; -/******************************************************************************/ -/* return error */ -static int DEFAULT_CC -lxrdp_event(struct mod* mod, int msg, long param1, long param2, - long param3, long param4) -{ - int x; - int y; - int flags; - int size; - int total_size; - int chanid; - int lchid; - char* data; - - LLOGLN(10, ("lxrdp_event: msg %d", msg)); - switch (msg) - { - case 15: /* key down */ - mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3); - break; - case 16: /* key up */ - mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3); - break; - case 17: /*Synchronize*/ - LLOGLN(0, ("Synchronized event handled")); - mod->inst->input->SynchronizeEvent(mod->inst->input, 0); - break; - case 100: /* mouse move */ - LLOGLN(10, ("mouse move %d %d", param1, param2)); - x = param1; - y = param2; - flags = PTR_FLAGS_MOVE; - mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); - break; - case 101: /* left button up */ - LLOGLN(10, ("left button up %d %d", param1, param2)); - x = param1; - y = param2; - flags = PTR_FLAGS_BUTTON1; - mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); - break; - case 102: /* left button down */ - LLOGLN(10, ("left button down %d %d", param1, param2)); - x = param1; - y = param2; - flags = PTR_FLAGS_BUTTON1 | PTR_FLAGS_DOWN; - mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); - break; - case 103: /* right button up */ - LLOGLN(10, ("right button up %d %d", param1, param2)); - x = param1; - y = param2; - flags = PTR_FLAGS_BUTTON2; - mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); - break; - case 104: /* right button down */ - LLOGLN(10, ("right button down %d %d", param1, param2)); - x = param1; - y = param2; - flags = PTR_FLAGS_BUTTON2 | PTR_FLAGS_DOWN; - mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); - break; - case 105: /* middle button up */ - LLOGLN(10, ("middle button up %d %d", param1, param2)); - x = param1; - y = param2; - flags = PTR_FLAGS_BUTTON3; - mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); - break; - case 106: /* middle button down */ - LLOGLN(10, ("middle button down %d %d", param1, param2)); - x = param1; - y = param2; - flags = PTR_FLAGS_BUTTON3 | PTR_FLAGS_DOWN; - mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); - break; - case 107: /* wheel up */ - flags = PTR_FLAGS_WHEEL | 0x0078; - mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0); - case 108: - break; - case 109: /* wheel down */ - flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; - mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0); - case 110: - break; - case 200: - LLOGLN(10, ("Invalidate request sent from client")); - RECTANGLE_16 *rectangle = (RECTANGLE_16 *) g_malloc(sizeof(RECTANGLE_16), 0); - /* The parameters are coded as follows param1 = MAKELONG(y, x), param2 =MAKELONG(h, w) - * #define MAKELONG(lo, hi) ((((hi) & 0xffff) << 16) | ((lo) & 0xffff)) - */ - rectangle->left = (param1 >> 16) & 0xffff; - rectangle->top = param1 & 0xffff; - rectangle->right = (((param2 >> 16) & 0xffff) + rectangle->left) - 1; - rectangle->bottom = ((param2 & 0xffff) + rectangle->top) - 1; - if (mod->inst->settings->refresh_rect) - { - if (mod->inst->update != NULL) - { - if (mod->inst->update->RefreshRect != NULL) - { - if (mod->inst->context != NULL) + if (connectErrorCode < ERRORSTART) { - LLOGLN(0, ("update rectangle left: %d top: %d bottom: %d right: %d", - rectangle->left, rectangle->top, rectangle->bottom, rectangle->right)); - mod->inst->update->RefreshRect(mod->inst->context, 1, rectangle); + if (strerror_r(connectErrorCode, buf, 128) != 0) + { + snprintf(buf, 128, "Errorcode from connect : %d", connectErrorCode); + } } else { - LLOGLN(0, ("Invalidate request -The context is null")); + switch (connectErrorCode) + { + case PREECONNECTERROR: + snprintf(buf, 128, "The error code from connect is " + "PREECONNECTERROR"); + break; + case UNDEFINEDCONNECTERROR: + snprintf(buf, 128, "The error code from connect is " + "UNDEFINEDCONNECTERROR"); + break; + case POSTCONNECTERROR: + snprintf(buf, 128, "The error code from connect is " + "POSTCONNECTERROR"); + break; + case DNSERROR: + snprintf(buf, 128, "The DNS system generated an error"); + break; + case DNSNAMENOTFOUND: + snprintf(buf, 128, "The DNS system could not find the " + "specified name"); + break; + case CONNECTERROR: + snprintf(buf, 128, "A general connect error was returned"); + break; + case MCSCONNECTINITIALERROR: + snprintf(buf, 128, "The error code from connect is " + "MCSCONNECTINITIALERROR"); + break; + case TLSCONNECTERROR: + snprintf(buf, 128, "Error in TLS handshake"); + break; + case AUTHENTICATIONERROR: + snprintf(buf, 128, "Authentication error check your password " + "and username"); + break; + default: + snprintf(buf, 128, "Unhandled Errorcode from connect : %d", + connectErrorCode); + break; + } } - } - else - { - LLOGLN(0, ("Invalidate request - RefreshRect is Null")); - } + + mod->server_msg(mod, buf, 0); + } + +#endif + return 1; + } + + return 0; +} + +/******************************************************************************/ +/* return error */ +static int DEFAULT_CC +lxrdp_event(struct mod *mod, int msg, long param1, long param2, + long param3, long param4) +{ + int x; + int y; + int flags; + int size; + int total_size; + int chanid; + int lchid; + char *data; + + LLOGLN(10, ("lxrdp_event: msg %d", msg)); + + switch (msg) + { + case 15: /* key down */ + mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3); + break; + case 16: /* key up */ + mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3); + break; + case 17: /*Synchronize*/ + LLOGLN(0, ("Synchronized event handled")); + mod->inst->input->SynchronizeEvent(mod->inst->input, 0); + break; + case 100: /* mouse move */ + LLOGLN(10, ("mouse move %d %d", param1, param2)); + x = param1; + y = param2; + flags = PTR_FLAGS_MOVE; + mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); + break; + case 101: /* left button up */ + LLOGLN(10, ("left button up %d %d", param1, param2)); + x = param1; + y = param2; + flags = PTR_FLAGS_BUTTON1; + mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); + break; + case 102: /* left button down */ + LLOGLN(10, ("left button down %d %d", param1, param2)); + x = param1; + y = param2; + flags = PTR_FLAGS_BUTTON1 | PTR_FLAGS_DOWN; + mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); + break; + case 103: /* right button up */ + LLOGLN(10, ("right button up %d %d", param1, param2)); + x = param1; + y = param2; + flags = PTR_FLAGS_BUTTON2; + mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); + break; + case 104: /* right button down */ + LLOGLN(10, ("right button down %d %d", param1, param2)); + x = param1; + y = param2; + flags = PTR_FLAGS_BUTTON2 | PTR_FLAGS_DOWN; + mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); + break; + case 105: /* middle button up */ + LLOGLN(10, ("middle button up %d %d", param1, param2)); + x = param1; + y = param2; + flags = PTR_FLAGS_BUTTON3; + mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); + break; + case 106: /* middle button down */ + LLOGLN(10, ("middle button down %d %d", param1, param2)); + x = param1; + y = param2; + flags = PTR_FLAGS_BUTTON3 | PTR_FLAGS_DOWN; + mod->inst->input->MouseEvent(mod->inst->input, flags, x, y); + break; + case 107: /* wheel up */ + flags = PTR_FLAGS_WHEEL | 0x0078; + mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0); + case 108: + break; + case 109: /* wheel down */ + flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; + mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0); + case 110: + break; + case 200: + LLOGLN(10, ("Invalidate request sent from client")); + RECTANGLE_16 *rectangle = (RECTANGLE_16 *) g_malloc(sizeof(RECTANGLE_16), 0); + /* The parameters are coded as follows param1 = MAKELONG(y, x), param2 =MAKELONG(h, w) + * #define MAKELONG(lo, hi) ((((hi) & 0xffff) << 16) | ((lo) & 0xffff)) + */ + rectangle->left = (param1 >> 16) & 0xffff; + rectangle->top = param1 & 0xffff; + rectangle->right = (((param2 >> 16) & 0xffff) + rectangle->left) - 1; + rectangle->bottom = ((param2 & 0xffff) + rectangle->top) - 1; + + if (mod->inst->settings->refresh_rect) + { + if (mod->inst->update != NULL) + { + if (mod->inst->update->RefreshRect != NULL) + { + if (mod->inst->context != NULL) + { + LLOGLN(0, ("update rectangle left: %d top: %d bottom: %d right: %d", + rectangle->left, rectangle->top, rectangle->bottom, rectangle->right)); + mod->inst->update->RefreshRect(mod->inst->context, 1, rectangle); + } + else + { + LLOGLN(0, ("Invalidate request -The context is null")); + } + } + else + { + LLOGLN(0, ("Invalidate request - RefreshRect is Null")); + } + } + else + { + LLOGLN(0, ("Invalidate request -the update pointer is null")); + } + } + else + { + LLOGLN(0, ("Invalidate request - warning - update rectangle is disabled")); + } + + g_free(rectangle); + break; + case 0x5555: + chanid = LOWORD(param1); + flags = HIWORD(param1); + size = (int)param2; + data = (char *)param3; + total_size = (int)param4; + LLOGLN(10, ("lxrdp_event: client to server flags %d", flags)); + + if ((chanid < 0) || (chanid >= mod->inst->settings->num_channels)) + { + LLOGLN(0, ("lxrdp_event: error chanid %d", chanid)); + break; + } + + lchid = mod->inst->settings->channels[chanid].channel_id; + + switch (flags & 3) + { + case 3: + mod->inst->SendChannelData(mod->inst, lchid, (tui8 *)data, total_size); + break; + case 2: + /* end */ + g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size); + mod->chan_buf_valid += size; + mod->inst->SendChannelData(mod->inst, lchid, (tui8 *)(mod->chan_buf), + total_size); + g_free(mod->chan_buf); + mod->chan_buf = 0; + mod->chan_buf_bytes = 0; + mod->chan_buf_valid = 0; + break; + case 1: + /* start */ + g_free(mod->chan_buf); + mod->chan_buf = (char *)g_malloc(total_size, 0); + mod->chan_buf_bytes = total_size; + mod->chan_buf_valid = 0; + g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size); + mod->chan_buf_valid += size; + break; + default: + /* middle */ + g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size); + mod->chan_buf_valid += size; + break; + } + + break; + default: + LLOGLN(0, ("Unhandled message type in eventhandler %d", msg)); + break; + } + + return 0; +} + +/******************************************************************************/ +/* return error */ +static int DEFAULT_CC +lxrdp_signal(struct mod *mod) +{ + LLOGLN(10, ("lxrdp_signal:")); + return 0; +} + +/******************************************************************************/ +/* return error */ +static int DEFAULT_CC +lxrdp_end(struct mod *mod) +{ + int i; + int j; + + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4096; i++) + { + g_free(mod->bitmap_cache[j][i].data); + } + } + + for (i = 0; i < 64; i++) + { + if (mod->brush_cache[i].data != mod->brush_cache[i].b8x8) + { + g_free(mod->brush_cache[i].data); + } + } + + LLOGLN(10, ("lxrdp_end:")); + return 0; +} + +/******************************************************************************/ +/* return error */ +static int DEFAULT_CC +lxrdp_set_param(struct mod *mod, char *name, char *value) +{ + rdpSettings *settings; + + LLOGLN(10, ("lxrdp_set_param: name [%s] value [%s]", name, value)); + settings = mod->inst->settings; + + LLOGLN(10, ("%p %d", settings->hostname, settings->encryption)); + + if (g_strcmp(name, "hostname") == 0) + { + } + else if (g_strcmp(name, "ip") == 0) + { + settings->hostname = g_strdup(value); + } + else if (g_strcmp(name, "port") == 0) + { + settings->port = g_atoi(value); + } + else if (g_strcmp(name, "keylayout") == 0) + { + } + else if (g_strcmp(name, "name") == 0) + { + } + else if (g_strcmp(name, "lib") == 0) + { + } + else if (g_strcmp(name, "username") == 0) + { + g_strncpy(mod->username, value, 255); + } + else if (g_strcmp(name, "password") == 0) + { + g_strncpy(mod->password, value, 255); + } + else if (g_strcmp(name, "client_info") == 0) + { + g_memcpy(&(mod->client_info), value, sizeof(mod->client_info)); + /* This is a Struct and cannot be printed in next else*/ + LLOGLN(10, ("Client_info struct ignored")); + } + else + { + LLOGLN(0, ("lxrdp_set_param: unknown name [%s] value [%s]", name, value)); + } + + return 0; +} + +/******************************************************************************/ +static int DEFAULT_CC +lxrdp_session_change(struct mod *mod, int a, int b) +{ + LLOGLN(10, ("lxrdp_session_change:")); + return 0; +} + +/******************************************************************************/ +static int DEFAULT_CC +lxrdp_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount, + tbus *write_objs, int *wcount, int *timeout) +{ + void **rfds; + void **wfds; + boolean ok; + + LLOGLN(10, ("lxrdp_get_wait_objs:")); + rfds = (void **)read_objs; + wfds = (void **)write_objs; + ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount); + + if (!ok) + { + LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed")); + return 1; + } + + return 0; +} + +/******************************************************************************/ +static int DEFAULT_CC +lxrdp_check_wait_objs(struct mod *mod) +{ + boolean ok; + + LLOGLN(10, ("lxrdp_check_wait_objs:")); + ok = freerdp_check_fds(mod->inst); + + if (!ok) + { + LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed")); + return 1; + } + + return 0; +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_begin_paint(rdpContext *context) +{ + struct mod *mod; + + LLOGLN(10, ("lfreerdp_begin_paint:")); + mod = ((struct mod_context *)context)->modi; + mod->server_begin_update(mod); +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_end_paint(rdpContext *context) +{ + struct mod *mod; + + LLOGLN(10, ("lfreerdp_end_paint:")); + mod = ((struct mod_context *)context)->modi; + mod->server_end_update(mod); +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_set_bounds(rdpContext *context, rdpBounds *bounds) +{ + struct mod *mod; + int x; + int y; + int cx; + int cy; + + LLOGLN(10, ("lfreerdp_set_bounds: %p", bounds)); + mod = ((struct mod_context *)context)->modi; + + if (bounds != 0) + { + x = bounds->left; + y = bounds->top; + cx = (bounds->right - bounds->left) + 1; + cy = (bounds->bottom - bounds->top) + 1; + mod->server_set_clip(mod, x, y, cx, cy); + } + else + { + mod->server_reset_clip(mod); + } +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap) +{ + struct mod *mod; + int index; + int cx; + int cy; + int server_bpp; + int server_Bpp; + int client_bpp; + int j; + int line_bytes; + BITMAP_DATA *bd; + char *dst_data; + char *dst_data1; + char *src; + char *dst; + + mod = ((struct mod_context *)context)->modi; + LLOGLN(10, ("lfreerdp_bitmap_update: %d %d", bitmap->number, bitmap->count)); + + server_bpp = mod->inst->settings->color_depth; + server_Bpp = (server_bpp + 7) / 8; + client_bpp = mod->bpp; + + for (index = 0; index < bitmap->number; index++) + { + bd = bitmap->rectangles + index; + cx = (bd->destRight - bd->destLeft) + 1; + cy = (bd->destBottom - bd->destTop) + 1; + line_bytes = server_Bpp * bd->width; + dst_data = (char *)g_malloc(bd->height * line_bytes + 16, 0); + + if (bd->compressed) + { + bitmap_decompress(bd->bitmapDataStream, (tui8 *)dst_data, bd->width, + bd->height, bd->bitmapLength, server_bpp, server_bpp); } else { - LLOGLN(0, ("Invalidate request -the update pointer is null")); + /* bitmap is upside down */ + src = (char *)(bd->bitmapDataStream); + dst = dst_data + bd->height * line_bytes; + + for (j = 0; j < bd->height; j++) + { + dst -= line_bytes; + g_memcpy(dst, src, line_bytes); + src += line_bytes; + } } - } - else - { - LLOGLN(0, ("Invalidate request - warning - update rectangle is disabled")); - } - g_free(rectangle); - break; - case 0x5555: - chanid = LOWORD(param1); - flags = HIWORD(param1); - size = (int)param2; - data = (char*)param3; - total_size = (int)param4; - LLOGLN(10, ("lxrdp_event: client to server flags %d", flags)); - if ((chanid < 0) || (chanid >= mod->inst->settings->num_channels)) - { - LLOGLN(0, ("lxrdp_event: error chanid %d", chanid)); - break; - } - lchid = mod->inst->settings->channels[chanid].channel_id; - switch (flags & 3) - { - case 3: - mod->inst->SendChannelData(mod->inst, lchid, (tui8*)data, total_size); - break; - case 2: - /* end */ - g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size); - mod->chan_buf_valid += size; - mod->inst->SendChannelData(mod->inst, lchid, (tui8*)(mod->chan_buf), - total_size); - g_free(mod->chan_buf); - mod->chan_buf = 0; - mod->chan_buf_bytes = 0; - mod->chan_buf_valid = 0; - break; - case 1: - /* start */ - g_free(mod->chan_buf); - mod->chan_buf = (char*)g_malloc(total_size, 0); - mod->chan_buf_bytes = total_size; - mod->chan_buf_valid = 0; - g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size); - mod->chan_buf_valid += size; - break; - default: - /* middle */ - g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size); - mod->chan_buf_valid += size; - break; - } - break; - default: - LLOGLN(0, ("Unhandled message type in eventhandler %d", msg)); - break; - } - return 0; -} -/******************************************************************************/ -/* return error */ -static int DEFAULT_CC -lxrdp_signal(struct mod* mod) -{ - LLOGLN(10, ("lxrdp_signal:")); - return 0; -} + dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data, + bd->width, bd->height, mod->colormap); + mod->server_paint_rect(mod, bd->destLeft, bd->destTop, cx, cy, + dst_data1, bd->width, bd->height, 0, 0); -/******************************************************************************/ -/* return error */ -static int DEFAULT_CC -lxrdp_end(struct mod* mod) -{ - int i; - int j; + if (dst_data1 != dst_data) + { + g_free(dst_data1); + } - for (j = 0; j < 4; j++) - { - for (i = 0; i < 4096; i++) - { - g_free(mod->bitmap_cache[j][i].data); + g_free(dst_data); } - } - for (i = 0; i < 64; i++) - { - if (mod->brush_cache[i].data != mod->brush_cache[i].b8x8) +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_dst_blt(rdpContext *context, DSTBLT_ORDER *dstblt) +{ + struct mod *mod; + + mod = ((struct mod_context *)context)->modi; + LLOGLN(10, ("lfreerdp_dst_blt:")); + mod->server_set_opcode(mod, dstblt->bRop); + mod->server_fill_rect(mod, dstblt->nLeftRect, dstblt->nTopRect, + dstblt->nWidth, dstblt->nHeight); + mod->server_set_opcode(mod, 0xcc); +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_pat_blt(rdpContext *context, PATBLT_ORDER *patblt) +{ + struct mod *mod; + int idx; + int fgcolor; + int bgcolor; + int server_bpp; + int client_bpp; + struct brush_item *bi; + + mod = ((struct mod_context *)context)->modi; + LLOGLN(10, ("lfreerdp_pat_blt:")); + + server_bpp = mod->inst->settings->color_depth; + client_bpp = mod->bpp; + LLOGLN(0, ("lfreerdp_pat_blt: bpp %d %d", server_bpp, client_bpp)); + + fgcolor = convert_color(server_bpp, client_bpp, + patblt->foreColor, mod->colormap); + bgcolor = convert_color(server_bpp, client_bpp, + patblt->backColor, mod->colormap); + + mod->server_set_mixmode(mod, 1); + mod->server_set_opcode(mod, patblt->bRop); + mod->server_set_fgcolor(mod, fgcolor); + mod->server_set_bgcolor(mod, bgcolor); + + if (patblt->brush.style & 0x80) { - g_free(mod->brush_cache[i].data); - } - } - LLOGLN(10, ("lxrdp_end:")); - return 0; -} + idx = patblt->brush.hatch; -/******************************************************************************/ -/* return error */ -static int DEFAULT_CC -lxrdp_set_param(struct mod* mod, char* name, char* value) -{ - rdpSettings* settings; + if ((idx < 0) || (idx >= 64)) + { + LLOGLN(0, ("lfreerdp_pat_blt: error")); + return; + } - LLOGLN(10, ("lxrdp_set_param: name [%s] value [%s]", name, value)); - settings = mod->inst->settings; - - LLOGLN(10, ("%p %d", settings->hostname, settings->encryption)); - - if (g_strcmp(name, "hostname") == 0) - { - } - else if (g_strcmp(name, "ip") == 0) - { - settings->hostname = g_strdup(value); - } - else if (g_strcmp(name, "port") == 0) - { - settings->port = g_atoi(value); - } - else if (g_strcmp(name, "keylayout") == 0) - { - } - else if (g_strcmp(name, "name") == 0) - { - } - else if (g_strcmp(name, "lib") == 0) - { - } - else if (g_strcmp(name, "username") == 0) - { - g_strncpy(mod->username, value, 255); - } - else if (g_strcmp(name, "password") == 0) - { - g_strncpy(mod->password, value, 255); - } - else if (g_strcmp(name, "client_info") == 0) - { - g_memcpy(&(mod->client_info), value, sizeof(mod->client_info)); - /* This is a Struct and cannot be printed in next else*/ - LLOGLN(10, ("Client_info struct ignored")); - } - else - { - LLOGLN(0, ("lxrdp_set_param: unknown name [%s] value [%s]", name, value)); - } - - return 0; -} - -/******************************************************************************/ -static int DEFAULT_CC -lxrdp_session_change(struct mod* mod, int a, int b) -{ - LLOGLN(10, ("lxrdp_session_change:")); - return 0; -} - -/******************************************************************************/ -static int DEFAULT_CC -lxrdp_get_wait_objs(struct mod* mod, tbus* read_objs, int* rcount, - tbus* write_objs, int* wcount, int* timeout) -{ - void** rfds; - void** wfds; - boolean ok; - - LLOGLN(10, ("lxrdp_get_wait_objs:")); - rfds = (void**)read_objs; - wfds = (void**)write_objs; - ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount); - if (!ok) - { - LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed")); - return 1; - } - return 0; -} - -/******************************************************************************/ -static int DEFAULT_CC -lxrdp_check_wait_objs(struct mod* mod) -{ - boolean ok; - - LLOGLN(10, ("lxrdp_check_wait_objs:")); - ok = freerdp_check_fds(mod->inst); - if (!ok) - { - LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed")); - return 1; - } - return 0; -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_begin_paint(rdpContext* context) -{ - struct mod* mod; - - LLOGLN(10, ("lfreerdp_begin_paint:")); - mod = ((struct mod_context*)context)->modi; - mod->server_begin_update(mod); -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_end_paint(rdpContext* context) -{ - struct mod* mod; - - LLOGLN(10, ("lfreerdp_end_paint:")); - mod = ((struct mod_context*)context)->modi; - mod->server_end_update(mod); -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_set_bounds(rdpContext* context, rdpBounds* bounds) -{ - struct mod* mod; - int x; - int y; - int cx; - int cy; - - LLOGLN(10, ("lfreerdp_set_bounds: %p", bounds)); - mod = ((struct mod_context*)context)->modi; - if (bounds != 0) - { - x = bounds->left; - y = bounds->top; - cx = (bounds->right - bounds->left) + 1; - cy = (bounds->bottom - bounds->top) + 1; - mod->server_set_clip(mod, x, y, cx, cy); - } - else - { - mod->server_reset_clip(mod); - } -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap) -{ - struct mod* mod; - int index; - int cx; - int cy; - int server_bpp; - int server_Bpp; - int client_bpp; - int j; - int line_bytes; - BITMAP_DATA* bd; - char* dst_data; - char* dst_data1; - char* src; - char* dst; - - mod = ((struct mod_context*)context)->modi; - LLOGLN(10, ("lfreerdp_bitmap_update: %d %d", bitmap->number, bitmap->count)); - - server_bpp = mod->inst->settings->color_depth; - server_Bpp = (server_bpp + 7) / 8; - client_bpp = mod->bpp; - - for (index = 0; index < bitmap->number; index++) - { - bd = bitmap->rectangles + index; - cx = (bd->destRight - bd->destLeft) + 1; - cy = (bd->destBottom - bd->destTop) + 1; - line_bytes = server_Bpp * bd->width; - dst_data = (char*)g_malloc(bd->height * line_bytes + 16, 0); - if (bd->compressed) - { - bitmap_decompress(bd->bitmapDataStream, (tui8*)dst_data, bd->width, - bd->height, bd->bitmapLength, server_bpp, server_bpp); + bi = mod->brush_cache + idx; + mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y, + 3, bi->b8x8); } else - { /* bitmap is upside down */ - src = (char*)(bd->bitmapDataStream); - dst = dst_data + bd->height * line_bytes; - for (j = 0; j < bd->height; j++) - { - dst -= line_bytes; - g_memcpy(dst, src, line_bytes); - src += line_bytes; - } - } - dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data, - bd->width, bd->height, mod->colormap); - mod->server_paint_rect(mod, bd->destLeft, bd->destTop, cx, cy, - dst_data1, bd->width, bd->height, 0, 0); - if (dst_data1 != dst_data) { - g_free(dst_data1); + mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y, + patblt->brush.style, + (char *)(patblt->brush.p8x8)); } - g_free(dst_data); - } + + mod->server_fill_rect(mod, patblt->nLeftRect, patblt->nTopRect, + patblt->nWidth, patblt->nHeight); + mod->server_set_opcode(mod, 0xcc); + mod->server_set_mixmode(mod, 0); + } /******************************************************************************/ static void DEFAULT_CC -lfreerdp_dst_blt(rdpContext* context, DSTBLT_ORDER* dstblt) +lfreerdp_scr_blt(rdpContext *context, SCRBLT_ORDER *scrblt) { - struct mod* mod; + struct mod *mod; - mod = ((struct mod_context*)context)->modi; - LLOGLN(10, ("lfreerdp_dst_blt:")); - mod->server_set_opcode(mod, dstblt->bRop); - mod->server_fill_rect(mod, dstblt->nLeftRect, dstblt->nTopRect, - dstblt->nWidth, dstblt->nHeight); - mod->server_set_opcode(mod, 0xcc); + mod = ((struct mod_context *)context)->modi; + LLOGLN(10, ("lfreerdp_scr_blt:")); + mod->server_set_opcode(mod, scrblt->bRop); + mod->server_screen_blt(mod, scrblt->nLeftRect, scrblt->nTopRect, + scrblt->nWidth, scrblt->nHeight, + scrblt->nXSrc, scrblt->nYSrc); + mod->server_set_opcode(mod, 0xcc); } /******************************************************************************/ static void DEFAULT_CC -lfreerdp_pat_blt(rdpContext* context, PATBLT_ORDER* patblt) +lfreerdp_opaque_rect(rdpContext *context, OPAQUE_RECT_ORDER *opaque_rect) { - struct mod* mod; - int idx; - int fgcolor; - int bgcolor; - int server_bpp; - int client_bpp; - struct brush_item* bi; + struct mod *mod; + int server_bpp; + int client_bpp; + int fgcolor; - mod = ((struct mod_context*)context)->modi; - LLOGLN(10, ("lfreerdp_pat_blt:")); + mod = ((struct mod_context *)context)->modi; + LLOGLN(10, ("lfreerdp_opaque_rect:")); + server_bpp = mod->inst->settings->color_depth; + client_bpp = mod->bpp; + fgcolor = convert_color(server_bpp, client_bpp, + opaque_rect->color, mod->colormap); + mod->server_set_fgcolor(mod, fgcolor); + mod->server_fill_rect(mod, opaque_rect->nLeftRect, opaque_rect->nTopRect, + opaque_rect->nWidth, opaque_rect->nHeight); +} - server_bpp = mod->inst->settings->color_depth; - client_bpp = mod->bpp; - LLOGLN(0, ("lfreerdp_pat_blt: bpp %d %d", server_bpp, client_bpp)); +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_mem_blt(rdpContext *context, MEMBLT_ORDER *memblt) +{ + int id; + int idx; + struct mod *mod; + struct bitmap_item *bi; - fgcolor = convert_color(server_bpp, client_bpp, - patblt->foreColor, mod->colormap); - bgcolor = convert_color(server_bpp, client_bpp, - patblt->backColor, mod->colormap); + mod = ((struct mod_context *)context)->modi; + LLOGLN(10, ("lfreerdp_mem_blt: cacheId %d cacheIndex %d", + memblt->cacheId, memblt->cacheIndex)); - mod->server_set_mixmode(mod, 1); - mod->server_set_opcode(mod, patblt->bRop); - mod->server_set_fgcolor(mod, fgcolor); - mod->server_set_bgcolor(mod, bgcolor); + id = memblt->cacheId; + idx = memblt->cacheIndex; - if (patblt->brush.style & 0x80) - { - idx = patblt->brush.hatch; - if ((idx < 0) || (idx >= 64)) + if (idx == 32767) /* BITMAPCACHE_WAITING_LIST_INDEX */ { - LLOGLN(0, ("lfreerdp_pat_blt: error")); - return; + idx = 4096 - 1; } - bi = mod->brush_cache + idx; - mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y, - 3, bi->b8x8); - } - else - { - mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y, - patblt->brush.style, - (char*)(patblt->brush.p8x8)); - } - mod->server_fill_rect(mod, patblt->nLeftRect, patblt->nTopRect, - patblt->nWidth, patblt->nHeight); - mod->server_set_opcode(mod, 0xcc); - mod->server_set_mixmode(mod, 0); + + if ((id < 0) || (id >= 4)) + { + LLOGLN(0, ("lfreerdp_mem_blt: bad id [%d]", id)); + return; + } + + if ((idx < 0) || (idx >= 4096)) + { + LLOGLN(0, ("lfreerdp_mem_blt: bad idx [%d]", idx)); + return; + } + + bi = &(mod->bitmap_cache[id][idx]); + + mod->server_set_opcode(mod, memblt->bRop); + mod->server_paint_rect(mod, memblt->nLeftRect, memblt->nTopRect, + memblt->nWidth, memblt->nHeight, + bi->data, bi->width, bi->height, + memblt->nXSrc, memblt->nYSrc); + mod->server_set_opcode(mod, 0xcc); } /******************************************************************************/ static void DEFAULT_CC -lfreerdp_scr_blt(rdpContext* context, SCRBLT_ORDER* scrblt) +lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index) { - struct mod* mod; + struct mod *mod; + int server_bpp; + int client_bpp; + int fgcolor; + int bgcolor; - mod = ((struct mod_context*)context)->modi; - LLOGLN(10, ("lfreerdp_scr_blt:")); - mod->server_set_opcode(mod, scrblt->bRop); - mod->server_screen_blt(mod, scrblt->nLeftRect, scrblt->nTopRect, - scrblt->nWidth, scrblt->nHeight, - scrblt->nXSrc, scrblt->nYSrc); - mod->server_set_opcode(mod, 0xcc); + mod = ((struct mod_context *)context)->modi; + LLOGLN(10, ("lfreerdp_glyph_index:")); + server_bpp = mod->inst->settings->color_depth; + client_bpp = mod->bpp; + fgcolor = convert_color(server_bpp, client_bpp, + glyph_index->foreColor, mod->colormap); + bgcolor = convert_color(server_bpp, client_bpp, + glyph_index->backColor, mod->colormap); + mod->server_set_bgcolor(mod, fgcolor); + mod->server_set_fgcolor(mod, bgcolor); + mod->server_draw_text(mod, glyph_index->cacheId, glyph_index->flAccel, + glyph_index->fOpRedundant, + glyph_index->bkLeft, glyph_index->bkTop, + glyph_index->bkRight, glyph_index->bkBottom, + glyph_index->opLeft, glyph_index->opTop, + glyph_index->opRight, glyph_index->opBottom, + glyph_index->x, glyph_index->y, + (char *)(glyph_index->data), glyph_index->cbData); } /******************************************************************************/ static void DEFAULT_CC -lfreerdp_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) +lfreerdp_line_to(rdpContext *context, LINE_TO_ORDER *line_to) { - struct mod* mod; - int server_bpp; - int client_bpp; - int fgcolor; + struct mod *mod; + int server_bpp; + int client_bpp; + int fgcolor; + int bgcolor; - mod = ((struct mod_context*)context)->modi; - LLOGLN(10, ("lfreerdp_opaque_rect:")); - server_bpp = mod->inst->settings->color_depth; - client_bpp = mod->bpp; - fgcolor = convert_color(server_bpp, client_bpp, - opaque_rect->color, mod->colormap); - mod->server_set_fgcolor(mod, fgcolor); - mod->server_fill_rect(mod, opaque_rect->nLeftRect, opaque_rect->nTopRect, - opaque_rect->nWidth, opaque_rect->nHeight); + mod = ((struct mod_context *)context)->modi; + LLOGLN(10, ("lfreerdp_line_to:")); + mod->server_set_opcode(mod, line_to->bRop2); + server_bpp = mod->inst->settings->color_depth; + client_bpp = mod->bpp; + fgcolor = convert_color(server_bpp, client_bpp, + line_to->penColor, mod->colormap); + bgcolor = convert_color(server_bpp, client_bpp, + line_to->backColor, mod->colormap); + mod->server_set_fgcolor(mod, fgcolor); + mod->server_set_bgcolor(mod, bgcolor); + mod->server_set_pen(mod, line_to->penStyle, line_to->penWidth); + mod->server_draw_line(mod, line_to->nXStart, line_to->nYStart, + line_to->nXEnd, line_to->nYEnd); + mod->server_set_opcode(mod, 0xcc); } /******************************************************************************/ static void DEFAULT_CC -lfreerdp_mem_blt(rdpContext* context, MEMBLT_ORDER* memblt) +lfreerdp_cache_bitmap(rdpContext *context, CACHE_BITMAP_ORDER *cache_bitmap_order) { - int id; - int idx; - struct mod* mod; - struct bitmap_item* bi; - - mod = ((struct mod_context*)context)->modi; - LLOGLN(10, ("lfreerdp_mem_blt: cacheId %d cacheIndex %d", - memblt->cacheId, memblt->cacheIndex)); - - id = memblt->cacheId; - idx = memblt->cacheIndex; - - if (idx == 32767) /* BITMAPCACHE_WAITING_LIST_INDEX */ - { - idx = 4096 - 1; - } - - if ((id < 0) || (id >= 4)) - { - LLOGLN(0, ("lfreerdp_mem_blt: bad id [%d]", id)); - return; - } - if ((idx < 0) || (idx >= 4096)) - { - LLOGLN(0, ("lfreerdp_mem_blt: bad idx [%d]", idx)); - return; - } - - bi = &(mod->bitmap_cache[id][idx]); - - mod->server_set_opcode(mod, memblt->bRop); - mod->server_paint_rect(mod, memblt->nLeftRect, memblt->nTopRect, - memblt->nWidth, memblt->nHeight, - bi->data, bi->width, bi->height, - memblt->nXSrc, memblt->nYSrc); - mod->server_set_opcode(mod, 0xcc); - -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyph_index) -{ - struct mod* mod; - int server_bpp; - int client_bpp; - int fgcolor; - int bgcolor; - - mod = ((struct mod_context*)context)->modi; - LLOGLN(10, ("lfreerdp_glyph_index:")); - server_bpp = mod->inst->settings->color_depth; - client_bpp = mod->bpp; - fgcolor = convert_color(server_bpp, client_bpp, - glyph_index->foreColor, mod->colormap); - bgcolor = convert_color(server_bpp, client_bpp, - glyph_index->backColor, mod->colormap); - mod->server_set_bgcolor(mod, fgcolor); - mod->server_set_fgcolor(mod, bgcolor); - mod->server_draw_text(mod, glyph_index->cacheId, glyph_index->flAccel, - glyph_index->fOpRedundant, - glyph_index->bkLeft, glyph_index->bkTop, - glyph_index->bkRight, glyph_index->bkBottom, - glyph_index->opLeft, glyph_index->opTop, - glyph_index->opRight, glyph_index->opBottom, - glyph_index->x, glyph_index->y, - (char*)(glyph_index->data), glyph_index->cbData); -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_line_to(rdpContext* context, LINE_TO_ORDER* line_to) -{ - struct mod* mod; - int server_bpp; - int client_bpp; - int fgcolor; - int bgcolor; - - mod = ((struct mod_context*)context)->modi; - LLOGLN(10, ("lfreerdp_line_to:")); - mod->server_set_opcode(mod, line_to->bRop2); - server_bpp = mod->inst->settings->color_depth; - client_bpp = mod->bpp; - fgcolor = convert_color(server_bpp, client_bpp, - line_to->penColor, mod->colormap); - bgcolor = convert_color(server_bpp, client_bpp, - line_to->backColor, mod->colormap); - mod->server_set_fgcolor(mod, fgcolor); - mod->server_set_bgcolor(mod, bgcolor); - mod->server_set_pen(mod, line_to->penStyle, line_to->penWidth); - mod->server_draw_line(mod, line_to->nXStart, line_to->nYStart, - line_to->nXEnd, line_to->nYEnd); - mod->server_set_opcode(mod, 0xcc); -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitmap_order) -{ - LLOGLN(10, ("lfreerdp_cache_bitmap:")); + LLOGLN(10, ("lfreerdp_cache_bitmap:")); } /******************************************************************************/ /* Turn the bitmap upside down*/ static void DEFAULT_CC -lfreerdp_upsidedown(uint8* destination, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, int server_Bpp) +lfreerdp_upsidedown(uint8 *destination, CACHE_BITMAP_V2_ORDER *cache_bitmap_v2_order, int server_Bpp) { - tui8* src; - tui8* dst; - int line_bytes; - int j; + tui8 *src; + tui8 *dst; + int line_bytes; + int j; - if (destination == NULL) - { - LLOGLN(0, ("lfreerdp_upsidedown: destination pointer is NULL !!!")); - return; - } - line_bytes = server_Bpp * cache_bitmap_v2_order->bitmapWidth; - src = cache_bitmap_v2_order->bitmapDataStream; - dst = destination + ((cache_bitmap_v2_order->bitmapHeight) * line_bytes); - for (j = 0; j < cache_bitmap_v2_order->bitmapHeight; j++) - { - dst -= line_bytes; - g_memcpy(dst, src, line_bytes); - src += line_bytes; - } -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_cache_bitmapV2(rdpContext* context, - CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order) -{ - char* dst_data; - char* dst_data1; - int bytes; - int width; - int height; - int id; - int idx; - int flags; - int server_bpp; - int server_Bpp; - int client_bpp; - struct mod* mod; - - LLOGLN(10, ("lfreerdp_cache_bitmapV2: %d %d 0x%8.8x compressed %d", - cache_bitmap_v2_order->cacheId, - cache_bitmap_v2_order->cacheIndex, - cache_bitmap_v2_order->flags, - cache_bitmap_v2_order->compressed)); - - mod = ((struct mod_context*)context)->modi; - id = cache_bitmap_v2_order->cacheId; - idx = cache_bitmap_v2_order->cacheIndex; - flags = cache_bitmap_v2_order->flags; - if (flags & 0x10) /* CBR2_DO_NOT_CACHE */ - { - idx = 4096 - 1; - } - if ((id < 0) || (id >= 4)) - { - LLOGLN(0, ("lfreerdp_cache_bitmapV2: bad id [%d]", id)); - return; - } - if ((idx < 0) || (idx >= 4096)) - { - LLOGLN(0, ("lfreerdp_cache_bitmapV2: bad idx [%d]", idx)); - return; - } - - server_bpp = mod->inst->settings->color_depth; - server_Bpp = (server_bpp + 7) / 8; - client_bpp = mod->bpp; - - width = cache_bitmap_v2_order->bitmapWidth; - height = cache_bitmap_v2_order->bitmapHeight; - bytes = width * height * server_Bpp + 16; - dst_data = (char*)g_malloc(bytes, 0); - if (cache_bitmap_v2_order->compressed) - { - bitmap_decompress(cache_bitmap_v2_order->bitmapDataStream, - (tui8*)dst_data, width, height, - cache_bitmap_v2_order->bitmapLength, - server_bpp, server_bpp); - } - else - { - /* Uncompressed bitmaps are upside down */ - lfreerdp_upsidedown((tui8*)dst_data, cache_bitmap_v2_order, server_Bpp); - LLOGLN(10, ("lfreerdp_cache_bitmapV2: upside down progressed")); - } - dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data, - width, height, mod->colormap); - g_free(mod->bitmap_cache[id][idx].data); - mod->bitmap_cache[id][idx].width = width; - mod->bitmap_cache[id][idx].height = height; - mod->bitmap_cache[id][idx].data = dst_data1; - if (dst_data != dst_data1) - { - g_free(dst_data); - } -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph_order) -{ - int index; - GLYPH_DATA* gd; - struct mod* mod; - - mod = ((struct mod_context*)context)->modi; - LLOGLN(10, ("lfreerdp_cache_glyph: %d", cache_glyph_order->cGlyphs)); - for (index = 0; index < cache_glyph_order->cGlyphs; index++) - { - gd = cache_glyph_order->glyphData[index]; - LLOGLN(10, (" %d %d %d %d %d", gd->cacheIndex, gd->x, gd->y, - gd->cx, gd->cy)); - mod->server_add_char(mod, cache_glyph_order->cacheId, gd->cacheIndex, - gd->x, gd->y, gd->cx, gd->cy, (char*)(gd->aj)); - xfree(gd->aj); - gd->aj = 0; - xfree(gd); - cache_glyph_order->glyphData[index] = 0; - } - xfree(cache_glyph_order->unicodeCharacters); - cache_glyph_order->unicodeCharacters = 0; -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush_order) -{ - int idx; - int bytes; - int bpp; - int cx; - int cy; - struct mod* mod; - - mod = ((struct mod_context*)context)->modi; - bpp = cache_brush_order->bpp; - cx = cache_brush_order->cx; - cy = cache_brush_order->cy; - idx = cache_brush_order->index; - bytes = cache_brush_order->length; - LLOGLN(10, ("lfreerdp_cache_brush: bpp %d cx %d cy %d idx %d bytes %d", - bpp, cx, cy, idx, bytes)); - if ((idx < 0) || (idx >= 64)) - { - LLOGLN(0, ("lfreerdp_cache_brush: error idx %d", idx)); - return; - } - if ((bpp != 1) || (cx != 8) || (cy != 8)) - { - LLOGLN(0, ("lfreerdp_cache_brush: error unsupported brush " - "bpp %d cx %d cy %d", bpp, cx, cy)); - return; - } - mod->brush_cache[idx].bpp = bpp; - mod->brush_cache[idx].width = cx; - mod->brush_cache[idx].height = cy; - mod->brush_cache[idx].data = mod->brush_cache[idx].b8x8; - if (bytes > 8) - { - bytes = 8; - } - g_memset(mod->brush_cache[idx].data, 0, 8); - if (bytes > 0) - { - if (bytes > 8) + if (destination == NULL) { - LLOGLN(0, ("lfreerdp_cache_brush: bytes to big %d", bytes)); - bytes = 8; + LLOGLN(0, ("lfreerdp_upsidedown: destination pointer is NULL !!!")); + return; } - g_memcpy(mod->brush_cache[idx].data, cache_brush_order->data, bytes); - } - LLOGLN(10, ("lfreerdp_cache_brush: out bpp %d cx %d cy %d idx %d bytes %d", - bpp, cx, cy, idx, bytes)); - xfree(cache_brush_order->data); - cache_brush_order->data = 0; + line_bytes = server_Bpp * cache_bitmap_v2_order->bitmapWidth; + src = cache_bitmap_v2_order->bitmapDataStream; + dst = destination + ((cache_bitmap_v2_order->bitmapHeight) * line_bytes); -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_pointer_position(rdpContext* context, - POINTER_POSITION_UPDATE* pointer_position) -{ - LLOGLN(0, ("lfreerdp_pointer_position:")); -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_pointer_system(rdpContext* context, - POINTER_SYSTEM_UPDATE* pointer_system) -{ - LLOGLN(0, ("lfreerdp_pointer_system: - no code here")); -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_pointer_color(rdpContext* context, - POINTER_COLOR_UPDATE* pointer_color) -{ - LLOGLN(0, ("lfreerdp_pointer_color:")); -} - -/******************************************************************************/ -static int APP_CC -lfreerdp_get_pixel(void* bits, int width, int height, int bpp, - int delta, int x, int y) -{ - int start; - int shift; - int pixel; - tui8* src8; - - if (bpp == 1) - { - src8 = (tui8*)bits; - start = (y * delta) + x / 8; - shift = x % 8; - pixel = (src8[start] & (0x80 >> shift)) != 0; - return pixel ? 0xffffff : 0; - } - else - { - LLOGLN(0, ("lfreerdp_get_pixel: unknown bpp %d", bpp)); - } - return 0; -} - -/******************************************************************************/ -static int APP_CC -lfreerdp_set_pixel(int pixel, void* bits, int width, int height, int bpp, - int delta, int x, int y) -{ - tui8* dst8; - int start; - int shift; - - if (bpp == 1) - { - dst8 = (tui8*)bits; - start = (y * delta) + x / 8; - shift = x % 8; - if (pixel) + for (j = 0; j < cache_bitmap_v2_order->bitmapHeight; j++) { - dst8[start] = dst8[start] | (0x80 >> shift); + dst -= line_bytes; + g_memcpy(dst, src, line_bytes); + src += line_bytes; + } +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_cache_bitmapV2(rdpContext *context, + CACHE_BITMAP_V2_ORDER *cache_bitmap_v2_order) +{ + char *dst_data; + char *dst_data1; + int bytes; + int width; + int height; + int id; + int idx; + int flags; + int server_bpp; + int server_Bpp; + int client_bpp; + struct mod *mod; + + LLOGLN(10, ("lfreerdp_cache_bitmapV2: %d %d 0x%8.8x compressed %d", + cache_bitmap_v2_order->cacheId, + cache_bitmap_v2_order->cacheIndex, + cache_bitmap_v2_order->flags, + cache_bitmap_v2_order->compressed)); + + mod = ((struct mod_context *)context)->modi; + id = cache_bitmap_v2_order->cacheId; + idx = cache_bitmap_v2_order->cacheIndex; + flags = cache_bitmap_v2_order->flags; + + if (flags & 0x10) /* CBR2_DO_NOT_CACHE */ + { + idx = 4096 - 1; + } + + if ((id < 0) || (id >= 4)) + { + LLOGLN(0, ("lfreerdp_cache_bitmapV2: bad id [%d]", id)); + return; + } + + if ((idx < 0) || (idx >= 4096)) + { + LLOGLN(0, ("lfreerdp_cache_bitmapV2: bad idx [%d]", idx)); + return; + } + + server_bpp = mod->inst->settings->color_depth; + server_Bpp = (server_bpp + 7) / 8; + client_bpp = mod->bpp; + + width = cache_bitmap_v2_order->bitmapWidth; + height = cache_bitmap_v2_order->bitmapHeight; + bytes = width * height * server_Bpp + 16; + dst_data = (char *)g_malloc(bytes, 0); + + if (cache_bitmap_v2_order->compressed) + { + bitmap_decompress(cache_bitmap_v2_order->bitmapDataStream, + (tui8 *)dst_data, width, height, + cache_bitmap_v2_order->bitmapLength, + server_bpp, server_bpp); } else { - dst8[start] = dst8[start] & ~(0x80 >> shift); + /* Uncompressed bitmaps are upside down */ + lfreerdp_upsidedown((tui8 *)dst_data, cache_bitmap_v2_order, server_Bpp); + LLOGLN(10, ("lfreerdp_cache_bitmapV2: upside down progressed")); } - } - else if (bpp == 24) - { - dst8 = (tui8*)bits; - dst8 += y * delta + x * 3; - dst8[0] = (pixel >> 0) & 0xff; - dst8[1] = (pixel >> 8) & 0xff; - dst8[2] = (pixel >> 16) & 0xff; - } - else - { - LLOGLN(0, ("lfreerdp_set_pixel: unknown bpp %d", bpp)); - } - return 0; + + dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data, + width, height, mod->colormap); + g_free(mod->bitmap_cache[id][idx].data); + mod->bitmap_cache[id][idx].width = width; + mod->bitmap_cache[id][idx].height = height; + mod->bitmap_cache[id][idx].data = dst_data1; + + if (dst_data != dst_data1) + { + g_free(dst_data); + } +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_cache_glyph(rdpContext *context, CACHE_GLYPH_ORDER *cache_glyph_order) +{ + int index; + GLYPH_DATA *gd; + struct mod *mod; + + mod = ((struct mod_context *)context)->modi; + LLOGLN(10, ("lfreerdp_cache_glyph: %d", cache_glyph_order->cGlyphs)); + + for (index = 0; index < cache_glyph_order->cGlyphs; index++) + { + gd = cache_glyph_order->glyphData[index]; + LLOGLN(10, (" %d %d %d %d %d", gd->cacheIndex, gd->x, gd->y, + gd->cx, gd->cy)); + mod->server_add_char(mod, cache_glyph_order->cacheId, gd->cacheIndex, + gd->x, gd->y, gd->cx, gd->cy, (char *)(gd->aj)); + xfree(gd->aj); + gd->aj = 0; + xfree(gd); + cache_glyph_order->glyphData[index] = 0; + } + + xfree(cache_glyph_order->unicodeCharacters); + cache_glyph_order->unicodeCharacters = 0; +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_cache_brush(rdpContext *context, CACHE_BRUSH_ORDER *cache_brush_order) +{ + int idx; + int bytes; + int bpp; + int cx; + int cy; + struct mod *mod; + + mod = ((struct mod_context *)context)->modi; + bpp = cache_brush_order->bpp; + cx = cache_brush_order->cx; + cy = cache_brush_order->cy; + idx = cache_brush_order->index; + bytes = cache_brush_order->length; + LLOGLN(10, ("lfreerdp_cache_brush: bpp %d cx %d cy %d idx %d bytes %d", + bpp, cx, cy, idx, bytes)); + + if ((idx < 0) || (idx >= 64)) + { + LLOGLN(0, ("lfreerdp_cache_brush: error idx %d", idx)); + return; + } + + if ((bpp != 1) || (cx != 8) || (cy != 8)) + { + LLOGLN(0, ("lfreerdp_cache_brush: error unsupported brush " + "bpp %d cx %d cy %d", bpp, cx, cy)); + return; + } + + mod->brush_cache[idx].bpp = bpp; + mod->brush_cache[idx].width = cx; + mod->brush_cache[idx].height = cy; + mod->brush_cache[idx].data = mod->brush_cache[idx].b8x8; + + if (bytes > 8) + { + bytes = 8; + } + + g_memset(mod->brush_cache[idx].data, 0, 8); + + if (bytes > 0) + { + if (bytes > 8) + { + LLOGLN(0, ("lfreerdp_cache_brush: bytes to big %d", bytes)); + bytes = 8; + } + + g_memcpy(mod->brush_cache[idx].data, cache_brush_order->data, bytes); + } + + LLOGLN(10, ("lfreerdp_cache_brush: out bpp %d cx %d cy %d idx %d bytes %d", + bpp, cx, cy, idx, bytes)); + + xfree(cache_brush_order->data); + cache_brush_order->data = 0; + +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_pointer_position(rdpContext *context, + POINTER_POSITION_UPDATE *pointer_position) +{ + LLOGLN(0, ("lfreerdp_pointer_position:")); +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_pointer_system(rdpContext *context, + POINTER_SYSTEM_UPDATE *pointer_system) +{ + LLOGLN(0, ("lfreerdp_pointer_system: - no code here")); +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_pointer_color(rdpContext *context, + POINTER_COLOR_UPDATE *pointer_color) +{ + LLOGLN(0, ("lfreerdp_pointer_color:")); } /******************************************************************************/ static int APP_CC -lfreerdp_convert_color_image(void* dst, int dst_width, int dst_height, +lfreerdp_get_pixel(void *bits, int width, int height, int bpp, + int delta, int x, int y) +{ + int start; + int shift; + int pixel; + tui8 *src8; + + if (bpp == 1) + { + src8 = (tui8 *)bits; + start = (y * delta) + x / 8; + shift = x % 8; + pixel = (src8[start] & (0x80 >> shift)) != 0; + return pixel ? 0xffffff : 0; + } + else + { + LLOGLN(0, ("lfreerdp_get_pixel: unknown bpp %d", bpp)); + } + + return 0; +} + +/******************************************************************************/ +static int APP_CC +lfreerdp_set_pixel(int pixel, void *bits, int width, int height, int bpp, + int delta, int x, int y) +{ + tui8 *dst8; + int start; + int shift; + + if (bpp == 1) + { + dst8 = (tui8 *)bits; + start = (y * delta) + x / 8; + shift = x % 8; + + if (pixel) + { + dst8[start] = dst8[start] | (0x80 >> shift); + } + else + { + dst8[start] = dst8[start] & ~(0x80 >> shift); + } + } + else if (bpp == 24) + { + dst8 = (tui8 *)bits; + dst8 += y * delta + x * 3; + dst8[0] = (pixel >> 0) & 0xff; + dst8[1] = (pixel >> 8) & 0xff; + dst8[2] = (pixel >> 16) & 0xff; + } + else + { + LLOGLN(0, ("lfreerdp_set_pixel: unknown bpp %d", bpp)); + } + + return 0; +} + +/******************************************************************************/ +static int APP_CC +lfreerdp_convert_color_image(void *dst, int dst_width, int dst_height, int dst_bpp, int dst_delta, - void* src, int src_width, int src_height, + void *src, int src_width, int src_height, int src_bpp, int src_delta) { - int i; - int j; - int pixel; + int i; + int j; + int pixel; - for (j = 0; j < dst_height; j++) - { - for (i = 0; i < dst_width; i++) + for (j = 0; j < dst_height; j++) { - pixel = lfreerdp_get_pixel(src, src_width, src_height, src_bpp, - src_delta, i, j); - lfreerdp_set_pixel(pixel, dst, dst_width, dst_height, dst_bpp, - dst_delta, i, j); + for (i = 0; i < dst_width; i++) + { + pixel = lfreerdp_get_pixel(src, src_width, src_height, src_bpp, + src_delta, i, j); + lfreerdp_set_pixel(pixel, dst, dst_width, dst_height, dst_bpp, + dst_delta, i, j); + } } - } - return 0; + + return 0; } /******************************************************************************/ static void DEFAULT_CC -lfreerdp_pointer_new(rdpContext* context, - POINTER_NEW_UPDATE* pointer_new) +lfreerdp_pointer_new(rdpContext *context, + POINTER_NEW_UPDATE *pointer_new) { - struct mod* mod; - int index; - tui8* dst; - tui8* src; + struct mod *mod; + int index; + tui8 *dst; + tui8 *src; - mod = ((struct mod_context*)context)->modi; - LLOGLN(0, ("lfreerdp_pointer_new:")); - LLOGLN(0, (" bpp %d", pointer_new->xorBpp)); - LLOGLN(0, (" width %d height %d", pointer_new->colorPtrAttr.width, - pointer_new->colorPtrAttr.height)); + mod = ((struct mod_context *)context)->modi; + LLOGLN(0, ("lfreerdp_pointer_new:")); + LLOGLN(0, (" bpp %d", pointer_new->xorBpp)); + LLOGLN(0, (" width %d height %d", pointer_new->colorPtrAttr.width, + pointer_new->colorPtrAttr.height)); - LLOGLN(0, (" lengthXorMask %d lengthAndMask %d", - pointer_new->colorPtrAttr.lengthXorMask, - pointer_new->colorPtrAttr.lengthAndMask)); + LLOGLN(0, (" lengthXorMask %d lengthAndMask %d", + pointer_new->colorPtrAttr.lengthXorMask, + pointer_new->colorPtrAttr.lengthAndMask)); - index = pointer_new->colorPtrAttr.cacheIndex; - if (pointer_new->xorBpp == 1 && - pointer_new->colorPtrAttr.width == 32 && - pointer_new->colorPtrAttr.height == 32 && - index < 32) - { - mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos; - mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos; + index = pointer_new->colorPtrAttr.cacheIndex; - dst = (tui8*)(mod->pointer_cache[index].data); - dst += 32 * 32 * 3 - 32 * 3; - src = pointer_new->colorPtrAttr.xorMaskData; - lfreerdp_convert_color_image(dst, 32, 32, 24, 32 * -3, - src, 32, 32, 1, 32 / 8); + if (pointer_new->xorBpp == 1 && + pointer_new->colorPtrAttr.width == 32 && + pointer_new->colorPtrAttr.height == 32 && + index < 32) + { + mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos; + mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos; - dst = (tui8*)(mod->pointer_cache[index].mask); - dst +=( 32 * 32 / 8) - (32 / 8); - src = pointer_new->colorPtrAttr.andMaskData; - lfreerdp_convert_color_image(dst, 32, 32, 1, 32 / -8, - src, 32, 32, 1, 32 / 8); + dst = (tui8 *)(mod->pointer_cache[index].data); + dst += 32 * 32 * 3 - 32 * 3; + src = pointer_new->colorPtrAttr.xorMaskData; + lfreerdp_convert_color_image(dst, 32, 32, 24, 32 * -3, + src, 32, 32, 1, 32 / 8); - //memcpy(mod->pointer_cache[index].mask, - // pointer_new->colorPtrAttr.andMaskData, 32 * 32 / 8); + dst = (tui8 *)(mod->pointer_cache[index].mask); + dst += ( 32 * 32 / 8) - (32 / 8); + src = pointer_new->colorPtrAttr.andMaskData; + lfreerdp_convert_color_image(dst, 32, 32, 1, 32 / -8, + src, 32, 32, 1, 32 / 8); + //memcpy(mod->pointer_cache[index].mask, + // pointer_new->colorPtrAttr.andMaskData, 32 * 32 / 8); + + mod->server_set_cursor(mod, mod->pointer_cache[index].hotx, + mod->pointer_cache[index].hoty, mod->pointer_cache[index].data, + mod->pointer_cache[index].mask); + } + else + { + LLOGLN(0, ("lfreerdp_pointer_new: error bpp %d width %d height %d", + pointer_new->xorBpp, pointer_new->colorPtrAttr.width, + pointer_new->colorPtrAttr.height)); + } + + xfree(pointer_new->colorPtrAttr.xorMaskData); + pointer_new->colorPtrAttr.xorMaskData = 0; + xfree(pointer_new->colorPtrAttr.andMaskData); + pointer_new->colorPtrAttr.andMaskData = 0; + +} + +/******************************************************************************/ +static void DEFAULT_CC +lfreerdp_pointer_cached(rdpContext *context, + POINTER_CACHED_UPDATE *pointer_cached) +{ + struct mod *mod; + int index; + + LLOGLN(10, ("lfreerdp_pointer_cached:")); + mod = ((struct mod_context *)context)->modi; + index = pointer_cached->cacheIndex; mod->server_set_cursor(mod, mod->pointer_cache[index].hotx, - mod->pointer_cache[index].hoty, mod->pointer_cache[index].data, - mod->pointer_cache[index].mask); - } - else - { - LLOGLN(0, ("lfreerdp_pointer_new: error bpp %d width %d height %d", - pointer_new->xorBpp, pointer_new->colorPtrAttr.width, - pointer_new->colorPtrAttr.height)); - } - - xfree(pointer_new->colorPtrAttr.xorMaskData); - pointer_new->colorPtrAttr.xorMaskData = 0; - xfree(pointer_new->colorPtrAttr.andMaskData); - pointer_new->colorPtrAttr.andMaskData = 0; - -} - -/******************************************************************************/ -static void DEFAULT_CC -lfreerdp_pointer_cached(rdpContext* context, - POINTER_CACHED_UPDATE* pointer_cached) -{ - struct mod* mod; - int index; - - LLOGLN(10, ("lfreerdp_pointer_cached:")); - mod = ((struct mod_context*)context)->modi; - index = pointer_cached->cacheIndex; - mod->server_set_cursor(mod, mod->pointer_cache[index].hotx, - mod->pointer_cache[index].hoty, mod->pointer_cache[index].data, - mod->pointer_cache[index].mask); + mod->pointer_cache[index].hoty, mod->pointer_cache[index].data, + mod->pointer_cache[index].mask); } /******************************************************************************/ static boolean DEFAULT_CC -lfreerdp_pre_connect(freerdp* instance) +lfreerdp_pre_connect(freerdp *instance) { - struct mod* mod; - int index; - int error; - int num_chans; - int ch_flags; - char ch_name[256]; - char* dst_ch_name; + struct mod *mod; + int index; + int error; + int num_chans; + int ch_flags; + char ch_name[256]; + char *dst_ch_name; - LLOGLN(0, ("lfreerdp_pre_connect:")); - mod = ((struct mod_context*)(instance->context))->modi; - num_chans = 0; - index = 0; - error = mod->server_query_channel(mod, index, ch_name, &ch_flags); - while (error == 0) - { - num_chans++; - LLOGLN(10, ("lfreerdp_pre_connect: got channel [%s], flags [0x%8.8x]", - ch_name, ch_flags)); - dst_ch_name = instance->settings->channels[index].name; - g_memset(dst_ch_name, 0, 8); - g_snprintf(dst_ch_name, 8, "%s", ch_name); - instance->settings->channels[index].options = ch_flags; - index++; + LLOGLN(0, ("lfreerdp_pre_connect:")); + mod = ((struct mod_context *)(instance->context))->modi; + num_chans = 0; + index = 0; error = mod->server_query_channel(mod, index, ch_name, &ch_flags); - } - instance->settings->num_channels = num_chans; - instance->settings->offscreen_bitmap_cache = false; - - instance->settings->glyph_cache = true; - instance->settings->glyphSupportLevel = GLYPH_SUPPORT_FULL; - instance->settings->order_support[NEG_GLYPH_INDEX_INDEX] = true; - instance->settings->order_support[NEG_FAST_GLYPH_INDEX] = false; - instance->settings->order_support[NEG_FAST_INDEX_INDEX] = false; - instance->settings->order_support[NEG_SCRBLT_INDEX] = true; - instance->settings->order_support[NEG_SAVEBITMAP_INDEX] = false; - - instance->settings->bitmap_cache = true; - instance->settings->order_support[NEG_MEMBLT_INDEX] = true; - instance->settings->order_support[NEG_MEMBLT_V2_INDEX] = true; - instance->settings->order_support[NEG_MEM3BLT_INDEX] = false; - instance->settings->order_support[NEG_MEM3BLT_V2_INDEX] = false; - instance->settings->bitmapCacheV2NumCells = 3; // 5; - instance->settings->bitmapCacheV2CellInfo[0].numEntries = 0x78; // 600; - instance->settings->bitmapCacheV2CellInfo[0].persistent = false; - instance->settings->bitmapCacheV2CellInfo[1].numEntries = 0x78; // 600; - instance->settings->bitmapCacheV2CellInfo[1].persistent = false; - instance->settings->bitmapCacheV2CellInfo[2].numEntries = 0x150; // 2048; - instance->settings->bitmapCacheV2CellInfo[2].persistent = false; - instance->settings->bitmapCacheV2CellInfo[3].numEntries = 0; // 4096; - instance->settings->bitmapCacheV2CellInfo[3].persistent = false; - instance->settings->bitmapCacheV2CellInfo[4].numEntries = 0; // 2048; - instance->settings->bitmapCacheV2CellInfo[4].persistent = false; - - instance->settings->order_support[NEG_MULTIDSTBLT_INDEX] = false; - instance->settings->order_support[NEG_MULTIPATBLT_INDEX] = false; - instance->settings->order_support[NEG_MULTISCRBLT_INDEX] = false; - instance->settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = false; - instance->settings->order_support[NEG_POLYLINE_INDEX] = false; - - instance->settings->username = g_strdup(mod->username); - instance->settings->password = g_strdup(mod->password); - - if (mod->client_info.rail_support_level > 0) - { - instance->settings->remote_app = true; - instance->settings->rail_langbar_supported = true; - instance->settings->workarea = true; - instance->settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG; - } - - // here - //instance->settings->rdp_version = 4; - - instance->update->BeginPaint = lfreerdp_begin_paint; - instance->update->EndPaint = lfreerdp_end_paint; - instance->update->SetBounds = lfreerdp_set_bounds; - instance->update->BitmapUpdate = lfreerdp_bitmap_update; - - instance->update->primary->DstBlt = lfreerdp_dst_blt; - instance->update->primary->PatBlt = lfreerdp_pat_blt; - instance->update->primary->ScrBlt = lfreerdp_scr_blt; - instance->update->primary->OpaqueRect = lfreerdp_opaque_rect; - instance->update->primary->MemBlt = lfreerdp_mem_blt; - instance->update->primary->GlyphIndex = lfreerdp_glyph_index; - instance->update->primary->LineTo = lfreerdp_line_to; - - instance->update->secondary->CacheBitmap = lfreerdp_cache_bitmap; - instance->update->secondary->CacheBitmapV2 = lfreerdp_cache_bitmapV2; - instance->update->secondary->CacheGlyph = lfreerdp_cache_glyph; - instance->update->secondary->CacheBrush = lfreerdp_cache_brush; - - instance->update->pointer->PointerPosition = lfreerdp_pointer_position; - instance->update->pointer->PointerSystem = lfreerdp_pointer_system; - instance->update->pointer->PointerColor = lfreerdp_pointer_color; - instance->update->pointer->PointerNew = lfreerdp_pointer_new; - instance->update->pointer->PointerCached = lfreerdp_pointer_cached; - - if ((mod->username[0] != 0) && (mod->password[0] != 0)) - { - /* since we have username and password, we can try nla */ - instance->settings->nla_security = 1; - } - else - { - instance->settings->nla_security = 0; - } - - return true; -} - -/*****************************************************************************/ -void DEFAULT_CC -lrail_WindowCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - WINDOW_STATE_ORDER* window_state) -{ - int index; - struct mod* mod; - struct rail_window_state_order wso; - UNICONV* uniconv; - - LLOGLN(0, ("llrail_WindowCreate:")); - uniconv = freerdp_uniconv_new(); - mod = ((struct mod_context*)context)->modi; - memset(&wso, 0, sizeof(wso)); - /* copy the window state order */ - wso.owner_window_id = window_state->ownerWindowId; - wso.style = window_state->style; - wso.extended_style = window_state->extendedStyle; - wso.show_state = window_state->showState; - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) - { - wso.title_info = freerdp_uniconv_in(uniconv, - window_state->titleInfo.string, window_state->titleInfo.length); - } - LLOGLN(0, ("lrail_WindowCreate: %s", wso.title_info)); - wso.client_offset_x = window_state->clientOffsetX; - wso.client_offset_y = window_state->clientOffsetY; - wso.client_area_width = window_state->clientAreaWidth; - wso.client_area_height = window_state->clientAreaHeight; - wso.rp_content = window_state->RPContent; - wso.root_parent_handle = window_state->rootParentHandle; - wso.window_offset_x = window_state->windowOffsetX; - wso.window_offset_y = window_state->windowOffsetY; - wso.window_client_delta_x = window_state->windowClientDeltaX; - wso.window_client_delta_y = window_state->windowClientDeltaY; - wso.window_width = window_state->windowWidth; - wso.window_height = window_state->windowHeight; - wso.num_window_rects = window_state->numWindowRects; - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) - { - wso.window_rects = (struct rail_window_rect*) - g_malloc(sizeof(struct rail_window_rect) * wso.num_window_rects, 0); - for (index = 0; index < wso.num_window_rects; index++) + while (error == 0) { - wso.window_rects[index].left = window_state->windowRects[index].left; - wso.window_rects[index].top = window_state->windowRects[index].top; - wso.window_rects[index].right = window_state->windowRects[index].right; - wso.window_rects[index].bottom = window_state->windowRects[index].bottom; + num_chans++; + LLOGLN(10, ("lfreerdp_pre_connect: got channel [%s], flags [0x%8.8x]", + ch_name, ch_flags)); + dst_ch_name = instance->settings->channels[index].name; + g_memset(dst_ch_name, 0, 8); + g_snprintf(dst_ch_name, 8, "%s", ch_name); + instance->settings->channels[index].options = ch_flags; + index++; + error = mod->server_query_channel(mod, index, ch_name, &ch_flags); } - } - wso.visible_offset_x = window_state->visibleOffsetX; - wso.visible_offset_y = window_state->visibleOffsetY; - wso.num_visibility_rects = window_state->numVisibilityRects; - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) - { - wso.visibility_rects = (struct rail_window_rect*) - g_malloc(sizeof(struct rail_window_rect) * wso.num_visibility_rects, 0); - for (index = 0; index < wso.num_visibility_rects; index++) + + instance->settings->num_channels = num_chans; + + instance->settings->offscreen_bitmap_cache = false; + + instance->settings->glyph_cache = true; + instance->settings->glyphSupportLevel = GLYPH_SUPPORT_FULL; + instance->settings->order_support[NEG_GLYPH_INDEX_INDEX] = true; + instance->settings->order_support[NEG_FAST_GLYPH_INDEX] = false; + instance->settings->order_support[NEG_FAST_INDEX_INDEX] = false; + instance->settings->order_support[NEG_SCRBLT_INDEX] = true; + instance->settings->order_support[NEG_SAVEBITMAP_INDEX] = false; + + instance->settings->bitmap_cache = true; + instance->settings->order_support[NEG_MEMBLT_INDEX] = true; + instance->settings->order_support[NEG_MEMBLT_V2_INDEX] = true; + instance->settings->order_support[NEG_MEM3BLT_INDEX] = false; + instance->settings->order_support[NEG_MEM3BLT_V2_INDEX] = false; + instance->settings->bitmapCacheV2NumCells = 3; // 5; + instance->settings->bitmapCacheV2CellInfo[0].numEntries = 0x78; // 600; + instance->settings->bitmapCacheV2CellInfo[0].persistent = false; + instance->settings->bitmapCacheV2CellInfo[1].numEntries = 0x78; // 600; + instance->settings->bitmapCacheV2CellInfo[1].persistent = false; + instance->settings->bitmapCacheV2CellInfo[2].numEntries = 0x150; // 2048; + instance->settings->bitmapCacheV2CellInfo[2].persistent = false; + instance->settings->bitmapCacheV2CellInfo[3].numEntries = 0; // 4096; + instance->settings->bitmapCacheV2CellInfo[3].persistent = false; + instance->settings->bitmapCacheV2CellInfo[4].numEntries = 0; // 2048; + instance->settings->bitmapCacheV2CellInfo[4].persistent = false; + + instance->settings->order_support[NEG_MULTIDSTBLT_INDEX] = false; + instance->settings->order_support[NEG_MULTIPATBLT_INDEX] = false; + instance->settings->order_support[NEG_MULTISCRBLT_INDEX] = false; + instance->settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = false; + instance->settings->order_support[NEG_POLYLINE_INDEX] = false; + + instance->settings->username = g_strdup(mod->username); + instance->settings->password = g_strdup(mod->password); + + if (mod->client_info.rail_support_level > 0) { - wso.visibility_rects[index].left = window_state->visibilityRects[index].left; - wso.visibility_rects[index].top = window_state->visibilityRects[index].top; - wso.visibility_rects[index].right = window_state->visibilityRects[index].right; - wso.visibility_rects[index].bottom = window_state->visibilityRects[index].bottom; + instance->settings->remote_app = true; + instance->settings->rail_langbar_supported = true; + instance->settings->workarea = true; + instance->settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG; } - } - mod->server_window_new_update(mod, orderInfo->windowId, &wso, - orderInfo->fieldFlags); + // here + //instance->settings->rdp_version = 4; - xfree(wso.title_info); - g_free(wso.window_rects); - g_free(wso.visibility_rects); - freerdp_uniconv_free(uniconv); -} + instance->update->BeginPaint = lfreerdp_begin_paint; + instance->update->EndPaint = lfreerdp_end_paint; + instance->update->SetBounds = lfreerdp_set_bounds; + instance->update->BitmapUpdate = lfreerdp_bitmap_update; -/*****************************************************************************/ -void DEFAULT_CC -lrail_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - WINDOW_STATE_ORDER* window_state) -{ - LLOGLN(0, ("lrail_WindowUpdate:")); - lrail_WindowCreate(context, orderInfo, window_state); -} + instance->update->primary->DstBlt = lfreerdp_dst_blt; + instance->update->primary->PatBlt = lfreerdp_pat_blt; + instance->update->primary->ScrBlt = lfreerdp_scr_blt; + instance->update->primary->OpaqueRect = lfreerdp_opaque_rect; + instance->update->primary->MemBlt = lfreerdp_mem_blt; + instance->update->primary->GlyphIndex = lfreerdp_glyph_index; + instance->update->primary->LineTo = lfreerdp_line_to; -/*****************************************************************************/ -void DEFAULT_CC -lrail_WindowDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) -{ - struct mod* mod; + instance->update->secondary->CacheBitmap = lfreerdp_cache_bitmap; + instance->update->secondary->CacheBitmapV2 = lfreerdp_cache_bitmapV2; + instance->update->secondary->CacheGlyph = lfreerdp_cache_glyph; + instance->update->secondary->CacheBrush = lfreerdp_cache_brush; - LLOGLN(0, ("lrail_WindowDelete:")); - mod = ((struct mod_context*)context)->modi; - mod->server_window_delete(mod, orderInfo->windowId); -} + instance->update->pointer->PointerPosition = lfreerdp_pointer_position; + instance->update->pointer->PointerSystem = lfreerdp_pointer_system; + instance->update->pointer->PointerColor = lfreerdp_pointer_color; + instance->update->pointer->PointerNew = lfreerdp_pointer_new; + instance->update->pointer->PointerCached = lfreerdp_pointer_cached; -/*****************************************************************************/ -void DEFAULT_CC -lrail_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - WINDOW_ICON_ORDER* window_icon) -{ - struct mod* mod; - struct rail_icon_info rii; - - LLOGLN(0, ("lrail_WindowIcon:")); - mod = ((struct mod_context*)context)->modi; - memset(&rii, 0, sizeof(rii)); - rii.bpp = window_icon->iconInfo->bpp; - rii.width = window_icon->iconInfo->width; - rii.height = window_icon->iconInfo->height; - rii.cmap_bytes = window_icon->iconInfo->cbColorTable; - rii.mask_bytes = window_icon->iconInfo->cbBitsMask; - rii.data_bytes = window_icon->iconInfo->cbBitsColor; - rii.mask = (char*)(window_icon->iconInfo->bitsMask); - rii.cmap = (char*)(window_icon->iconInfo->colorTable); - rii.data = (char*)(window_icon->iconInfo->bitsColor); - mod->server_window_icon(mod, orderInfo->windowId, - window_icon->iconInfo->cacheEntry, - window_icon->iconInfo->cacheId, &rii, - orderInfo->fieldFlags); -} - -/*****************************************************************************/ -void DEFAULT_CC -lrail_WindowCachedIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - WINDOW_CACHED_ICON_ORDER* window_cached_icon) -{ - struct mod* mod; - - LLOGLN(0, ("lrail_WindowCachedIcon:")); - mod = ((struct mod_context*)context)->modi; - mod->server_window_cached_icon(mod, orderInfo->windowId, - window_cached_icon->cachedIcon.cacheEntry, - window_cached_icon->cachedIcon.cacheId, - orderInfo->fieldFlags); -} - -/*****************************************************************************/ -void DEFAULT_CC -lrail_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - NOTIFY_ICON_STATE_ORDER* notify_icon_state) -{ - struct mod* mod; - struct rail_notify_state_order rnso; - UNICONV* uniconv; - - - LLOGLN(0, ("lrail_NotifyIconCreate:")); - uniconv = freerdp_uniconv_new(); - - mod = ((struct mod_context*)context)->modi; - - memset(&rnso, 0, sizeof(rnso)); - rnso.version = notify_icon_state->version; - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) - { - rnso.tool_tip = freerdp_uniconv_in(uniconv, - notify_icon_state->toolTip.string, notify_icon_state->toolTip.length); - } - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) - { - rnso.infotip.timeout = notify_icon_state->infoTip.timeout; - rnso.infotip.flags = notify_icon_state->infoTip.flags; - rnso.infotip.text = freerdp_uniconv_in(uniconv, - notify_icon_state->infoTip.text.string, - notify_icon_state->infoTip.text.length); - rnso.infotip.title = freerdp_uniconv_in(uniconv, - notify_icon_state->infoTip.title.string, - notify_icon_state->infoTip.title.length); - } - rnso.state = notify_icon_state->state; - rnso.icon_cache_entry = notify_icon_state->icon.cacheEntry; - rnso.icon_cache_id = notify_icon_state->icon.cacheId; - - rnso.icon_info.bpp = notify_icon_state->icon.bpp; - rnso.icon_info.width = notify_icon_state->icon.width; - rnso.icon_info.height = notify_icon_state->icon.height; - rnso.icon_info.cmap_bytes = notify_icon_state->icon.cbColorTable; - rnso.icon_info.mask_bytes = notify_icon_state->icon.cbBitsMask; - rnso.icon_info.data_bytes = notify_icon_state->icon.cbBitsColor; - rnso.icon_info.mask = (char*)(notify_icon_state->icon.bitsMask); - rnso.icon_info.cmap = (char*)(notify_icon_state->icon.colorTable); - rnso.icon_info.data = (char*)(notify_icon_state->icon.bitsColor); - - mod->server_notify_new_update(mod, orderInfo->windowId, - orderInfo->notifyIconId, - &rnso, orderInfo->fieldFlags); - - xfree(rnso.tool_tip); - xfree(rnso.infotip.text); - xfree(rnso.infotip.title); - freerdp_uniconv_free(uniconv); - -} - -/*****************************************************************************/ -void DEFAULT_CC -lrail_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - NOTIFY_ICON_STATE_ORDER* notify_icon_state) -{ - LLOGLN(0, ("lrail_NotifyIconUpdate:")); - lrail_NotifyIconCreate(context, orderInfo, notify_icon_state); -} - -/*****************************************************************************/ -void DEFAULT_CC -lrail_NotifyIconDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) -{ - struct mod* mod; - - LLOGLN(0, ("lrail_NotifyIconDelete:")); - mod = ((struct mod_context*)context)->modi; - mod->server_notify_delete(mod, orderInfo->windowId, - orderInfo->notifyIconId); -} - -/*****************************************************************************/ -void DEFAULT_CC -lrail_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - MONITORED_DESKTOP_ORDER* monitored_desktop) -{ - int index; - struct mod* mod; - struct rail_monitored_desktop_order rmdo; - - LLOGLN(0, ("lrail_MonitoredDesktop:")); - mod = ((struct mod_context*)context)->modi; - memset(&rmdo, 0, sizeof(rmdo)); - rmdo.active_window_id = monitored_desktop->activeWindowId; - rmdo.num_window_ids = monitored_desktop->numWindowIds; - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) - { - if (rmdo.num_window_ids > 0) + if ((mod->username[0] != 0) && (mod->password[0] != 0)) { - rmdo.window_ids = (int*)g_malloc(sizeof(int) * rmdo.num_window_ids, 0); - for (index = 0; index < rmdo.num_window_ids; index++) - { - rmdo.window_ids[index] = monitored_desktop->windowIds[index]; - } + /* since we have username and password, we can try nla */ + instance->settings->nla_security = 1; } - } - mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags); - g_free(rmdo.window_ids); + else + { + instance->settings->nla_security = 0; + } + + return true; } /*****************************************************************************/ void DEFAULT_CC -lrail_NonMonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo, + WINDOW_STATE_ORDER *window_state) { - struct mod* mod; - struct rail_monitored_desktop_order rmdo; + int index; + struct mod *mod; + struct rail_window_state_order wso; + UNICONV *uniconv; - LLOGLN(0, ("lrail_NonMonitoredDesktop:")); - mod = ((struct mod_context*)context)->modi; - memset(&rmdo, 0, sizeof(rmdo)); - mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags); + LLOGLN(0, ("llrail_WindowCreate:")); + uniconv = freerdp_uniconv_new(); + mod = ((struct mod_context *)context)->modi; + memset(&wso, 0, sizeof(wso)); + /* copy the window state order */ + wso.owner_window_id = window_state->ownerWindowId; + wso.style = window_state->style; + wso.extended_style = window_state->extendedStyle; + wso.show_state = window_state->showState; + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) + { + wso.title_info = freerdp_uniconv_in(uniconv, + window_state->titleInfo.string, window_state->titleInfo.length); + } + + LLOGLN(0, ("lrail_WindowCreate: %s", wso.title_info)); + wso.client_offset_x = window_state->clientOffsetX; + wso.client_offset_y = window_state->clientOffsetY; + wso.client_area_width = window_state->clientAreaWidth; + wso.client_area_height = window_state->clientAreaHeight; + wso.rp_content = window_state->RPContent; + wso.root_parent_handle = window_state->rootParentHandle; + wso.window_offset_x = window_state->windowOffsetX; + wso.window_offset_y = window_state->windowOffsetY; + wso.window_client_delta_x = window_state->windowClientDeltaX; + wso.window_client_delta_y = window_state->windowClientDeltaY; + wso.window_width = window_state->windowWidth; + wso.window_height = window_state->windowHeight; + wso.num_window_rects = window_state->numWindowRects; + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) + { + wso.window_rects = (struct rail_window_rect *) + g_malloc(sizeof(struct rail_window_rect) * wso.num_window_rects, 0); + + for (index = 0; index < wso.num_window_rects; index++) + { + wso.window_rects[index].left = window_state->windowRects[index].left; + wso.window_rects[index].top = window_state->windowRects[index].top; + wso.window_rects[index].right = window_state->windowRects[index].right; + wso.window_rects[index].bottom = window_state->windowRects[index].bottom; + } + } + + wso.visible_offset_x = window_state->visibleOffsetX; + wso.visible_offset_y = window_state->visibleOffsetY; + wso.num_visibility_rects = window_state->numVisibilityRects; + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) + { + wso.visibility_rects = (struct rail_window_rect *) + g_malloc(sizeof(struct rail_window_rect) * wso.num_visibility_rects, 0); + + for (index = 0; index < wso.num_visibility_rects; index++) + { + wso.visibility_rects[index].left = window_state->visibilityRects[index].left; + wso.visibility_rects[index].top = window_state->visibilityRects[index].top; + wso.visibility_rects[index].right = window_state->visibilityRects[index].right; + wso.visibility_rects[index].bottom = window_state->visibilityRects[index].bottom; + } + } + + mod->server_window_new_update(mod, orderInfo->windowId, &wso, + orderInfo->fieldFlags); + + xfree(wso.title_info); + g_free(wso.window_rects); + g_free(wso.visibility_rects); + freerdp_uniconv_free(uniconv); +} + +/*****************************************************************************/ +void DEFAULT_CC +lrail_WindowUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo, + WINDOW_STATE_ORDER *window_state) +{ + LLOGLN(0, ("lrail_WindowUpdate:")); + lrail_WindowCreate(context, orderInfo, window_state); +} + +/*****************************************************************************/ +void DEFAULT_CC +lrail_WindowDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo) +{ + struct mod *mod; + + LLOGLN(0, ("lrail_WindowDelete:")); + mod = ((struct mod_context *)context)->modi; + mod->server_window_delete(mod, orderInfo->windowId); +} + +/*****************************************************************************/ +void DEFAULT_CC +lrail_WindowIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo, + WINDOW_ICON_ORDER *window_icon) +{ + struct mod *mod; + struct rail_icon_info rii; + + LLOGLN(0, ("lrail_WindowIcon:")); + mod = ((struct mod_context *)context)->modi; + memset(&rii, 0, sizeof(rii)); + rii.bpp = window_icon->iconInfo->bpp; + rii.width = window_icon->iconInfo->width; + rii.height = window_icon->iconInfo->height; + rii.cmap_bytes = window_icon->iconInfo->cbColorTable; + rii.mask_bytes = window_icon->iconInfo->cbBitsMask; + rii.data_bytes = window_icon->iconInfo->cbBitsColor; + rii.mask = (char *)(window_icon->iconInfo->bitsMask); + rii.cmap = (char *)(window_icon->iconInfo->colorTable); + rii.data = (char *)(window_icon->iconInfo->bitsColor); + mod->server_window_icon(mod, orderInfo->windowId, + window_icon->iconInfo->cacheEntry, + window_icon->iconInfo->cacheId, &rii, + orderInfo->fieldFlags); +} + +/*****************************************************************************/ +void DEFAULT_CC +lrail_WindowCachedIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo, + WINDOW_CACHED_ICON_ORDER *window_cached_icon) +{ + struct mod *mod; + + LLOGLN(0, ("lrail_WindowCachedIcon:")); + mod = ((struct mod_context *)context)->modi; + mod->server_window_cached_icon(mod, orderInfo->windowId, + window_cached_icon->cachedIcon.cacheEntry, + window_cached_icon->cachedIcon.cacheId, + orderInfo->fieldFlags); +} + +/*****************************************************************************/ +void DEFAULT_CC +lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo, + NOTIFY_ICON_STATE_ORDER *notify_icon_state) +{ + struct mod *mod; + struct rail_notify_state_order rnso; + UNICONV *uniconv; + + + LLOGLN(0, ("lrail_NotifyIconCreate:")); + uniconv = freerdp_uniconv_new(); + + mod = ((struct mod_context *)context)->modi; + + memset(&rnso, 0, sizeof(rnso)); + rnso.version = notify_icon_state->version; + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) + { + rnso.tool_tip = freerdp_uniconv_in(uniconv, + notify_icon_state->toolTip.string, notify_icon_state->toolTip.length); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) + { + rnso.infotip.timeout = notify_icon_state->infoTip.timeout; + rnso.infotip.flags = notify_icon_state->infoTip.flags; + rnso.infotip.text = freerdp_uniconv_in(uniconv, + notify_icon_state->infoTip.text.string, + notify_icon_state->infoTip.text.length); + rnso.infotip.title = freerdp_uniconv_in(uniconv, + notify_icon_state->infoTip.title.string, + notify_icon_state->infoTip.title.length); + } + + rnso.state = notify_icon_state->state; + rnso.icon_cache_entry = notify_icon_state->icon.cacheEntry; + rnso.icon_cache_id = notify_icon_state->icon.cacheId; + + rnso.icon_info.bpp = notify_icon_state->icon.bpp; + rnso.icon_info.width = notify_icon_state->icon.width; + rnso.icon_info.height = notify_icon_state->icon.height; + rnso.icon_info.cmap_bytes = notify_icon_state->icon.cbColorTable; + rnso.icon_info.mask_bytes = notify_icon_state->icon.cbBitsMask; + rnso.icon_info.data_bytes = notify_icon_state->icon.cbBitsColor; + rnso.icon_info.mask = (char *)(notify_icon_state->icon.bitsMask); + rnso.icon_info.cmap = (char *)(notify_icon_state->icon.colorTable); + rnso.icon_info.data = (char *)(notify_icon_state->icon.bitsColor); + + mod->server_notify_new_update(mod, orderInfo->windowId, + orderInfo->notifyIconId, + &rnso, orderInfo->fieldFlags); + + xfree(rnso.tool_tip); + xfree(rnso.infotip.text); + xfree(rnso.infotip.title); + freerdp_uniconv_free(uniconv); + +} + +/*****************************************************************************/ +void DEFAULT_CC +lrail_NotifyIconUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo, + NOTIFY_ICON_STATE_ORDER *notify_icon_state) +{ + LLOGLN(0, ("lrail_NotifyIconUpdate:")); + lrail_NotifyIconCreate(context, orderInfo, notify_icon_state); +} + +/*****************************************************************************/ +void DEFAULT_CC +lrail_NotifyIconDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo) +{ + struct mod *mod; + + LLOGLN(0, ("lrail_NotifyIconDelete:")); + mod = ((struct mod_context *)context)->modi; + mod->server_notify_delete(mod, orderInfo->windowId, + orderInfo->notifyIconId); +} + +/*****************************************************************************/ +void DEFAULT_CC +lrail_MonitoredDesktop(rdpContext *context, WINDOW_ORDER_INFO *orderInfo, + MONITORED_DESKTOP_ORDER *monitored_desktop) +{ + int index; + struct mod *mod; + struct rail_monitored_desktop_order rmdo; + + LLOGLN(0, ("lrail_MonitoredDesktop:")); + mod = ((struct mod_context *)context)->modi; + memset(&rmdo, 0, sizeof(rmdo)); + rmdo.active_window_id = monitored_desktop->activeWindowId; + rmdo.num_window_ids = monitored_desktop->numWindowIds; + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) + { + if (rmdo.num_window_ids > 0) + { + rmdo.window_ids = (int *)g_malloc(sizeof(int) * rmdo.num_window_ids, 0); + + for (index = 0; index < rmdo.num_window_ids; index++) + { + rmdo.window_ids[index] = monitored_desktop->windowIds[index]; + } + } + } + + mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags); + g_free(rmdo.window_ids); +} + +/*****************************************************************************/ +void DEFAULT_CC +lrail_NonMonitoredDesktop(rdpContext *context, WINDOW_ORDER_INFO *orderInfo) +{ + struct mod *mod; + struct rail_monitored_desktop_order rmdo; + + LLOGLN(0, ("lrail_NonMonitoredDesktop:")); + mod = ((struct mod_context *)context)->modi; + memset(&rmdo, 0, sizeof(rmdo)); + mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags); } /******************************************************************************/ static boolean DEFAULT_CC -lfreerdp_post_connect(freerdp* instance) +lfreerdp_post_connect(freerdp *instance) { - struct mod* mod; + struct mod *mod; - LLOGLN(0, ("lfreerdp_post_connect:")); - mod = ((struct mod_context*)(instance->context))->modi; - g_memset(mod->password, 0, sizeof(mod->password)); + LLOGLN(0, ("lfreerdp_post_connect:")); + mod = ((struct mod_context *)(instance->context))->modi; + g_memset(mod->password, 0, sizeof(mod->password)); - mod->inst->update->window->WindowCreate = lrail_WindowCreate; - mod->inst->update->window->WindowUpdate = lrail_WindowUpdate; - mod->inst->update->window->WindowDelete = lrail_WindowDelete; - mod->inst->update->window->WindowIcon = lrail_WindowIcon; - mod->inst->update->window->WindowCachedIcon = lrail_WindowCachedIcon; - mod->inst->update->window->NotifyIconCreate = lrail_NotifyIconCreate; - mod->inst->update->window->NotifyIconUpdate = lrail_NotifyIconUpdate; - mod->inst->update->window->NotifyIconDelete = lrail_NotifyIconDelete; - mod->inst->update->window->MonitoredDesktop = lrail_MonitoredDesktop; - mod->inst->update->window->NonMonitoredDesktop = lrail_NonMonitoredDesktop; + mod->inst->update->window->WindowCreate = lrail_WindowCreate; + mod->inst->update->window->WindowUpdate = lrail_WindowUpdate; + mod->inst->update->window->WindowDelete = lrail_WindowDelete; + mod->inst->update->window->WindowIcon = lrail_WindowIcon; + mod->inst->update->window->WindowCachedIcon = lrail_WindowCachedIcon; + mod->inst->update->window->NotifyIconCreate = lrail_NotifyIconCreate; + mod->inst->update->window->NotifyIconUpdate = lrail_NotifyIconUpdate; + mod->inst->update->window->NotifyIconDelete = lrail_NotifyIconDelete; + mod->inst->update->window->MonitoredDesktop = lrail_MonitoredDesktop; + mod->inst->update->window->NonMonitoredDesktop = lrail_NonMonitoredDesktop; - return true; + return true; } /******************************************************************************/ static void DEFAULT_CC -lfreerdp_context_new(freerdp* instance, rdpContext* context) +lfreerdp_context_new(freerdp *instance, rdpContext *context) { - LLOGLN(0, ("lfreerdp_context_new: %p", context)); + LLOGLN(0, ("lfreerdp_context_new: %p", context)); } /******************************************************************************/ static void DEFAULT_CC -lfreerdp_context_free(freerdp* instance, rdpContext* context) +lfreerdp_context_free(freerdp *instance, rdpContext *context) { - LLOGLN(0, ("lfreerdp_context_free:")); + LLOGLN(0, ("lfreerdp_context_free:")); } /******************************************************************************/ static int DEFAULT_CC -lfreerdp_receive_channel_data(freerdp* instance, int channelId, uint8* data, +lfreerdp_receive_channel_data(freerdp *instance, int channelId, uint8 *data, int size, int flags, int total_size) { - struct mod* mod; - int lchid; - int index; - int error; + struct mod *mod; + int lchid; + int index; + int error; - mod = ((struct mod_context*)(instance->context))->modi; - lchid = -1; - for (index = 0; index < instance->settings->num_channels; index++) - { - if (instance->settings->channels[index].channel_id == channelId) + mod = ((struct mod_context *)(instance->context))->modi; + lchid = -1; + + for (index = 0; index < instance->settings->num_channels; index++) { - lchid = index; - break; + if (instance->settings->channels[index].channel_id == channelId) + { + lchid = index; + break; + } } - } - if (lchid >= 0) - { - LLOGLN(10, ("lfreerdp_receive_channel_data: server to client")); - error = mod->server_send_to_channel(mod, lchid, (char*)data, size, - total_size, flags); - if (error != 0) + + if (lchid >= 0) { - LLOGLN(0, ("lfreerdp_receive_channel_data: error %d", error)); + LLOGLN(10, ("lfreerdp_receive_channel_data: server to client")); + error = mod->server_send_to_channel(mod, lchid, (char *)data, size, + total_size, flags); + + if (error != 0) + { + LLOGLN(0, ("lfreerdp_receive_channel_data: error %d", error)); + } } - } - else - { - LLOGLN(0, ("lfreerdp_receive_channel_data: bad lchid")); - } - return 0; + else + { + LLOGLN(0, ("lfreerdp_receive_channel_data: bad lchid")); + } + + return 0; } /******************************************************************************/ static boolean DEFAULT_CC -lfreerdp_authenticate(freerdp* instance, char** username, - char** password, char** domain) +lfreerdp_authenticate(freerdp *instance, char **username, + char **password, char **domain) { - LLOGLN(0, ("lfreerdp_authenticate:")); - return true; + LLOGLN(0, ("lfreerdp_authenticate:")); + return true; } /******************************************************************************/ static boolean DEFAULT_CC -lfreerdp_verify_certificate(freerdp* instance, char* subject, char* issuer, - char* fingerprint) +lfreerdp_verify_certificate(freerdp *instance, char *subject, char *issuer, + char *fingerprint) { - LLOGLN(0, ("lfreerdp_verify_certificate:")); - return true; + LLOGLN(0, ("lfreerdp_verify_certificate:")); + return true; } /******************************************************************************/ -struct mod* EXPORT_CC +struct mod *EXPORT_CC mod_init(void) { - struct mod* mod; - modContext* lcon; + struct mod *mod; + modContext *lcon; - LLOGLN(0, ("mod_init:")); - mod = (struct mod*)g_malloc(sizeof(struct mod), 1); - freerdp_get_version(&(mod->vmaj), &(mod->vmin), &(mod->vrev)); - LLOGLN(0, (" FreeRDP version major %d minor %d revision %d", - mod->vmaj, mod->vmin, mod->vrev)); - mod->size = sizeof(struct mod); - mod->version = CURRENT_MOD_VER; - mod->handle = (tbus)mod; - mod->mod_connect = lxrdp_connect; - mod->mod_start = lxrdp_start; - mod->mod_event = lxrdp_event; - mod->mod_signal = lxrdp_signal; - mod->mod_end = lxrdp_end; - mod->mod_set_param = lxrdp_set_param; - mod->mod_session_change = lxrdp_session_change; - mod->mod_get_wait_objs = lxrdp_get_wait_objs; - mod->mod_check_wait_objs = lxrdp_check_wait_objs; + LLOGLN(0, ("mod_init:")); + mod = (struct mod *)g_malloc(sizeof(struct mod), 1); + freerdp_get_version(&(mod->vmaj), &(mod->vmin), &(mod->vrev)); + LLOGLN(0, (" FreeRDP version major %d minor %d revision %d", + mod->vmaj, mod->vmin, mod->vrev)); + mod->size = sizeof(struct mod); + mod->version = CURRENT_MOD_VER; + mod->handle = (tbus)mod; + mod->mod_connect = lxrdp_connect; + mod->mod_start = lxrdp_start; + mod->mod_event = lxrdp_event; + mod->mod_signal = lxrdp_signal; + mod->mod_end = lxrdp_end; + mod->mod_set_param = lxrdp_set_param; + mod->mod_session_change = lxrdp_session_change; + mod->mod_get_wait_objs = lxrdp_get_wait_objs; + mod->mod_check_wait_objs = lxrdp_check_wait_objs; - mod->inst = freerdp_new(); - mod->inst->PreConnect = lfreerdp_pre_connect; - mod->inst->PostConnect = lfreerdp_post_connect; - mod->inst->context_size = sizeof(modContext); - mod->inst->ContextNew = lfreerdp_context_new; - mod->inst->ContextFree = lfreerdp_context_free; - mod->inst->ReceiveChannelData = lfreerdp_receive_channel_data; - mod->inst->Authenticate = lfreerdp_authenticate; - mod->inst->VerifyCertificate = lfreerdp_verify_certificate; + mod->inst = freerdp_new(); + mod->inst->PreConnect = lfreerdp_pre_connect; + mod->inst->PostConnect = lfreerdp_post_connect; + mod->inst->context_size = sizeof(modContext); + mod->inst->ContextNew = lfreerdp_context_new; + mod->inst->ContextFree = lfreerdp_context_free; + mod->inst->ReceiveChannelData = lfreerdp_receive_channel_data; + mod->inst->Authenticate = lfreerdp_authenticate; + mod->inst->VerifyCertificate = lfreerdp_verify_certificate; - freerdp_context_new(mod->inst); + freerdp_context_new(mod->inst); - lcon = (modContext*)(mod->inst->context); - lcon->modi = mod; - LLOGLN(10, ("mod_init: mod %p", mod)); + lcon = (modContext *)(mod->inst->context); + lcon->modi = mod; + LLOGLN(10, ("mod_init: mod %p", mod)); - return mod; + return mod; } /******************************************************************************/ int EXPORT_CC -mod_exit(struct mod* mod) +mod_exit(struct mod *mod) { - LLOGLN(0, ("mod_exit:")); - if (mod == 0) - { - return 0; - } - if (mod->inst == NULL) - { - LLOGLN(0, ("mod_exit - null pointer for inst:")); + LLOGLN(0, ("mod_exit:")); + + if (mod == 0) + { + return 0; + } + + if (mod->inst == NULL) + { + LLOGLN(0, ("mod_exit - null pointer for inst:")); + g_free(mod); + return 0 ; + } + + freerdp_disconnect(mod->inst); + + if ((mod->vmaj == 1) && (mod->vmin == 0) && (mod->vrev == 1)) + { + /* this version has a bug with double free in freerdp_free */ + } + else + { + freerdp_context_free(mod->inst); + } + + freerdp_free(mod->inst); g_free(mod); - return 0 ; - } - freerdp_disconnect(mod->inst); - if ((mod->vmaj == 1) && (mod->vmin == 0) && (mod->vrev == 1)) - { - /* this version has a bug with double free in freerdp_free */ - } - else - { - freerdp_context_free(mod->inst); - } - freerdp_free(mod->inst); - g_free(mod); - return 0; + return 0; } diff --git a/genkeymap/genkeymap.c b/genkeymap/genkeymap.c index 0d0a9a44..46513513 100644 --- a/genkeymap/genkeymap.c +++ b/genkeymap/genkeymap.c @@ -41,75 +41,87 @@ int main(int argc, char **argv) { - const char* programname; - char text[256]; - char* displayname = NULL; - char* outfname; - char* sections[5] = {"noshift", "shift", "altgr", "capslock", "shiftcapslock"}; - int states[5] = {0, 1, 0x80, 2, 3}; - int i; - int idx; - int char_count; - int nbytes = 0; - int unicode; - Display* dpy; - KeySym ks; - FILE* outf; - XKeyPressedEvent e; - wchar_t wtext[256]; + const char *programname; + char text[256]; + char *displayname = NULL; + char *outfname; + char *sections[5] = {"noshift", "shift", "altgr", "capslock", "shiftcapslock"}; + int states[5] = {0, 1, 0x80, 2, 3}; + int i; + int idx; + int char_count; + int nbytes = 0; + int unicode; + Display *dpy; + KeySym ks; + FILE *outf; + XKeyPressedEvent e; + wchar_t wtext[256]; + + setlocale(LC_CTYPE, ""); + programname = argv[0]; + + if (argc != 2) + { + fprintf(stderr, "Usage: %s out_filename\n", programname); + fprintf(stderr, "Example: %s /etc/xrdp/km-0409.ini\n", programname); + return 1; + } + + outfname = argv[1]; + dpy = XOpenDisplay(displayname); + + if (!dpy) + { + fprintf(stderr, "%s: unable to open display '%s'\n", + programname, XDisplayName(displayname)); + return 1; + } + + outf = fopen(outfname, "w"); + + if (outf == NULL) + { + fprintf(stderr, "%s: unable to create file '%s'\n", programname, outfname); + XCloseDisplay(dpy); + return 1; + } + + memset(&e, 0, sizeof(e)); + e.type = KeyPress; + e.serial = 16; + e.send_event = True; + e.display = dpy; + e.same_screen = True; + + for (idx = 0; idx < 5; idx++) /* Sections and states */ + { + fprintf(outf, "[%s]\n", sections[idx]); + e.state = states[idx]; + + for (i = 8; i <= 137; i++) /* Keycodes */ + { + e.keycode = i; + nbytes = XLookupString(&e, text, 255, &ks, NULL); + text[nbytes] = 0; + char_count = mbstowcs(wtext, text, 255); + unicode = 0; + + if (char_count == 1) + { + unicode = wtext[0]; + } + + fprintf(outf, "Key%d=%d:%d\n", i, (int) ks, unicode); + } + + if (idx != 4) + { + fprintf(outf, "\n"); + } + } - setlocale(LC_CTYPE, ""); - programname = argv[0]; - if (argc != 2) - { - fprintf(stderr, "Usage: %s out_filename\n", programname); - fprintf(stderr, "Example: %s /etc/xrdp/km-0409.ini\n", programname); - return 1; - } - outfname = argv[1]; - dpy = XOpenDisplay(displayname); - if (!dpy) - { - fprintf(stderr, "%s: unable to open display '%s'\n", - programname, XDisplayName(displayname)); - return 1; - } - outf = fopen(outfname, "w"); - if (outf == NULL) - { - fprintf(stderr, "%s: unable to create file '%s'\n", programname, outfname); XCloseDisplay(dpy); - return 1; - } - memset(&e, 0, sizeof(e)); - e.type = KeyPress; - e.serial = 16; - e.send_event = True; - e.display = dpy; - e.same_screen = True; - for (idx = 0; idx < 5; idx++) /* Sections and states */ - { - fprintf(outf, "[%s]\n", sections[idx]); - e.state = states[idx]; - for (i = 8; i <= 137; i++) /* Keycodes */ - { - e.keycode = i; - nbytes = XLookupString(&e, text, 255, &ks, NULL); - text[nbytes] = 0; - char_count = mbstowcs(wtext, text, 255); - unicode = 0; - if (char_count == 1) - { - unicode = wtext[0]; - } - fprintf(outf, "Key%d=%d:%d\n", i, (int) ks, unicode); - } - if (idx != 4) - { - fprintf(outf, "\n"); - } - } - XCloseDisplay(dpy); - fclose(outf); - return 0; + fclose(outf); + return 0; } diff --git a/keygen/keygen.c b/keygen/keygen.c index e984572b..d1495011 100644 --- a/keygen/keygen.c +++ b/keygen/keygen.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2007-2010 - - rsa key generator for xrdp - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * rsa key generator for xrdp + */ /* references: @@ -37,74 +35,74 @@ static tui8 g_exponent[4] = { - 0x01, 0x00, 0x01, 0x00 + 0x01, 0x00, 0x01, 0x00 }; static tui8 g_ppk_e[4] = { - 0x5B, 0x7B, 0x88, 0xC0 + 0x5B, 0x7B, 0x88, 0xC0 }; static tui8 g_ppk_n[72] = { - 0x3D, 0x3A, 0x5E, 0xBD, 0x72, 0x43, 0x3E, 0xC9, - 0x4D, 0xBB, 0xC1, 0x1E, 0x4A, 0xBA, 0x5F, 0xCB, - 0x3E, 0x88, 0x20, 0x87, 0xEF, 0xF5, 0xC1, 0xE2, - 0xD7, 0xB7, 0x6B, 0x9A, 0xF2, 0x52, 0x45, 0x95, - 0xCE, 0x63, 0x65, 0x6B, 0x58, 0x3A, 0xFE, 0xEF, - 0x7C, 0xE7, 0xBF, 0xFE, 0x3D, 0xF6, 0x5C, 0x7D, - 0x6C, 0x5E, 0x06, 0x09, 0x1A, 0xF5, 0x61, 0xBB, - 0x20, 0x93, 0x09, 0x5F, 0x05, 0x6D, 0xEA, 0x87, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x3D, 0x3A, 0x5E, 0xBD, 0x72, 0x43, 0x3E, 0xC9, + 0x4D, 0xBB, 0xC1, 0x1E, 0x4A, 0xBA, 0x5F, 0xCB, + 0x3E, 0x88, 0x20, 0x87, 0xEF, 0xF5, 0xC1, 0xE2, + 0xD7, 0xB7, 0x6B, 0x9A, 0xF2, 0x52, 0x45, 0x95, + 0xCE, 0x63, 0x65, 0x6B, 0x58, 0x3A, 0xFE, 0xEF, + 0x7C, 0xE7, 0xBF, 0xFE, 0x3D, 0xF6, 0x5C, 0x7D, + 0x6C, 0x5E, 0x06, 0x09, 0x1A, 0xF5, 0x61, 0xBB, + 0x20, 0x93, 0x09, 0x5F, 0x05, 0x6D, 0xEA, 0x87, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static tui8 g_ppk_d[108] = { - 0x87, 0xA7, 0x19, 0x32, 0xDA, 0x11, 0x87, 0x55, - 0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xF8, - 0x24, 0x3E, 0xE6, 0xFA, 0xE9, 0x67, 0x49, 0x94, - 0xCF, 0x92, 0xCC, 0x33, 0x99, 0xE8, 0x08, 0x60, - 0x17, 0x9A, 0x12, 0x9F, 0x24, 0xDD, 0xB1, 0x24, - 0x99, 0xC7, 0x3A, 0xB8, 0x0A, 0x7B, 0x0D, 0xDD, - 0x35, 0x07, 0x79, 0x17, 0x0B, 0x51, 0x9B, 0xB3, - 0xC7, 0x10, 0x01, 0x13, 0xE7, 0x3F, 0xF3, 0x5F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x87, 0xA7, 0x19, 0x32, 0xDA, 0x11, 0x87, 0x55, + 0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xF8, + 0x24, 0x3E, 0xE6, 0xFA, 0xE9, 0x67, 0x49, 0x94, + 0xCF, 0x92, 0xCC, 0x33, 0x99, 0xE8, 0x08, 0x60, + 0x17, 0x9A, 0x12, 0x9F, 0x24, 0xDD, 0xB1, 0x24, + 0x99, 0xC7, 0x3A, 0xB8, 0x0A, 0x7B, 0x0D, 0xDD, + 0x35, 0x07, 0x79, 0x17, 0x0B, 0x51, 0x9B, 0xB3, + 0xC7, 0x10, 0x01, 0x13, 0xE7, 0x3F, 0xF3, 0x5F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; static tui8 g_testkey[176] = { - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x5c, 0x00, - 0x52, 0x53, 0x41, 0x31, 0x48, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x79, 0x6f, 0xb4, 0xdf, - 0xa6, 0x95, 0xb9, 0xa9, 0x61, 0xe3, 0xc4, 0x5e, - 0xff, 0x6b, 0xd8, 0x81, 0x8a, 0x12, 0x4a, 0x93, - 0x42, 0x97, 0x18, 0x93, 0xac, 0xd1, 0x3a, 0x38, - 0x3c, 0x68, 0x50, 0x19, 0x31, 0xb6, 0x84, 0x51, - 0x79, 0xfb, 0x1c, 0xe7, 0xe3, 0x99, 0x20, 0xc7, - 0x84, 0xdf, 0xd1, 0xaa, 0xb5, 0x15, 0xef, 0x47, - 0x7e, 0xfc, 0x88, 0xeb, 0x29, 0xc3, 0x27, 0x5a, - 0x35, 0xf8, 0xfd, 0xaa, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x48, 0x00, - 0x32, 0x3b, 0xde, 0x6f, 0x18, 0x97, 0x1e, 0xc3, - 0x6b, 0x2b, 0x2d, 0xe4, 0xfc, 0x2d, 0xa2, 0x8e, - 0x32, 0x3c, 0xf3, 0x1b, 0x24, 0x90, 0x57, 0x4d, - 0x8e, 0xe4, 0x69, 0xfc, 0x16, 0x8d, 0x41, 0x92, - 0x78, 0xc7, 0x9c, 0xb4, 0x26, 0xff, 0xe8, 0x3e, - 0xa1, 0x8a, 0xf5, 0x57, 0xc0, 0x7f, 0x3e, 0x21, - 0x17, 0x32, 0x30, 0x6f, 0x79, 0xe1, 0x36, 0xcd, - 0xb6, 0x8e, 0xbe, 0x57, 0x57, 0xd2, 0xa9, 0x36 + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x5c, 0x00, + 0x52, 0x53, 0x41, 0x31, 0x48, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x79, 0x6f, 0xb4, 0xdf, + 0xa6, 0x95, 0xb9, 0xa9, 0x61, 0xe3, 0xc4, 0x5e, + 0xff, 0x6b, 0xd8, 0x81, 0x8a, 0x12, 0x4a, 0x93, + 0x42, 0x97, 0x18, 0x93, 0xac, 0xd1, 0x3a, 0x38, + 0x3c, 0x68, 0x50, 0x19, 0x31, 0xb6, 0x84, 0x51, + 0x79, 0xfb, 0x1c, 0xe7, 0xe3, 0x99, 0x20, 0xc7, + 0x84, 0xdf, 0xd1, 0xaa, 0xb5, 0x15, 0xef, 0x47, + 0x7e, 0xfc, 0x88, 0xeb, 0x29, 0xc3, 0x27, 0x5a, + 0x35, 0xf8, 0xfd, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x48, 0x00, + 0x32, 0x3b, 0xde, 0x6f, 0x18, 0x97, 0x1e, 0xc3, + 0x6b, 0x2b, 0x2d, 0xe4, 0xfc, 0x2d, 0xa2, 0x8e, + 0x32, 0x3c, 0xf3, 0x1b, 0x24, 0x90, 0x57, 0x4d, + 0x8e, 0xe4, 0x69, 0xfc, 0x16, 0x8d, 0x41, 0x92, + 0x78, 0xc7, 0x9c, 0xb4, 0x26, 0xff, 0xe8, 0x3e, + 0xa1, 0x8a, 0xf5, 0x57, 0xc0, 0x7f, 0x3e, 0x21, + 0x17, 0x32, 0x30, 0x6f, 0x79, 0xe1, 0x36, 0xcd, + 0xb6, 0x8e, 0xbe, 0x57, 0x57, 0xd2, 0xa9, 0x36 }; /* this is the installed signature */ -char inst_pub_sig[]="0x6a,0x41,0xb1,0x43,0xcf,0x47,0x6f,0xf1,0xe6,0xcc,0xa1,\ +char inst_pub_sig[] = "0x6a,0x41,0xb1,0x43,0xcf,0x47,0x6f,0xf1,0xe6,0xcc,0xa1,\ 0x72,0x97,0xd9,0xe1,0x85,0x15,0xb3,0xc2,0x39,0xa0,0xa6,0x26,0x1a,0xb6,\ 0x49,0x01,0xfa,0xa6,0xda,0x60,0xd7,0x45,0xf7,0x2c,0xee,0xe4,0x8e,0x64,\ 0x2e,0x37,0x49,0xf0,0x4c,0x94,0x6f,0x08,0xf5,0x63,0x4c,0x56,0x29,0x55,\ @@ -115,212 +113,230 @@ char inst_pub_sig[]="0x6a,0x41,0xb1,0x43,0xcf,0x47,0x6f,0xf1,0xe6,0xcc,0xa1,\ static int APP_CC out_params(void) { - g_writeln(""); - g_writeln("xrdp rsa key gen utility examples"); - g_writeln(" xrdp-keygen xrdp ['path and file name' | auto]"); - g_writeln(" xrdp-keygen test"); - g_writeln(""); - return 0; + g_writeln(""); + g_writeln("xrdp rsa key gen utility examples"); + g_writeln(" xrdp-keygen xrdp ['path and file name' | auto]"); + g_writeln(" xrdp-keygen test"); + g_writeln(""); + return 0; } /*****************************************************************************/ /* this is the special key signing algorithm */ static int APP_CC -sign_key(char* e_data, int e_len, char* n_data, int n_len, - char* sign_data, int sign_len) +sign_key(char *e_data, int e_len, char *n_data, int n_len, + char *sign_data, int sign_len) { - char* key; - char* md5_final; - void* md5; + char *key; + char *md5_final; + void *md5; - if ((e_len != 4) || (n_len != 64) || (sign_len != 64)) - { - return 1; - } - key = (char*)g_malloc(176, 0); - md5_final = (char*)g_malloc(64, 0); - md5 = ssl_md5_info_create(); - /* copy the test key */ - g_memcpy(key, g_testkey, 176); - /* replace e and n */ - g_memcpy(key + 32, e_data, 4); - g_memcpy(key + 36, n_data, 64); - ssl_md5_clear(md5); - /* the first 108 bytes */ - ssl_md5_transform(md5, key, 108); - /* set the whole thing with 0xff */ - g_memset(md5_final, 0xff, 64); - /* digest 16 bytes */ - ssl_md5_complete(md5, md5_final); - /* set non 0xff array items */ - md5_final[16] = 0; - md5_final[62] = 1; - md5_final[63] = 0; - /* encrypt */ - ssl_mod_exp(sign_data, 64, md5_final, 64, (char*)g_ppk_n, 64, - (char*)g_ppk_d, 64); - /* cleanup */ - ssl_md5_info_delete(md5); - g_free(key); - g_free(md5_final); - return 0; + if ((e_len != 4) || (n_len != 64) || (sign_len != 64)) + { + return 1; + } + + key = (char *)g_malloc(176, 0); + md5_final = (char *)g_malloc(64, 0); + md5 = ssl_md5_info_create(); + /* copy the test key */ + g_memcpy(key, g_testkey, 176); + /* replace e and n */ + g_memcpy(key + 32, e_data, 4); + g_memcpy(key + 36, n_data, 64); + ssl_md5_clear(md5); + /* the first 108 bytes */ + ssl_md5_transform(md5, key, 108); + /* set the whole thing with 0xff */ + g_memset(md5_final, 0xff, 64); + /* digest 16 bytes */ + ssl_md5_complete(md5, md5_final); + /* set non 0xff array items */ + md5_final[16] = 0; + md5_final[62] = 1; + md5_final[63] = 0; + /* encrypt */ + ssl_mod_exp(sign_data, 64, md5_final, 64, (char *)g_ppk_n, 64, + (char *)g_ppk_d, 64); + /* cleanup */ + ssl_md5_info_delete(md5); + g_free(key); + g_free(md5_final); + return 0; } /*****************************************************************************/ static int APP_CC -write_out_line(int fd, char* name, char* data, int len) +write_out_line(int fd, char *name, char *data, int len) { - int max; - int error; - int index; - int data_item; - int buf_pos; - char* buf; - char* text; + int max; + int error; + int index; + int data_item; + int buf_pos; + char *buf; + char *text; - text = (char*)g_malloc(256, 0); - max = len; - max = max * 10; - buf_pos = g_strlen(name); - max = max + buf_pos + 16; - buf = (char*)g_malloc(max, 0); - g_strncpy(buf, name, max - 1); - buf[buf_pos] = '='; - buf_pos++; - for (index = 0; index < len; index++) - { - data_item = (tui8)(data[index]); - g_snprintf(text, 255, "0x%2.2x", data_item); - if (index != 0) + text = (char *)g_malloc(256, 0); + max = len; + max = max * 10; + buf_pos = g_strlen(name); + max = max + buf_pos + 16; + buf = (char *)g_malloc(max, 0); + g_strncpy(buf, name, max - 1); + buf[buf_pos] = '='; + buf_pos++; + + for (index = 0; index < len; index++) { - buf[buf_pos] = ','; - buf_pos++; + data_item = (tui8)(data[index]); + g_snprintf(text, 255, "0x%2.2x", data_item); + + if (index != 0) + { + buf[buf_pos] = ','; + buf_pos++; + } + + buf[buf_pos] = text[0]; + buf_pos++; + buf[buf_pos] = text[1]; + buf_pos++; + buf[buf_pos] = text[2]; + buf_pos++; + buf[buf_pos] = text[3]; + buf_pos++; } - buf[buf_pos] = text[0]; + + buf[buf_pos] = '\n'; buf_pos++; - buf[buf_pos] = text[1]; - buf_pos++; - buf[buf_pos] = text[2]; - buf_pos++; - buf[buf_pos] = text[3]; - buf_pos++; - } - buf[buf_pos] = '\n'; - buf_pos++; - buf[buf_pos] = 0; - error = g_file_write(fd, buf, buf_pos) == -1; - g_free(buf); - g_free(text); - return error; + buf[buf_pos] = 0; + error = g_file_write(fd, buf, buf_pos) == -1; + g_free(buf); + g_free(text); + return error; } /*****************************************************************************/ static int APP_CC -save_all(char* e_data, int e_len, char* n_data, int n_len, - char* d_data, int d_len, char* sign_data, int sign_len, - const char* path_and_file_name) +save_all(char *e_data, int e_len, char *n_data, int n_len, + char *d_data, int d_len, char *sign_data, int sign_len, + const char *path_and_file_name) { - int fd; - char filename[256]; + int fd; + char filename[256]; - if (path_and_file_name == 0) - { - g_strncpy(filename, "rsakeys.ini", 255); - } - else - { - g_strncpy(filename, path_and_file_name, 255); - } - g_writeln("saving to %s", filename); - g_writeln(""); - if (g_file_exist(filename)) - { - if (g_file_delete(filename) == 0) + if (path_and_file_name == 0) { - g_writeln("problem deleting %s, maybe no rights", filename); - return 1; + g_strncpy(filename, "rsakeys.ini", 255); } - } - fd = g_file_open(filename); - if (fd > 0) - { - if (g_file_write(fd, "[keys]\n", 7) == -1) + else { - g_writeln("problem writing to %s, maybe no rights", filename); - return 1; + g_strncpy(filename, path_and_file_name, 255); } - write_out_line(fd, "pub_exp", e_data, e_len); - write_out_line(fd, "pub_mod", n_data, n_len); - write_out_line(fd, "pub_sig", sign_data, sign_len); - write_out_line(fd, "pri_exp", d_data, d_len); - } - else - { - g_writeln("problem opening %s, maybe no rights", filename); - return 1; - } - g_file_close(fd); - return 0; -} -/*****************************************************************************/ -static int APP_CC -key_gen(const char* path_and_file_name) -{ - char* e_data; - char* n_data; - char* d_data; - char* sign_data; - int e_len; - int n_len; - int d_len; - int sign_len; - int error; - - e_data = (char*)g_exponent; - n_data = (char*)g_malloc(64, 0); - d_data = (char*)g_malloc(64, 0); - sign_data = (char*)g_malloc(64, 0); - e_len = 4; - n_len = 64; - d_len = 64; - sign_len = 64; - error = 0; - g_writeln(""); - g_writeln("Generating %d bit rsa key...", MY_KEY_SIZE); - g_writeln(""); - if (error == 0) - { - error = ssl_gen_key_xrdp1(MY_KEY_SIZE, e_data, e_len, n_data, n_len, - d_data, d_len); - if (error != 0) - { - g_writeln("error %d in key_gen, ssl_gen_key_xrdp1", error); - } - } - if (error == 0) - { - g_writeln("ssl_gen_key_xrdp1 ok"); + g_writeln("saving to %s", filename); g_writeln(""); - error = sign_key(e_data, e_len, n_data, n_len, sign_data, sign_len); - if (error != 0) + + if (g_file_exist(filename)) { - g_writeln("error %d in key_gen, sign_key", error); + if (g_file_delete(filename) == 0) + { + g_writeln("problem deleting %s, maybe no rights", filename); + return 1; + } } - } - if (error == 0) - { - error = save_all(e_data, e_len, n_data, n_len, d_data, d_len, - sign_data, sign_len, path_and_file_name); - if (error != 0) + + fd = g_file_open(filename); + + if (fd > 0) { - g_writeln("error %d in key_gen, save_all", error); + if (g_file_write(fd, "[keys]\n", 7) == -1) + { + g_writeln("problem writing to %s, maybe no rights", filename); + return 1; + } + + write_out_line(fd, "pub_exp", e_data, e_len); + write_out_line(fd, "pub_mod", n_data, n_len); + write_out_line(fd, "pub_sig", sign_data, sign_len); + write_out_line(fd, "pri_exp", d_data, d_len); } - } - g_free(n_data); - g_free(d_data); - g_free(sign_data); - return error; + else + { + g_writeln("problem opening %s, maybe no rights", filename); + return 1; + } + + g_file_close(fd); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +key_gen(const char *path_and_file_name) +{ + char *e_data; + char *n_data; + char *d_data; + char *sign_data; + int e_len; + int n_len; + int d_len; + int sign_len; + int error; + + e_data = (char *)g_exponent; + n_data = (char *)g_malloc(64, 0); + d_data = (char *)g_malloc(64, 0); + sign_data = (char *)g_malloc(64, 0); + e_len = 4; + n_len = 64; + d_len = 64; + sign_len = 64; + error = 0; + g_writeln(""); + g_writeln("Generating %d bit rsa key...", MY_KEY_SIZE); + g_writeln(""); + + if (error == 0) + { + error = ssl_gen_key_xrdp1(MY_KEY_SIZE, e_data, e_len, n_data, n_len, + d_data, d_len); + + if (error != 0) + { + g_writeln("error %d in key_gen, ssl_gen_key_xrdp1", error); + } + } + + if (error == 0) + { + g_writeln("ssl_gen_key_xrdp1 ok"); + g_writeln(""); + error = sign_key(e_data, e_len, n_data, n_len, sign_data, sign_len); + + if (error != 0) + { + g_writeln("error %d in key_gen, sign_key", error); + } + } + + if (error == 0) + { + error = save_all(e_data, e_len, n_data, n_len, d_data, d_len, + sign_data, sign_len, path_and_file_name); + + if (error != 0) + { + g_writeln("error %d in key_gen, save_all", error); + } + } + + g_free(n_data); + g_free(d_data); + g_free(sign_data); + return error; } /*****************************************************************************/ @@ -328,146 +344,156 @@ key_gen(const char* path_and_file_name) static int APP_CC key_gen_run_it(void) { - int fd; - int index; - int rv; - struct list* names; - struct list* values; - char* name; - char* value; + int fd; + int index; + int rv; + struct list *names; + struct list *values; + char *name; + char *value; - if (!g_file_exist("/etc/xrdp/rsakeys.ini")) - { - return 1; - } - if (g_file_get_size("/etc/xrdp/rsakeys.ini") < 10) - { - return 1; - } - fd = g_file_open("/etc/xrdp/rsakeys.ini"); - if (fd < 0) - { - return 1; - } - rv = 0; - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - if (file_read_section(fd, "keys", names, values) == 0) - { - for (index = 0; index < names->count; index++) + if (!g_file_exist("/etc/xrdp/rsakeys.ini")) { - name = (char*)list_get_item(names, index); - value = (char*)list_get_item(values, index); - if (g_strcasecmp(name, "pub_sig") == 0) - { - if (g_strcasecmp(value, inst_pub_sig) == 0) - { - rv = 1; - } - } + return 1; } - } - else - { - g_writeln("error reading keys section of rsakeys.ini"); - } - list_delete(names); - list_delete(values); - g_file_close(fd); - return rv; + + if (g_file_get_size("/etc/xrdp/rsakeys.ini") < 10) + { + return 1; + } + + fd = g_file_open("/etc/xrdp/rsakeys.ini"); + + if (fd < 0) + { + return 1; + } + + rv = 0; + names = list_create(); + names->auto_free = 1; + values = list_create(); + values->auto_free = 1; + + if (file_read_section(fd, "keys", names, values) == 0) + { + for (index = 0; index < names->count; index++) + { + name = (char *)list_get_item(names, index); + value = (char *)list_get_item(values, index); + + if (g_strcasecmp(name, "pub_sig") == 0) + { + if (g_strcasecmp(value, inst_pub_sig) == 0) + { + rv = 1; + } + } + } + } + else + { + g_writeln("error reading keys section of rsakeys.ini"); + } + + list_delete(names); + list_delete(values); + g_file_close(fd); + return rv; } /*****************************************************************************/ static int APP_CC key_gen_auto(void) { - if (key_gen_run_it()) - { - return key_gen("/etc/xrdp/rsakeys.ini"); - } - g_writeln("xrdp-keygen does not need to run"); - return 0; + if (key_gen_run_it()) + { + return key_gen("/etc/xrdp/rsakeys.ini"); + } + + g_writeln("xrdp-keygen does not need to run"); + return 0; } /*****************************************************************************/ static int APP_CC key_test(void) { - char* md5_final; - char* sig; - void* md5; + char *md5_final; + char *sig; + void *md5; - md5_final = (char*)g_malloc(64, 0); - sig = (char*)g_malloc(64, 0); - md5 = ssl_md5_info_create(); - g_writeln("original key is:"); - g_hexdump((char*)g_testkey, 176); - g_writeln("original exponent is:"); - g_hexdump((char*)g_testkey + 32, 4); - g_writeln("original modulus is:"); - g_hexdump((char*)g_testkey + 36, 64); - g_writeln("original signature is:"); - g_hexdump((char*)g_testkey + 112, 64); - ssl_md5_clear(md5); - ssl_md5_transform(md5, (char*)g_testkey, 108); - g_memset(md5_final, 0xff, 64); - ssl_md5_complete(md5, md5_final); - g_writeln("md5 hash of first 108 bytes of this key is:"); - g_hexdump(md5_final, 16); - md5_final[16] = 0; - md5_final[62] = 1; - md5_final[63] = 0; - ssl_mod_exp(sig, 64, md5_final, 64, (char*)g_ppk_n, 64, (char*)g_ppk_d, 64); - g_writeln("produced signature(this should match original \ + md5_final = (char *)g_malloc(64, 0); + sig = (char *)g_malloc(64, 0); + md5 = ssl_md5_info_create(); + g_writeln("original key is:"); + g_hexdump((char *)g_testkey, 176); + g_writeln("original exponent is:"); + g_hexdump((char *)g_testkey + 32, 4); + g_writeln("original modulus is:"); + g_hexdump((char *)g_testkey + 36, 64); + g_writeln("original signature is:"); + g_hexdump((char *)g_testkey + 112, 64); + ssl_md5_clear(md5); + ssl_md5_transform(md5, (char *)g_testkey, 108); + g_memset(md5_final, 0xff, 64); + ssl_md5_complete(md5, md5_final); + g_writeln("md5 hash of first 108 bytes of this key is:"); + g_hexdump(md5_final, 16); + md5_final[16] = 0; + md5_final[62] = 1; + md5_final[63] = 0; + ssl_mod_exp(sig, 64, md5_final, 64, (char *)g_ppk_n, 64, (char *)g_ppk_d, 64); + g_writeln("produced signature(this should match original \ signature above) is:"); - g_hexdump(sig, 64); - g_memset(md5_final, 0, 64); - ssl_mod_exp(md5_final, 64, (char*)g_testkey + 112, 64, (char*)g_ppk_n, 64, - (char*)g_ppk_e, 4); - g_writeln("decrypted hash of first 108 bytes of this key is:"); - g_hexdump(md5_final, 64); - ssl_md5_info_delete(md5); - g_free(md5_final); - g_free(sig); - return 0; + g_hexdump(sig, 64); + g_memset(md5_final, 0, 64); + ssl_mod_exp(md5_final, 64, (char *)g_testkey + 112, 64, (char *)g_ppk_n, 64, + (char *)g_ppk_e, 4); + g_writeln("decrypted hash of first 108 bytes of this key is:"); + g_hexdump(md5_final, 64); + ssl_md5_info_delete(md5); + g_free(md5_final); + g_free(sig); + return 0; } /*****************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - if (argc > 1) - { - if (g_strcasecmp(argv[1], "xrdp") == 0) + if (argc > 1) { - if (argc > 2) - { - if (g_strcasecmp(argv[2], "auto") == 0) + if (g_strcasecmp(argv[1], "xrdp") == 0) { - if (g_getuid() != 0) - { - g_writeln("must run as root"); - return 0; - } - return key_gen_auto(); + if (argc > 2) + { + if (g_strcasecmp(argv[2], "auto") == 0) + { + if (g_getuid() != 0) + { + g_writeln("must run as root"); + return 0; + } + + return key_gen_auto(); + } + else + { + return key_gen(argv[2]); + } + } + else + { + return key_gen(0); + } } - else + else if (g_strcasecmp(argv[1], "test") == 0) { - return key_gen(argv[2]); + return key_test(); } - } - else - { - return key_gen(0); - } } - else if (g_strcasecmp(argv[1], "test") == 0) - { - return key_test(); - } - } - out_params(); - return 0; + + out_params(); + return 0; } diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 3f8307c2..a391b93b 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -1,672 +1,720 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - this is the interface to libxrdp - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * this is the interface to libxrdp + */ #include "libxrdp.h" /******************************************************************************/ -struct xrdp_session* EXPORT_CC -libxrdp_init(tbus id, struct trans* trans) +struct xrdp_session *EXPORT_CC +libxrdp_init(tbus id, struct trans *trans) { - struct xrdp_session* session; + struct xrdp_session *session; - session = (struct xrdp_session*)g_malloc(sizeof(struct xrdp_session), 1); - session->id = id; - session->rdp = xrdp_rdp_create(session, trans); - session->orders = xrdp_orders_create(session, (struct xrdp_rdp*)session->rdp); - session->client_info = &(((struct xrdp_rdp*)session->rdp)->client_info); - make_stream(session->s); - init_stream(session->s, 8192 * 2); - return session; + session = (struct xrdp_session *)g_malloc(sizeof(struct xrdp_session), 1); + session->id = id; + session->rdp = xrdp_rdp_create(session, trans); + session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp); + session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info); + make_stream(session->s); + init_stream(session->s, 8192 * 2); + return session; } /******************************************************************************/ int EXPORT_CC -libxrdp_exit(struct xrdp_session* session) +libxrdp_exit(struct xrdp_session *session) { - if (session == 0) - { + if (session == 0) + { + return 0; + } + + xrdp_orders_delete((struct xrdp_orders *)session->orders); + xrdp_rdp_delete((struct xrdp_rdp *)session->rdp); + free_stream(session->s); + g_free(session); return 0; - } - xrdp_orders_delete((struct xrdp_orders*)session->orders); - xrdp_rdp_delete((struct xrdp_rdp*)session->rdp); - free_stream(session->s); - g_free(session); - return 0; } /******************************************************************************/ int EXPORT_CC -libxrdp_disconnect(struct xrdp_session* session) +libxrdp_disconnect(struct xrdp_session *session) { - return xrdp_rdp_disconnect((struct xrdp_rdp*)session->rdp); + return xrdp_rdp_disconnect((struct xrdp_rdp *)session->rdp); } /******************************************************************************/ int EXPORT_CC -libxrdp_process_incomming(struct xrdp_session* session) +libxrdp_process_incomming(struct xrdp_session *session) { - return xrdp_rdp_incoming((struct xrdp_rdp*)session->rdp); + return xrdp_rdp_incoming((struct xrdp_rdp *)session->rdp); } /******************************************************************************/ int EXPORT_CC -libxrdp_process_data(struct xrdp_session* session) +libxrdp_process_data(struct xrdp_session *session) { - int cont; - int rv; - int code; - int term; - int dead_lock_counter; + int cont; + int rv; + int code; + int term; + int dead_lock_counter; - term = 0; - cont = 1; - rv = 0; - dead_lock_counter = 0; - while ((cont || !session->up_and_running) && !term) - { - if (session->is_term != 0) + term = 0; + cont = 1; + rv = 0; + dead_lock_counter = 0; + + while ((cont || !session->up_and_running) && !term) { - if (session->is_term()) - { - term = 1; - } - } - code = 0; - if (xrdp_rdp_recv((struct xrdp_rdp*)(session->rdp), - session->s, &code) != 0) - { - rv = 1; - break; - } - DEBUG(("libxrdp_process_data code %d", code)); - switch (code) - { - case -1: - xrdp_rdp_send_demand_active((struct xrdp_rdp*)session->rdp); - session->up_and_running = 0; - break; - case 0: - dead_lock_counter++; - break; - case RDP_PDU_CONFIRM_ACTIVE: /* 3 */ - xrdp_rdp_process_confirm_active((struct xrdp_rdp*)session->rdp, - session->s); - break; - case RDP_PDU_DATA: /* 7 */ - if (xrdp_rdp_process_data((struct xrdp_rdp*)session->rdp, - session->s) != 0) + if (session->is_term != 0) { - DEBUG(("libxrdp_process_data returned non zero")); - cont = 0; - term = 1; + if (session->is_term()) + { + term = 1; + } + } + + code = 0; + + if (xrdp_rdp_recv((struct xrdp_rdp *)(session->rdp), + session->s, &code) != 0) + { + rv = 1; + break; + } + + DEBUG(("libxrdp_process_data code %d", code)); + + switch (code) + { + case -1: + xrdp_rdp_send_demand_active((struct xrdp_rdp *)session->rdp); + session->up_and_running = 0; + break; + case 0: + dead_lock_counter++; + break; + case RDP_PDU_CONFIRM_ACTIVE: /* 3 */ + xrdp_rdp_process_confirm_active((struct xrdp_rdp *)session->rdp, + session->s); + break; + case RDP_PDU_DATA: /* 7 */ + + if (xrdp_rdp_process_data((struct xrdp_rdp *)session->rdp, + session->s) != 0) + { + DEBUG(("libxrdp_process_data returned non zero")); + cont = 0; + term = 1; + } + + break; + default: + g_writeln("unknown in libxrdp_process_data"); + dead_lock_counter++; + break; + } + + if (dead_lock_counter > 100000) + { + /*This situation can happen and this is a workaround*/ + cont = 0; + g_writeln("Serious programming error we were locked in a deadly loop") ; + g_writeln("remaining :%d", session->s->end - session->s->next_packet); + session->s->next_packet = 0; + } + + if (cont) + { + cont = (session->s->next_packet != 0) && + (session->s->next_packet < session->s->end); } - break; - default: - g_writeln("unknown in libxrdp_process_data"); - dead_lock_counter++; - break; } - if (dead_lock_counter > 100000) - { - /*This situation can happen and this is a workaround*/ - cont = 0; - g_writeln("Serious programming error we were locked in a deadly loop") ; - g_writeln("remaining :%d",session->s->end-session->s->next_packet); - session->s->next_packet = 0; - } - if (cont) - { - cont = (session->s->next_packet != 0) && - (session->s->next_packet < session->s->end); - } - } - return rv; + + return rv; } /******************************************************************************/ int EXPORT_CC -libxrdp_send_palette(struct xrdp_session* session, int* palette) +libxrdp_send_palette(struct xrdp_session *session, int *palette) { - int i = 0; - int color = 0; - struct stream* s = (struct stream *)NULL; + int i = 0; + int color = 0; + struct stream *s = (struct stream *)NULL; - if (session->client_info->bpp > 8) - { + if (session->client_info->bpp > 8) + { + return 0; + } + + DEBUG(("libxrdp_send_palette sending palette")); + /* clear orders */ + libxrdp_orders_force_send(session); + make_stream(s); + init_stream(s, 8192); + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_UPDATE_PALETTE); + out_uint16_le(s, 0); + out_uint16_le(s, 256); /* # of colors */ + out_uint16_le(s, 0); + + for (i = 0; i < 256; i++) + { + color = palette[i]; + out_uint8(s, color >> 16); + out_uint8(s, color >> 8); + out_uint8(s, color); + } + + s_mark_end(s); + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_UPDATE); + free_stream(s); + /* send the orders palette too */ + libxrdp_orders_init(session); + libxrdp_orders_send_palette(session, palette, 0); + libxrdp_orders_send(session); return 0; - } - DEBUG(("libxrdp_send_palette sending palette")); - /* clear orders */ - libxrdp_orders_force_send(session); - make_stream(s); - init_stream(s, 8192); - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_UPDATE_PALETTE); - out_uint16_le(s, 0); - out_uint16_le(s, 256); /* # of colors */ - out_uint16_le(s, 0); - for (i = 0; i < 256; i++) - { - color = palette[i]; - out_uint8(s, color >> 16); - out_uint8(s, color >> 8); - out_uint8(s, color); - } - s_mark_end(s); - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, RDP_DATA_PDU_UPDATE); - free_stream(s); - /* send the orders palette too */ - libxrdp_orders_init(session); - libxrdp_orders_send_palette(session, palette, 0); - libxrdp_orders_send(session); - return 0; } /******************************************************************************/ int EXPORT_CC -libxrdp_send_bell(struct xrdp_session* session) +libxrdp_send_bell(struct xrdp_session *session) { - struct stream* s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - DEBUG(("libxrdp_send_bell sending bell signal")); - /* see MS documentation: Server play sound PDU, TS_PLAY_SOUND_PDU_DATA */ + DEBUG(("libxrdp_send_bell sending bell signal")); + /* see MS documentation: Server play sound PDU, TS_PLAY_SOUND_PDU_DATA */ - make_stream(s); - init_stream(s, 8192); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint32_le(s, 440); /* frequency */ + out_uint32_le(s, 100); /* duration (ms) */ + s_mark_end(s); + + if (xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_PLAY_SOUND) != 0) + { + free_stream(s); + return 1; + } - if (xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s) != 0) - { free_stream(s); - return 1; - } - out_uint32_le(s, 440); /* frequency */ - out_uint32_le(s, 100); /* duration (ms) */ - s_mark_end(s); - if (xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, RDP_DATA_PDU_PLAY_SOUND) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ int EXPORT_CC -libxrdp_send_bitmap(struct xrdp_session* session, int width, int height, - int bpp, char* data, int x, int y, int cx, int cy) +libxrdp_send_bitmap(struct xrdp_session *session, int width, int height, + int bpp, char *data, int x, int y, int cx, int cy) { - int line_size = 0; - int i = 0; - int j = 0; - int total_lines = 0; - int lines_sending = 0; - int Bpp = 0; - int e = 0; - int bufsize = 0; - int total_bufsize = 0; - int num_updates = 0; - char* p_num_updates = (char *)NULL; - char* p = (char *)NULL; - char* q = (char *)NULL; - struct stream* s = (struct stream *)NULL; - struct stream* temp_s = (struct stream *)NULL; + int line_size = 0; + int i = 0; + int j = 0; + int total_lines = 0; + int lines_sending = 0; + int Bpp = 0; + int e = 0; + int bufsize = 0; + int total_bufsize = 0; + int num_updates = 0; + char *p_num_updates = (char *)NULL; + char *p = (char *)NULL; + char *q = (char *)NULL; + struct stream *s = (struct stream *)NULL; + struct stream *temp_s = (struct stream *)NULL; - DEBUG(("libxrdp_send_bitmap sending bitmap")); - Bpp = (bpp + 7) / 8; - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - line_size = width * Bpp; - make_stream(s); - init_stream(s, 8192); - if (session->client_info->use_bitmap_comp) - { - make_stream(temp_s); - init_stream(temp_s, 65536); - i = 0; - if (cy <= height) + DEBUG(("libxrdp_send_bitmap sending bitmap")); + Bpp = (bpp + 7) / 8; + e = width % 4; + + if (e != 0) { - i = cy; + e = 4 - e; } - while (i > 0) + + line_size = width * Bpp; + make_stream(s); + init_stream(s, 8192); + + if (session->client_info->use_bitmap_comp) { - total_bufsize = 0; - num_updates = 0; - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_UPDATE_BITMAP); - p_num_updates = s->p; - out_uint8s(s, 2); /* num_updates set later */ - do - { - if (session->client_info->op1) + make_stream(temp_s); + init_stream(temp_s, 65536); + i = 0; + + if (cy <= height) { - s_push_layer(s, channel_hdr, 18); + i = cy; } - else + + while (i > 0) { - s_push_layer(s, channel_hdr, 26); + total_bufsize = 0; + num_updates = 0; + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_UPDATE_BITMAP); + p_num_updates = s->p; + out_uint8s(s, 2); /* num_updates set later */ + + do + { + if (session->client_info->op1) + { + s_push_layer(s, channel_hdr, 18); + } + else + { + s_push_layer(s, channel_hdr, 26); + } + + p = s->p; + lines_sending = xrdp_bitmap_compress(data, width, height, + s, bpp, + 4096 - total_bufsize, + i - 1, temp_s, e); + + if (lines_sending == 0) + { + break; + } + + num_updates++; + bufsize = s->p - p; + total_bufsize += bufsize; + i = i - lines_sending; + s_mark_end(s); + s_pop_layer(s, channel_hdr); + out_uint16_le(s, x); /* left */ + out_uint16_le(s, y + i); /* top */ + out_uint16_le(s, (x + cx) - 1); /* right */ + out_uint16_le(s, (y + i + lines_sending) - 1); /* bottom */ + out_uint16_le(s, width + e); /* width */ + out_uint16_le(s, lines_sending); /* height */ + out_uint16_le(s, bpp); /* bpp */ + + if (session->client_info->op1) + { + out_uint16_le(s, 0x401); /* compress */ + out_uint16_le(s, bufsize); /* compressed size */ + j = (width + e) * Bpp; + j = j * lines_sending; + } + else + { + out_uint16_le(s, 0x1); /* compress */ + out_uint16_le(s, bufsize + 8); + out_uint8s(s, 2); /* pad */ + out_uint16_le(s, bufsize); /* compressed size */ + j = (width + e) * Bpp; + out_uint16_le(s, j); /* line size */ + j = j * lines_sending; + out_uint16_le(s, j); /* final size */ + } + + if (j > 32768) + { + g_writeln("error, decompressed size too big, its %d", j); + } + + if (bufsize > 8192) + { + g_writeln("error, compressed size too big, its %d", bufsize); + } + + s->p = s->end; + } + while (total_bufsize < 4096 && i > 0); + + p_num_updates[0] = num_updates; + p_num_updates[1] = num_updates >> 8; + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, + RDP_DATA_PDU_UPDATE); + + if (total_bufsize > 8192) + { + g_writeln("error, total compressed size too big, its %d", + total_bufsize); + } } - p = s->p; - lines_sending = xrdp_bitmap_compress(data, width, height, - s, bpp, - 4096 - total_bufsize, - i - 1, temp_s, e); - if (lines_sending == 0) - { - break; - } - num_updates++; - bufsize = s->p - p; - total_bufsize += bufsize; - i = i - lines_sending; - s_mark_end(s); - s_pop_layer(s, channel_hdr); - out_uint16_le(s, x); /* left */ - out_uint16_le(s, y + i); /* top */ - out_uint16_le(s, (x + cx) - 1); /* right */ - out_uint16_le(s, (y + i + lines_sending) - 1); /* bottom */ - out_uint16_le(s, width + e); /* width */ - out_uint16_le(s, lines_sending); /* height */ - out_uint16_le(s, bpp); /* bpp */ - if (session->client_info->op1) - { - out_uint16_le(s, 0x401); /* compress */ - out_uint16_le(s, bufsize); /* compressed size */ - j = (width + e) * Bpp; - j = j * lines_sending; - } - else - { - out_uint16_le(s, 0x1); /* compress */ - out_uint16_le(s, bufsize + 8); - out_uint8s(s, 2); /* pad */ - out_uint16_le(s, bufsize); /* compressed size */ - j = (width + e) * Bpp; - out_uint16_le(s, j); /* line size */ - j = j * lines_sending; - out_uint16_le(s, j); /* final size */ - } - if (j > 32768) - { - g_writeln("error, decompressed size too big, its %d", j); - } - if (bufsize > 8192) - { - g_writeln("error, compressed size too big, its %d", bufsize); - } - s->p = s->end; - } while (total_bufsize < 4096 && i > 0); - p_num_updates[0] = num_updates; - p_num_updates[1] = num_updates >> 8; - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, - RDP_DATA_PDU_UPDATE); - if (total_bufsize > 8192) - { - g_writeln("error, total compressed size too big, its %d", - total_bufsize); - } + + free_stream(temp_s); } - free_stream(temp_s); - } - else - { - total_lines = height; - i = 0; + else + { + total_lines = height; + i = 0; + p = data; + + if (line_size > 0 && total_lines > 0) + { + while (i < total_lines) + { + lines_sending = 4096 / (line_size + e * Bpp); + + if (i + lines_sending > total_lines) + { + lines_sending = total_lines - i; + } + + p = p + line_size * lines_sending; + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_UPDATE_BITMAP); + out_uint16_le(s, 1); /* num updates */ + out_uint16_le(s, x); + out_uint16_le(s, y + i); + out_uint16_le(s, (x + cx) - 1); + out_uint16_le(s, (y + i + lines_sending) - 1); + out_uint16_le(s, width + e); + out_uint16_le(s, lines_sending); + out_uint16_le(s, bpp); /* bpp */ + out_uint16_le(s, 0); /* compress */ + out_uint16_le(s, (line_size + e * Bpp) * lines_sending); /* bufsize */ + q = p; + + for (j = 0; j < lines_sending; j++) + { + q = q - line_size; + out_uint8a(s, q, line_size); /* B_ENDIAN doesn't work here, todo */ + out_uint8s(s, e * Bpp); + } + + s_mark_end(s); + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, + RDP_DATA_PDU_UPDATE); + i = i + lines_sending; + } + } + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_send_pointer(struct xrdp_session *session, int cache_idx, + char *data, char *mask, int x, int y) +{ + struct stream *s; + char *p; + int i; + int j; + + DEBUG(("libxrdp_send_pointer sending cursor")); + make_stream(s); + init_stream(s, 8192); + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_POINTER_COLOR); + out_uint16_le(s, 0); /* pad */ + out_uint16_le(s, cache_idx); /* cache_idx */ + out_uint16_le(s, x); + out_uint16_le(s, y); + out_uint16_le(s, 32); + out_uint16_le(s, 32); + out_uint16_le(s, 128); + out_uint16_le(s, 3072); p = data; - if (line_size > 0 && total_lines > 0) + + for (i = 0; i < 32; i++) { - while (i < total_lines) - { - lines_sending = 4096 / (line_size + e * Bpp); - if (i + lines_sending > total_lines) + for (j = 0; j < 32; j++) { - lines_sending = total_lines - i; + out_uint8(s, *p); + p++; + out_uint8(s, *p); + p++; + out_uint8(s, *p); + p++; } - p = p + line_size * lines_sending; - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_UPDATE_BITMAP); - out_uint16_le(s, 1); /* num updates */ - out_uint16_le(s, x); - out_uint16_le(s, y + i); - out_uint16_le(s, (x + cx) - 1); - out_uint16_le(s, (y + i + lines_sending) - 1); - out_uint16_le(s, width + e); - out_uint16_le(s, lines_sending); - out_uint16_le(s, bpp); /* bpp */ - out_uint16_le(s, 0); /* compress */ - out_uint16_le(s, (line_size + e * Bpp) * lines_sending); /* bufsize */ - q = p; - for (j = 0; j < lines_sending; j++) - { - q = q - line_size; - out_uint8a(s, q, line_size); /* B_ENDIAN doesn't work here, todo */ - out_uint8s(s, e * Bpp); - } - s_mark_end(s); - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, - RDP_DATA_PDU_UPDATE); - i = i + lines_sending; - } } - } - free_stream(s); - return 0; + + out_uint8a(s, mask, 128); /* mask */ + s_mark_end(s); + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_POINTER); + free_stream(s); + return 0; } /*****************************************************************************/ int EXPORT_CC -libxrdp_send_pointer(struct xrdp_session* session, int cache_idx, - char* data, char* mask, int x, int y) +libxrdp_set_pointer(struct xrdp_session *session, int cache_idx) { - struct stream* s; - char* p; - int i; - int j; + struct stream *s; - DEBUG(("libxrdp_send_pointer sending cursor")); - make_stream(s); - init_stream(s, 8192); - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_POINTER_COLOR); - out_uint16_le(s, 0); /* pad */ - out_uint16_le(s, cache_idx); /* cache_idx */ - out_uint16_le(s, x); - out_uint16_le(s, y); - out_uint16_le(s, 32); - out_uint16_le(s, 32); - out_uint16_le(s, 128); - out_uint16_le(s, 3072); - p = data; - for (i = 0; i < 32; i++) - { - for (j = 0; j < 32; j++) - { - out_uint8(s, *p); - p++; - out_uint8(s, *p); - p++; - out_uint8(s, *p); - p++; - } - } - out_uint8a(s, mask, 128); /* mask */ - s_mark_end(s); - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, RDP_DATA_PDU_POINTER); - free_stream(s); - return 0; -} - -/*****************************************************************************/ -int EXPORT_CC -libxrdp_set_pointer(struct xrdp_session* session, int cache_idx) -{ - struct stream* s; - - DEBUG(("libxrdp_set_pointer sending cursor index")); - make_stream(s); - init_stream(s, 8192); - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_POINTER_CACHED); - out_uint16_le(s, 0); /* pad */ - out_uint16_le(s, cache_idx); /* cache_idx */ - s_mark_end(s); - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, RDP_DATA_PDU_POINTER); - free_stream(s); - return 0; + DEBUG(("libxrdp_set_pointer sending cursor index")); + make_stream(s); + init_stream(s, 8192); + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_POINTER_CACHED); + out_uint16_le(s, 0); /* pad */ + out_uint16_le(s, cache_idx); /* cache_idx */ + s_mark_end(s); + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_POINTER); + free_stream(s); + return 0; } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_init(struct xrdp_session* session) +libxrdp_orders_init(struct xrdp_session *session) { - return xrdp_orders_init((struct xrdp_orders*)session->orders); + return xrdp_orders_init((struct xrdp_orders *)session->orders); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_send(struct xrdp_session* session) +libxrdp_orders_send(struct xrdp_session *session) { - return xrdp_orders_send((struct xrdp_orders*)session->orders); + return xrdp_orders_send((struct xrdp_orders *)session->orders); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_force_send(struct xrdp_session* session) +libxrdp_orders_force_send(struct xrdp_session *session) { - return xrdp_orders_force_send((struct xrdp_orders*)session->orders); + return xrdp_orders_force_send((struct xrdp_orders *)session->orders); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_rect(struct xrdp_session* session, int x, int y, - int cx, int cy, int color, struct xrdp_rect* rect) +libxrdp_orders_rect(struct xrdp_session *session, int x, int y, + int cx, int cy, int color, struct xrdp_rect *rect) { - return xrdp_orders_rect((struct xrdp_orders*)session->orders, - x, y, cx, cy, color, rect); + return xrdp_orders_rect((struct xrdp_orders *)session->orders, + x, y, cx, cy, color, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_screen_blt(struct xrdp_session* session, int x, int y, +libxrdp_orders_screen_blt(struct xrdp_session *session, int x, int y, int cx, int cy, int srcx, int srcy, - int rop, struct xrdp_rect* rect) + int rop, struct xrdp_rect *rect) { - return xrdp_orders_screen_blt((struct xrdp_orders*)session->orders, - x, y, cx, cy, srcx, srcy, rop, rect); + return xrdp_orders_screen_blt((struct xrdp_orders *)session->orders, + x, y, cx, cy, srcx, srcy, rop, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_pat_blt(struct xrdp_session* session, int x, int y, +libxrdp_orders_pat_blt(struct xrdp_session *session, int x, int y, int cx, int cy, int rop, int bg_color, - int fg_color, struct xrdp_brush* brush, - struct xrdp_rect* rect) + int fg_color, struct xrdp_brush *brush, + struct xrdp_rect *rect) { - return xrdp_orders_pat_blt((struct xrdp_orders*)session->orders, - x, y, cx, cy, rop, bg_color, fg_color, - brush, rect); + return xrdp_orders_pat_blt((struct xrdp_orders *)session->orders, + x, y, cx, cy, rop, bg_color, fg_color, + brush, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_dest_blt(struct xrdp_session* session, int x, int y, +libxrdp_orders_dest_blt(struct xrdp_session *session, int x, int y, int cx, int cy, int rop, - struct xrdp_rect* rect) + struct xrdp_rect *rect) { - return xrdp_orders_dest_blt((struct xrdp_orders*)session->orders, - x, y, cx, cy, rop, rect); + return xrdp_orders_dest_blt((struct xrdp_orders *)session->orders, + x, y, cx, cy, rop, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_line(struct xrdp_session* session, int mix_mode, +libxrdp_orders_line(struct xrdp_session *session, int mix_mode, int startx, int starty, int endx, int endy, int rop, int bg_color, - struct xrdp_pen* pen, - struct xrdp_rect* rect) + struct xrdp_pen *pen, + struct xrdp_rect *rect) { - return xrdp_orders_line((struct xrdp_orders*)session->orders, - mix_mode, startx, starty, endx, endy, - rop, bg_color, pen, rect); + return xrdp_orders_line((struct xrdp_orders *)session->orders, + mix_mode, startx, starty, endx, endy, + rop, bg_color, pen, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_mem_blt(struct xrdp_session* session, int cache_id, +libxrdp_orders_mem_blt(struct xrdp_session *session, int cache_id, int color_table, int x, int y, int cx, int cy, int rop, int srcx, int srcy, - int cache_idx, struct xrdp_rect* rect) + int cache_idx, struct xrdp_rect *rect) { - return xrdp_orders_mem_blt((struct xrdp_orders*)session->orders, - cache_id, color_table, x, y, cx, cy, rop, - srcx, srcy, cache_idx, rect); + return xrdp_orders_mem_blt((struct xrdp_orders *)session->orders, + cache_id, color_table, x, y, cx, cy, rop, + srcx, srcy, cache_idx, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_text(struct xrdp_session* session, +libxrdp_orders_text(struct xrdp_session *session, int font, int flags, int mixmode, int fg_color, int bg_color, int clip_left, int clip_top, int clip_right, int clip_bottom, int box_left, int box_top, int box_right, int box_bottom, - int x, int y, char* data, int data_len, - struct xrdp_rect* rect) + int x, int y, char *data, int data_len, + struct xrdp_rect *rect) { - return xrdp_orders_text((struct xrdp_orders*)session->orders, - font, flags, mixmode, fg_color, bg_color, - clip_left, clip_top, clip_right, clip_bottom, - box_left, box_top, box_right, box_bottom, - x, y, data, data_len, rect); + return xrdp_orders_text((struct xrdp_orders *)session->orders, + font, flags, mixmode, fg_color, bg_color, + clip_left, clip_top, clip_right, clip_bottom, + box_left, box_top, box_right, box_bottom, + x, y, data, data_len, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_send_palette(struct xrdp_session* session, int* palette, +libxrdp_orders_send_palette(struct xrdp_session *session, int *palette, int cache_id) { - return xrdp_orders_send_palette((struct xrdp_orders*)session->orders, - palette, cache_id); + return xrdp_orders_send_palette((struct xrdp_orders *)session->orders, + palette, cache_id); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_raw_bitmap(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_raw_bitmap(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - return xrdp_orders_send_raw_bitmap((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx); + return xrdp_orders_send_raw_bitmap((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_bitmap(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_bitmap(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - return xrdp_orders_send_bitmap((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx); + return xrdp_orders_send_bitmap((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_font(struct xrdp_session* session, - struct xrdp_font_char* font_char, +libxrdp_orders_send_font(struct xrdp_session *session, + struct xrdp_font_char *font_char, int font_index, int char_index) { - return xrdp_orders_send_font((struct xrdp_orders*)session->orders, - font_char, font_index, char_index); + return xrdp_orders_send_font((struct xrdp_orders *)session->orders, + font_char, font_index, char_index); } /*****************************************************************************/ int EXPORT_CC -libxrdp_reset(struct xrdp_session* session, +libxrdp_reset(struct xrdp_session *session, int width, int height, int bpp) { - if (session->client_info != 0) - { - /* older client can't resize */ - if (session->client_info->build <= 419) + if (session->client_info != 0) { - return 0; + /* older client can't resize */ + if (session->client_info->build <= 419) + { + return 0; + } + + /* if same, don't need to do anything */ + if (session->client_info->width == width && + session->client_info->height == height && + session->client_info->bpp == bpp) + { + return 0; + } + + session->client_info->width = width; + session->client_info->height = height; + session->client_info->bpp = bpp; } - /* if same, don't need to do anything */ - if (session->client_info->width == width && - session->client_info->height == height && - session->client_info->bpp == bpp) + else { - return 0; + return 1; } - session->client_info->width = width; - session->client_info->height = height; - session->client_info->bpp = bpp; - } - else - { - return 1; - } - /* this will send any lingering orders */ - if (xrdp_orders_reset((struct xrdp_orders*)session->orders) != 0) - { - return 1; - } - /* shut down the rdp client */ - if (xrdp_rdp_send_deactive((struct xrdp_rdp*)session->rdp) != 0) - { - return 1; - } - /* this should do the resizing */ - if (xrdp_rdp_send_demand_active((struct xrdp_rdp*)session->rdp) != 0) - { - return 1; - } - /* process till up and running */ - session->up_and_running = 0; - if (libxrdp_process_data(session) != 0) - { - g_writeln("non handled error from libxrdp_process_data"); - } - return 0; + + /* this will send any lingering orders */ + if (xrdp_orders_reset((struct xrdp_orders *)session->orders) != 0) + { + return 1; + } + + /* shut down the rdp client */ + if (xrdp_rdp_send_deactive((struct xrdp_rdp *)session->rdp) != 0) + { + return 1; + } + + /* this should do the resizing */ + if (xrdp_rdp_send_demand_active((struct xrdp_rdp *)session->rdp) != 0) + { + return 1; + } + + /* process till up and running */ + session->up_and_running = 0; + + if (libxrdp_process_data(session) != 0) + { + g_writeln("non handled error from libxrdp_process_data"); + } + + return 0; } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_raw_bitmap2(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_raw_bitmap2(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - return xrdp_orders_send_raw_bitmap2((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx); + return xrdp_orders_send_raw_bitmap2((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_bitmap2(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_bitmap2(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx, int hints) { - return xrdp_orders_send_bitmap2((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx, hints); + return xrdp_orders_send_bitmap2((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx, hints); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_bitmap3(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_bitmap3(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx, int hints) { - return xrdp_orders_send_bitmap3((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx, hints); + return xrdp_orders_send_bitmap3((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx, hints); } /*****************************************************************************/ @@ -675,226 +723,243 @@ libxrdp_orders_send_bitmap3(struct xrdp_session* session, based. either channel_name or channel_flags can be passed in nil if they are not needed */ int EXPORT_CC -libxrdp_query_channel(struct xrdp_session* session, int index, - char* channel_name, int* channel_flags) +libxrdp_query_channel(struct xrdp_session *session, int index, + char *channel_name, int *channel_flags) { - int count = 0; - struct xrdp_rdp* rdp = (struct xrdp_rdp *)NULL; - struct xrdp_mcs* mcs = (struct xrdp_mcs *)NULL; - struct mcs_channel_item* channel_item = (struct mcs_channel_item *)NULL; + int count = 0; + struct xrdp_rdp *rdp = (struct xrdp_rdp *)NULL; + struct xrdp_mcs *mcs = (struct xrdp_mcs *)NULL; + struct mcs_channel_item *channel_item = (struct mcs_channel_item *)NULL; - rdp = (struct xrdp_rdp*)session->rdp; - mcs = rdp->sec_layer->mcs_layer; - if (mcs->channel_list == NULL) - { - g_writeln("libxrdp_query_channel - No channel initialized"); - return 1 ; - } - count = mcs->channel_list->count; - if (index < 0 || index >= count) - { - return 1; - } - channel_item = (struct mcs_channel_item*) - list_get_item(mcs->channel_list, index); - if (channel_item == 0) - { - /* this should not happen */ - g_writeln("libxrdp_query_channel - channel item is 0"); - return 1; - } - if (channel_name != 0) - { - g_strncpy(channel_name, channel_item->name, 8); - } - if (channel_flags != 0) - { - *channel_flags = channel_item->flags; - } - return 0; + rdp = (struct xrdp_rdp *)session->rdp; + mcs = rdp->sec_layer->mcs_layer; + + if (mcs->channel_list == NULL) + { + g_writeln("libxrdp_query_channel - No channel initialized"); + return 1 ; + } + + count = mcs->channel_list->count; + + if (index < 0 || index >= count) + { + return 1; + } + + channel_item = (struct mcs_channel_item *) + list_get_item(mcs->channel_list, index); + + if (channel_item == 0) + { + /* this should not happen */ + g_writeln("libxrdp_query_channel - channel item is 0"); + return 1; + } + + if (channel_name != 0) + { + g_strncpy(channel_name, channel_item->name, 8); + } + + if (channel_flags != 0) + { + *channel_flags = channel_item->flags; + } + + return 0; } /*****************************************************************************/ /* returns a zero based index of the channel, -1 if error or it dosen't exist */ int EXPORT_CC -libxrdp_get_channel_id(struct xrdp_session* session, char* name) +libxrdp_get_channel_id(struct xrdp_session *session, char *name) { - int index = 0; - int count = 0; - struct xrdp_rdp* rdp = NULL; - struct xrdp_mcs* mcs = NULL; - struct mcs_channel_item* channel_item = NULL; + int index = 0; + int count = 0; + struct xrdp_rdp *rdp = NULL; + struct xrdp_mcs *mcs = NULL; + struct mcs_channel_item *channel_item = NULL; - rdp = (struct xrdp_rdp*)session->rdp; - mcs = rdp->sec_layer->mcs_layer; - if (mcs->channel_list == NULL) - { - g_writeln("libxrdp_get_channel_id No channel initialized"); - return -1 ; - } - count = mcs->channel_list->count; - for (index = 0; index < count; index++) - { - channel_item = (struct mcs_channel_item*) - list_get_item(mcs->channel_list, index); - if (channel_item != 0) + rdp = (struct xrdp_rdp *)session->rdp; + mcs = rdp->sec_layer->mcs_layer; + + if (mcs->channel_list == NULL) { - if (g_strcasecmp(name, channel_item->name) == 0) - { - return index; - } + g_writeln("libxrdp_get_channel_id No channel initialized"); + return -1 ; } - } - return -1; + + count = mcs->channel_list->count; + + for (index = 0; index < count; index++) + { + channel_item = (struct mcs_channel_item *) + list_get_item(mcs->channel_list, index); + + if (channel_item != 0) + { + if (g_strcasecmp(name, channel_item->name) == 0) + { + return index; + } + } + } + + return -1; } /*****************************************************************************/ int EXPORT_CC -libxrdp_send_to_channel(struct xrdp_session* session, int channel_id, - char* data, int data_len, +libxrdp_send_to_channel(struct xrdp_session *session, int channel_id, + char *data, int data_len, int total_data_len, int flags) { - struct xrdp_rdp* rdp = NULL; - struct xrdp_sec* sec = NULL; - struct xrdp_channel* chan = NULL; - struct stream* s = NULL; + struct xrdp_rdp *rdp = NULL; + struct xrdp_sec *sec = NULL; + struct xrdp_channel *chan = NULL; + struct stream *s = NULL; + + rdp = (struct xrdp_rdp *)session->rdp; + sec = rdp->sec_layer; + chan = sec->chan_layer; + make_stream(s); + init_stream(s, data_len + 1024); /* this should be big enough */ + + if (xrdp_channel_init(chan, s) != 0) + { + free_stream(s); + return 1; + } + + /* here we make a copy of the data */ + out_uint8a(s, data, data_len); + s_mark_end(s); + + if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0) + { + g_writeln("Debug - data NOT sent to channel"); + free_stream(s); + return 1; + } - rdp = (struct xrdp_rdp*)session->rdp; - sec = rdp->sec_layer; - chan = sec->chan_layer; - make_stream(s); - init_stream(s, data_len + 1024); /* this should be big enough */ - if (xrdp_channel_init(chan, s) != 0) - { free_stream(s); - return 1; - } - /* here we make a copy of the data */ - out_uint8a(s, data, data_len); - s_mark_end(s); - if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0) - { - g_writeln("Debug - data NOT sent to channel"); - free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_brush(struct xrdp_session* session, +libxrdp_orders_send_brush(struct xrdp_session *session, int width, int height, int bpp, int type, - int size, char* data, int cache_id) + int size, char *data, int cache_id) { - return xrdp_orders_send_brush((struct xrdp_orders*)session->orders, - width, height, bpp, type, size, data, - cache_id); + return xrdp_orders_send_brush((struct xrdp_orders *)session->orders, + width, height, bpp, type, size, data, + cache_id); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id, +libxrdp_orders_send_create_os_surface(struct xrdp_session *session, int id, int width, int height, - struct list* del_list) + struct list *del_list) { - return xrdp_orders_send_create_os_surface - ((struct xrdp_orders*)(session->orders), id, - width, height, del_list); + return xrdp_orders_send_create_os_surface + ((struct xrdp_orders *)(session->orders), id, + width, height, del_list); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id) +libxrdp_orders_send_switch_os_surface(struct xrdp_session *session, int id) { - return xrdp_orders_send_switch_os_surface - ((struct xrdp_orders*)(session->orders), id); + return xrdp_orders_send_switch_os_surface + ((struct xrdp_orders *)(session->orders), id); } /*****************************************************************************/ int EXPORT_CC -libxrdp_window_new_update(struct xrdp_session* session, int window_id, - struct rail_window_state_order* window_state, +libxrdp_window_new_update(struct xrdp_session *session, int window_id, + struct rail_window_state_order *window_state, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_window_new_update(orders, window_id, - window_state, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_window_new_update(orders, window_id, + window_state, flags); } /*****************************************************************************/ int EXPORT_CC -libxrdp_window_delete(struct xrdp_session* session, int window_id) +libxrdp_window_delete(struct xrdp_session *session, int window_id) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_window_delete(orders, window_id); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_window_delete(orders, window_id); } /*****************************************************************************/ int EXPORT_CC -libxrdp_window_icon(struct xrdp_session* session, int window_id, +libxrdp_window_icon(struct xrdp_session *session, int window_id, int cache_entry, int cache_id, - struct rail_icon_info* icon_info, int flags) + struct rail_icon_info *icon_info, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_window_icon(orders, window_id, cache_entry, - cache_id, icon_info, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_window_icon(orders, window_id, cache_entry, + cache_id, icon_info, flags); } /*****************************************************************************/ int EXPORT_CC -libxrdp_window_cached_icon(struct xrdp_session* session, int window_id, +libxrdp_window_cached_icon(struct xrdp_session *session, int window_id, int cache_entry, int cache_id, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_window_cached_icon(orders, window_id, cache_entry, - cache_id, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_window_cached_icon(orders, window_id, cache_entry, + cache_id, flags); } /*****************************************************************************/ int EXPORT_CC -libxrdp_notify_new_update(struct xrdp_session* session, +libxrdp_notify_new_update(struct xrdp_session *session, int window_id, int notify_id, - struct rail_notify_state_order* notify_state, + struct rail_notify_state_order *notify_state, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_notify_new_update(orders, window_id, notify_id, - notify_state, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_notify_new_update(orders, window_id, notify_id, + notify_state, flags); } /*****************************************************************************/ int DEFAULT_CC -libxrdp_notify_delete(struct xrdp_session* session, +libxrdp_notify_delete(struct xrdp_session *session, int window_id, int notify_id) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_notify_delete(orders, window_id, notify_id); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_notify_delete(orders, window_id, notify_id); } /*****************************************************************************/ int DEFAULT_CC -libxrdp_monitored_desktop(struct xrdp_session* session, - struct rail_monitored_desktop_order* mdo, +libxrdp_monitored_desktop(struct xrdp_session *session, + struct rail_monitored_desktop_order *mdo, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_monitored_desktop(orders, mdo, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_monitored_desktop(orders, mdo, flags); } diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index b066db95..34924715 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - libxrdp header - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2010 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * libxrdp header + */ #if !defined(LIBXRDP_H) #define LIBXRDP_H diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index 4f3504e6..ebfc348c 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - header file for use with libxrdp.so / xrdp.dll - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2010 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * header file for use with libxrdp.so / xrdp.dll + */ #ifndef LIBXRDPINC_H #define LIBXRDPINC_H diff --git a/libxrdp/xrdp_bitmap_compress.c b/libxrdp/xrdp_bitmap_compress.c index fcaab1f7..87538450 100644 --- a/libxrdp/xrdp_bitmap_compress.c +++ b/libxrdp/xrdp_bitmap_compress.c @@ -1,1474 +1,1570 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - bitmap compressor - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * bitmap compressor + */ #include "libxrdp.h" /*****************************************************************************/ #define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ -{ \ - if (in_ptr == 0) \ - { \ - in_pixel = 0; \ - } \ - else if (in_x < in_w) \ - { \ - in_pixel = GETPIXEL8(in_ptr, in_x, in_y, in_w); \ - } \ - else \ - { \ - in_pixel = in_last_pixel; \ - } \ -} + { \ + if (in_ptr == 0) \ + { \ + in_pixel = 0; \ + } \ + else if (in_x < in_w) \ + { \ + in_pixel = GETPIXEL8(in_ptr, in_x, in_y, in_w); \ + } \ + else \ + { \ + in_pixel = in_last_pixel; \ + } \ + } /*****************************************************************************/ #define IN_PIXEL16(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ -{ \ - if (in_ptr == 0) \ - { \ - in_pixel = 0; \ - } \ - else if (in_x < in_w) \ - { \ - in_pixel = GETPIXEL16(in_ptr, in_x, in_y, in_w); \ - } \ - else \ - { \ - in_pixel = in_last_pixel; \ - } \ -} + { \ + if (in_ptr == 0) \ + { \ + in_pixel = 0; \ + } \ + else if (in_x < in_w) \ + { \ + in_pixel = GETPIXEL16(in_ptr, in_x, in_y, in_w); \ + } \ + else \ + { \ + in_pixel = in_last_pixel; \ + } \ + } /*****************************************************************************/ #define IN_PIXEL32(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ -{ \ - if (in_ptr == 0) \ - { \ - in_pixel = 0; \ - } \ - else if (in_x < in_w) \ - { \ - in_pixel = GETPIXEL32(in_ptr, in_x, in_y, in_w); \ - } \ - else \ - { \ - in_pixel = in_last_pixel; \ - } \ -} + { \ + if (in_ptr == 0) \ + { \ + in_pixel = 0; \ + } \ + else if (in_x < in_w) \ + { \ + in_pixel = GETPIXEL32(in_ptr, in_x, in_y, in_w); \ + } \ + else \ + { \ + in_pixel = in_last_pixel; \ + } \ + } /*****************************************************************************/ /* color */ #define OUT_COLOR_COUNT1(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x3 << 5) | in_count; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_data); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x60); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_data); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf3); \ - out_uint16_le(in_s, in_count); \ - out_uint8(in_s, in_data); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x3 << 5) | in_count; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_data); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x60); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_data); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf3); \ + out_uint16_le(in_s, in_count); \ + out_uint8(in_s, in_data); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* color */ #define OUT_COLOR_COUNT2(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x3 << 5) | in_count; \ - out_uint8(in_s, temp); \ - out_uint16_le(in_s, in_data); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x60); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - out_uint16_le(in_s, in_data); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf3); \ - out_uint16_le(in_s, in_count); \ - out_uint16_le(in_s, in_data); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x3 << 5) | in_count; \ + out_uint8(in_s, temp); \ + out_uint16_le(in_s, in_data); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x60); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + out_uint16_le(in_s, in_data); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf3); \ + out_uint16_le(in_s, in_count); \ + out_uint16_le(in_s, in_data); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* color */ #define OUT_COLOR_COUNT3(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x3 << 5) | in_count; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_data & 0xff); \ - out_uint8(in_s, (in_data >> 8) & 0xff); \ - out_uint8(in_s, (in_data >> 16) & 0xff); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x60); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_data & 0xff); \ - out_uint8(in_s, (in_data >> 8) & 0xff); \ - out_uint8(in_s, (in_data >> 16) & 0xff); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf3); \ - out_uint16_le(in_s, in_count); \ - out_uint8(in_s, in_data & 0xff); \ - out_uint8(in_s, (in_data >> 8) & 0xff); \ - out_uint8(in_s, (in_data >> 16) & 0xff); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x3 << 5) | in_count; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_data & 0xff); \ + out_uint8(in_s, (in_data >> 8) & 0xff); \ + out_uint8(in_s, (in_data >> 16) & 0xff); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x60); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_data & 0xff); \ + out_uint8(in_s, (in_data >> 8) & 0xff); \ + out_uint8(in_s, (in_data >> 16) & 0xff); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf3); \ + out_uint16_le(in_s, in_count); \ + out_uint8(in_s, in_data & 0xff); \ + out_uint8(in_s, (in_data >> 8) & 0xff); \ + out_uint8(in_s, (in_data >> 16) & 0xff); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* copy */ #define OUT_COPY_COUNT1(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x4 << 5) | in_count; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_data->data, in_count); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x80); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_data->data, in_count); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf4); \ - out_uint16_le(in_s, in_count); \ - out_uint8a(in_s, in_data->data, in_count); \ - } \ - } \ - in_count = 0; \ - init_stream(in_data, 0); \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x4 << 5) | in_count; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_data->data, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x80); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_data->data, in_count); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf4); \ + out_uint16_le(in_s, in_count); \ + out_uint8a(in_s, in_data->data, in_count); \ + } \ + } \ + in_count = 0; \ + init_stream(in_data, 0); \ + } /*****************************************************************************/ /* copy */ #define OUT_COPY_COUNT2(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x4 << 5) | in_count; \ - out_uint8(in_s, temp); \ - temp = in_count * 2; \ - out_uint8a(in_s, in_data->data, temp); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x80); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - temp = in_count * 2; \ - out_uint8a(in_s, in_data->data, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf4); \ - out_uint16_le(in_s, in_count); \ - temp = in_count * 2; \ - out_uint8a(in_s, in_data->data, temp); \ - } \ - } \ - in_count = 0; \ - init_stream(in_data, 0); \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x4 << 5) | in_count; \ + out_uint8(in_s, temp); \ + temp = in_count * 2; \ + out_uint8a(in_s, in_data->data, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x80); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + temp = in_count * 2; \ + out_uint8a(in_s, in_data->data, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf4); \ + out_uint16_le(in_s, in_count); \ + temp = in_count * 2; \ + out_uint8a(in_s, in_data->data, temp); \ + } \ + } \ + in_count = 0; \ + init_stream(in_data, 0); \ + } /*****************************************************************************/ /* copy */ #define OUT_COPY_COUNT3(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x4 << 5) | in_count; \ - out_uint8(in_s, temp); \ - temp = in_count * 3; \ - out_uint8a(in_s, in_data->end, temp); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x80); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - temp = in_count * 3; \ - out_uint8a(in_s, in_data->end, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf4); \ - out_uint16_le(in_s, in_count); \ - temp = in_count * 3; \ - out_uint8a(in_s, in_data->end, temp); \ - } \ - } \ - in_count = 0; \ - init_stream(in_data, 0); \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x4 << 5) | in_count; \ + out_uint8(in_s, temp); \ + temp = in_count * 3; \ + out_uint8a(in_s, in_data->end, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x80); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + temp = in_count * 3; \ + out_uint8a(in_s, in_data->end, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf4); \ + out_uint16_le(in_s, in_count); \ + temp = in_count * 3; \ + out_uint8a(in_s, in_data->end, temp); \ + } \ + } \ + in_count = 0; \ + init_stream(in_data, 0); \ + } /*****************************************************************************/ /* bicolor */ #define OUT_BICOLOR_COUNT1(in_count, in_s, in_color1, in_color2) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count / 2 < 16) \ { \ - temp = (0xe << 4) | (in_count / 2); \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_color1); \ - out_uint8(in_s, in_color2); \ - } \ - else if (in_count / 2 < 256 + 16) \ - { \ - out_uint8(in_s, 0xe0); \ - temp = in_count / 2 - 16; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_color1); \ - out_uint8(in_s, in_color2); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf8); \ - temp = in_count / 2; \ - out_uint16_le(in_s, temp); \ - out_uint8(in_s, in_color1); \ - out_uint8(in_s, in_color2); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count / 2 < 16) \ + { \ + temp = (0xe << 4) | (in_count / 2); \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_color1); \ + out_uint8(in_s, in_color2); \ + } \ + else if (in_count / 2 < 256 + 16) \ + { \ + out_uint8(in_s, 0xe0); \ + temp = in_count / 2 - 16; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_color1); \ + out_uint8(in_s, in_color2); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf8); \ + temp = in_count / 2; \ + out_uint16_le(in_s, temp); \ + out_uint8(in_s, in_color1); \ + out_uint8(in_s, in_color2); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* bicolor */ #define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count / 2 < 16) \ { \ - temp = (0xe << 4) | (in_count / 2); \ - out_uint8(in_s, temp); \ - out_uint16_le(in_s, in_color1); \ - out_uint16_le(in_s, in_color2); \ - } \ - else if (in_count / 2 < 256 + 16) \ - { \ - out_uint8(in_s, 0xe0); \ - temp = in_count / 2 - 16; \ - out_uint8(in_s, temp); \ - out_uint16_le(in_s, in_color1); \ - out_uint16_le(in_s, in_color2); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf8); \ - temp = in_count / 2; \ - out_uint16_le(in_s, temp); \ - out_uint16_le(in_s, in_color1); \ - out_uint16_le(in_s, in_color2); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count / 2 < 16) \ + { \ + temp = (0xe << 4) | (in_count / 2); \ + out_uint8(in_s, temp); \ + out_uint16_le(in_s, in_color1); \ + out_uint16_le(in_s, in_color2); \ + } \ + else if (in_count / 2 < 256 + 16) \ + { \ + out_uint8(in_s, 0xe0); \ + temp = in_count / 2 - 16; \ + out_uint8(in_s, temp); \ + out_uint16_le(in_s, in_color1); \ + out_uint16_le(in_s, in_color2); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf8); \ + temp = in_count / 2; \ + out_uint16_le(in_s, temp); \ + out_uint16_le(in_s, in_color1); \ + out_uint16_le(in_s, in_color2); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* bicolor */ #define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count / 2 < 16) \ { \ - temp = (0xe << 4) | (in_count / 2); \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_color1 & 0xff); \ - out_uint8(in_s, (in_color1 >> 8) & 0xff); \ - out_uint8(in_s, (in_color1 >> 16) & 0xff); \ - out_uint8(in_s, in_color2 & 0xff); \ - out_uint8(in_s, (in_color2 >> 8) & 0xff); \ - out_uint8(in_s, (in_color2 >> 16) & 0xff); \ - } \ - else if (in_count / 2 < 256 + 16) \ - { \ - out_uint8(in_s, 0xe0); \ - temp = in_count / 2 - 16; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_color1 & 0xff); \ - out_uint8(in_s, (in_color1 >> 8) & 0xff); \ - out_uint8(in_s, (in_color1 >> 16) & 0xff); \ - out_uint8(in_s, in_color2 & 0xff); \ - out_uint8(in_s, (in_color2 >> 8) & 0xff); \ - out_uint8(in_s, (in_color2 >> 16) & 0xff); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf8); \ - temp = in_count / 2; \ - out_uint16_le(in_s, temp); \ - out_uint8(in_s, in_color1 & 0xff); \ - out_uint8(in_s, (in_color1 >> 8) & 0xff); \ - out_uint8(in_s, (in_color1 >> 16) & 0xff); \ - out_uint8(in_s, in_color2 & 0xff); \ - out_uint8(in_s, (in_color2 >> 8) & 0xff); \ - out_uint8(in_s, (in_color2 >> 16) & 0xff); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count / 2 < 16) \ + { \ + temp = (0xe << 4) | (in_count / 2); \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_color1 & 0xff); \ + out_uint8(in_s, (in_color1 >> 8) & 0xff); \ + out_uint8(in_s, (in_color1 >> 16) & 0xff); \ + out_uint8(in_s, in_color2 & 0xff); \ + out_uint8(in_s, (in_color2 >> 8) & 0xff); \ + out_uint8(in_s, (in_color2 >> 16) & 0xff); \ + } \ + else if (in_count / 2 < 256 + 16) \ + { \ + out_uint8(in_s, 0xe0); \ + temp = in_count / 2 - 16; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_color1 & 0xff); \ + out_uint8(in_s, (in_color1 >> 8) & 0xff); \ + out_uint8(in_s, (in_color1 >> 16) & 0xff); \ + out_uint8(in_s, in_color2 & 0xff); \ + out_uint8(in_s, (in_color2 >> 8) & 0xff); \ + out_uint8(in_s, (in_color2 >> 16) & 0xff); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf8); \ + temp = in_count / 2; \ + out_uint16_le(in_s, temp); \ + out_uint8(in_s, in_color1 & 0xff); \ + out_uint8(in_s, (in_color1 >> 8) & 0xff); \ + out_uint8(in_s, (in_color1 >> 16) & 0xff); \ + out_uint8(in_s, in_color2 & 0xff); \ + out_uint8(in_s, (in_color2 >> 8) & 0xff); \ + out_uint8(in_s, (in_color2 >> 16) & 0xff); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fill */ #define OUT_FILL_COUNT1(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - out_uint8(in_s, in_count); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x0); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf0); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + out_uint8(in_s, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x0); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf0); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fill */ #define OUT_FILL_COUNT2(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - out_uint8(in_s, in_count); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x0); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf0); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + out_uint8(in_s, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x0); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf0); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fill */ #define OUT_FILL_COUNT3(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - out_uint8(in_s, in_count); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x0); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf0); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + out_uint8(in_s, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x0); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf0); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* mix */ #define OUT_MIX_COUNT1(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x1 << 5) | in_count; \ - out_uint8(in_s, temp); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x20); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf1); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x1 << 5) | in_count; \ + out_uint8(in_s, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x20); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf1); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* mix */ #define OUT_MIX_COUNT2(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x1 << 5) | in_count; \ - out_uint8(in_s, temp); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x20); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf1); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x1 << 5) | in_count; \ + out_uint8(in_s, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x20); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf1); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* mix */ #define OUT_MIX_COUNT3(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x1 << 5) | in_count; \ - out_uint8(in_s, temp); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x20); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf1); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x1 << 5) | in_count; \ + out_uint8(in_s, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x20); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf1); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fom */ #define OUT_FOM_COUNT1(in_count, in_s, in_mask, in_mask_len) \ -{ \ - if (in_count > 0) \ - { \ - if ((in_count % 8) == 0 && in_count < 249) \ { \ - temp = (0x2 << 5) | (in_count / 8); \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else if (in_count < 256) \ - { \ - out_uint8(in_s, 0x40); \ - temp = in_count - 1; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf2); \ - out_uint16_le(in_s, in_count); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if ((in_count % 8) == 0 && in_count < 249) \ + { \ + temp = (0x2 << 5) | (in_count / 8); \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else if (in_count < 256) \ + { \ + out_uint8(in_s, 0x40); \ + temp = in_count - 1; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf2); \ + out_uint16_le(in_s, in_count); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fom */ #define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \ -{ \ - if (in_count > 0) \ - { \ - if ((in_count % 8) == 0 && in_count < 249) \ { \ - temp = (0x2 << 5) | (in_count / 8); \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else if (in_count < 256) \ - { \ - out_uint8(in_s, 0x40); \ - temp = in_count - 1; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf2); \ - out_uint16_le(in_s, in_count); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if ((in_count % 8) == 0 && in_count < 249) \ + { \ + temp = (0x2 << 5) | (in_count / 8); \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else if (in_count < 256) \ + { \ + out_uint8(in_s, 0x40); \ + temp = in_count - 1; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf2); \ + out_uint16_le(in_s, in_count); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fill or mix (fom) */ #define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \ -{ \ - if (in_count > 0) \ - { \ - if ((in_count % 8) == 0 && in_count < 249) \ { \ - temp = (0x2 << 5) | (in_count / 8); \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else if (in_count < 256) \ - { \ - out_uint8(in_s, 0x40); \ - temp = in_count - 1; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf2); \ - out_uint16_le(in_s, in_count); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if ((in_count % 8) == 0 && in_count < 249) \ + { \ + temp = (0x2 << 5) | (in_count / 8); \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else if (in_count < 256) \ + { \ + out_uint8(in_s, 0x40); \ + temp = in_count - 1; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf2); \ + out_uint16_le(in_s, in_count); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ #define TEST_FILL \ -((last_line == 0 && pixel == 0) || \ - (last_line != 0 && pixel == ypixel)) + ((last_line == 0 && pixel == 0) || \ + (last_line != 0 && pixel == ypixel)) #define TEST_MIX \ -((last_line == 0 && pixel == mix) || \ - (last_line != 0 && pixel == (ypixel ^ mix))) + ((last_line == 0 && pixel == mix) || \ + (last_line != 0 && pixel == (ypixel ^ mix))) #define TEST_FOM (TEST_FILL || TEST_MIX) #define TEST_COLOR (pixel == last_pixel) #define TEST_BICOLOR \ -( \ - (pixel != last_pixel) && \ - ( \ - (!bicolor_spin && pixel == bicolor1 && last_pixel == bicolor2) || \ - (bicolor_spin && pixel == bicolor2 && last_pixel == bicolor1) \ - ) \ -) + ( \ + (pixel != last_pixel) && \ + ( \ + (!bicolor_spin && pixel == bicolor1 && last_pixel == bicolor2) || \ + (bicolor_spin && pixel == bicolor2 && last_pixel == bicolor1) \ + ) \ + ) #define RESET_COUNTS \ -{ \ - bicolor_count = 0; \ - fill_count = 0; \ - color_count = 0; \ - mix_count = 0; \ - fom_count = 0; \ - fom_mask_len = 0; \ - bicolor_spin = 0; \ -} + { \ + bicolor_count = 0; \ + fill_count = 0; \ + color_count = 0; \ + mix_count = 0; \ + fom_count = 0; \ + fom_mask_len = 0; \ + bicolor_spin = 0; \ + } /*****************************************************************************/ int APP_CC -xrdp_bitmap_compress(char* in_data, int width, int height, - struct stream* s, int bpp, int byte_limit, - int start_line, struct stream* temp_s, +xrdp_bitmap_compress(char *in_data, int width, int height, + struct stream *s, int bpp, int byte_limit, + int start_line, struct stream *temp_s, int e) { - char* line; - char* last_line; - char fom_mask[8192]; /* good for up to 64K bitmap */ - int lines_sent; - int pixel; - int count; - int color_count; - int last_pixel; - int bicolor_count; - int bicolor1; - int bicolor2; - int bicolor_spin; - int end; - int i; - int out_count; - int ypixel; - int last_ypixel; - int fill_count; - int mix_count; - int mix; - int fom_count; - int fom_mask_len; - int temp; /* used in macros */ + char *line; + char *last_line; + char fom_mask[8192]; /* good for up to 64K bitmap */ + int lines_sent; + int pixel; + int count; + int color_count; + int last_pixel; + int bicolor_count; + int bicolor1; + int bicolor2; + int bicolor_spin; + int end; + int i; + int out_count; + int ypixel; + int last_ypixel; + int fill_count; + int mix_count; + int mix; + int fom_count; + int fom_mask_len; + int temp; /* used in macros */ - init_stream(temp_s, 0); - fom_mask_len = 0; - last_line = 0; - lines_sent = 0; - end = width + e; - count = 0; - color_count = 0; - last_pixel = 0; - last_ypixel = 0; - bicolor_count = 0; - bicolor1 = 0; - bicolor2 = 0; - bicolor_spin = 0; - fill_count = 0; - mix_count = 0; - fom_count = 0; - if (bpp == 8) - { - mix = 0xff; - out_count = end; - line = in_data + width * start_line; - while (start_line >= 0 && out_count < 32768) + init_stream(temp_s, 0); + fom_mask_len = 0; + last_line = 0; + lines_sent = 0; + end = width + e; + count = 0; + color_count = 0; + last_pixel = 0; + last_ypixel = 0; + bicolor_count = 0; + bicolor1 = 0; + bicolor2 = 0; + bicolor_spin = 0; + fill_count = 0; + mix_count = 0; + fom_count = 0; + + if (bpp == 8) { - i = (s->p - s->data) + count; - if (i - color_count >= byte_limit && - i - bicolor_count >= byte_limit && - i - fill_count >= byte_limit && - i - mix_count >= byte_limit && - i - fom_count >= byte_limit) - { - break; - } - out_count += end; - for (i = 0; i < end; i++) - { - /* read next pixel */ - IN_PIXEL8(line, i, 0, width, last_pixel, pixel); - IN_PIXEL8(last_line, i, 0, width, last_ypixel, ypixel); - if (!TEST_FILL) + mix = 0xff; + out_count = end; + line = in_data + width * start_line; + + while (start_line >= 0 && out_count < 32768) + { + i = (s->p - s->data) + count; + + if (i - color_count >= byte_limit && + i - bicolor_count >= byte_limit && + i - fill_count >= byte_limit && + i - mix_count >= byte_limit && + i - fom_count >= byte_limit) + { + break; + } + + out_count += end; + + for (i = 0; i < end; i++) + { + /* read next pixel */ + IN_PIXEL8(line, i, 0, width, last_pixel, pixel); + IN_PIXEL8(last_line, i, 0, width, last_ypixel, ypixel); + + if (!TEST_FILL) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FILL_COUNT1(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + } + + if (!TEST_MIX) + { + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_MIX_COUNT1(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + } + + if (!TEST_COLOR) + { + if (color_count > 3 && + color_count >= fill_count && + color_count >= bicolor_count && + color_count >= mix_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_COLOR_COUNT1(color_count, s, last_pixel); + RESET_COUNTS; + } + + color_count = 0; + } + + if (!TEST_BICOLOR) + { + if (bicolor_count > 3 && + bicolor_count >= fill_count && + bicolor_count >= color_count && + bicolor_count >= mix_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); + } + + RESET_COUNTS; + } + + bicolor_count = 0; + bicolor1 = last_pixel; + bicolor2 = pixel; + bicolor_spin = 0; + } + + if (!TEST_FOM) + { + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + if (TEST_FILL) + { + fill_count++; + } + + if (TEST_MIX) + { + mix_count++; + } + + if (TEST_COLOR) + { + color_count++; + } + + if (TEST_BICOLOR) + { + bicolor_spin = !bicolor_spin; + bicolor_count++; + } + + if (TEST_FOM) + { + if ((fom_count % 8) == 0) + { + fom_mask[fom_mask_len] = 0; + fom_mask_len++; + } + + if (pixel == (ypixel ^ mix)) + { + fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); + } + + fom_count++; + } + + out_uint8(temp_s, pixel); + count++; + last_pixel = pixel; + last_ypixel = ypixel; + } + + /* can't take fix, mix, or fom past first line */ + if (last_line == 0) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FILL_COUNT1(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_MIX_COUNT1(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + last_line = line; + line = line - width; + start_line--; + lines_sent++; + } + + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) { - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { count -= fill_count; OUT_COPY_COUNT1(count, s, temp_s); OUT_FILL_COUNT1(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; } - if (!TEST_MIX) + else if (mix_count > 3 && + mix_count >= color_count && + mix_count >= bicolor_count && + mix_count >= fill_count && + mix_count >= fom_count) { - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { count -= mix_count; OUT_COPY_COUNT1(count, s, temp_s); OUT_MIX_COUNT1(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; } - if (!TEST_COLOR) + else if (color_count > 3 && + color_count >= mix_count && + color_count >= bicolor_count && + color_count >= fill_count && + color_count >= fom_count) { - if (color_count > 3 && - color_count >= fill_count && - color_count >= bicolor_count && - color_count >= mix_count && - color_count >= fom_count) - { count -= color_count; OUT_COPY_COUNT1(count, s, temp_s); OUT_COLOR_COUNT1(color_count, s, last_pixel); - RESET_COUNTS; - } - color_count = 0; } - if (!TEST_BICOLOR) + else if (bicolor_count > 3 && + bicolor_count >= mix_count && + bicolor_count >= color_count && + bicolor_count >= fill_count && + bicolor_count >= fom_count) { - if (bicolor_count > 3 && - bicolor_count >= fill_count && - bicolor_count >= color_count && - bicolor_count >= mix_count && - bicolor_count >= fom_count) - { if ((bicolor_count % 2) == 0) { - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); } else { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); } - RESET_COUNTS; - } - bicolor_count = 0; - bicolor1 = last_pixel; - bicolor2 = pixel; - bicolor_spin = 0; + + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); } - if (!TEST_FOM) + else if (fom_count > 3 && + fom_count >= mix_count && + fom_count >= color_count && + fom_count >= fill_count && + fom_count >= bicolor_count) { - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { count -= fom_count; OUT_COPY_COUNT1(count, s, temp_s); OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; } - if (TEST_FILL) + else { - fill_count++; + OUT_COPY_COUNT1(count, s, temp_s); } - if (TEST_MIX) + } + else if ((bpp == 15) || (bpp == 16)) + { + mix = (bpp == 15) ? 0xba1f : 0xffff; + out_count = end * 2; + line = in_data + width * start_line * 2; + + while (start_line >= 0 && out_count < 32768) { - mix_count++; + i = (s->p - s->data) + count * 2; + + if (i - (color_count * 2) >= byte_limit && + i - (bicolor_count * 2) >= byte_limit && + i - (fill_count * 2) >= byte_limit && + i - (mix_count * 2) >= byte_limit && + i - (fom_count * 2) >= byte_limit) + { + break; + } + + out_count += end * 2; + + for (i = 0; i < end; i++) + { + /* read next pixel */ + IN_PIXEL16(line, i, 0, width, last_pixel, pixel); + IN_PIXEL16(last_line, i, 0, width, last_ypixel, ypixel); + + if (!TEST_FILL) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FILL_COUNT2(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + } + + if (!TEST_MIX) + { + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_MIX_COUNT2(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + } + + if (!TEST_COLOR) + { + if (color_count > 3 && + color_count >= fill_count && + color_count >= bicolor_count && + color_count >= mix_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_COLOR_COUNT2(color_count, s, last_pixel); + RESET_COUNTS; + } + + color_count = 0; + } + + if (!TEST_BICOLOR) + { + if (bicolor_count > 3 && + bicolor_count >= fill_count && + bicolor_count >= color_count && + bicolor_count >= mix_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); + } + + RESET_COUNTS; + } + + bicolor_count = 0; + bicolor1 = last_pixel; + bicolor2 = pixel; + bicolor_spin = 0; + } + + if (!TEST_FOM) + { + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + if (TEST_FILL) + { + fill_count++; + } + + if (TEST_MIX) + { + mix_count++; + } + + if (TEST_COLOR) + { + color_count++; + } + + if (TEST_BICOLOR) + { + bicolor_spin = !bicolor_spin; + bicolor_count++; + } + + if (TEST_FOM) + { + if ((fom_count % 8) == 0) + { + fom_mask[fom_mask_len] = 0; + fom_mask_len++; + } + + if (pixel == (ypixel ^ mix)) + { + fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); + } + + fom_count++; + } + + out_uint16_le(temp_s, pixel); + count++; + last_pixel = pixel; + last_ypixel = ypixel; + } + + /* can't take fix, mix, or fom past first line */ + if (last_line == 0) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FILL_COUNT2(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_MIX_COUNT2(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + last_line = line; + line = line - width * 2; + start_line--; + lines_sent++; } - if (TEST_COLOR) - { - color_count++; - } - if (TEST_BICOLOR) - { - bicolor_spin = !bicolor_spin; - bicolor_count++; - } - if (TEST_FOM) - { - if ((fom_count % 8) == 0) - { - fom_mask[fom_mask_len] = 0; - fom_mask_len++; - } - if (pixel == (ypixel ^ mix)) - { - fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); - } - fom_count++; - } - out_uint8(temp_s, pixel); - count++; - last_pixel = pixel; - last_ypixel = ypixel; - } - /* can't take fix, mix, or fom past first line */ - if (last_line == 0) - { + if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) { - count -= fill_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_FILL_COUNT1(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_MIX_COUNT1(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; - } - last_line = line; - line = line - width; - start_line--; - lines_sent++; - } - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { - count -= fill_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_FILL_COUNT1(fill_count, s); - } - else if (mix_count > 3 && - mix_count >= color_count && - mix_count >= bicolor_count && - mix_count >= fill_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_MIX_COUNT1(mix_count, s); - } - else if (color_count > 3 && - color_count >= mix_count && - color_count >= bicolor_count && - color_count >= fill_count && - color_count >= fom_count) - { - count -= color_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_COLOR_COUNT1(color_count, s, last_pixel); - } - else if (bicolor_count > 3 && - bicolor_count >= mix_count && - bicolor_count >= color_count && - bicolor_count >= fill_count && - bicolor_count >= fom_count) - { - if ((bicolor_count % 2) == 0) - { - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); - } - else - { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); - } - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); - } - else if (fom_count > 3 && - fom_count >= mix_count && - fom_count >= color_count && - fom_count >= fill_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); - } - else - { - OUT_COPY_COUNT1(count, s, temp_s); - } - } - else if ((bpp == 15) || (bpp == 16)) - { - mix = (bpp == 15) ? 0xba1f : 0xffff; - out_count = end * 2; - line = in_data + width * start_line * 2; - while (start_line >= 0 && out_count < 32768) - { - i = (s->p - s->data) + count * 2; - if (i - (color_count * 2) >= byte_limit && - i - (bicolor_count * 2) >= byte_limit && - i - (fill_count * 2) >= byte_limit && - i - (mix_count * 2) >= byte_limit && - i - (fom_count * 2) >= byte_limit) - { - break; - } - out_count += end * 2; - for (i = 0; i < end; i++) - { - /* read next pixel */ - IN_PIXEL16(line, i, 0, width, last_pixel, pixel); - IN_PIXEL16(last_line, i, 0, width, last_ypixel, ypixel); - if (!TEST_FILL) - { - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { count -= fill_count; OUT_COPY_COUNT2(count, s, temp_s); OUT_FILL_COUNT2(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; } - if (!TEST_MIX) + else if (mix_count > 3 && + mix_count >= color_count && + mix_count >= bicolor_count && + mix_count >= fill_count && + mix_count >= fom_count) { - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { count -= mix_count; OUT_COPY_COUNT2(count, s, temp_s); OUT_MIX_COUNT2(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; } - if (!TEST_COLOR) + else if (color_count > 3 && + color_count >= mix_count && + color_count >= bicolor_count && + color_count >= fill_count && + color_count >= fom_count) { - if (color_count > 3 && - color_count >= fill_count && - color_count >= bicolor_count && - color_count >= mix_count && - color_count >= fom_count) - { count -= color_count; OUT_COPY_COUNT2(count, s, temp_s); OUT_COLOR_COUNT2(color_count, s, last_pixel); - RESET_COUNTS; - } - color_count = 0; } - if (!TEST_BICOLOR) + else if (bicolor_count > 3 && + bicolor_count >= mix_count && + bicolor_count >= color_count && + bicolor_count >= fill_count && + bicolor_count >= fom_count) { - if (bicolor_count > 3 && - bicolor_count >= fill_count && - bicolor_count >= color_count && - bicolor_count >= mix_count && - bicolor_count >= fom_count) - { if ((bicolor_count % 2) == 0) { - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); } else { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); } - RESET_COUNTS; - } - bicolor_count = 0; - bicolor1 = last_pixel; - bicolor2 = pixel; - bicolor_spin = 0; + + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); } - if (!TEST_FOM) + else if (fom_count > 3 && + fom_count >= mix_count && + fom_count >= color_count && + fom_count >= fill_count && + fom_count >= bicolor_count) { - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { count -= fom_count; OUT_COPY_COUNT2(count, s, temp_s); OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; } - if (TEST_FILL) + else { - fill_count++; + OUT_COPY_COUNT2(count, s, temp_s); } - if (TEST_MIX) + } + else if (bpp == 24) + { + mix = 0xffffff; + out_count = end * 3; + line = in_data + width * start_line * 4; + + while (start_line >= 0 && out_count < 32768) { - mix_count++; + i = (s->p - s->data) + count * 3; + + if (i - (color_count * 3) >= byte_limit && + i - (bicolor_count * 3) >= byte_limit && + i - (fill_count * 3) >= byte_limit && + i - (mix_count * 3) >= byte_limit && + i - (fom_count * 3) >= byte_limit) + { + break; + } + + out_count += end * 3; + + for (i = 0; i < end; i++) + { + /* read next pixel */ + IN_PIXEL32(line, i, 0, width, last_pixel, pixel); + IN_PIXEL32(last_line, i, 0, width, last_ypixel, ypixel); + + if (!TEST_FILL) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FILL_COUNT3(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + } + + if (!TEST_MIX) + { + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_MIX_COUNT3(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + } + + if (!TEST_COLOR) + { + if (color_count > 3 && + color_count >= fill_count && + color_count >= bicolor_count && + color_count >= mix_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_COLOR_COUNT3(color_count, s, last_pixel); + RESET_COUNTS; + } + + color_count = 0; + } + + if (!TEST_BICOLOR) + { + if (bicolor_count > 3 && + bicolor_count >= fill_count && + bicolor_count >= color_count && + bicolor_count >= mix_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); + } + + RESET_COUNTS; + } + + bicolor_count = 0; + bicolor1 = last_pixel; + bicolor2 = pixel; + bicolor_spin = 0; + } + + if (!TEST_FOM) + { + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + if (TEST_FILL) + { + fill_count++; + } + + if (TEST_MIX) + { + mix_count++; + } + + if (TEST_COLOR) + { + color_count++; + } + + if (TEST_BICOLOR) + { + bicolor_spin = !bicolor_spin; + bicolor_count++; + } + + if (TEST_FOM) + { + if ((fom_count % 8) == 0) + { + fom_mask[fom_mask_len] = 0; + fom_mask_len++; + } + + if (pixel == (ypixel ^ mix)) + { + fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); + } + + fom_count++; + } + + out_uint8(temp_s, pixel & 0xff); + out_uint8(temp_s, (pixel >> 8) & 0xff); + out_uint8(temp_s, (pixel >> 16) & 0xff); + count++; + last_pixel = pixel; + last_ypixel = ypixel; + } + + /* can't take fix, mix, or fom past first line */ + if (last_line == 0) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FILL_COUNT3(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_MIX_COUNT3(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + last_line = line; + line = line - width * 4; + start_line--; + lines_sent++; } - if (TEST_COLOR) - { - color_count++; - } - if (TEST_BICOLOR) - { - bicolor_spin = !bicolor_spin; - bicolor_count++; - } - if (TEST_FOM) - { - if ((fom_count % 8) == 0) - { - fom_mask[fom_mask_len] = 0; - fom_mask_len++; - } - if (pixel == (ypixel ^ mix)) - { - fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); - } - fom_count++; - } - out_uint16_le(temp_s, pixel); - count++; - last_pixel = pixel; - last_ypixel = ypixel; - } - /* can't take fix, mix, or fom past first line */ - if (last_line == 0) - { + if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) { - count -= fill_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_FILL_COUNT2(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_MIX_COUNT2(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; - } - last_line = line; - line = line - width * 2; - start_line--; - lines_sent++; - } - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { - count -= fill_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_FILL_COUNT2(fill_count, s); - } - else if (mix_count > 3 && - mix_count >= color_count && - mix_count >= bicolor_count && - mix_count >= fill_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_MIX_COUNT2(mix_count, s); - } - else if (color_count > 3 && - color_count >= mix_count && - color_count >= bicolor_count && - color_count >= fill_count && - color_count >= fom_count) - { - count -= color_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_COLOR_COUNT2(color_count, s, last_pixel); - } - else if (bicolor_count > 3 && - bicolor_count >= mix_count && - bicolor_count >= color_count && - bicolor_count >= fill_count && - bicolor_count >= fom_count) - { - if ((bicolor_count % 2) == 0) - { - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); - } - else - { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); - } - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); - } - else if (fom_count > 3 && - fom_count >= mix_count && - fom_count >= color_count && - fom_count >= fill_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); - } - else - { - OUT_COPY_COUNT2(count, s, temp_s); - } - } - else if (bpp == 24) - { - mix = 0xffffff; - out_count = end * 3; - line = in_data + width * start_line * 4; - while (start_line >= 0 && out_count < 32768) - { - i = (s->p - s->data) + count * 3; - if (i - (color_count * 3) >= byte_limit && - i - (bicolor_count * 3) >= byte_limit && - i - (fill_count * 3) >= byte_limit && - i - (mix_count * 3) >= byte_limit && - i - (fom_count * 3) >= byte_limit) - { - break; - } - out_count += end * 3; - for (i = 0; i < end; i++) - { - /* read next pixel */ - IN_PIXEL32(line, i, 0, width, last_pixel, pixel); - IN_PIXEL32(last_line, i, 0, width, last_ypixel, ypixel); - if (!TEST_FILL) - { - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { count -= fill_count; OUT_COPY_COUNT3(count, s, temp_s); OUT_FILL_COUNT3(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; } - if (!TEST_MIX) + else if (mix_count > 3 && + mix_count >= color_count && + mix_count >= bicolor_count && + mix_count >= fill_count && + mix_count >= fom_count) { - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { count -= mix_count; OUT_COPY_COUNT3(count, s, temp_s); OUT_MIX_COUNT3(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; } - if (!TEST_COLOR) + else if (color_count > 3 && + color_count >= mix_count && + color_count >= bicolor_count && + color_count >= fill_count && + color_count >= fom_count) { - if (color_count > 3 && - color_count >= fill_count && - color_count >= bicolor_count && - color_count >= mix_count && - color_count >= fom_count) - { count -= color_count; OUT_COPY_COUNT3(count, s, temp_s); OUT_COLOR_COUNT3(color_count, s, last_pixel); - RESET_COUNTS; - } - color_count = 0; } - if (!TEST_BICOLOR) + else if (bicolor_count > 3 && + bicolor_count >= mix_count && + bicolor_count >= color_count && + bicolor_count >= fill_count && + bicolor_count >= fom_count) { - if (bicolor_count > 3 && - bicolor_count >= fill_count && - bicolor_count >= color_count && - bicolor_count >= mix_count && - bicolor_count >= fom_count) - { if ((bicolor_count % 2) == 0) { - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); } else { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); } - RESET_COUNTS; - } - bicolor_count = 0; - bicolor1 = last_pixel; - bicolor2 = pixel; - bicolor_spin = 0; + + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); } - if (!TEST_FOM) + else if (fom_count > 3 && + fom_count >= mix_count && + fom_count >= color_count && + fom_count >= fill_count && + fom_count >= bicolor_count) { - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { count -= fom_count; OUT_COPY_COUNT3(count, s, temp_s); OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; } - if (TEST_FILL) + else { - fill_count++; + OUT_COPY_COUNT3(count, s, temp_s); } - if (TEST_MIX) - { - mix_count++; - } - if (TEST_COLOR) - { - color_count++; - } - if (TEST_BICOLOR) - { - bicolor_spin = !bicolor_spin; - bicolor_count++; - } - if (TEST_FOM) - { - if ((fom_count % 8) == 0) - { - fom_mask[fom_mask_len] = 0; - fom_mask_len++; - } - if (pixel == (ypixel ^ mix)) - { - fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); - } - fom_count++; - } - out_uint8(temp_s, pixel & 0xff); - out_uint8(temp_s, (pixel >> 8) & 0xff); - out_uint8(temp_s, (pixel >> 16) & 0xff); - count++; - last_pixel = pixel; - last_ypixel = ypixel; - } - /* can't take fix, mix, or fom past first line */ - if (last_line == 0) - { - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { - count -= fill_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_FILL_COUNT3(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_MIX_COUNT3(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; - } - last_line = line; - line = line - width * 4; - start_line--; - lines_sent++; } - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { - count -= fill_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_FILL_COUNT3(fill_count, s); - } - else if (mix_count > 3 && - mix_count >= color_count && - mix_count >= bicolor_count && - mix_count >= fill_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_MIX_COUNT3(mix_count, s); - } - else if (color_count > 3 && - color_count >= mix_count && - color_count >= bicolor_count && - color_count >= fill_count && - color_count >= fom_count) - { - count -= color_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_COLOR_COUNT3(color_count, s, last_pixel); - } - else if (bicolor_count > 3 && - bicolor_count >= mix_count && - bicolor_count >= color_count && - bicolor_count >= fill_count && - bicolor_count >= fom_count) - { - if ((bicolor_count % 2) == 0) - { - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); - } - else - { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); - } - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); - } - else if (fom_count > 3 && - fom_count >= mix_count && - fom_count >= color_count && - fom_count >= fill_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); - } - else - { - OUT_COPY_COUNT3(count, s, temp_s); - } - } - return lines_sent; + + return lines_sent; } diff --git a/libxrdp/xrdp_channel.c b/libxrdp/xrdp_channel.c index 2b3d23a5..6f40b751 100644 --- a/libxrdp/xrdp_channel.c +++ b/libxrdp/xrdp_channel.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2006-2010 - - channel layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2006-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * channel layer + */ #include "libxrdp.h" @@ -31,86 +29,96 @@ /*****************************************************************************/ /* returns pointer or nil on error */ -static struct mcs_channel_item* APP_CC -xrdp_channel_get_item(struct xrdp_channel* self, int channel_id) +static struct mcs_channel_item *APP_CC +xrdp_channel_get_item(struct xrdp_channel *self, int channel_id) { - struct mcs_channel_item* channel; - if(self->mcs_layer->channel_list==NULL) - { - g_writeln("xrdp_channel_get_item - No channel initialized"); - return NULL ; - } - channel = (struct mcs_channel_item*) - list_get_item(self->mcs_layer->channel_list, channel_id); - return channel; + struct mcs_channel_item *channel; + + if (self->mcs_layer->channel_list == NULL) + { + g_writeln("xrdp_channel_get_item - No channel initialized"); + return NULL ; + } + + channel = (struct mcs_channel_item *) + list_get_item(self->mcs_layer->channel_list, channel_id); + return channel; } /*****************************************************************************/ -struct xrdp_channel* APP_CC -xrdp_channel_create(struct xrdp_sec* owner, struct xrdp_mcs* mcs_layer) +struct xrdp_channel *APP_CC +xrdp_channel_create(struct xrdp_sec *owner, struct xrdp_mcs *mcs_layer) { - struct xrdp_channel* self; + struct xrdp_channel *self; - self = (struct xrdp_channel*)g_malloc(sizeof(struct xrdp_channel), 1); - self->sec_layer = owner; - self->mcs_layer = mcs_layer; - return self; + self = (struct xrdp_channel *)g_malloc(sizeof(struct xrdp_channel), 1); + self->sec_layer = owner; + self->mcs_layer = mcs_layer; + return self; } /*****************************************************************************/ /* returns error */ void APP_CC -xrdp_channel_delete(struct xrdp_channel* self) +xrdp_channel_delete(struct xrdp_channel *self) { - if (self == 0) - { - return; - } - g_memset(self,0,sizeof(struct xrdp_channel)); - g_free(self); + if (self == 0) + { + return; + } + + g_memset(self, 0, sizeof(struct xrdp_channel)); + g_free(self); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_channel_init(struct xrdp_channel* self, struct stream* s) +xrdp_channel_init(struct xrdp_channel *self, struct stream *s) { - if (xrdp_sec_init(self->sec_layer, s) != 0) - { - return 1; - } - s_push_layer(s, channel_hdr, 8); - return 0; + if (xrdp_sec_init(self->sec_layer, s) != 0) + { + return 1; + } + + s_push_layer(s, channel_hdr, 8); + return 0; } /*****************************************************************************/ /* returns error */ /* This sends data out to the secure layer. */ int APP_CC -xrdp_channel_send(struct xrdp_channel* self, struct stream* s, int channel_id, +xrdp_channel_send(struct xrdp_channel *self, struct stream *s, int channel_id, int total_data_len, int flags) { - struct mcs_channel_item* channel; + struct mcs_channel_item *channel; - channel = xrdp_channel_get_item(self, channel_id); - if (channel == NULL) - { - g_writeln("xrdp_channel_send - no such channel"); - return 1; - } - s_pop_layer(s, channel_hdr); - out_uint32_le(s, total_data_len); - if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL) - { - flags |= CHANNEL_FLAG_SHOW_PROTOCOL; - } - out_uint32_le(s, flags); - if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0) - { - g_writeln("xrdp_channel_send - failure sending data"); - return 1; - } - return 0; + channel = xrdp_channel_get_item(self, channel_id); + + if (channel == NULL) + { + g_writeln("xrdp_channel_send - no such channel"); + return 1; + } + + s_pop_layer(s, channel_hdr); + out_uint32_le(s, total_data_len); + + if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL) + { + flags |= CHANNEL_FLAG_SHOW_PROTOCOL; + } + + out_uint32_le(s, flags); + + if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0) + { + g_writeln("xrdp_channel_send - failure sending data"); + return 1; + } + + return 0; } /*****************************************************************************/ @@ -118,36 +126,38 @@ xrdp_channel_send(struct xrdp_channel* self, struct stream* s, int channel_id, /* this will inform the callback, whatever it is that some channel data is ready. the default for this is a call to xrdp_wm.c. */ static int APP_CC -xrdp_channel_call_callback(struct xrdp_channel* self, struct stream* s, +xrdp_channel_call_callback(struct xrdp_channel *self, struct stream *s, int channel_id, int total_data_len, int flags) { - struct xrdp_session* session; - int rv; - int size; + struct xrdp_session *session; + int rv; + int size; - rv = 0; - session = self->sec_layer->rdp_layer->session; - if (session != 0) - { - if (session->callback != 0) + rv = 0; + session = self->sec_layer->rdp_layer->session; + + if (session != 0) { - size = (int)(s->end - s->p); - /* in xrdp_wm.c */ - rv = session->callback(session->id, 0x5555, - MAKELONG(channel_id, flags), - size, (tbus)(s->p), total_data_len); + if (session->callback != 0) + { + size = (int)(s->end - s->p); + /* in xrdp_wm.c */ + rv = session->callback(session->id, 0x5555, + MAKELONG(channel_id, flags), + size, (tbus)(s->p), total_data_len); + } + else + { + g_writeln("in xrdp_channel_call_callback, session->callback is nil"); + } } else { - g_writeln("in xrdp_channel_call_callback, session->callback is nil"); + g_writeln("in xrdp_channel_call_callback, session is nil"); } - } - else - { - g_writeln("in xrdp_channel_call_callback, session is nil"); - } - return rv; + + return rv; } /*****************************************************************************/ @@ -157,30 +167,32 @@ xrdp_channel_call_callback(struct xrdp_channel* self, struct stream* s, 'chanid' passed in here is the mcs channel id so it MCS_GLOBAL_CHANNEL plus something. */ int APP_CC -xrdp_channel_process(struct xrdp_channel* self, struct stream* s, +xrdp_channel_process(struct xrdp_channel *self, struct stream *s, int chanid) { - int length; - int flags; - int rv; - int channel_id; - struct mcs_channel_item* channel; + int length; + int flags; + int rv; + int channel_id; + struct mcs_channel_item *channel; - /* this assumes that the channels are in order of chanid(mcs channel id) - but they should be, see xrdp_sec_process_mcs_data_channels - the first channel should be MCS_GLOBAL_CHANNEL + 1, second - one should be MCS_GLOBAL_CHANNEL + 2, and so on */ - channel_id = (chanid - MCS_GLOBAL_CHANNEL) - 1; - channel = xrdp_channel_get_item(self, channel_id); - if (channel == NULL) - { - g_writeln("xrdp_channel_process, channel not found"); - return 1; - } - rv = 0; - in_uint32_le(s, length); - in_uint32_le(s, flags); - rv = xrdp_channel_call_callback(self, s, channel_id, length, flags); - return rv; + /* this assumes that the channels are in order of chanid(mcs channel id) + but they should be, see xrdp_sec_process_mcs_data_channels + the first channel should be MCS_GLOBAL_CHANNEL + 1, second + one should be MCS_GLOBAL_CHANNEL + 2, and so on */ + channel_id = (chanid - MCS_GLOBAL_CHANNEL) - 1; + channel = xrdp_channel_get_item(self, channel_id); + + if (channel == NULL) + { + g_writeln("xrdp_channel_process, channel not found"); + return 1; + } + + rv = 0; + in_uint32_le(s, length); + in_uint32_le(s, flags); + rv = xrdp_channel_call_callback(self, s, channel_id, length, flags); + return rv; } diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 9a147b1b..35d90407 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -20,177 +20,190 @@ #include "libxrdp.h" /*****************************************************************************/ -struct xrdp_fastpath* APP_CC -xrdp_fastpath_create(struct xrdp_session* session) +struct xrdp_fastpath *APP_CC +xrdp_fastpath_create(struct xrdp_session *session) { - struct xrdp_fastpath* self; + struct xrdp_fastpath *self; - self = (struct xrdp_fastpath*)g_malloc(sizeof(struct xrdp_fastpath), 1); - self->tcp_layer = - ((struct xrdp_rdp*)session->rdp)->sec_layer-> - mcs_layer->iso_layer->tcp_layer; - make_stream(self->out_s); - init_stream(self->out_s, FASTPATH_MAX_PACKET_SIZE); - return self; + self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1); + self->tcp_layer = + ((struct xrdp_rdp *)session->rdp)->sec_layer-> + mcs_layer->iso_layer->tcp_layer; + make_stream(self->out_s); + init_stream(self->out_s, FASTPATH_MAX_PACKET_SIZE); + return self; } /*****************************************************************************/ void APP_CC -xrdp_fastpath_delete(struct xrdp_fastpath* self) +xrdp_fastpath_delete(struct xrdp_fastpath *self) { - if (self == 0) - { - return; - } - free_stream(self->out_s); - g_free(self); + if (self == 0) + { + return; + } + + free_stream(self->out_s); + g_free(self); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_fastpath_reset(struct xrdp_fastpath* self) +xrdp_fastpath_reset(struct xrdp_fastpath *self) { - return 0; + return 0; } int APP_CC -xrdp_fastpath_init(struct xrdp_fastpath* self) +xrdp_fastpath_init(struct xrdp_fastpath *self) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -xrdp_fastpath_send_update_pdu(struct xrdp_fastpath* self, tui8 updateCode, - struct stream* s) +xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode, + struct stream *s) { - tui16 len; - tui16 maxLen; - tui32 payloadLeft; - tui8 fragment; - struct stream* s_send; - int compression; - int i; - int i32; + tui16 len; + tui16 maxLen; + tui32 payloadLeft; + tui8 fragment; + struct stream *s_send; + int compression; + int i; + int i32; - compression = 0; - s_send = self->out_s; - maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */ - payloadLeft = (s->end - s->data); - for (i = 0; payloadLeft > 0; i++) - { - if (payloadLeft > maxLen) + compression = 0; + s_send = self->out_s; + maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */ + payloadLeft = (s->end - s->data); + + for (i = 0; payloadLeft > 0; i++) { - len = maxLen; + if (payloadLeft > maxLen) + { + len = maxLen; + } + else + { + len = payloadLeft; + } + + payloadLeft -= len; + + if (payloadLeft == 0) + { + fragment = i ? FASTPATH_FRAGMENT_LAST : FASTPATH_FRAGMENT_SINGLE; + } + else + { + fragment = i ? FASTPATH_FRAGMENT_NEXT : FASTPATH_FRAGMENT_FIRST; + } + + init_stream(s_send, 0); + out_uint8(s_send, 0); /* fOutputHeader */ + i32 = ((len + 6) >> 8) | 0x80; + out_uint8(s_send, i32); /* use 2 bytes for length even length < 128 ??? */ + i32 = (len + 6) & 0xff; + out_uint8(s_send, i32); + i32 = (updateCode & 0x0f) | ((fragment & 0x03) << 4) | + ((compression & 0x03) << 6); + out_uint8(s_send, i32); + out_uint16_le(s_send, len); + s_copy(s_send, s, len); + s_mark_end(s_send); + + if (xrdp_tcp_send(self->tcp_layer, s_send) != 0) + { + return 1; + } } - else - { - len = payloadLeft; - } - payloadLeft -= len; - if (payloadLeft == 0) - { - fragment = i ? FASTPATH_FRAGMENT_LAST : FASTPATH_FRAGMENT_SINGLE; - } - else - { - fragment = i ? FASTPATH_FRAGMENT_NEXT : FASTPATH_FRAGMENT_FIRST; - } - init_stream(s_send, 0); - out_uint8(s_send, 0); /* fOutputHeader */ - i32 = ((len + 6) >> 8) | 0x80; - out_uint8(s_send, i32); /* use 2 bytes for length even length < 128 ??? */ - i32 = (len + 6) & 0xff; - out_uint8(s_send, i32); - i32 = (updateCode & 0x0f) | ((fragment & 0x03) << 4) | - ((compression & 0x03) << 6); - out_uint8(s_send, i32); - out_uint16_le(s_send, len); - s_copy(s_send, s, len); - s_mark_end(s_send); - if (xrdp_tcp_send(self->tcp_layer, s_send) != 0) - { - return 1; - } - } - return 0; + + return 0; } /*****************************************************************************/ int -xrdp_fastpath_process_update(struct xrdp_fastpath* self, tui8 updateCode, - tui32 size, struct stream* s) +xrdp_fastpath_process_update(struct xrdp_fastpath *self, tui8 updateCode, + tui32 size, struct stream *s) { - switch (updateCode) - { - case FASTPATH_UPDATETYPE_ORDERS: - case FASTPATH_UPDATETYPE_BITMAP: - case FASTPATH_UPDATETYPE_PALETTE: - case FASTPATH_UPDATETYPE_SYNCHRONIZE: - case FASTPATH_UPDATETYPE_SURFCMDS: - case FASTPATH_UPDATETYPE_PTR_NULL: - case FASTPATH_UPDATETYPE_PTR_DEFAULT: - case FASTPATH_UPDATETYPE_PTR_POSITION: - case FASTPATH_UPDATETYPE_COLOR: - case FASTPATH_UPDATETYPE_CACHED: - case FASTPATH_UPDATETYPE_POINTER: - break; - default: - g_writeln("xrdp_fastpath_process_update: unknown updateCode 0x%X", - updateCode); - break; - } + switch (updateCode) + { + case FASTPATH_UPDATETYPE_ORDERS: + case FASTPATH_UPDATETYPE_BITMAP: + case FASTPATH_UPDATETYPE_PALETTE: + case FASTPATH_UPDATETYPE_SYNCHRONIZE: + case FASTPATH_UPDATETYPE_SURFCMDS: + case FASTPATH_UPDATETYPE_PTR_NULL: + case FASTPATH_UPDATETYPE_PTR_DEFAULT: + case FASTPATH_UPDATETYPE_PTR_POSITION: + case FASTPATH_UPDATETYPE_COLOR: + case FASTPATH_UPDATETYPE_CACHED: + case FASTPATH_UPDATETYPE_POINTER: + break; + default: + g_writeln("xrdp_fastpath_process_update: unknown updateCode 0x%X", + updateCode); + break; + } - return 0; + return 0; } /*****************************************************************************/ int APP_CC -xrdp_fastpath_process_data(struct xrdp_fastpath* self, struct stream* s, +xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s, tui8 header) { - tui8 encryptionFlags; - tui8 numberEvents; - tui8 length2; - tui8 updateHeader; - tui8 updateCode; - tui8 updateFrag; - tui8 updateComp; - tui16 length; - tui32 size; + tui8 encryptionFlags; + tui8 numberEvents; + tui8 length2; + tui8 updateHeader; + tui8 updateCode; + tui8 updateFrag; + tui8 updateComp; + tui16 length; + tui32 size; - encryptionFlags = (header & 0xc0) >> 6; - numberEvents = (header & 0x3c) >> 2; - xrdp_tcp_recv(self->tcp_layer, s, 1); - in_uint8(s, length); - if (length & 0x80) - { + encryptionFlags = (header & 0xc0) >> 6; + numberEvents = (header & 0x3c) >> 2; xrdp_tcp_recv(self->tcp_layer, s, 1); - in_uint8(s, length2); - length = (length & 0x7f) << 8 + length2 - 3; - } - else - { - length -= 2; - } - xrdp_tcp_recv(self->tcp_layer, s, length); - if (encryptionFlags != 0) - { - /* TODO decryption ...*/ - } - /* parse updateHeader */ - in_uint8(s, updateHeader); - updateCode = (updateHeader & 0x0f); - updateFrag = (updateHeader & 0x30) >> 4; - updateComp = (updateHeader & 0xc0) >> 6; - if (updateFrag && updateComp) - { - /* TODO */ - g_writeln("xrdp_fastpath_process_data: updateFrag=%d, updateComp=%d", - updateFrag,updateComp); - return 1; - } - in_uint16_le(s, size); - return xrdp_fastpath_process_update(self, updateCode, size, s); + in_uint8(s, length); + + if (length & 0x80) + { + xrdp_tcp_recv(self->tcp_layer, s, 1); + in_uint8(s, length2); + length = (length & 0x7f) << 8 + length2 - 3; + } + else + { + length -= 2; + } + + xrdp_tcp_recv(self->tcp_layer, s, length); + + if (encryptionFlags != 0) + { + /* TODO decryption ...*/ + } + + /* parse updateHeader */ + in_uint8(s, updateHeader); + updateCode = (updateHeader & 0x0f); + updateFrag = (updateHeader & 0x30) >> 4; + updateComp = (updateHeader & 0xc0) >> 6; + + if (updateFrag && updateComp) + { + /* TODO */ + g_writeln("xrdp_fastpath_process_data: updateFrag=%d, updateComp=%d", + updateFrag, updateComp); + return 1; + } + + in_uint16_le(s, size); + return xrdp_fastpath_process_update(self, updateCode, size, s); } diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 7fee92e6..8dedc131 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -1,197 +1,216 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - iso layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * iso layer + */ #include "libxrdp.h" /*****************************************************************************/ -struct xrdp_iso* APP_CC -xrdp_iso_create(struct xrdp_mcs* owner, struct trans* trans) +struct xrdp_iso *APP_CC +xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans) { - struct xrdp_iso* self; + struct xrdp_iso *self; - DEBUG((" in xrdp_iso_create")); - self = (struct xrdp_iso*)g_malloc(sizeof(struct xrdp_iso), 1); - self->mcs_layer = owner; - self->tcp_layer = xrdp_tcp_create(self, trans); - DEBUG((" out xrdp_iso_create")); - return self; + DEBUG((" in xrdp_iso_create")); + self = (struct xrdp_iso *)g_malloc(sizeof(struct xrdp_iso), 1); + self->mcs_layer = owner; + self->tcp_layer = xrdp_tcp_create(self, trans); + DEBUG((" out xrdp_iso_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_iso_delete(struct xrdp_iso* self) +xrdp_iso_delete(struct xrdp_iso *self) { - if (self == 0) - { - return; - } - xrdp_tcp_delete(self->tcp_layer); - g_free(self); + if (self == 0) + { + return; + } + + xrdp_tcp_delete(self->tcp_layer); + g_free(self); } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_iso_recv_msg(struct xrdp_iso* self, struct stream* s, int* code) +xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) { - int ver; - int len; + int ver; + int len; + + *code = 0; + + if (xrdp_tcp_recv(self->tcp_layer, s, 4) != 0) + { + return 1; + } + + in_uint8(s, ver); + + if (ver != 3) + { + return 1; + } - *code = 0; - if (xrdp_tcp_recv(self->tcp_layer, s, 4) != 0) - { - return 1; - } - in_uint8(s, ver); - if (ver != 3) - { - return 1; - } - in_uint8s(s, 1); - in_uint16_be(s, len); - if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) - { - return 1; - } - in_uint8s(s, 1); - in_uint8(s, *code); - if (*code == ISO_PDU_DT) - { in_uint8s(s, 1); - } - else - { - in_uint8s(s, 5); - } - return 0; + in_uint16_be(s, len); + + if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) + { + return 1; + } + + in_uint8s(s, 1); + in_uint8(s, *code); + + if (*code == ISO_PDU_DT) + { + in_uint8s(s, 1); + } + else + { + in_uint8s(s, 5); + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_iso_recv(struct xrdp_iso* self, struct stream* s) +xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) { - int code; + int code; - DEBUG((" in xrdp_iso_recv")); - if (xrdp_iso_recv_msg(self, s, &code) != 0) - { - DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); - return 1; - } - if (code != ISO_PDU_DT) - { - DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT")); - return 1; - } - DEBUG((" out xrdp_iso_recv")); - return 0; + DEBUG((" in xrdp_iso_recv")); + + if (xrdp_iso_recv_msg(self, s, &code) != 0) + { + DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); + return 1; + } + + if (code != ISO_PDU_DT) + { + DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT")); + return 1; + } + + DEBUG((" out xrdp_iso_recv")); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_iso_send_msg(struct xrdp_iso* self, struct stream* s, int code) +xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code) { - if (xrdp_tcp_init(self->tcp_layer, s) != 0) - { - return 1; - } - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, 11); /* length */ - out_uint8(s, 6); - out_uint8(s, code); - out_uint16_le(s, 0); - out_uint16_le(s, 0); - out_uint8(s, 0); - s_mark_end(s); - if (xrdp_tcp_send(self->tcp_layer, s) != 0) - { - return 1; - } - return 0; + if (xrdp_tcp_init(self->tcp_layer, s) != 0) + { + return 1; + } + + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, 11); /* length */ + out_uint8(s, 6); + out_uint8(s, code); + out_uint16_le(s, 0); + out_uint16_le(s, 0); + out_uint8(s, 0); + s_mark_end(s); + + if (xrdp_tcp_send(self->tcp_layer, s) != 0) + { + return 1; + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_iso_incoming(struct xrdp_iso* self) +xrdp_iso_incoming(struct xrdp_iso *self) { - int code; - struct stream* s; + int code; + struct stream *s; - make_stream(s); - init_stream(s, 8192); - DEBUG((" in xrdp_iso_incoming")); - if (xrdp_iso_recv_msg(self, s, &code) != 0) - { + make_stream(s); + init_stream(s, 8192); + DEBUG((" in xrdp_iso_incoming")); + + if (xrdp_iso_recv_msg(self, s, &code) != 0) + { + free_stream(s); + return 1; + } + + if (code != ISO_PDU_CR) + { + free_stream(s); + return 1; + } + + if (xrdp_iso_send_msg(self, s, ISO_PDU_CC) != 0) + { + free_stream(s); + return 1; + } + + DEBUG((" out xrdp_iso_incoming")); free_stream(s); - return 1; - } - if (code != ISO_PDU_CR) - { - free_stream(s); - return 1; - } - if (xrdp_iso_send_msg(self, s, ISO_PDU_CC) != 0) - { - free_stream(s); - return 1; - } - DEBUG((" out xrdp_iso_incoming")); - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_iso_init(struct xrdp_iso* self, struct stream* s) +xrdp_iso_init(struct xrdp_iso *self, struct stream *s) { - xrdp_tcp_init(self->tcp_layer, s); - s_push_layer(s, iso_hdr, 7); - return 0; + xrdp_tcp_init(self->tcp_layer, s); + s_push_layer(s, iso_hdr, 7); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_iso_send(struct xrdp_iso* self, struct stream* s) +xrdp_iso_send(struct xrdp_iso *self, struct stream *s) { - int len; + int len; - DEBUG((" in xrdp_iso_send")); - s_pop_layer(s, iso_hdr); - len = s->end - s->p; - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, len); - out_uint8(s, 2); - out_uint8(s, ISO_PDU_DT); - out_uint8(s, 0x80); - if (xrdp_tcp_send(self->tcp_layer, s) != 0) - { - return 1; - } - DEBUG((" out xrdp_iso_send")); - return 0; + DEBUG((" in xrdp_iso_send")); + s_pop_layer(s, iso_hdr); + len = s->end - s->p; + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, len); + out_uint8(s, 2); + out_uint8(s, ISO_PDU_DT); + out_uint8(s, 0x80); + + if (xrdp_tcp_send(self->tcp_layer, s) != 0) + { + return 1; + } + + DEBUG((" out xrdp_iso_send")); + return 0; } diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c index 8561982f..f8681e2b 100644 --- a/libxrdp/xrdp_jpeg_compress.c +++ b/libxrdp/xrdp_jpeg_compress.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2012 - - jpeg compressor - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * jpeg compressor + */ #include "libxrdp.h" @@ -33,10 +31,10 @@ struct mydata_comp { - char* cb; - int cb_bytes; - int total_done; - int overwrite; + char *cb; + int cb_bytes; + int total_done; + int overwrite; }; /*****************************************************************************/ @@ -44,13 +42,13 @@ struct mydata_comp static void DEFAULT_CC my_init_destination(j_compress_ptr cinfo) { - struct mydata_comp* md; + struct mydata_comp *md; - md = (struct mydata_comp*)(cinfo->client_data); - md->total_done = 0; - md->overwrite = 0; - cinfo->dest->next_output_byte = md->cb; - cinfo->dest->free_in_buffer = md->cb_bytes; + md = (struct mydata_comp *)(cinfo->client_data); + md->total_done = 0; + md->overwrite = 0; + cinfo->dest->next_output_byte = md->cb; + cinfo->dest->free_in_buffer = md->cb_bytes; } /*****************************************************************************/ @@ -58,16 +56,16 @@ my_init_destination(j_compress_ptr cinfo) static int DEFAULT_CC my_empty_output_buffer(j_compress_ptr cinfo) { - struct mydata_comp* md; - int chunk_bytes; + struct mydata_comp *md; + int chunk_bytes; - md = (struct mydata_comp*)(cinfo->client_data); - chunk_bytes = md->cb_bytes; - md->total_done += chunk_bytes; - cinfo->dest->next_output_byte = md->cb; - cinfo->dest->free_in_buffer = md->cb_bytes; - md->overwrite = 1; - return 1; + md = (struct mydata_comp *)(cinfo->client_data); + chunk_bytes = md->cb_bytes; + md->total_done += chunk_bytes; + cinfo->dest->next_output_byte = md->cb; + cinfo->dest->free_in_buffer = md->cb_bytes; + md->overwrite = 1; + return 1; } /*****************************************************************************/ @@ -75,149 +73,158 @@ my_empty_output_buffer(j_compress_ptr cinfo) static void DEFAULT_CC my_term_destination(j_compress_ptr cinfo) { - struct mydata_comp* md; - int chunk_bytes; + struct mydata_comp *md; + int chunk_bytes; - md = (struct mydata_comp*)(cinfo->client_data); - chunk_bytes = md->cb_bytes - cinfo->dest->free_in_buffer; - md->total_done += chunk_bytes; + md = (struct mydata_comp *)(cinfo->client_data); + chunk_bytes = md->cb_bytes - cinfo->dest->free_in_buffer; + md->total_done += chunk_bytes; } /*****************************************************************************/ static int APP_CC -jp_do_compress(char* data, int width, int height, int bpp, int quality, - char* comp_data, int* comp_data_bytes) +jp_do_compress(char *data, int width, int height, int bpp, int quality, + char *comp_data, int *comp_data_bytes) { - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - struct jpeg_destination_mgr dst_mgr; - struct mydata_comp md; - JSAMPROW row_pointer[4]; - int Bpp; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_destination_mgr dst_mgr; + struct mydata_comp md; + JSAMPROW row_pointer[4]; + int Bpp; - Bpp = (bpp + 7) / 8; - memset(&cinfo, 0, sizeof(cinfo)); - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - memset(&md, 0, sizeof(md)); - md.cb = comp_data, - md.cb_bytes = *comp_data_bytes; - cinfo.client_data = &md; - memset(&dst_mgr, 0, sizeof(dst_mgr)); - dst_mgr.init_destination = my_init_destination; - dst_mgr.empty_output_buffer = my_empty_output_buffer; - dst_mgr.term_destination = my_term_destination; - cinfo.dest = &dst_mgr; - cinfo.image_width = width; - cinfo.image_height = height; - cinfo.input_components = Bpp; - cinfo.in_color_space = JCS_RGB; - jpeg_set_defaults(&cinfo); - cinfo.num_components = 3; - cinfo.dct_method = JDCT_FLOAT; - jpeg_set_quality(&cinfo, quality, 1); - jpeg_start_compress(&cinfo, 1); - while (cinfo.next_scanline + 3 < cinfo.image_height) - { - row_pointer[0] = data; - data += width * Bpp; - row_pointer[1] = data; - data += width * Bpp; - row_pointer[2] = data; - data += width * Bpp; - row_pointer[3] = data; - data += width * Bpp; - jpeg_write_scanlines(&cinfo, row_pointer, 4); - } - while (cinfo.next_scanline < cinfo.image_height) - { - row_pointer[0] = data; - data += width * Bpp; - jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - jpeg_finish_compress(&cinfo); - *comp_data_bytes = md.total_done; - jpeg_destroy_compress(&cinfo); - if (md.overwrite) - { - return 1; - } - return 0; + Bpp = (bpp + 7) / 8; + memset(&cinfo, 0, sizeof(cinfo)); + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + memset(&md, 0, sizeof(md)); + md.cb = comp_data, + md.cb_bytes = *comp_data_bytes; + cinfo.client_data = &md; + memset(&dst_mgr, 0, sizeof(dst_mgr)); + dst_mgr.init_destination = my_init_destination; + dst_mgr.empty_output_buffer = my_empty_output_buffer; + dst_mgr.term_destination = my_term_destination; + cinfo.dest = &dst_mgr; + cinfo.image_width = width; + cinfo.image_height = height; + cinfo.input_components = Bpp; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + cinfo.num_components = 3; + cinfo.dct_method = JDCT_FLOAT; + jpeg_set_quality(&cinfo, quality, 1); + jpeg_start_compress(&cinfo, 1); + + while (cinfo.next_scanline + 3 < cinfo.image_height) + { + row_pointer[0] = data; + data += width * Bpp; + row_pointer[1] = data; + data += width * Bpp; + row_pointer[2] = data; + data += width * Bpp; + row_pointer[3] = data; + data += width * Bpp; + jpeg_write_scanlines(&cinfo, row_pointer, 4); + } + + while (cinfo.next_scanline < cinfo.image_height) + { + row_pointer[0] = data; + data += width * Bpp; + jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + + jpeg_finish_compress(&cinfo); + *comp_data_bytes = md.total_done; + jpeg_destroy_compress(&cinfo); + + if (md.overwrite) + { + return 1; + } + + return 0; } /*****************************************************************************/ static int APP_CC -jpeg_compress(char* in_data, int width, int height, - struct stream* s, struct stream* temp_s, int bpp, +jpeg_compress(char *in_data, int width, int height, + struct stream *s, struct stream *temp_s, int bpp, int byte_limit, int e, int quality) { - char* data; - tui32* src32; - tui16* src16; - tui8* dst8; - tui32 pixel; - int red; - int blue; - int green; - int j; - int i; - int cdata_bytes; + char *data; + tui32 *src32; + tui16 *src16; + tui8 *dst8; + tui32 pixel; + int red; + int blue; + int green; + int j; + int i; + int cdata_bytes; - data = temp_s->data; - dst8 = data; - if (bpp == 24) - { - src32 = (tui32*)in_data; - for (j = 0; j < height; j++) + data = temp_s->data; + dst8 = data; + + if (bpp == 24) { - for (i = 0; i < width; i++) - { - pixel = src32[i + j * width]; - SPLITCOLOR32(red, green, blue, pixel); - *(dst8++)= blue; - *(dst8++)= green; - *(dst8++)= red; - } - for (i = 0; i < e; i++) - { - *(dst8++) = blue; - *(dst8++) = green; - *(dst8++) = red; - } + src32 = (tui32 *)in_data; + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + pixel = src32[i + j * width]; + SPLITCOLOR32(red, green, blue, pixel); + *(dst8++) = blue; + *(dst8++) = green; + *(dst8++) = red; + } + + for (i = 0; i < e; i++) + { + *(dst8++) = blue; + *(dst8++) = green; + *(dst8++) = red; + } + } } - } - else - { - g_writeln("bpp wrong %d", bpp); - } - cdata_bytes = byte_limit; - jp_do_compress(data, width + e, height, 24, quality, s->p, &cdata_bytes); - s->p += cdata_bytes; - return cdata_bytes; + else + { + g_writeln("bpp wrong %d", bpp); + } + + cdata_bytes = byte_limit; + jp_do_compress(data, width + e, height, 24, quality, s->p, &cdata_bytes); + s->p += cdata_bytes; + return cdata_bytes; } /*****************************************************************************/ int APP_CC -xrdp_jpeg_compress(char* in_data, int width, int height, - struct stream* s, int bpp, int byte_limit, - int start_line, struct stream* temp_s, +xrdp_jpeg_compress(char *in_data, int width, int height, + struct stream *s, int bpp, int byte_limit, + int start_line, struct stream *temp_s, int e, int quality) { - jpeg_compress(in_data, width, height, s, temp_s, bpp, byte_limit, - e, quality); - return height; + jpeg_compress(in_data, width, height, s, temp_s, bpp, byte_limit, + e, quality); + return height; } #else /*****************************************************************************/ int APP_CC -xrdp_jpeg_compress(char* in_data, int width, int height, - struct stream* s, int bpp, int byte_limit, - int start_line, struct stream* temp_s, +xrdp_jpeg_compress(char *in_data, int width, int height, + struct stream *s, int bpp, int byte_limit, + int start_line, struct stream *temp_s, int e, int quality) { - return height; + return height; } #endif diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 618a3433..a2793960 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -1,642 +1,721 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - mcs layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * mcs layer + */ #include "libxrdp.h" /*****************************************************************************/ -struct xrdp_mcs* APP_CC -xrdp_mcs_create(struct xrdp_sec* owner, struct trans* trans, - struct stream* client_mcs_data, - struct stream* server_mcs_data) +struct xrdp_mcs *APP_CC +xrdp_mcs_create(struct xrdp_sec *owner, struct trans *trans, + struct stream *client_mcs_data, + struct stream *server_mcs_data) { - struct xrdp_mcs* self; + struct xrdp_mcs *self; - DEBUG((" in xrdp_mcs_create")); - self = (struct xrdp_mcs*)g_malloc(sizeof(struct xrdp_mcs), 1); - self->sec_layer = owner; - self->userid = 1; - self->chanid = 1001; - self->client_mcs_data = client_mcs_data; - self->server_mcs_data = server_mcs_data; - self->iso_layer = xrdp_iso_create(self, trans); - self->channel_list = list_create(); - DEBUG((" out xrdp_mcs_create")); - return self; + DEBUG((" in xrdp_mcs_create")); + self = (struct xrdp_mcs *)g_malloc(sizeof(struct xrdp_mcs), 1); + self->sec_layer = owner; + self->userid = 1; + self->chanid = 1001; + self->client_mcs_data = client_mcs_data; + self->server_mcs_data = server_mcs_data; + self->iso_layer = xrdp_iso_create(self, trans); + self->channel_list = list_create(); + DEBUG((" out xrdp_mcs_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_mcs_delete(struct xrdp_mcs* self) +xrdp_mcs_delete(struct xrdp_mcs *self) { - struct mcs_channel_item* channel_item; - int index; - int count; + struct mcs_channel_item *channel_item; + int index; + int count; - if (self == 0) - { - return; - } - /* here we have to free the channel items and anything in them */ - count = self->channel_list->count; - for (index = count - 1; index >= 0; index--) - { - channel_item = (struct mcs_channel_item*) - list_get_item(self->channel_list, index); - g_free(channel_item); - } - list_delete(self->channel_list); - xrdp_iso_delete(self->iso_layer); - /* make sure we get null pointer exception if struct is used again. */ - DEBUG(("xrdp_mcs_delete processed")) - g_memset(self,0,sizeof(struct xrdp_mcs)) ; - g_free(self); + if (self == 0) + { + return; + } + + /* here we have to free the channel items and anything in them */ + count = self->channel_list->count; + + for (index = count - 1; index >= 0; index--) + { + channel_item = (struct mcs_channel_item *) + list_get_item(self->channel_list, index); + g_free(channel_item); + } + + list_delete(self->channel_list); + xrdp_iso_delete(self->iso_layer); + /* make sure we get null pointer exception if struct is used again. */ + DEBUG(("xrdp_mcs_delete processed")) + g_memset(self, 0, sizeof(struct xrdp_mcs)) ; + g_free(self); } /*****************************************************************************/ /* This function sends channel join confirm*/ /* returns error = 1 ok = 0*/ static int APP_CC -xrdp_mcs_send_cjcf(struct xrdp_mcs* self, int userid, int chanid) +xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid) { - struct stream* s; + struct stream *s; + + DEBUG((" in xrdp_mcs_send_cjcf")); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_cjcf error")); + return 1; + } + + out_uint8(s, (MCS_CJCF << 2) | 2); + out_uint8(s, 0); + out_uint16_be(s, userid); + out_uint16_be(s, chanid); /* TODO Explain why we send this two times */ + out_uint16_be(s, chanid); + s_mark_end(s); + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_cjcf error")); + return 1; + } - DEBUG((" in xrdp_mcs_send_cjcf")); - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_init(self->iso_layer, s) != 0) - { free_stream(s); - DEBUG((" out xrdp_mcs_send_cjcf error")); - return 1; - } - out_uint8(s, (MCS_CJCF << 2) | 2); - out_uint8(s, 0); - out_uint16_be(s, userid); - out_uint16_be(s, chanid); /* TODO Explain why we send this two times */ - out_uint16_be(s, chanid); - s_mark_end(s); - if (xrdp_iso_send(self->iso_layer, s) != 0) - { - free_stream(s); - DEBUG((" out xrdp_mcs_send_cjcf error")); - return 1; - } - free_stream(s); - DEBUG((" out xrdp_mcs_send_cjcf")); - return 0; + DEBUG((" out xrdp_mcs_send_cjcf")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan) +xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan) { - int appid; - int opcode; - int len; - int userid; - int chanid; + int appid; + int opcode; + int len; + int userid; + int chanid; - DEBUG((" in xrdp_mcs_recv")); - while (1) - { - if (xrdp_iso_recv(self->iso_layer, s) != 0) + DEBUG((" in xrdp_mcs_recv")); + + while (1) { - DEBUG((" out xrdp_mcs_recv xrdp_iso_recv returned non zero")); - return 1; + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + DEBUG((" out xrdp_mcs_recv xrdp_iso_recv returned non zero")); + return 1; + } + + in_uint8(s, opcode); + appid = opcode >> 2; + + if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */ + { + g_writeln("received Disconnect Provider Ultimatum"); + DEBUG((" out xrdp_mcs_recv appid != MCS_DPUM")); + return 1; + } + + /* this is channels getting added from the client */ + if (appid == MCS_CJRQ) + { + g_writeln("channel join request received"); + in_uint16_be(s, userid); + in_uint16_be(s, chanid); + DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid)); + + if (xrdp_mcs_send_cjcf(self, userid, chanid) != 0) + { + g_writeln("Non handled error from xrdp_mcs_send_cjcf") ; + } + + continue; + } + + if (appid == MCS_SDRQ || appid == MCS_SDIN) + { + break ; + } + else + { + g_writeln("Recieved an unhandled appid:%d", appid); + } + + break; } - in_uint8(s, opcode); - appid = opcode >> 2; - if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */ + + if (appid != MCS_SDRQ) { - g_writeln("received Disconnect Provider Ultimatum"); - DEBUG((" out xrdp_mcs_recv appid != MCS_DPUM")); - return 1; + DEBUG((" out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid)); + return 1; } - /* this is channels getting added from the client */ - if (appid == MCS_CJRQ) + + in_uint8s(s, 2); + in_uint16_be(s, *chan); + in_uint8s(s, 1); + in_uint8(s, len); + + if (len & 0x80) { - g_writeln("channel join request received"); - in_uint16_be(s, userid); - in_uint16_be(s, chanid); - DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid)); - if(xrdp_mcs_send_cjcf(self, userid, chanid)!=0) - { - g_writeln("Non handled error from xrdp_mcs_send_cjcf") ; - } - continue; + in_uint8s(s, 1); } - if(appid==MCS_SDRQ || appid==MCS_SDIN) + + DEBUG((" out xrdp_mcs_recv")); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s, + int tag_val, int *len) +{ + int tag; + int l; + int i; + + if (tag_val > 0xff) { - break ; + in_uint16_be(s, tag); } else { - g_writeln("Recieved an unhandled appid:%d",appid); + in_uint8(s, tag); } - break; - } - if (appid != MCS_SDRQ) - { - DEBUG((" out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid)); - return 1; - } - in_uint8s(s, 2); - in_uint16_be(s, *chan); - in_uint8s(s, 1); - in_uint8(s, len); - if (len & 0x80) - { - in_uint8s(s, 1); - } - DEBUG((" out xrdp_mcs_recv")); - return 0; -} -/*****************************************************************************/ -/* returns error */ -static int APP_CC -xrdp_mcs_ber_parse_header(struct xrdp_mcs* self, struct stream* s, - int tag_val, int* len) -{ - int tag; - int l; - int i; - - if (tag_val > 0xff) - { - in_uint16_be(s, tag); - } - else - { - in_uint8(s, tag); - } - if (tag != tag_val) - { - return 1; - } - in_uint8(s, l); - if (l & 0x80) - { - l = l & ~0x80; - *len = 0; - while (l > 0) + if (tag != tag_val) { - in_uint8(s, i); - *len = (*len << 8) | i; - l--; + return 1; + } + + in_uint8(s, l); + + if (l & 0x80) + { + l = l & ~0x80; + *len = 0; + + while (l > 0) + { + in_uint8(s, i); + *len = (*len << 8) | i; + l--; + } + } + else + { + *len = l; + } + + if (s_check(s)) + { + return 0; + } + else + { + return 1; } - } - else - { - *len = l; - } - if (s_check(s)) - { - return 0; - } - else - { - return 1; - } } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_parse_domain_params(struct xrdp_mcs* self, struct stream* s) +xrdp_mcs_parse_domain_params(struct xrdp_mcs *self, struct stream *s) { - int len; + int len; - if (xrdp_mcs_ber_parse_header(self, s, MCS_TAG_DOMAIN_PARAMS, &len) != 0) - { - return 1; - } - in_uint8s(s, len); - if (s_check(s)) - { - return 0; - } - else - { - return 1; - } + if (xrdp_mcs_ber_parse_header(self, s, MCS_TAG_DOMAIN_PARAMS, &len) != 0) + { + return 1; + } + + in_uint8s(s, len); + + if (s_check(s)) + { + return 0; + } + else + { + return 1; + } } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_recv_connect_initial(struct xrdp_mcs* self) +xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self) { - int len; - struct stream* s; + int len; + struct stream *s; - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_ber_parse_header(self, s, MCS_CONNECT_INITIAL, &len) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) - { - free_stream(s); - return 1; - } - in_uint8s(s, len); - if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) - { - free_stream(s); - return 1; - } - in_uint8s(s, len); - if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0) - { - free_stream(s); - return 1; - } - in_uint8s(s, len); - if (xrdp_mcs_parse_domain_params(self, s) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_parse_domain_params(self, s) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_parse_domain_params(self, s) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) - { - free_stream(s); - return 1; - } - /* make a copy of client mcs data */ - init_stream(self->client_mcs_data, len); - out_uint8a(self->client_mcs_data, s->p, len); - in_uint8s(s, len); - s_mark_end(self->client_mcs_data); - if (s_check_end(s)) - { - free_stream(s); - return 0; - } - else - { - free_stream(s); - return 1; - } + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_ber_parse_header(self, s, MCS_CONNECT_INITIAL, &len) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) + { + free_stream(s); + return 1; + } + + in_uint8s(s, len); + + if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) + { + free_stream(s); + return 1; + } + + in_uint8s(s, len); + + if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0) + { + free_stream(s); + return 1; + } + + in_uint8s(s, len); + + if (xrdp_mcs_parse_domain_params(self, s) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_parse_domain_params(self, s) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_parse_domain_params(self, s) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) + { + free_stream(s); + return 1; + } + + /* make a copy of client mcs data */ + init_stream(self->client_mcs_data, len); + out_uint8a(self->client_mcs_data, s->p, len); + in_uint8s(s, len); + s_mark_end(self->client_mcs_data); + + if (s_check_end(s)) + { + free_stream(s); + return 0; + } + else + { + free_stream(s); + return 1; + } } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_recv_edrq(struct xrdp_mcs* self) +xrdp_mcs_recv_edrq(struct xrdp_mcs *self) { - int opcode; - struct stream* s; + int opcode; + struct stream *s; - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_EDRQ) - { - free_stream(s); - return 1; - } - in_uint8s(s, 2); - in_uint8s(s, 2); - if (opcode & 2) - { - in_uint16_be(s, self->userid); - } - if (!(s_check_end(s))) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} + make_stream(s); + init_stream(s, 8192); -/*****************************************************************************/ -/* returns error */ -static int APP_CC -xrdp_mcs_recv_aurq(struct xrdp_mcs* self) -{ - int opcode; - struct stream* s; + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_AURQ) - { - free_stream(s); - return 1; - } - if (opcode & 2) - { - in_uint16_be(s, self->userid); - } - if (!(s_check_end(s))) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} + in_uint8(s, opcode); -/*****************************************************************************/ -/* returns error */ -static int APP_CC -xrdp_mcs_send_aucf(struct xrdp_mcs* self) -{ - struct stream* s; + if ((opcode >> 2) != MCS_EDRQ) + { + free_stream(s); + return 1; + } - DEBUG((" in xrdp_mcs_send_aucf")); - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_init(self->iso_layer, s) != 0) - { - free_stream(s); - DEBUG((" out xrdp_mcs_send_aucf error")); - return 1; - } - out_uint8(s, ((MCS_AUCF << 2) | 2)); - out_uint8s(s, 1); - out_uint16_be(s, self->userid); - s_mark_end(s); - if (xrdp_iso_send(self->iso_layer, s) != 0) - { - free_stream(s); - DEBUG((" out xrdp_mcs_send_aucf error")); - return 1; - } - free_stream(s); - DEBUG((" out xrdp_mcs_send_aucf")); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -xrdp_mcs_recv_cjrq(struct xrdp_mcs* self) -{ - int opcode; - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_CJRQ) - { - free_stream(s); - return 1; - } - in_uint8s(s, 4); - if (opcode & 2) - { in_uint8s(s, 2); - } - if (!(s_check_end(s))) - { + in_uint8s(s, 2); + + if (opcode & 2) + { + in_uint16_be(s, self->userid); + } + + if (!(s_check_end(s))) + { + free_stream(s); + return 1; + } + free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_ber_out_header(struct xrdp_mcs* self, struct stream* s, +xrdp_mcs_recv_aurq(struct xrdp_mcs *self) +{ + int opcode; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + in_uint8(s, opcode); + + if ((opcode >> 2) != MCS_AURQ) + { + free_stream(s); + return 1; + } + + if (opcode & 2) + { + in_uint16_be(s, self->userid); + } + + if (!(s_check_end(s))) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_mcs_send_aucf(struct xrdp_mcs *self) +{ + struct stream *s; + + DEBUG((" in xrdp_mcs_send_aucf")); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_aucf error")); + return 1; + } + + out_uint8(s, ((MCS_AUCF << 2) | 2)); + out_uint8s(s, 1); + out_uint16_be(s, self->userid); + s_mark_end(s); + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_aucf error")); + return 1; + } + + free_stream(s); + DEBUG((" out xrdp_mcs_send_aucf")); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_mcs_recv_cjrq(struct xrdp_mcs *self) +{ + int opcode; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + in_uint8(s, opcode); + + if ((opcode >> 2) != MCS_CJRQ) + { + free_stream(s); + return 1; + } + + in_uint8s(s, 4); + + if (opcode & 2) + { + in_uint8s(s, 2); + } + + if (!(s_check_end(s))) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_mcs_ber_out_header(struct xrdp_mcs *self, struct stream *s, int tag_val, int len) { - if (tag_val > 0xff) - { - out_uint16_be(s, tag_val); - } - else - { - out_uint8(s, tag_val); - } - if (len >= 0x80) - { - out_uint8(s, 0x82); - out_uint16_be(s, len); - } - else - { - out_uint8(s, len); - } - return 0; + if (tag_val > 0xff) + { + out_uint16_be(s, tag_val); + } + else + { + out_uint8(s, tag_val); + } + + if (len >= 0x80) + { + out_uint8(s, 0x82); + out_uint16_be(s, len); + } + else + { + out_uint8(s, len); + } + + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_ber_out_int8(struct xrdp_mcs* self, struct stream* s, int value) +xrdp_mcs_ber_out_int8(struct xrdp_mcs *self, struct stream *s, int value) { - xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); - out_uint8(s, value); - return 0; + xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); + out_uint8(s, value); + return 0; } #if 0 /* not used */ /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_ber_out_int16(struct xrdp_mcs* self, struct stream* s, int value) +xrdp_mcs_ber_out_int16(struct xrdp_mcs *self, struct stream *s, int value) { - xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 2); - out_uint8(s, (value >> 8)); - out_uint8(s, value); - return 0; + xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 2); + out_uint8(s, (value >> 8)); + out_uint8(s, value); + return 0; } #endif /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_ber_out_int24(struct xrdp_mcs* self, struct stream* s, int value) +xrdp_mcs_ber_out_int24(struct xrdp_mcs *self, struct stream *s, int value) { - xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 3); - out_uint8(s, (value >> 16)); - out_uint8(s, (value >> 8)); - out_uint8(s, value); - return 0; + xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 3); + out_uint8(s, (value >> 16)); + out_uint8(s, (value >> 8)); + out_uint8(s, value); + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_out_domain_params(struct xrdp_mcs* self, struct stream* s, +xrdp_mcs_out_domain_params(struct xrdp_mcs *self, struct stream *s, int max_channels, int max_users, int max_tokens, int max_pdu_size) { - xrdp_mcs_ber_out_header(self, s, MCS_TAG_DOMAIN_PARAMS, 26); - xrdp_mcs_ber_out_int8(self, s, max_channels); - xrdp_mcs_ber_out_int8(self, s, max_users); - xrdp_mcs_ber_out_int8(self, s, max_tokens); - xrdp_mcs_ber_out_int8(self, s, 1); - xrdp_mcs_ber_out_int8(self, s, 0); - xrdp_mcs_ber_out_int8(self, s, 1); - xrdp_mcs_ber_out_int24(self, s, max_pdu_size); - xrdp_mcs_ber_out_int8(self, s, 2); - return 0; + xrdp_mcs_ber_out_header(self, s, MCS_TAG_DOMAIN_PARAMS, 26); + xrdp_mcs_ber_out_int8(self, s, max_channels); + xrdp_mcs_ber_out_int8(self, s, max_users); + xrdp_mcs_ber_out_int8(self, s, max_tokens); + xrdp_mcs_ber_out_int8(self, s, 1); + xrdp_mcs_ber_out_int8(self, s, 0); + xrdp_mcs_ber_out_int8(self, s, 1); + xrdp_mcs_ber_out_int24(self, s, max_pdu_size); + xrdp_mcs_ber_out_int8(self, s, 2); + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_send_connect_response(struct xrdp_mcs* self) +xrdp_mcs_send_connect_response(struct xrdp_mcs *self) { - int data_len; - struct stream* s; + int data_len; + struct stream *s; + + DEBUG((" in xrdp_mcs_send_connect_response")); + make_stream(s); + init_stream(s, 8192); + data_len = self->server_mcs_data->end - self->server_mcs_data->data; + xrdp_iso_init(self->iso_layer, s); + xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE, data_len + 38); + xrdp_mcs_ber_out_header(self, s, BER_TAG_RESULT, 1); + out_uint8(s, 0); + xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); + out_uint8(s, 0); + xrdp_mcs_out_domain_params(self, s, 22, 3, 0, 0xfff8); + xrdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, data_len); + /* mcs data */ + out_uint8a(s, self->server_mcs_data->data, data_len); + s_mark_end(s); + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_connect_response error")); + return 1; + } - DEBUG((" in xrdp_mcs_send_connect_response")); - make_stream(s); - init_stream(s, 8192); - data_len = self->server_mcs_data->end - self->server_mcs_data->data; - xrdp_iso_init(self->iso_layer, s); - xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE, data_len + 38); - xrdp_mcs_ber_out_header(self, s, BER_TAG_RESULT, 1); - out_uint8(s, 0); - xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); - out_uint8(s, 0); - xrdp_mcs_out_domain_params(self, s, 22, 3, 0, 0xfff8); - xrdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, data_len); - /* mcs data */ - out_uint8a(s, self->server_mcs_data->data, data_len); - s_mark_end(s); - if (xrdp_iso_send(self->iso_layer, s) != 0) - { free_stream(s); - DEBUG((" out xrdp_mcs_send_connect_response error")); - return 1; - } - free_stream(s); - DEBUG((" out xrdp_mcs_send_connect_response")); - return 0; + DEBUG((" out xrdp_mcs_send_connect_response")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_incoming(struct xrdp_mcs* self) +xrdp_mcs_incoming(struct xrdp_mcs *self) { - DEBUG((" in xrdp_mcs_incoming")); - if (xrdp_iso_incoming(self->iso_layer) != 0) - { - return 1; - } - if (xrdp_mcs_recv_connect_initial(self) != 0) - { - return 1; - } - /* in xrdp_sec.c */ - if (xrdp_sec_process_mcs_data(self->sec_layer) != 0) - { - return 1; - } - /* in xrdp_sec.c */ - if (xrdp_sec_out_mcs_data(self->sec_layer) != 0) - { - return 1; - } - if (xrdp_mcs_send_connect_response(self) != 0) - { - return 1; - } - if (xrdp_mcs_recv_edrq(self) != 0) - { - return 1; - } - if (xrdp_mcs_recv_aurq(self) != 0) - { - return 1; - } - if (xrdp_mcs_send_aucf(self) != 0) - { - return 1; - } - if (xrdp_mcs_recv_cjrq(self) != 0) - { - return 1; - } - if (xrdp_mcs_send_cjcf(self, self->userid, - self->userid + MCS_USERCHANNEL_BASE) != 0) - { - return 1; - } - if (xrdp_mcs_recv_cjrq(self) != 0) - { - return 1; - } - if (xrdp_mcs_send_cjcf(self, self->userid, MCS_GLOBAL_CHANNEL) != 0) - { - return 1; - } - DEBUG((" out xrdp_mcs_incoming")); - return 0; + DEBUG((" in xrdp_mcs_incoming")); + + if (xrdp_iso_incoming(self->iso_layer) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_connect_initial(self) != 0) + { + return 1; + } + + /* in xrdp_sec.c */ + if (xrdp_sec_process_mcs_data(self->sec_layer) != 0) + { + return 1; + } + + /* in xrdp_sec.c */ + if (xrdp_sec_out_mcs_data(self->sec_layer) != 0) + { + return 1; + } + + if (xrdp_mcs_send_connect_response(self) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_edrq(self) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_aurq(self) != 0) + { + return 1; + } + + if (xrdp_mcs_send_aucf(self) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_cjrq(self) != 0) + { + return 1; + } + + if (xrdp_mcs_send_cjcf(self, self->userid, + self->userid + MCS_USERCHANNEL_BASE) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_cjrq(self) != 0) + { + return 1; + } + + if (xrdp_mcs_send_cjcf(self, self->userid, MCS_GLOBAL_CHANNEL) != 0) + { + return 1; + } + + DEBUG((" out xrdp_mcs_incoming")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_init(struct xrdp_mcs* self, struct stream* s) +xrdp_mcs_init(struct xrdp_mcs *self, struct stream *s) { - xrdp_iso_init(self->iso_layer, s); - s_push_layer(s, mcs_hdr, 8); - return 0; + xrdp_iso_init(self->iso_layer, s); + s_push_layer(s, mcs_hdr, 8); + return 0; } /*****************************************************************************/ @@ -644,118 +723,132 @@ xrdp_mcs_init(struct xrdp_mcs* self, struct stream* s) /* Inform the callback that an mcs packet has been sent. This is needed so the module can send any high priority mcs packets like audio. */ static int APP_CC -xrdp_mcs_call_callback(struct xrdp_mcs* self) +xrdp_mcs_call_callback(struct xrdp_mcs *self) { - int rv; - struct xrdp_session* session; + int rv; + struct xrdp_session *session; - rv = 0; - /* if there is a callback, call it here */ - session = self->sec_layer->rdp_layer->session; - if (session != 0) - { - if (session->callback != 0) + rv = 0; + /* if there is a callback, call it here */ + session = self->sec_layer->rdp_layer->session; + + if (session != 0) { - /* in xrdp_wm.c */ - rv = session->callback(session->id, 0x5556, 0, 0, 0, 0); + if (session->callback != 0) + { + /* in xrdp_wm.c */ + rv = session->callback(session->id, 0x5556, 0, 0, 0, 0); + } + else + { + g_writeln("in xrdp_mcs_send, session->callback is nil"); + } } else { - g_writeln("in xrdp_mcs_send, session->callback is nil"); + g_writeln("in xrdp_mcs_send, session is nil"); } - } - else - { - g_writeln("in xrdp_mcs_send, session is nil"); - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_send(struct xrdp_mcs* self, struct stream* s, int chan) +xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan) { - int len; - char* lp; - //static int max_len = 0; + int len; + char *lp; + //static int max_len = 0; - DEBUG((" in xrdp_mcs_send")); - s_pop_layer(s, mcs_hdr); - len = (s->end - s->p) - 8; - if (len > 8192 * 2) - { - g_writeln("error in xrdp_mcs_send, size too bog, its %d", len); - } - //if (len > max_len) - //{ - // max_len = len; - // g_printf("mcs max length is %d\r\n", max_len); - //} - //g_printf("mcs length %d max length is %d\r\n", len, max_len); - //g_printf("mcs length %d\r\n", len); - out_uint8(s, MCS_SDIN << 2); - out_uint16_be(s, self->userid); - out_uint16_be(s, chan); - out_uint8(s, 0x70); - if (len >= 128) - { - len = len | 0x8000; - out_uint16_be(s, len); - } - else - { - out_uint8(s, len); - /* move everything up one byte */ - lp = s->p; - while (lp < s->end) + DEBUG((" in xrdp_mcs_send")); + s_pop_layer(s, mcs_hdr); + len = (s->end - s->p) - 8; + + if (len > 8192 * 2) { - lp[0] = lp[1]; - lp++; + g_writeln("error in xrdp_mcs_send, size too bog, its %d", len); } - s->end--; - } - if (xrdp_iso_send(self->iso_layer, s) != 0) - { - DEBUG((" out xrdp_mcs_send error")); - return 1; - } - /* todo, do we need to call this for every mcs packet, - maybe every 5 or so */ - if (chan == MCS_GLOBAL_CHANNEL) - { - xrdp_mcs_call_callback(self); - } - DEBUG((" out xrdp_mcs_send")); - return 0; + + //if (len > max_len) + //{ + // max_len = len; + // g_printf("mcs max length is %d\r\n", max_len); + //} + //g_printf("mcs length %d max length is %d\r\n", len, max_len); + //g_printf("mcs length %d\r\n", len); + out_uint8(s, MCS_SDIN << 2); + out_uint16_be(s, self->userid); + out_uint16_be(s, chan); + out_uint8(s, 0x70); + + if (len >= 128) + { + len = len | 0x8000; + out_uint16_be(s, len); + } + else + { + out_uint8(s, len); + /* move everything up one byte */ + lp = s->p; + + while (lp < s->end) + { + lp[0] = lp[1]; + lp++; + } + + s->end--; + } + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + DEBUG((" out xrdp_mcs_send error")); + return 1; + } + + /* todo, do we need to call this for every mcs packet, + maybe every 5 or so */ + if (chan == MCS_GLOBAL_CHANNEL) + { + xrdp_mcs_call_callback(self); + } + + DEBUG((" out xrdp_mcs_send")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_disconnect(struct xrdp_mcs* self) +xrdp_mcs_disconnect(struct xrdp_mcs *self) { - struct stream* s; + struct stream *s; + + DEBUG((" in xrdp_mcs_disconnect")); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_disconnect error")); + return 1; + } + + out_uint8(s, (MCS_DPUM << 2) | 1); + out_uint8(s, 0x80); + s_mark_end(s); + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_disconnect error")); + return 1; + } - DEBUG((" in xrdp_mcs_disconnect")); - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_init(self->iso_layer, s) != 0) - { free_stream(s); - DEBUG((" out xrdp_mcs_disconnect error")); - return 1; - } - out_uint8(s, (MCS_DPUM << 2) | 1); - out_uint8(s, 0x80); - s_mark_end(s); - if (xrdp_iso_send(self->iso_layer, s) != 0) - { - free_stream(s); - DEBUG((" out xrdp_mcs_disconnect error")); - return 1; - } - free_stream(s); - DEBUG((" out xrdp_mcs_disconnect")); - return 0; + DEBUG((" out xrdp_mcs_disconnect")); + return 0; } diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c index e7739e3e..438151da 100644 --- a/libxrdp/xrdp_orders.c +++ b/libxrdp/xrdp_orders.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - orders - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * orders + */ #include "libxrdp.h" @@ -28,138 +26,151 @@ #define LLOG_LEVEL 2 #define LLOGLN(_log_level, _params) \ -{ \ - if (_log_level < LLOG_LEVEL) \ - { \ - g_write("xrdp_orders.c [%10.10u]: ", g_time3()); \ - g_writeln _params ; \ - } \ -} + { \ + if (_log_level < LLOG_LEVEL) \ + { \ + g_write("xrdp_orders.c [%10.10u]: ", g_time3()); \ + g_writeln _params ; \ + } \ + } /*****************************************************************************/ -struct xrdp_orders* APP_CC -xrdp_orders_create(struct xrdp_session* session, struct xrdp_rdp* rdp_layer) +struct xrdp_orders *APP_CC +xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer) { - struct xrdp_orders* self; + struct xrdp_orders *self; - self = (struct xrdp_orders*)g_malloc(sizeof(struct xrdp_orders), 1); - self->session = session; - self->rdp_layer = rdp_layer; - make_stream(self->out_s); - init_stream(self->out_s, 16384); - self->orders_state.clip_right = 1; /* silly rdp right clip */ - self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ - return self; + self = (struct xrdp_orders *)g_malloc(sizeof(struct xrdp_orders), 1); + self->session = session; + self->rdp_layer = rdp_layer; + make_stream(self->out_s); + init_stream(self->out_s, 16384); + self->orders_state.clip_right = 1; /* silly rdp right clip */ + self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ + return self; } /*****************************************************************************/ void APP_CC -xrdp_orders_delete(struct xrdp_orders* self) +xrdp_orders_delete(struct xrdp_orders *self) { - if (self == 0) - { - return; - } - free_stream(self->out_s); - g_free(self->orders_state.text_data); - g_free(self); + if (self == 0) + { + return; + } + + free_stream(self->out_s); + g_free(self->orders_state.text_data); + g_free(self); } /*****************************************************************************/ /* set all values to zero */ /* returns error */ int APP_CC -xrdp_orders_reset(struct xrdp_orders* self) +xrdp_orders_reset(struct xrdp_orders *self) { - if (xrdp_orders_force_send(self) != 0) - { - return 1; - } - g_free(self->orders_state.text_data); - g_memset(&(self->orders_state), 0, sizeof(self->orders_state)); - self->order_count_ptr = 0; - self->order_count = 0; - self->order_level = 0; - self->orders_state.clip_right = 1; /* silly rdp right clip */ - self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ - return 0; -} + if (xrdp_orders_force_send(self) != 0) + { + return 1; + } -/*****************************************************************************/ -/* returns error */ -int APP_CC -xrdp_orders_init(struct xrdp_orders* self) -{ - self->order_level++; - if (self->order_level == 1) - { + g_free(self->orders_state.text_data); + g_memset(&(self->orders_state), 0, sizeof(self->orders_state)); + self->order_count_ptr = 0; self->order_count = 0; - /* is this big enough */ - if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0) - { - return 1; - } - out_uint16_le(self->out_s, RDP_UPDATE_ORDERS); - out_uint8s(self->out_s, 2); /* pad */ - self->order_count_ptr = self->out_s->p; - out_uint8s(self->out_s, 2); /* number of orders, set later */ - out_uint8s(self->out_s, 2); /* pad */ - } - return 0; + self->order_level = 0; + self->orders_state.clip_right = 1; /* silly rdp right clip */ + self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_orders_send(struct xrdp_orders* self) +xrdp_orders_init(struct xrdp_orders *self) { - int rv; + self->order_level++; - rv = 0; - if (self->order_level > 0) - { - self->order_level--; - if ((self->order_level == 0) && (self->order_count > 0)) + if (self->order_level == 1) { - s_mark_end(self->out_s); - DEBUG(("xrdp_orders_send sending %d orders", self->order_count)); - self->order_count_ptr[0] = self->order_count; - self->order_count_ptr[1] = self->order_count >> 8; - self->order_count = 0; - if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, - RDP_DATA_PDU_UPDATE) != 0) - { - rv = 1; - } + self->order_count = 0; + + /* is this big enough */ + if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0) + { + return 1; + } + + out_uint16_le(self->out_s, RDP_UPDATE_ORDERS); + out_uint8s(self->out_s, 2); /* pad */ + self->order_count_ptr = self->out_s->p; + out_uint8s(self->out_s, 2); /* number of orders, set later */ + out_uint8s(self->out_s, 2); /* pad */ } - } - return rv; + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_orders_force_send(struct xrdp_orders* self) +xrdp_orders_send(struct xrdp_orders *self) { - if (self == 0) - { - return 1; - } - if ((self->order_level > 0) && (self->order_count > 0)) - { - s_mark_end(self->out_s); - DEBUG(("xrdp_orders_force_send sending %d orders", self->order_count)); - self->order_count_ptr[0] = self->order_count; - self->order_count_ptr[1] = self->order_count >> 8; - if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, - RDP_DATA_PDU_UPDATE) != 0) + int rv; + + rv = 0; + + if (self->order_level > 0) { - return 1; + self->order_level--; + + if ((self->order_level == 0) && (self->order_count > 0)) + { + s_mark_end(self->out_s); + DEBUG(("xrdp_orders_send sending %d orders", self->order_count)); + self->order_count_ptr[0] = self->order_count; + self->order_count_ptr[1] = self->order_count >> 8; + self->order_count = 0; + + if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, + RDP_DATA_PDU_UPDATE) != 0) + { + rv = 1; + } + } } - } - self->order_count = 0; - self->order_level = 0; - return 0; + + return rv; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +xrdp_orders_force_send(struct xrdp_orders *self) +{ + if (self == 0) + { + return 1; + } + + if ((self->order_level > 0) && (self->order_count > 0)) + { + s_mark_end(self->out_s); + DEBUG(("xrdp_orders_force_send sending %d orders", self->order_count)); + self->order_count_ptr[0] = self->order_count; + self->order_count_ptr[1] = self->order_count >> 8; + + if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, + RDP_DATA_PDU_UPDATE) != 0) + { + return 1; + } + } + + self->order_count = 0; + self->order_level = 0; + return 0; } /*****************************************************************************/ @@ -167,232 +178,258 @@ xrdp_orders_force_send(struct xrdp_orders* self) /* send what we got and init a new one */ /* returns error */ int APP_CC -xrdp_orders_check(struct xrdp_orders* self, int max_size) +xrdp_orders_check(struct xrdp_orders *self, int max_size) { - int size; - int max_packet_size; + int size; + int max_packet_size; - if (self->rdp_layer->client_info.bpp == 8) - { - max_packet_size = 8000; - } - else - { - max_packet_size = 16000; - } - if (self->order_level < 1) - { - if (max_size > max_packet_size) + if (self->rdp_layer->client_info.bpp == 8) { - return 1; + max_packet_size = 8000; } else { - return 0; + max_packet_size = 16000; } - } - size = (int)(self->out_s->p - self->order_count_ptr); - if ((size < 0) || (size > max_packet_size)) - { - return 1; - } - if ((size + max_size + 100) > max_packet_size) - { - xrdp_orders_force_send(self); - xrdp_orders_init(self); - } - return 0; + + if (self->order_level < 1) + { + if (max_size > max_packet_size) + { + return 1; + } + else + { + return 0; + } + } + + size = (int)(self->out_s->p - self->order_count_ptr); + + if ((size < 0) || (size > max_packet_size)) + { + return 1; + } + + if ((size + max_size + 100) > max_packet_size) + { + xrdp_orders_force_send(self); + xrdp_orders_init(self); + } + + return 0; } /*****************************************************************************/ /* check if rect is the same as the last one sent */ /* returns boolean */ static int APP_CC -xrdp_orders_last_bounds(struct xrdp_orders* self, struct xrdp_rect* rect) +xrdp_orders_last_bounds(struct xrdp_orders *self, struct xrdp_rect *rect) { - if (rect == 0) - { + if (rect == 0) + { + return 0; + } + + if ((rect->left == self->orders_state.clip_left) && + (rect->top == self->orders_state.clip_top) && + (rect->right == self->orders_state.clip_right) && + (rect->bottom == self->orders_state.clip_bottom)) + { + return 1; + } + return 0; - } - if ((rect->left == self->orders_state.clip_left) && - (rect->top == self->orders_state.clip_top) && - (rect->right == self->orders_state.clip_right) && - (rect->bottom == self->orders_state.clip_bottom)) - { - return 1; - } - return 0; } /*****************************************************************************/ /* check if all coords are withing 256 bytes */ /* returns boolean */ static int APP_CC -xrdp_orders_send_delta(struct xrdp_orders* self, int* vals, int count) +xrdp_orders_send_delta(struct xrdp_orders *self, int *vals, int count) { - int i; + int i; - for (i = 0; i < count; i += 2) - { - if (g_abs(vals[i] - vals[i + 1]) >= 128) + for (i = 0; i < count; i += 2) { - return 0; + if (g_abs(vals[i] - vals[i + 1]) >= 128) + { + return 0; + } } - } - return 1; + + return 1; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_orders_out_bounds(struct xrdp_orders* self, struct xrdp_rect* rect) +xrdp_orders_out_bounds(struct xrdp_orders *self, struct xrdp_rect *rect) { - char* bounds_flags_ptr; - int bounds_flags; + char *bounds_flags_ptr; + int bounds_flags; - bounds_flags = 0; - bounds_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - /* left */ - if (rect->left == self->orders_state.clip_left) - { - } - else if (g_abs(rect->left - self->orders_state.clip_left) < 128) - { - bounds_flags |= 0x10; - } - else - { - bounds_flags |= 0x01; - } - /* top */ - if (rect->top == self->orders_state.clip_top) - { - } - else if (g_abs(rect->top - self->orders_state.clip_top) < 128) - { - bounds_flags |= 0x20; - } - else - { - bounds_flags |= 0x02; - } - /* right */ - if (rect->right == self->orders_state.clip_right) - { - } - else if (g_abs(rect->right - self->orders_state.clip_right) < 128) - { - bounds_flags |= 0x40; - } - else - { - bounds_flags |= 0x04; - } - /* bottom */ - if (rect->bottom == self->orders_state.clip_bottom) - { - } - else if (g_abs(rect->bottom - self->orders_state.clip_bottom) < 128) - { - bounds_flags |= 0x80; - } - else - { - bounds_flags |= 0x08; - } - /* left */ - if (bounds_flags & 0x01) - { - out_uint16_le(self->out_s, rect->left); - } - else if (bounds_flags & 0x10) - { - out_uint8(self->out_s, rect->left - self->orders_state.clip_left); - } - self->orders_state.clip_left = rect->left; - /* top */ - if (bounds_flags & 0x02) - { - out_uint16_le(self->out_s, rect->top); - } - else if (bounds_flags & 0x20) - { - out_uint8(self->out_s, rect->top - self->orders_state.clip_top); - } - self->orders_state.clip_top = rect->top; - /* right */ - if (bounds_flags & 0x04) - { - out_uint16_le(self->out_s, rect->right - 1); /* silly rdp right clip */ - } - else if (bounds_flags & 0x40) - { - out_uint8(self->out_s, rect->right - self->orders_state.clip_right); - } - self->orders_state.clip_right = rect->right; - /* bottom */ - if (bounds_flags & 0x08) - { - out_uint16_le(self->out_s, rect->bottom - 1); /* silly rdp bottom clip */ - } - else if (bounds_flags & 0x80) - { - out_uint8(self->out_s, rect->bottom - self->orders_state.clip_bottom); - } - self->orders_state.clip_bottom = rect->bottom; - /* set flags */ - *bounds_flags_ptr = bounds_flags; - return 0; + bounds_flags = 0; + bounds_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + /* left */ + if (rect->left == self->orders_state.clip_left) + { + } + else if (g_abs(rect->left - self->orders_state.clip_left) < 128) + { + bounds_flags |= 0x10; + } + else + { + bounds_flags |= 0x01; + } + + /* top */ + if (rect->top == self->orders_state.clip_top) + { + } + else if (g_abs(rect->top - self->orders_state.clip_top) < 128) + { + bounds_flags |= 0x20; + } + else + { + bounds_flags |= 0x02; + } + + /* right */ + if (rect->right == self->orders_state.clip_right) + { + } + else if (g_abs(rect->right - self->orders_state.clip_right) < 128) + { + bounds_flags |= 0x40; + } + else + { + bounds_flags |= 0x04; + } + + /* bottom */ + if (rect->bottom == self->orders_state.clip_bottom) + { + } + else if (g_abs(rect->bottom - self->orders_state.clip_bottom) < 128) + { + bounds_flags |= 0x80; + } + else + { + bounds_flags |= 0x08; + } + + /* left */ + if (bounds_flags & 0x01) + { + out_uint16_le(self->out_s, rect->left); + } + else if (bounds_flags & 0x10) + { + out_uint8(self->out_s, rect->left - self->orders_state.clip_left); + } + + self->orders_state.clip_left = rect->left; + + /* top */ + if (bounds_flags & 0x02) + { + out_uint16_le(self->out_s, rect->top); + } + else if (bounds_flags & 0x20) + { + out_uint8(self->out_s, rect->top - self->orders_state.clip_top); + } + + self->orders_state.clip_top = rect->top; + + /* right */ + if (bounds_flags & 0x04) + { + out_uint16_le(self->out_s, rect->right - 1); /* silly rdp right clip */ + } + else if (bounds_flags & 0x40) + { + out_uint8(self->out_s, rect->right - self->orders_state.clip_right); + } + + self->orders_state.clip_right = rect->right; + + /* bottom */ + if (bounds_flags & 0x08) + { + out_uint16_le(self->out_s, rect->bottom - 1); /* silly rdp bottom clip */ + } + else if (bounds_flags & 0x80) + { + out_uint8(self->out_s, rect->bottom - self->orders_state.clip_bottom); + } + + self->orders_state.clip_bottom = rect->bottom; + /* set flags */ + *bounds_flags_ptr = bounds_flags; + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_order_pack_small_or_tiny(struct xrdp_orders* self, - char* order_flags_ptr, int orders_flags, - char* present_ptr, int present, +xrdp_order_pack_small_or_tiny(struct xrdp_orders *self, + char *order_flags_ptr, int orders_flags, + char *present_ptr, int present, int present_size) { - int move_up_count = 0; - int index = 0; - int size = 0; - int keep_looking = 1; + int move_up_count = 0; + int index = 0; + int size = 0; + int keep_looking = 1; - move_up_count = 0; - keep_looking = 1; - for (index = present_size - 1; index >= 0; index--) - { - if (keep_looking) + move_up_count = 0; + keep_looking = 1; + + for (index = present_size - 1; index >= 0; index--) { - if (((present >> (index * 8)) & 0xff) == 0) - { - move_up_count++; - } - else - { - keep_looking = 0; - } + if (keep_looking) + { + if (((present >> (index * 8)) & 0xff) == 0) + { + move_up_count++; + } + else + { + keep_looking = 0; + } + } + + present_ptr[index] = present >> (index * 8); } - present_ptr[index] = present >> (index * 8); - } - if (move_up_count > 0) - { - /* move_up_count should be 0, 1, 2, or 3 - shifting it 6 will make it RDP_ORDER_TINY(0x80) or - RDP_ORDER_SMALL(0x40) or both */ - orders_flags |= move_up_count << 6; - size = (int)(self->out_s->p - present_ptr); - size -= present_size; - for (index = 0; index < size; index++) + + if (move_up_count > 0) { - present_ptr[index + (present_size - move_up_count)] = - present_ptr[index + present_size]; + /* move_up_count should be 0, 1, 2, or 3 + shifting it 6 will make it RDP_ORDER_TINY(0x80) or + RDP_ORDER_SMALL(0x40) or both */ + orders_flags |= move_up_count << 6; + size = (int)(self->out_s->p - present_ptr); + size -= present_size; + + for (index = 0; index < size; index++) + { + present_ptr[index + (present_size - move_up_count)] = + present_ptr[index + present_size]; + } + + self->out_s->p -= move_up_count; } - self->out_s->p -= move_up_count; - } - order_flags_ptr[0] = orders_flags; - return 0; + + order_flags_ptr[0] = orders_flags; + return 0; } /*****************************************************************************/ @@ -400,140 +437,166 @@ xrdp_order_pack_small_or_tiny(struct xrdp_orders* self, /* send a solid rect to client */ /* max size 23 */ int APP_CC -xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy, - int color, struct xrdp_rect* rect) +xrdp_orders_rect(struct xrdp_orders *self, int x, int y, int cx, int cy, + int color, struct xrdp_rect *rect) { - int order_flags; - int vals[8]; - int present; - char* present_ptr; - char* order_flags_ptr; + int order_flags; + int vals[8]; + int present; + char *present_ptr; + char *order_flags_ptr; - xrdp_orders_check(self, 23); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_RECT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_RECT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) + xrdp_orders_check(self, 23); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_RECT) { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } + order_flags |= RDP_ORDER_CHANGE; } - } - vals[0] = x; - vals[1] = self->orders_state.rect_x; - vals[2] = y; - vals[3] = self->orders_state.rect_y; - vals[4] = cx; - vals[5] = self->orders_state.rect_cx; - vals[6] = cy; - vals[7] = self->orders_state.rect_cy; - if (xrdp_orders_send_delta(self, vals, 8)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 1 byte */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (x != self->orders_state.rect_x) - { - present |= 0x01; - if (order_flags & RDP_ORDER_DELTA) + + self->orders_state.last_order = RDP_ORDER_RECT; + + if (rect != 0) { - out_uint8(self->out_s, x - self->orders_state.rect_x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - else + + vals[0] = x; + vals[1] = self->orders_state.rect_x; + vals[2] = y; + vals[3] = self->orders_state.rect_y; + vals[4] = cx; + vals[5] = self->orders_state.rect_cx; + vals[6] = cy; + vals[7] = self->orders_state.rect_cy; + + if (xrdp_orders_send_delta(self, vals, 8)) { - out_uint16_le(self->out_s, x); + order_flags |= RDP_ORDER_DELTA; } - self->orders_state.rect_x = x; - } - if (y != self->orders_state.rect_y) - { - present |= 0x02; - if (order_flags & RDP_ORDER_DELTA) + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint8(self->out_s, y - self->orders_state.rect_y); + out_uint8(self->out_s, self->orders_state.last_order); } - else + + present = 0; + /* present, set later, 1 byte */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint16_le(self->out_s, y); + xrdp_orders_out_bounds(self, rect); } - self->orders_state.rect_y = y; - } - if (cx != self->orders_state.rect_cx) - { - present |= 0x04; - if (order_flags & RDP_ORDER_DELTA) + + if (x != self->orders_state.rect_x) { - out_uint8(self->out_s, cx - self->orders_state.rect_cx); + present |= 0x01; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.rect_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.rect_x = x; } - else + + if (y != self->orders_state.rect_y) { - out_uint16_le(self->out_s, cx); + present |= 0x02; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.rect_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.rect_y = y; } - self->orders_state.rect_cx = cx; - } - if (cy != self->orders_state.rect_cy) - { - present |= 0x08; - if (order_flags & RDP_ORDER_DELTA) + + if (cx != self->orders_state.rect_cx) { - out_uint8(self->out_s, cy - self->orders_state.rect_cy); + present |= 0x04; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.rect_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.rect_cx = cx; } - else + + if (cy != self->orders_state.rect_cy) { - out_uint16_le(self->out_s, cy); + present |= 0x08; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.rect_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.rect_cy = cy; } - self->orders_state.rect_cy = cy; - } - if ((color & 0xff) != (self->orders_state.rect_color & 0xff)) - { - present |= 0x10; - self->orders_state.rect_color = - (self->orders_state.rect_color & 0xffff00) | (color & 0xff); - out_uint8(self->out_s, color); - } - if ((color & 0xff00) != (self->orders_state.rect_color & 0xff00)) - { - present |= 0x20; - self->orders_state.rect_color = - (self->orders_state.rect_color & 0xff00ff) | (color & 0xff00); - out_uint8(self->out_s, color >> 8); - } - if ((color & 0xff0000) != (self->orders_state.rect_color & 0xff0000)) - { - present |= 0x40; - self->orders_state.rect_color = - (self->orders_state.rect_color & 0x00ffff) | (color & 0xff0000); - out_uint8(self->out_s, color >> 16); - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 1); - return 0; + + if ((color & 0xff) != (self->orders_state.rect_color & 0xff)) + { + present |= 0x10; + self->orders_state.rect_color = + (self->orders_state.rect_color & 0xffff00) | (color & 0xff); + out_uint8(self->out_s, color); + } + + if ((color & 0xff00) != (self->orders_state.rect_color & 0xff00)) + { + present |= 0x20; + self->orders_state.rect_color = + (self->orders_state.rect_color & 0xff00ff) | (color & 0xff00); + out_uint8(self->out_s, color >> 8); + } + + if ((color & 0xff0000) != (self->orders_state.rect_color & 0xff0000)) + { + present |= 0x40; + self->orders_state.rect_color = + (self->orders_state.rect_color & 0x00ffff) | (color & 0xff0000); + out_uint8(self->out_s, color >> 16); + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 1); + return 0; } /*****************************************************************************/ @@ -541,156 +604,186 @@ xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy, /* send a screen blt order */ /* max size 25 */ int APP_CC -xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y, +xrdp_orders_screen_blt(struct xrdp_orders *self, int x, int y, int cx, int cy, int srcx, int srcy, - int rop, struct xrdp_rect* rect) + int rop, struct xrdp_rect *rect) { - int order_flags = 0; - int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int present = 0; - char* present_ptr = (char *)NULL; - char* order_flags_ptr = (char *)NULL; + int order_flags = 0; + int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int present = 0; + char *present_ptr = (char *)NULL; + char *order_flags_ptr = (char *)NULL; - xrdp_orders_check(self, 25); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_SCREENBLT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_SCREENBLT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) + xrdp_orders_check(self, 25); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_SCREENBLT) { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } + order_flags |= RDP_ORDER_CHANGE; } - } - vals[0] = x; - vals[1] = self->orders_state.scr_blt_x; - vals[2] = y; - vals[3] = self->orders_state.scr_blt_y; - vals[4] = cx; - vals[5] = self->orders_state.scr_blt_cx; - vals[6] = cy; - vals[7] = self->orders_state.scr_blt_cy; - vals[8] = srcx; - vals[9] = self->orders_state.scr_blt_srcx; - vals[10] = srcy; - vals[11] = self->orders_state.scr_blt_srcy; - if (xrdp_orders_send_delta(self, vals, 12)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 1 byte */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (x != self->orders_state.scr_blt_x) - { - present |= 0x01; - if (order_flags & RDP_ORDER_DELTA) + + self->orders_state.last_order = RDP_ORDER_SCREENBLT; + + if (rect != 0) { - out_uint8(self->out_s, x - self->orders_state.scr_blt_x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - else + + vals[0] = x; + vals[1] = self->orders_state.scr_blt_x; + vals[2] = y; + vals[3] = self->orders_state.scr_blt_y; + vals[4] = cx; + vals[5] = self->orders_state.scr_blt_cx; + vals[6] = cy; + vals[7] = self->orders_state.scr_blt_cy; + vals[8] = srcx; + vals[9] = self->orders_state.scr_blt_srcx; + vals[10] = srcy; + vals[11] = self->orders_state.scr_blt_srcy; + + if (xrdp_orders_send_delta(self, vals, 12)) { - out_uint16_le(self->out_s, x); + order_flags |= RDP_ORDER_DELTA; } - self->orders_state.scr_blt_x = x; - } - if (y != self->orders_state.scr_blt_y) - { - present |= 0x02; - if (order_flags & RDP_ORDER_DELTA) + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint8(self->out_s, y - self->orders_state.scr_blt_y); + out_uint8(self->out_s, self->orders_state.last_order); } - else + + present = 0; + /* present, set later, 1 byte */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint16_le(self->out_s, y); + xrdp_orders_out_bounds(self, rect); } - self->orders_state.scr_blt_y = y; - } - if (cx != self->orders_state.scr_blt_cx) - { - present |= 0x04; - if (order_flags & RDP_ORDER_DELTA) + + if (x != self->orders_state.scr_blt_x) { - out_uint8(self->out_s, cx - self->orders_state.scr_blt_cx); + present |= 0x01; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.scr_blt_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.scr_blt_x = x; } - else + + if (y != self->orders_state.scr_blt_y) { - out_uint16_le(self->out_s, cx); + present |= 0x02; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.scr_blt_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.scr_blt_y = y; } - self->orders_state.scr_blt_cx = cx; - } - if (cy != self->orders_state.scr_blt_cy) - { - present |= 0x08; - if (order_flags & RDP_ORDER_DELTA) + + if (cx != self->orders_state.scr_blt_cx) { - out_uint8(self->out_s, cy - self->orders_state.scr_blt_cy); + present |= 0x04; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.scr_blt_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.scr_blt_cx = cx; } - else + + if (cy != self->orders_state.scr_blt_cy) { - out_uint16_le(self->out_s, cy); + present |= 0x08; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.scr_blt_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.scr_blt_cy = cy; } - self->orders_state.scr_blt_cy = cy; - } - if (rop != self->orders_state.scr_blt_rop) - { - present |= 0x10; - out_uint8(self->out_s, rop); - self->orders_state.scr_blt_rop = rop; - } - if (srcx != self->orders_state.scr_blt_srcx) - { - present |= 0x20; - if (order_flags & RDP_ORDER_DELTA) + + if (rop != self->orders_state.scr_blt_rop) { - out_uint8(self->out_s, srcx - self->orders_state.scr_blt_srcx); + present |= 0x10; + out_uint8(self->out_s, rop); + self->orders_state.scr_blt_rop = rop; } - else + + if (srcx != self->orders_state.scr_blt_srcx) { - out_uint16_le(self->out_s, srcx); + present |= 0x20; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcx - self->orders_state.scr_blt_srcx); + } + else + { + out_uint16_le(self->out_s, srcx); + } + + self->orders_state.scr_blt_srcx = srcx; } - self->orders_state.scr_blt_srcx = srcx; - } - if (srcy != self->orders_state.scr_blt_srcy) - { - present |= 0x40; - if (order_flags & RDP_ORDER_DELTA) + + if (srcy != self->orders_state.scr_blt_srcy) { - out_uint8(self->out_s, srcy - self->orders_state.scr_blt_srcy); + present |= 0x40; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcy - self->orders_state.scr_blt_srcy); + } + else + { + out_uint16_le(self->out_s, srcy); + } + + self->orders_state.scr_blt_srcy = srcy; } - else - { - out_uint16_le(self->out_s, srcy); - } - self->orders_state.scr_blt_srcy = srcy; - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 1); - return 0; + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 1); + return 0; } /*****************************************************************************/ @@ -698,182 +791,215 @@ xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y, /* send a pat blt order */ /* max size 39 */ int APP_CC -xrdp_orders_pat_blt(struct xrdp_orders* self, int x, int y, +xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y, int cx, int cy, int rop, int bg_color, - int fg_color, struct xrdp_brush* brush, - struct xrdp_rect* rect) + int fg_color, struct xrdp_brush *brush, + struct xrdp_rect *rect) { - int order_flags; - int present; - int vals[8]; - char* present_ptr; - char* order_flags_ptr; - struct xrdp_brush blank_brush; + int order_flags; + int present; + int vals[8]; + char *present_ptr; + char *order_flags_ptr; + struct xrdp_brush blank_brush; - xrdp_orders_check(self, 39); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_PATBLT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_PATBLT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) + xrdp_orders_check(self, 39); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_PATBLT) { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } + order_flags |= RDP_ORDER_CHANGE; } - } - vals[0] = x; - vals[1] = self->orders_state.pat_blt_x; - vals[2] = y; - vals[3] = self->orders_state.pat_blt_y; - vals[4] = cx; - vals[5] = self->orders_state.pat_blt_cx; - vals[6] = cy; - vals[7] = self->orders_state.pat_blt_cy; - if (xrdp_orders_send_delta(self, vals, 8)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 2 bytes */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 2); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (x != self->orders_state.pat_blt_x) - { - present |= 0x0001; - if (order_flags & RDP_ORDER_DELTA) + + self->orders_state.last_order = RDP_ORDER_PATBLT; + + if (rect != 0) { - out_uint8(self->out_s, x - self->orders_state.pat_blt_x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - else + + vals[0] = x; + vals[1] = self->orders_state.pat_blt_x; + vals[2] = y; + vals[3] = self->orders_state.pat_blt_y; + vals[4] = cx; + vals[5] = self->orders_state.pat_blt_cx; + vals[6] = cy; + vals[7] = self->orders_state.pat_blt_cy; + + if (xrdp_orders_send_delta(self, vals, 8)) { - out_uint16_le(self->out_s, x); + order_flags |= RDP_ORDER_DELTA; } - self->orders_state.pat_blt_x = x; - } - if (y != self->orders_state.pat_blt_y) - { - present |= 0x0002; - if (order_flags & RDP_ORDER_DELTA) + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint8(self->out_s, y - self->orders_state.pat_blt_y); + out_uint8(self->out_s, self->orders_state.last_order); } - else + + present = 0; + /* present, set later, 2 bytes */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 2); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint16_le(self->out_s, y); + xrdp_orders_out_bounds(self, rect); } - self->orders_state.pat_blt_y = y; - } - if (cx != self->orders_state.pat_blt_cx) - { - present |= 0x0004; - if (order_flags & RDP_ORDER_DELTA) + + if (x != self->orders_state.pat_blt_x) { - out_uint8(self->out_s, cx - self->orders_state.pat_blt_cx); + present |= 0x0001; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.pat_blt_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.pat_blt_x = x; } - else + + if (y != self->orders_state.pat_blt_y) { - out_uint16_le(self->out_s, cx); + present |= 0x0002; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.pat_blt_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.pat_blt_y = y; } - self->orders_state.pat_blt_cx = cx; - } - if (cy != self->orders_state.pat_blt_cy) - { - present |= 0x0008; - if (order_flags & RDP_ORDER_DELTA) + + if (cx != self->orders_state.pat_blt_cx) { - out_uint8(self->out_s, cy - self->orders_state.pat_blt_cy); + present |= 0x0004; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.pat_blt_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.pat_blt_cx = cx; } - else + + if (cy != self->orders_state.pat_blt_cy) { - out_uint16_le(self->out_s, cy); + present |= 0x0008; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.pat_blt_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.pat_blt_cy = cy; } - self->orders_state.pat_blt_cy = cy; - } - if (rop != self->orders_state.pat_blt_rop) - { - present |= 0x0010; - /* PATCOPY PATPAINT PATINVERT DSTINVERT BLACKNESS WHITENESS */ - out_uint8(self->out_s, rop); - self->orders_state.pat_blt_rop = rop; - } - if (bg_color != self->orders_state.pat_blt_bg_color) - { - present |= 0x0020; - out_uint8(self->out_s, bg_color); - out_uint8(self->out_s, bg_color >> 8); - out_uint8(self->out_s, bg_color >> 16); - self->orders_state.pat_blt_bg_color = bg_color; - } - if (fg_color != self->orders_state.pat_blt_fg_color) - { - present |= 0x0040; - out_uint8(self->out_s, fg_color); - out_uint8(self->out_s, fg_color >> 8); - out_uint8(self->out_s, fg_color >> 16); - self->orders_state.pat_blt_fg_color = fg_color; - } - if (brush == 0) /* if nil use blank one */ - { /* todo can we just set style to zero */ - g_memset(&blank_brush, 0, sizeof(struct xrdp_brush)); - brush = &blank_brush; - } - if (brush->x_orgin != self->orders_state.pat_blt_brush.x_orgin) - { - present |= 0x0080; - out_uint8(self->out_s, brush->x_orgin); - self->orders_state.pat_blt_brush.x_orgin = brush->x_orgin; - } - if (brush->y_orgin != self->orders_state.pat_blt_brush.y_orgin) - { - present |= 0x0100; - out_uint8(self->out_s, brush->y_orgin); - self->orders_state.pat_blt_brush.y_orgin = brush->y_orgin; - } - if (brush->style != self->orders_state.pat_blt_brush.style) - { - present |= 0x0200; - out_uint8(self->out_s, brush->style); - self->orders_state.pat_blt_brush.style = brush->style; - } - if (brush->pattern[0] != self->orders_state.pat_blt_brush.pattern[0]) - { - present |= 0x0400; - out_uint8(self->out_s, brush->pattern[0]); - self->orders_state.pat_blt_brush.pattern[0] = brush->pattern[0]; - } - if (g_memcmp(brush->pattern + 1, - self->orders_state.pat_blt_brush.pattern + 1, 7) != 0) - { - present |= 0x0800; - out_uint8a(self->out_s, brush->pattern + 1, 7); - g_memcpy(self->orders_state.pat_blt_brush.pattern + 1, - brush->pattern + 1, 7); - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 2); - return 0; + + if (rop != self->orders_state.pat_blt_rop) + { + present |= 0x0010; + /* PATCOPY PATPAINT PATINVERT DSTINVERT BLACKNESS WHITENESS */ + out_uint8(self->out_s, rop); + self->orders_state.pat_blt_rop = rop; + } + + if (bg_color != self->orders_state.pat_blt_bg_color) + { + present |= 0x0020; + out_uint8(self->out_s, bg_color); + out_uint8(self->out_s, bg_color >> 8); + out_uint8(self->out_s, bg_color >> 16); + self->orders_state.pat_blt_bg_color = bg_color; + } + + if (fg_color != self->orders_state.pat_blt_fg_color) + { + present |= 0x0040; + out_uint8(self->out_s, fg_color); + out_uint8(self->out_s, fg_color >> 8); + out_uint8(self->out_s, fg_color >> 16); + self->orders_state.pat_blt_fg_color = fg_color; + } + + if (brush == 0) /* if nil use blank one */ + { + /* todo can we just set style to zero */ + g_memset(&blank_brush, 0, sizeof(struct xrdp_brush)); + brush = &blank_brush; + } + + if (brush->x_orgin != self->orders_state.pat_blt_brush.x_orgin) + { + present |= 0x0080; + out_uint8(self->out_s, brush->x_orgin); + self->orders_state.pat_blt_brush.x_orgin = brush->x_orgin; + } + + if (brush->y_orgin != self->orders_state.pat_blt_brush.y_orgin) + { + present |= 0x0100; + out_uint8(self->out_s, brush->y_orgin); + self->orders_state.pat_blt_brush.y_orgin = brush->y_orgin; + } + + if (brush->style != self->orders_state.pat_blt_brush.style) + { + present |= 0x0200; + out_uint8(self->out_s, brush->style); + self->orders_state.pat_blt_brush.style = brush->style; + } + + if (brush->pattern[0] != self->orders_state.pat_blt_brush.pattern[0]) + { + present |= 0x0400; + out_uint8(self->out_s, brush->pattern[0]); + self->orders_state.pat_blt_brush.pattern[0] = brush->pattern[0]; + } + + if (g_memcmp(brush->pattern + 1, + self->orders_state.pat_blt_brush.pattern + 1, 7) != 0) + { + present |= 0x0800; + out_uint8a(self->out_s, brush->pattern + 1, 7); + g_memcpy(self->orders_state.pat_blt_brush.pattern + 1, + brush->pattern + 1, 7); + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 2); + return 0; } /*****************************************************************************/ @@ -881,126 +1007,150 @@ xrdp_orders_pat_blt(struct xrdp_orders* self, int x, int y, /* send a dest blt order */ /* max size 21 */ int APP_CC -xrdp_orders_dest_blt(struct xrdp_orders* self, int x, int y, +xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y, int cx, int cy, int rop, - struct xrdp_rect* rect) + struct xrdp_rect *rect) { - int order_flags; - int vals[8]; - int present; - char* present_ptr; - char* order_flags_ptr; + int order_flags; + int vals[8]; + int present; + char *present_ptr; + char *order_flags_ptr; - xrdp_orders_check(self, 21); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_DESTBLT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_DESTBLT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) + xrdp_orders_check(self, 21); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_DESTBLT) { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } + order_flags |= RDP_ORDER_CHANGE; } - } - vals[0] = x; - vals[1] = self->orders_state.dest_blt_x; - vals[2] = y; - vals[3] = self->orders_state.dest_blt_y; - vals[4] = cx; - vals[5] = self->orders_state.dest_blt_cx; - vals[6] = cy; - vals[7] = self->orders_state.dest_blt_cy; - if (xrdp_orders_send_delta(self, vals, 8)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 1 byte */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (x != self->orders_state.dest_blt_x) - { - present |= 0x01; - if (order_flags & RDP_ORDER_DELTA) + + self->orders_state.last_order = RDP_ORDER_DESTBLT; + + if (rect != 0) { - out_uint8(self->out_s, x - self->orders_state.dest_blt_x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - else + + vals[0] = x; + vals[1] = self->orders_state.dest_blt_x; + vals[2] = y; + vals[3] = self->orders_state.dest_blt_y; + vals[4] = cx; + vals[5] = self->orders_state.dest_blt_cx; + vals[6] = cy; + vals[7] = self->orders_state.dest_blt_cy; + + if (xrdp_orders_send_delta(self, vals, 8)) { - out_uint16_le(self->out_s, x); + order_flags |= RDP_ORDER_DELTA; } - self->orders_state.dest_blt_x = x; - } - if (y != self->orders_state.dest_blt_y) - { - present |= 0x02; - if (order_flags & RDP_ORDER_DELTA) + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint8(self->out_s, y - self->orders_state.dest_blt_y); + out_uint8(self->out_s, self->orders_state.last_order); } - else + + present = 0; + /* present, set later, 1 byte */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint16_le(self->out_s, y); + xrdp_orders_out_bounds(self, rect); } - self->orders_state.dest_blt_y = y; - } - if (cx != self->orders_state.dest_blt_cx) - { - present |= 0x04; - if (order_flags & RDP_ORDER_DELTA) + + if (x != self->orders_state.dest_blt_x) { - out_uint8(self->out_s, cx - self->orders_state.dest_blt_cx); + present |= 0x01; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.dest_blt_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.dest_blt_x = x; } - else + + if (y != self->orders_state.dest_blt_y) { - out_uint16_le(self->out_s, cx); + present |= 0x02; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.dest_blt_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.dest_blt_y = y; } - self->orders_state.dest_blt_cx = cx; - } - if (cy != self->orders_state.dest_blt_cy) - { - present |= 0x08; - if (order_flags & RDP_ORDER_DELTA) + + if (cx != self->orders_state.dest_blt_cx) { - out_uint8(self->out_s, cy - self->orders_state.dest_blt_cy); + present |= 0x04; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.dest_blt_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.dest_blt_cx = cx; } - else + + if (cy != self->orders_state.dest_blt_cy) { - out_uint16_le(self->out_s, cy); + present |= 0x08; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.dest_blt_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.dest_blt_cy = cy; } - self->orders_state.dest_blt_cy = cy; - } - if (rop != self->orders_state.dest_blt_rop) - { - present |= 0x10; - out_uint8(self->out_s, rop); - self->orders_state.dest_blt_rop = rop; - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 1); - return 0; + + if (rop != self->orders_state.dest_blt_rop) + { + present |= 0x10; + out_uint8(self->out_s, rop); + self->orders_state.dest_blt_rop = rop; + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 1); + return 0; } /*****************************************************************************/ @@ -1008,182 +1158,214 @@ xrdp_orders_dest_blt(struct xrdp_orders* self, int x, int y, /* send a line order */ /* max size 32 */ int APP_CC -xrdp_orders_line(struct xrdp_orders* self, int mix_mode, +xrdp_orders_line(struct xrdp_orders *self, int mix_mode, int startx, int starty, int endx, int endy, int rop, int bg_color, - struct xrdp_pen* pen, - struct xrdp_rect* rect) + struct xrdp_pen *pen, + struct xrdp_rect *rect) { - int order_flags = 0; - int vals[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - int present = 0; - char* present_ptr = (char *)NULL; - char* order_flags_ptr = (char *)NULL; - struct xrdp_pen blank_pen; + int order_flags = 0; + int vals[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int present = 0; + char *present_ptr = (char *)NULL; + char *order_flags_ptr = (char *)NULL; + struct xrdp_pen blank_pen; - g_memset(&blank_pen,0,sizeof(struct xrdp_pen)); - - /* if mix mode or rop are out of range, mstsc build 6000+ will parse the orders - wrong */ - if ((mix_mode < 1) || (mix_mode > 2)) /* TRANSPARENT(1) or OPAQUE(2) */ - { - mix_mode = 1; - } - if ((rop < 1) || (rop > 0x10)) - { - rop = 0x0d; /* R2_COPYPEN */ - } - xrdp_orders_check(self, 32); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_LINE) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_LINE; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (MIN(endx, startx) < rect->left || - MIN(endy, starty) < rect->top || - MAX(endx, startx) >= rect->right || - MAX(endy, starty) >= rect->bottom) - { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } - } - } - vals[0] = startx; - vals[1] = self->orders_state.line_startx; - vals[2] = starty; - vals[3] = self->orders_state.line_starty; - vals[4] = endx; - vals[5] = self->orders_state.line_endx; - vals[6] = endy; - vals[7] = self->orders_state.line_endy; - if (xrdp_orders_send_delta(self, vals, 8)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 2 bytes */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 2); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (mix_mode != self->orders_state.line_mix_mode) - { - present |= 0x0001; - out_uint16_le(self->out_s, mix_mode); - self->orders_state.line_mix_mode = mix_mode; - } - if (startx != self->orders_state.line_startx) - { - present |= 0x0002; - if (order_flags & RDP_ORDER_DELTA) - { - out_uint8(self->out_s, startx - self->orders_state.line_startx); - } - else - { - out_uint16_le(self->out_s, startx); - } - self->orders_state.line_startx = startx; - } - if (starty != self->orders_state.line_starty) - { - present |= 0x0004; - if (order_flags & RDP_ORDER_DELTA) - { - out_uint8(self->out_s, starty - self->orders_state.line_starty); - } - else - { - out_uint16_le(self->out_s, starty); - } - self->orders_state.line_starty = starty; - } - if (endx != self->orders_state.line_endx) - { - present |= 0x0008; - if (order_flags & RDP_ORDER_DELTA) - { - out_uint8(self->out_s, endx - self->orders_state.line_endx); - } - else - { - out_uint16_le(self->out_s, endx); - } - self->orders_state.line_endx = endx; - } - if (endy != self->orders_state.line_endy) - { - present |= 0x0010; - if (order_flags & RDP_ORDER_DELTA) - { - out_uint8(self->out_s, endy - self->orders_state.line_endy); - } - else - { - out_uint16_le(self->out_s, endy); - } - self->orders_state.line_endy = endy; - } - if (bg_color != self->orders_state.line_bg_color) - { - present |= 0x0020; - out_uint8(self->out_s, bg_color); - out_uint8(self->out_s, bg_color >> 8); - out_uint8(self->out_s, bg_color >> 16); - self->orders_state.line_bg_color = bg_color; - } - if (rop != self->orders_state.line_rop) - { - present |= 0x0040; - out_uint8(self->out_s, rop); - self->orders_state.line_rop = rop; - } - if (pen == 0) - { g_memset(&blank_pen, 0, sizeof(struct xrdp_pen)); - pen = &blank_pen; - } - if (pen->style != self->orders_state.line_pen.style) - { - present |= 0x0080; - out_uint8(self->out_s, pen->style); - self->orders_state.line_pen.style = pen->style; - } - if (pen->width != self->orders_state.line_pen.width) - { - present |= 0x0100; - out_uint8(self->out_s, pen->width); - self->orders_state.line_pen.width = pen->width; - } - if (pen->color != self->orders_state.line_pen.color) - { - present |= 0x0200; - out_uint8(self->out_s, pen->color); - out_uint8(self->out_s, pen->color >> 8); - out_uint8(self->out_s, pen->color >> 16); - self->orders_state.line_pen.color = pen->color; - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 2); - return 0; + + /* if mix mode or rop are out of range, mstsc build 6000+ will parse the orders + wrong */ + if ((mix_mode < 1) || (mix_mode > 2)) /* TRANSPARENT(1) or OPAQUE(2) */ + { + mix_mode = 1; + } + + if ((rop < 1) || (rop > 0x10)) + { + rop = 0x0d; /* R2_COPYPEN */ + } + + xrdp_orders_check(self, 32); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_LINE) + { + order_flags |= RDP_ORDER_CHANGE; + } + + self->orders_state.last_order = RDP_ORDER_LINE; + + if (rect != 0) + { + /* if clip is present, still check if its needed */ + if (MIN(endx, startx) < rect->left || + MIN(endy, starty) < rect->top || + MAX(endx, startx) >= rect->right || + MAX(endy, starty) >= rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } + } + + vals[0] = startx; + vals[1] = self->orders_state.line_startx; + vals[2] = starty; + vals[3] = self->orders_state.line_starty; + vals[4] = endx; + vals[5] = self->orders_state.line_endx; + vals[6] = endy; + vals[7] = self->orders_state.line_endy; + + if (xrdp_orders_send_delta(self, vals, 8)) + { + order_flags |= RDP_ORDER_DELTA; + } + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) + { + out_uint8(self->out_s, self->orders_state.last_order); + } + + present = 0; + /* present, set later, 2 bytes */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 2); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) + { + xrdp_orders_out_bounds(self, rect); + } + + if (mix_mode != self->orders_state.line_mix_mode) + { + present |= 0x0001; + out_uint16_le(self->out_s, mix_mode); + self->orders_state.line_mix_mode = mix_mode; + } + + if (startx != self->orders_state.line_startx) + { + present |= 0x0002; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, startx - self->orders_state.line_startx); + } + else + { + out_uint16_le(self->out_s, startx); + } + + self->orders_state.line_startx = startx; + } + + if (starty != self->orders_state.line_starty) + { + present |= 0x0004; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, starty - self->orders_state.line_starty); + } + else + { + out_uint16_le(self->out_s, starty); + } + + self->orders_state.line_starty = starty; + } + + if (endx != self->orders_state.line_endx) + { + present |= 0x0008; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, endx - self->orders_state.line_endx); + } + else + { + out_uint16_le(self->out_s, endx); + } + + self->orders_state.line_endx = endx; + } + + if (endy != self->orders_state.line_endy) + { + present |= 0x0010; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, endy - self->orders_state.line_endy); + } + else + { + out_uint16_le(self->out_s, endy); + } + + self->orders_state.line_endy = endy; + } + + if (bg_color != self->orders_state.line_bg_color) + { + present |= 0x0020; + out_uint8(self->out_s, bg_color); + out_uint8(self->out_s, bg_color >> 8); + out_uint8(self->out_s, bg_color >> 16); + self->orders_state.line_bg_color = bg_color; + } + + if (rop != self->orders_state.line_rop) + { + present |= 0x0040; + out_uint8(self->out_s, rop); + self->orders_state.line_rop = rop; + } + + if (pen == 0) + { + g_memset(&blank_pen, 0, sizeof(struct xrdp_pen)); + pen = &blank_pen; + } + + if (pen->style != self->orders_state.line_pen.style) + { + present |= 0x0080; + out_uint8(self->out_s, pen->style); + self->orders_state.line_pen.style = pen->style; + } + + if (pen->width != self->orders_state.line_pen.width) + { + present |= 0x0100; + out_uint8(self->out_s, pen->width); + self->orders_state.line_pen.width = pen->width; + } + + if (pen->color != self->orders_state.line_pen.color) + { + present |= 0x0200; + out_uint8(self->out_s, pen->color); + out_uint8(self->out_s, pen->color >> 8); + out_uint8(self->out_s, pen->color >> 16); + self->orders_state.line_pen.color = pen->color; + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 2); + return 0; } /*****************************************************************************/ @@ -1191,541 +1373,617 @@ xrdp_orders_line(struct xrdp_orders* self, int mix_mode, /* send a mem blt order */ /* max size 30 */ int APP_CC -xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id, +xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id, int color_table, int x, int y, int cx, int cy, int rop, int srcx, int srcy, - int cache_idx, struct xrdp_rect* rect) + int cache_idx, struct xrdp_rect *rect) { - int order_flags = 0; - int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int present = 0; - char* present_ptr = (char *)NULL; - char* order_flags_ptr = (char *)NULL; + int order_flags = 0; + int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int present = 0; + char *present_ptr = (char *)NULL; + char *order_flags_ptr = (char *)NULL; - xrdp_orders_check(self, 30); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_MEMBLT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_MEMBLT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) + xrdp_orders_check(self, 30); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_MEMBLT) { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } + order_flags |= RDP_ORDER_CHANGE; } - } - vals[0] = x; - vals[1] = self->orders_state.mem_blt_x; - vals[2] = y; - vals[3] = self->orders_state.mem_blt_y; - vals[4] = cx; - vals[5] = self->orders_state.mem_blt_cx; - vals[6] = cy; - vals[7] = self->orders_state.mem_blt_cy; - vals[8] = srcx; - vals[9] = self->orders_state.mem_blt_srcx; - vals[10] = srcy; - vals[11] = self->orders_state.mem_blt_srcy; - if (xrdp_orders_send_delta(self, vals, 12)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 2 bytes */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 2); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (cache_id != self->orders_state.mem_blt_cache_id || - color_table != self->orders_state.mem_blt_color_table) - { - present |= 0x0001; - out_uint8(self->out_s, cache_id); - out_uint8(self->out_s, color_table); - self->orders_state.mem_blt_cache_id = cache_id; - self->orders_state.mem_blt_color_table = color_table; - } - if (x != self->orders_state.mem_blt_x) - { - present |= 0x0002; - if (order_flags & RDP_ORDER_DELTA) + + self->orders_state.last_order = RDP_ORDER_MEMBLT; + + if (rect != 0) { - out_uint8(self->out_s, x - self->orders_state.mem_blt_x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - else + + vals[0] = x; + vals[1] = self->orders_state.mem_blt_x; + vals[2] = y; + vals[3] = self->orders_state.mem_blt_y; + vals[4] = cx; + vals[5] = self->orders_state.mem_blt_cx; + vals[6] = cy; + vals[7] = self->orders_state.mem_blt_cy; + vals[8] = srcx; + vals[9] = self->orders_state.mem_blt_srcx; + vals[10] = srcy; + vals[11] = self->orders_state.mem_blt_srcy; + + if (xrdp_orders_send_delta(self, vals, 12)) { - out_uint16_le(self->out_s, x); + order_flags |= RDP_ORDER_DELTA; } - self->orders_state.mem_blt_x = x; - } - if (y != self->orders_state.mem_blt_y) - { - present |= 0x0004; - if (order_flags & RDP_ORDER_DELTA) + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint8(self->out_s, y - self->orders_state.mem_blt_y); + out_uint8(self->out_s, self->orders_state.last_order); } - else + + present = 0; + /* present, set later, 2 bytes */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 2); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint16_le(self->out_s, y); + xrdp_orders_out_bounds(self, rect); } - self->orders_state.mem_blt_y = y; - } - if (cx != self->orders_state.mem_blt_cx) - { - present |= 0x0008; - if (order_flags & RDP_ORDER_DELTA) + + if (cache_id != self->orders_state.mem_blt_cache_id || + color_table != self->orders_state.mem_blt_color_table) { - out_uint8(self->out_s, cx - self->orders_state.mem_blt_cx); + present |= 0x0001; + out_uint8(self->out_s, cache_id); + out_uint8(self->out_s, color_table); + self->orders_state.mem_blt_cache_id = cache_id; + self->orders_state.mem_blt_color_table = color_table; } - else + + if (x != self->orders_state.mem_blt_x) { - out_uint16_le(self->out_s, cx); + present |= 0x0002; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.mem_blt_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.mem_blt_x = x; } - self->orders_state.mem_blt_cx = cx; - } - if (cy != self->orders_state.mem_blt_cy) - { - present |= 0x0010; - if (order_flags & RDP_ORDER_DELTA) + + if (y != self->orders_state.mem_blt_y) { - out_uint8(self->out_s, cy - self->orders_state.mem_blt_cy); + present |= 0x0004; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.mem_blt_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.mem_blt_y = y; } - else + + if (cx != self->orders_state.mem_blt_cx) { - out_uint16_le(self->out_s, cy); + present |= 0x0008; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.mem_blt_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.mem_blt_cx = cx; } - self->orders_state.mem_blt_cy = cy; - } - if (rop != self->orders_state.mem_blt_rop) - { - present |= 0x0020; - out_uint8(self->out_s, rop); - self->orders_state.mem_blt_rop = rop; - } - if (srcx != self->orders_state.mem_blt_srcx) - { - present |= 0x0040; - if (order_flags & RDP_ORDER_DELTA) + + if (cy != self->orders_state.mem_blt_cy) { - out_uint8(self->out_s, srcx - self->orders_state.mem_blt_srcx); + present |= 0x0010; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.mem_blt_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.mem_blt_cy = cy; } - else + + if (rop != self->orders_state.mem_blt_rop) { - out_uint16_le(self->out_s, srcx); + present |= 0x0020; + out_uint8(self->out_s, rop); + self->orders_state.mem_blt_rop = rop; } - self->orders_state.mem_blt_srcx = srcx; - } - if (srcy != self->orders_state.mem_blt_srcy) - { - present |= 0x0080; - if (order_flags & RDP_ORDER_DELTA) + + if (srcx != self->orders_state.mem_blt_srcx) { - out_uint8(self->out_s, srcy - self->orders_state.mem_blt_srcy); + present |= 0x0040; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcx - self->orders_state.mem_blt_srcx); + } + else + { + out_uint16_le(self->out_s, srcx); + } + + self->orders_state.mem_blt_srcx = srcx; } - else + + if (srcy != self->orders_state.mem_blt_srcy) { - out_uint16_le(self->out_s, srcy); + present |= 0x0080; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcy - self->orders_state.mem_blt_srcy); + } + else + { + out_uint16_le(self->out_s, srcy); + } + + self->orders_state.mem_blt_srcy = srcy; } - self->orders_state.mem_blt_srcy = srcy; - } - if (cache_idx != self->orders_state.mem_blt_cache_idx) - { - present |= 0x0100; - out_uint16_le(self->out_s, cache_idx); - self->orders_state.mem_blt_cache_idx = cache_idx; - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 2); - return 0; + + if (cache_idx != self->orders_state.mem_blt_cache_idx) + { + present |= 0x0100; + out_uint16_le(self->out_s, cache_idx); + self->orders_state.mem_blt_cache_idx = cache_idx; + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 2); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_orders_text(struct xrdp_orders* self, +xrdp_orders_text(struct xrdp_orders *self, int font, int flags, int mixmode, int fg_color, int bg_color, int clip_left, int clip_top, int clip_right, int clip_bottom, int box_left, int box_top, int box_right, int box_bottom, - int x, int y, char* data, int data_len, - struct xrdp_rect* rect) + int x, int y, char *data, int data_len, + struct xrdp_rect *rect) { - int order_flags = 0; - int present = 0; - char* present_ptr = (char *)NULL; - char* order_flags_ptr = (char *)NULL; + int order_flags = 0; + int present = 0; + char *present_ptr = (char *)NULL; + char *order_flags_ptr = (char *)NULL; - xrdp_orders_check(self, 100); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_TEXT2) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_TEXT2; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if ((box_right - box_left > 1 && - (box_left < rect->left || - box_top < rect->top || - box_right > rect->right || - box_bottom > rect->bottom)) || - (clip_left < rect->left || - clip_top < rect->top || - clip_right > rect->right || - clip_bottom > rect->bottom)) + xrdp_orders_check(self, 100); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_TEXT2) { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } + order_flags |= RDP_ORDER_CHANGE; } - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 3 bytes */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 3); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (font != self->orders_state.text_font) - { - present |= 0x000001; - out_uint8(self->out_s, font); - self->orders_state.text_font = font; - } - if (flags != self->orders_state.text_flags) - { - present |= 0x000002; - out_uint8(self->out_s, flags); - self->orders_state.text_flags = flags; - } - /* unknown */ - if (mixmode != self->orders_state.text_mixmode) - { - present |= 0x000008; - out_uint8(self->out_s, mixmode); - self->orders_state.text_mixmode = mixmode; - } - if (fg_color != self->orders_state.text_fg_color) - { - present |= 0x000010; - out_uint8(self->out_s, fg_color); - out_uint8(self->out_s, fg_color >> 8); - out_uint8(self->out_s, fg_color >> 16); - self->orders_state.text_fg_color = fg_color; - } - if (bg_color != self->orders_state.text_bg_color) - { - present |= 0x000020; - out_uint8(self->out_s, bg_color); - out_uint8(self->out_s, bg_color >> 8); - out_uint8(self->out_s, bg_color >> 16); - self->orders_state.text_bg_color = bg_color; - } - if (clip_left != self->orders_state.text_clip_left) - { - present |= 0x000040; - out_uint16_le(self->out_s, clip_left); - self->orders_state.text_clip_left = clip_left; - } - if (clip_top != self->orders_state.text_clip_top) - { - present |= 0x000080; - out_uint16_le(self->out_s, clip_top); - self->orders_state.text_clip_top = clip_top; - } - if (clip_right != self->orders_state.text_clip_right) - { - present |= 0x000100; - out_uint16_le(self->out_s, clip_right); - self->orders_state.text_clip_right = clip_right; - } - if (clip_bottom != self->orders_state.text_clip_bottom) - { - present |= 0x000200; - out_uint16_le(self->out_s, clip_bottom); - self->orders_state.text_clip_bottom = clip_bottom; - } - if (box_left != self->orders_state.text_box_left) - { - present |= 0x000400; - out_uint16_le(self->out_s, box_left); - self->orders_state.text_box_left = box_left; - } - if (box_top != self->orders_state.text_box_top) - { - present |= 0x000800; - out_uint16_le(self->out_s, box_top); - self->orders_state.text_box_top = box_top; - } - if (box_right != self->orders_state.text_box_right) - { - present |= 0x001000; - out_uint16_le(self->out_s, box_right); - self->orders_state.text_box_right = box_right; - } - if (box_bottom != self->orders_state.text_box_bottom) - { - present |= 0x002000; - out_uint16_le(self->out_s, box_bottom); - self->orders_state.text_box_bottom = box_bottom; - } - if (x != self->orders_state.text_x) - { - present |= 0x080000; - out_uint16_le(self->out_s, x); - self->orders_state.text_x = x; - } - if (y != self->orders_state.text_y) - { - present |= 0x100000; - out_uint16_le(self->out_s, y); - self->orders_state.text_y = y; - } - { - /* always send text */ - present |= 0x200000; - out_uint8(self->out_s, data_len); - out_uint8a(self->out_s, data, data_len); - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 3); - return 0; + + self->orders_state.last_order = RDP_ORDER_TEXT2; + + if (rect != 0) + { + /* if clip is present, still check if its needed */ + if ((box_right - box_left > 1 && + (box_left < rect->left || + box_top < rect->top || + box_right > rect->right || + box_bottom > rect->bottom)) || + (clip_left < rect->left || + clip_top < rect->top || + clip_right > rect->right || + clip_bottom > rect->bottom)) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } + } + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) + { + out_uint8(self->out_s, self->orders_state.last_order); + } + + present = 0; + /* present, set later, 3 bytes */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 3); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) + { + xrdp_orders_out_bounds(self, rect); + } + + if (font != self->orders_state.text_font) + { + present |= 0x000001; + out_uint8(self->out_s, font); + self->orders_state.text_font = font; + } + + if (flags != self->orders_state.text_flags) + { + present |= 0x000002; + out_uint8(self->out_s, flags); + self->orders_state.text_flags = flags; + } + + /* unknown */ + if (mixmode != self->orders_state.text_mixmode) + { + present |= 0x000008; + out_uint8(self->out_s, mixmode); + self->orders_state.text_mixmode = mixmode; + } + + if (fg_color != self->orders_state.text_fg_color) + { + present |= 0x000010; + out_uint8(self->out_s, fg_color); + out_uint8(self->out_s, fg_color >> 8); + out_uint8(self->out_s, fg_color >> 16); + self->orders_state.text_fg_color = fg_color; + } + + if (bg_color != self->orders_state.text_bg_color) + { + present |= 0x000020; + out_uint8(self->out_s, bg_color); + out_uint8(self->out_s, bg_color >> 8); + out_uint8(self->out_s, bg_color >> 16); + self->orders_state.text_bg_color = bg_color; + } + + if (clip_left != self->orders_state.text_clip_left) + { + present |= 0x000040; + out_uint16_le(self->out_s, clip_left); + self->orders_state.text_clip_left = clip_left; + } + + if (clip_top != self->orders_state.text_clip_top) + { + present |= 0x000080; + out_uint16_le(self->out_s, clip_top); + self->orders_state.text_clip_top = clip_top; + } + + if (clip_right != self->orders_state.text_clip_right) + { + present |= 0x000100; + out_uint16_le(self->out_s, clip_right); + self->orders_state.text_clip_right = clip_right; + } + + if (clip_bottom != self->orders_state.text_clip_bottom) + { + present |= 0x000200; + out_uint16_le(self->out_s, clip_bottom); + self->orders_state.text_clip_bottom = clip_bottom; + } + + if (box_left != self->orders_state.text_box_left) + { + present |= 0x000400; + out_uint16_le(self->out_s, box_left); + self->orders_state.text_box_left = box_left; + } + + if (box_top != self->orders_state.text_box_top) + { + present |= 0x000800; + out_uint16_le(self->out_s, box_top); + self->orders_state.text_box_top = box_top; + } + + if (box_right != self->orders_state.text_box_right) + { + present |= 0x001000; + out_uint16_le(self->out_s, box_right); + self->orders_state.text_box_right = box_right; + } + + if (box_bottom != self->orders_state.text_box_bottom) + { + present |= 0x002000; + out_uint16_le(self->out_s, box_bottom); + self->orders_state.text_box_bottom = box_bottom; + } + + if (x != self->orders_state.text_x) + { + present |= 0x080000; + out_uint16_le(self->out_s, x); + self->orders_state.text_x = x; + } + + if (y != self->orders_state.text_y) + { + present |= 0x100000; + out_uint16_le(self->out_s, y); + self->orders_state.text_y = y; + } + + { + /* always send text */ + present |= 0x200000; + out_uint8(self->out_s, data_len); + out_uint8a(self->out_s, data, data_len); + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 3); + return 0; } /*****************************************************************************/ /* returns error */ /* when a palette gets sent, send the main palette too */ int APP_CC -xrdp_orders_send_palette(struct xrdp_orders* self, int* palette, +xrdp_orders_send_palette(struct xrdp_orders *self, int *palette, int cache_id) { - int order_flags; - int len; - int i; + int order_flags; + int len; + int i; - xrdp_orders_check(self, 2000); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = 1027 - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 0); /* flags */ - out_uint8(self->out_s, RDP_ORDER_COLCACHE); /* type */ - out_uint8(self->out_s, cache_id); - out_uint16_le(self->out_s, 256); /* num colors */ - for (i = 0; i < 256; i++) - { - out_uint8(self->out_s, palette[i]); - out_uint8(self->out_s, palette[i] >> 8); - out_uint8(self->out_s, palette[i] >> 16); - out_uint8(self->out_s, 0); - } - return 0; + xrdp_orders_check(self, 2000); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = 1027 - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 0); /* flags */ + out_uint8(self->out_s, RDP_ORDER_COLCACHE); /* type */ + out_uint8(self->out_s, cache_id); + out_uint16_le(self->out_s, 256); /* num colors */ + + for (i = 0; i < 256; i++) + { + out_uint8(self->out_s, palette[i]); + out_uint8(self->out_s, palette[i] >> 8); + out_uint8(self->out_s, palette[i] >> 16); + out_uint8(self->out_s, 0); + } + + return 0; } /*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 16 */ int APP_CC -xrdp_orders_send_raw_bitmap(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_raw_bitmap(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - int order_flags = 0; - int len = 0; - int bufsize = 0; - int Bpp = 0; - int i = 0; - int j = 0; - int pixel = 0; - int e = 0; + int order_flags = 0; + int len = 0; + int bufsize = 0; + int Bpp = 0; + int i = 0; + int j = 0; + int pixel = 0; + int e = 0; - if (width > 64) - { - g_writeln("error, width > 64"); - return 1; - } - if (height > 64) - { - g_writeln("error, height > 64"); - return 1; - } - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - Bpp = (bpp + 7) / 8; - bufsize = (width + e) * height * Bpp; - xrdp_orders_check(self, bufsize + 16); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (bufsize + 9) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 8); /* flags */ - out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE); /* type */ - out_uint8(self->out_s, cache_id); - out_uint8s(self->out_s, 1); /* pad */ - out_uint8(self->out_s, width + e); - out_uint8(self->out_s, height); - out_uint8(self->out_s, bpp); - out_uint16_le(self->out_s, bufsize); - out_uint16_le(self->out_s, cache_idx); - for (i = height - 1; i >= 0; i--) - { - for (j = 0; j < width; j++) + if (width > 64) { - if (Bpp == 3) - { - pixel = GETPIXEL32(data, j, i, width); - out_uint8(self->out_s, pixel >> 16); - out_uint8(self->out_s, pixel >> 8); - out_uint8(self->out_s, pixel); - } - else if (Bpp == 2) - { - pixel = GETPIXEL16(data, j, i, width); - out_uint8(self->out_s, pixel); - out_uint8(self->out_s, pixel >> 8); - } - else if (Bpp == 1) - { - pixel = GETPIXEL8(data, j, i, width); - out_uint8(self->out_s, pixel); - } + g_writeln("error, width > 64"); + return 1; } - for (j = 0; j < e; j++) + + if (height > 64) { - out_uint8s(self->out_s, Bpp); + g_writeln("error, height > 64"); + return 1; } - } - return 0; + + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + Bpp = (bpp + 7) / 8; + bufsize = (width + e) * height * Bpp; + xrdp_orders_check(self, bufsize + 16); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 9) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 8); /* flags */ + out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE); /* type */ + out_uint8(self->out_s, cache_id); + out_uint8s(self->out_s, 1); /* pad */ + out_uint8(self->out_s, width + e); + out_uint8(self->out_s, height); + out_uint8(self->out_s, bpp); + out_uint16_le(self->out_s, bufsize); + out_uint16_le(self->out_s, cache_idx); + + for (i = height - 1; i >= 0; i--) + { + for (j = 0; j < width; j++) + { + if (Bpp == 3) + { + pixel = GETPIXEL32(data, j, i, width); + out_uint8(self->out_s, pixel >> 16); + out_uint8(self->out_s, pixel >> 8); + out_uint8(self->out_s, pixel); + } + else if (Bpp == 2) + { + pixel = GETPIXEL16(data, j, i, width); + out_uint8(self->out_s, pixel); + out_uint8(self->out_s, pixel >> 8); + } + else if (Bpp == 1) + { + pixel = GETPIXEL8(data, j, i, width); + out_uint8(self->out_s, pixel); + } + } + + for (j = 0; j < e; j++) + { + out_uint8s(self->out_s, Bpp); + } + } + + return 0; } /*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 16 */ int APP_CC -xrdp_orders_send_bitmap(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_bitmap(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - int order_flags = 0; - int len = 0; - int bufsize = 0; - int Bpp = 0; - int i = 0; - int lines_sending = 0; - int e = 0; - struct stream* s = NULL; - struct stream* temp_s = NULL; - char* p = NULL; + int order_flags = 0; + int len = 0; + int bufsize = 0; + int Bpp = 0; + int i = 0; + int lines_sending = 0; + int e = 0; + struct stream *s = NULL; + struct stream *temp_s = NULL; + char *p = NULL; - if (width > 64) - { - g_writeln("error, width > 64"); - return 1; - } - if (height > 64) - { - g_writeln("error, height > 64"); - return 1; - } - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - make_stream(s); - init_stream(s, 16384); - make_stream(temp_s); - init_stream(temp_s, 16384); - p = s->p; - i = height; - lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, - i - 1, temp_s, e); - if (lines_sending != height) - { + if (width > 64) + { + g_writeln("error, width > 64"); + return 1; + } + + if (height > 64) + { + g_writeln("error, height > 64"); + return 1; + } + + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + make_stream(s); + init_stream(s, 16384); + make_stream(temp_s); + init_stream(temp_s, 16384); + p = s->p; + i = height; + lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, + i - 1, temp_s, e); + + if (lines_sending != height) + { + free_stream(s); + free_stream(temp_s); + g_writeln("error in xrdp_orders_send_bitmap, lines_sending(%d) != \ +height(%d)", lines_sending, height); + return 1; + } + + bufsize = (int)(s->p - p); + Bpp = (bpp + 7) / 8; + xrdp_orders_check(self, bufsize + 16); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + + if (self->rdp_layer->client_info.op2) + { + len = (bufsize + 9) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 1024); /* flags */ + } + else + { + len = (bufsize + 9 + 8) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 8); /* flags */ + } + + out_uint8(self->out_s, RDP_ORDER_BMPCACHE); /* type */ + out_uint8(self->out_s, cache_id); + out_uint8s(self->out_s, 1); /* pad */ + out_uint8(self->out_s, width + e); + out_uint8(self->out_s, height); + out_uint8(self->out_s, bpp); + out_uint16_le(self->out_s, bufsize/* + 8*/); + out_uint16_le(self->out_s, cache_idx); + + if (!self->rdp_layer->client_info.op2) + { + out_uint8s(self->out_s, 2); /* pad */ + out_uint16_le(self->out_s, bufsize); + out_uint16_le(self->out_s, (width + e) * Bpp); /* line size */ + out_uint16_le(self->out_s, (width + e) * + Bpp * height); /* final size */ + } + + out_uint8a(self->out_s, s->data, bufsize); free_stream(s); free_stream(temp_s); - g_writeln("error in xrdp_orders_send_bitmap, lines_sending(%d) != \ -height(%d)", lines_sending, height); - return 1; - } - bufsize = (int)(s->p - p); - Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 16); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - if (self->rdp_layer->client_info.op2) - { - len = (bufsize + 9) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 1024); /* flags */ - } - else - { - len = (bufsize + 9 + 8) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 8); /* flags */ - } - out_uint8(self->out_s, RDP_ORDER_BMPCACHE); /* type */ - out_uint8(self->out_s, cache_id); - out_uint8s(self->out_s, 1); /* pad */ - out_uint8(self->out_s, width + e); - out_uint8(self->out_s, height); - out_uint8(self->out_s, bpp); - out_uint16_le(self->out_s, bufsize/* + 8*/); - out_uint16_le(self->out_s, cache_idx); - if (!self->rdp_layer->client_info.op2) - { - out_uint8s(self->out_s, 2); /* pad */ - out_uint16_le(self->out_s, bufsize); - out_uint16_le(self->out_s, (width + e) * Bpp); /* line size */ - out_uint16_le(self->out_s, (width + e) * - Bpp * height); /* final size */ - } - out_uint8a(self->out_s, s->data, bufsize); - free_stream(s); - free_stream(temp_s); - return 0; + return 0; } /*****************************************************************************/ @@ -1733,457 +1991,492 @@ height(%d)", lines_sending, height); /* max size datasize + 18*/ /* todo, only sends one for now */ int APP_CC -xrdp_orders_send_font(struct xrdp_orders* self, - struct xrdp_font_char* font_char, +xrdp_orders_send_font(struct xrdp_orders *self, + struct xrdp_font_char *font_char, int font_index, int char_index) { - int order_flags = 0; - int datasize = 0; - int len = 0; + int order_flags = 0; + int datasize = 0; + int len = 0; - datasize = FONT_DATASIZE(font_char); - xrdp_orders_check(self, datasize + 18); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (datasize + 12) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 8); /* flags */ - out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */ - out_uint8(self->out_s, font_index); - out_uint8(self->out_s, 1); /* num of chars */ - out_uint16_le(self->out_s, char_index); - out_uint16_le(self->out_s, font_char->offset); - out_uint16_le(self->out_s, font_char->baseline); - out_uint16_le(self->out_s, font_char->width); - out_uint16_le(self->out_s, font_char->height); - out_uint8a(self->out_s, font_char->data, datasize); - return 0; + datasize = FONT_DATASIZE(font_char); + xrdp_orders_check(self, datasize + 18); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (datasize + 12) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 8); /* flags */ + out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */ + out_uint8(self->out_s, font_index); + out_uint8(self->out_s, 1); /* num of chars */ + out_uint16_le(self->out_s, char_index); + out_uint16_le(self->out_s, font_char->offset); + out_uint16_le(self->out_s, font_char->baseline); + out_uint16_le(self->out_s, font_char->width); + out_uint16_le(self->out_s, font_char->height); + out_uint8a(self->out_s, font_char->data, datasize); + return 0; } /*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 14 */ int APP_CC -xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - int order_flags = 0; - int len = 0; - int bufsize = 0; - int Bpp = 0; - int i = 0; - int j = 0; - int pixel = 0; - int e = 0; + int order_flags = 0; + int len = 0; + int bufsize = 0; + int Bpp = 0; + int i = 0; + int j = 0; + int pixel = 0; + int e = 0; - if (width > 64) - { - g_writeln("error, width > 64"); - return 1; - } - if (height > 64) - { - g_writeln("error, height > 64"); - return 1; - } - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - Bpp = (bpp + 7) / 8; - bufsize = (width + e) * height * Bpp; - xrdp_orders_check(self, bufsize + 14); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (bufsize + 6) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); - out_uint16_le(self->out_s, i); /* flags */ - out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE2); /* type */ - out_uint8(self->out_s, width + e); - out_uint8(self->out_s, height); - out_uint16_be(self->out_s, bufsize | 0x4000); - i = ((cache_idx >> 8) & 0xff) | 0x80; - out_uint8(self->out_s, i); - i = cache_idx & 0xff; - out_uint8(self->out_s, i); - for (i = height - 1; i >= 0; i--) - { - for (j = 0; j < width; j++) + if (width > 64) { - if (Bpp == 3) - { - pixel = GETPIXEL32(data, j, i, width); - out_uint8(self->out_s, pixel >> 16); - out_uint8(self->out_s, pixel >> 8); - out_uint8(self->out_s, pixel); - } - else if (Bpp == 2) - { - pixel = GETPIXEL16(data, j, i, width); - out_uint8(self->out_s, pixel); - out_uint8(self->out_s, pixel >> 8); - } - else if (Bpp == 1) - { - pixel = GETPIXEL8(data, j, i, width); - out_uint8(self->out_s, pixel); - } + g_writeln("error, width > 64"); + return 1; } - for (j = 0; j < e; j++) + + if (height > 64) { - out_uint8s(self->out_s, Bpp); + g_writeln("error, height > 64"); + return 1; } - } - return 0; + + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + Bpp = (bpp + 7) / 8; + bufsize = (width + e) * height * Bpp; + xrdp_orders_check(self, bufsize + 14); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 6) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); + out_uint16_le(self->out_s, i); /* flags */ + out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE2); /* type */ + out_uint8(self->out_s, width + e); + out_uint8(self->out_s, height); + out_uint16_be(self->out_s, bufsize | 0x4000); + i = ((cache_idx >> 8) & 0xff) | 0x80; + out_uint8(self->out_s, i); + i = cache_idx & 0xff; + out_uint8(self->out_s, i); + + for (i = height - 1; i >= 0; i--) + { + for (j = 0; j < width; j++) + { + if (Bpp == 3) + { + pixel = GETPIXEL32(data, j, i, width); + out_uint8(self->out_s, pixel >> 16); + out_uint8(self->out_s, pixel >> 8); + out_uint8(self->out_s, pixel); + } + else if (Bpp == 2) + { + pixel = GETPIXEL16(data, j, i, width); + out_uint8(self->out_s, pixel); + out_uint8(self->out_s, pixel >> 8); + } + else if (Bpp == 1) + { + pixel = GETPIXEL8(data, j, i, width); + out_uint8(self->out_s, pixel); + } + } + + for (j = 0; j < e; j++) + { + out_uint8s(self->out_s, Bpp); + } + } + + return 0; } /*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 14 */ int APP_CC -xrdp_orders_send_bitmap2(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_bitmap2(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx, int hints) { - int order_flags = 0; - int len = 0; - int bufsize = 0; - int Bpp = 0; - int i = 0; - int lines_sending = 0; - int e = 0; - struct stream* s = NULL; - struct stream* temp_s = NULL; - char* p = NULL; + int order_flags = 0; + int len = 0; + int bufsize = 0; + int Bpp = 0; + int i = 0; + int lines_sending = 0; + int e = 0; + struct stream *s = NULL; + struct stream *temp_s = NULL; + char *p = NULL; - if (width > 64) - { - g_writeln("error, width > 64"); - return 1; - } - if (height > 64) - { - g_writeln("error, height > 64"); - return 1; - } - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - make_stream(s); - init_stream(s, 16384); - make_stream(temp_s); - init_stream(temp_s, 16384); - p = s->p; - i = height; - lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, + if (width > 64) + { + g_writeln("error, width > 64"); + return 1; + } + + if (height > 64) + { + g_writeln("error, height > 64"); + return 1; + } + + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + make_stream(s); + init_stream(s, 16384); + make_stream(temp_s); + init_stream(temp_s, 16384); + p = s->p; + i = height; + lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, i - 1, temp_s, e); - if (lines_sending != height) - { + + if (lines_sending != height) + { + free_stream(s); + free_stream(temp_s); + g_writeln("error in xrdp_orders_send_bitmap2, lines_sending(%d) != \ +height(%d)", lines_sending, height); + return 1; + } + + bufsize = (int)(s->p - p); + Bpp = (bpp + 7) / 8; + xrdp_orders_check(self, bufsize + 14); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 6) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); + i = i | (0x08 << 7); /* CBR2_NO_BITMAP_COMPRESSION_HDR */ + out_uint16_le(self->out_s, i); /* flags */ + out_uint8(self->out_s, RDP_ORDER_BMPCACHE2); /* type */ + out_uint8(self->out_s, width + e); + out_uint8(self->out_s, height); + out_uint16_be(self->out_s, bufsize | 0x4000); + i = ((cache_idx >> 8) & 0xff) | 0x80; + out_uint8(self->out_s, i); + i = cache_idx & 0xff; + out_uint8(self->out_s, i); + out_uint8a(self->out_s, s->data, bufsize); free_stream(s); free_stream(temp_s); - g_writeln("error in xrdp_orders_send_bitmap2, lines_sending(%d) != \ -height(%d)", lines_sending, height); - return 1; - } - bufsize = (int)(s->p - p); - Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 14); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (bufsize + 6) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); - i = i | (0x08 << 7); /* CBR2_NO_BITMAP_COMPRESSION_HDR */ - out_uint16_le(self->out_s, i); /* flags */ - out_uint8(self->out_s, RDP_ORDER_BMPCACHE2); /* type */ - out_uint8(self->out_s, width + e); - out_uint8(self->out_s, height); - out_uint16_be(self->out_s, bufsize | 0x4000); - i = ((cache_idx >> 8) & 0xff) | 0x80; - out_uint8(self->out_s, i); - i = cache_idx & 0xff; - out_uint8(self->out_s, i); - out_uint8a(self->out_s, s->data, bufsize); - free_stream(s); - free_stream(temp_s); - return 0; + return 0; } /*****************************************************************************/ static int -xrdp_orders_send_as_jpeg(struct xrdp_orders* self, +xrdp_orders_send_as_jpeg(struct xrdp_orders *self, int width, int height, int bpp, int hints) { - if (hints & 1) - { - return 0; - } - if (bpp != 24) - { - return 0; - } - if (width * height < 64) - { - return 0; - } - return 1; + if (hints & 1) + { + return 0; + } + + if (bpp != 24) + { + return 0; + } + + if (width * height < 64) + { + return 0; + } + + return 1; } #if defined(XRDP_FREERDP1) /*****************************************************************************/ /* secondary drawing order (bitmap v3) using remotefx compression */ static int APP_CC -xrdp_orders_send_as_rfx(struct xrdp_orders* self, +xrdp_orders_send_as_rfx(struct xrdp_orders *self, int width, int height, int bpp, int hints) { - if (hints & 1) - { - return 0; - } - if (bpp != 24) - { - return 0; - } - if (width * height < 64) - { - return 0; - } - return 1; + if (hints & 1) + { + return 0; + } + + if (bpp != 24) + { + return 0; + } + + if (width * height < 64) + { + return 0; + } + + return 1; } #endif /*****************************************************************************/ static int APP_CC -xrdp_orders_out_v3(struct xrdp_orders* self, int cache_id, int cache_idx, - char* buf, int bufsize, int width, int height, int bpp, +xrdp_orders_out_v3(struct xrdp_orders *self, int cache_id, int cache_idx, + char *buf, int bufsize, int width, int height, int bpp, int codec_id) { - int Bpp; - int order_flags; - int len; - int i; + int Bpp; + int order_flags; + int len; + int i; - Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 30); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (bufsize + 22) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); - out_uint16_le(self->out_s, i); /* flags */ - out_uint8(self->out_s, RDP_ORDER_BMPCACHE3); /* type */ - /* cache index */ - out_uint16_le(self->out_s, cache_idx); - /* persistant cache key 1/2 */ - out_uint32_le(self->out_s, 0); - out_uint32_le(self->out_s, 0); - /* bitmap data */ - out_uint8(self->out_s, bpp); - out_uint8(self->out_s, 0); /* reserved */ - out_uint8(self->out_s, 0); /* reserved */ - out_uint8(self->out_s, codec_id); - out_uint16_le(self->out_s, width); - out_uint16_le(self->out_s, height); - out_uint32_le(self->out_s, bufsize); - out_uint8a(self->out_s, buf, bufsize); - return 0; + Bpp = (bpp + 7) / 8; + xrdp_orders_check(self, bufsize + 30); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 22) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); + out_uint16_le(self->out_s, i); /* flags */ + out_uint8(self->out_s, RDP_ORDER_BMPCACHE3); /* type */ + /* cache index */ + out_uint16_le(self->out_s, cache_idx); + /* persistant cache key 1/2 */ + out_uint32_le(self->out_s, 0); + out_uint32_le(self->out_s, 0); + /* bitmap data */ + out_uint8(self->out_s, bpp); + out_uint8(self->out_s, 0); /* reserved */ + out_uint8(self->out_s, 0); /* reserved */ + out_uint8(self->out_s, codec_id); + out_uint16_le(self->out_s, width); + out_uint16_le(self->out_s, height); + out_uint32_le(self->out_s, bufsize); + out_uint8a(self->out_s, buf, bufsize); + return 0; } /*****************************************************************************/ /* secondary drawing order (bitmap v3) using remotefx compression */ int APP_CC -xrdp_orders_send_bitmap3(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_bitmap3(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx, int hints) { - int e; - int bufsize; - int quality; - struct stream* xr_s; /* xrdp stream */ - struct stream* temp_s; /* xrdp stream */ - struct xrdp_client_info* ci; + int e; + int bufsize; + int quality; + struct stream *xr_s; /* xrdp stream */ + struct stream *temp_s; /* xrdp stream */ + struct xrdp_client_info *ci; #if defined(XRDP_FREERDP1) - STREAM* fr_s; /* FreeRDP stream */ - RFX_CONTEXT* context; - RFX_RECT rect; + STREAM *fr_s; /* FreeRDP stream */ + RFX_CONTEXT *context; + RFX_RECT rect; #endif - ci = &(self->rdp_layer->client_info); - if (ci->v3_codec_id == 0) - { - return 2; - } - if (ci->v3_codec_id == ci->rfx_codec_id) - { + ci = &(self->rdp_layer->client_info); + + if (ci->v3_codec_id == 0) + { + return 2; + } + + if (ci->v3_codec_id == ci->rfx_codec_id) + { #if defined(XRDP_FREERDP1) - if (!xrdp_orders_send_as_rfx(self, width, height, bpp, hints)) - { - return 2; - } - LLOGLN(10, ("xrdp_orders_send_bitmap3: rfx")); - context = (RFX_CONTEXT*)(self->rdp_layer->rfx_enc); - make_stream(xr_s); - init_stream(xr_s, 16384); - fr_s = stream_new(0); - stream_attach(fr_s, (tui8*)(xr_s->data), 16384); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - rfx_compose_message(context, fr_s, &rect, 1, (tui8*)data, width, - height, width * 4); - bufsize = stream_get_length(fr_s); - xrdp_orders_out_v3(self, cache_id, cache_idx, (char*)(fr_s->data), bufsize, - width, height, bpp,ci->v3_codec_id); - stream_detach(fr_s); - stream_free(fr_s); - free_stream(xr_s); - return 0; + + if (!xrdp_orders_send_as_rfx(self, width, height, bpp, hints)) + { + return 2; + } + + LLOGLN(10, ("xrdp_orders_send_bitmap3: rfx")); + context = (RFX_CONTEXT *)(self->rdp_layer->rfx_enc); + make_stream(xr_s); + init_stream(xr_s, 16384); + fr_s = stream_new(0); + stream_attach(fr_s, (tui8 *)(xr_s->data), 16384); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + rfx_compose_message(context, fr_s, &rect, 1, (tui8 *)data, width, + height, width * 4); + bufsize = stream_get_length(fr_s); + xrdp_orders_out_v3(self, cache_id, cache_idx, (char *)(fr_s->data), bufsize, + width, height, bpp, ci->v3_codec_id); + stream_detach(fr_s); + stream_free(fr_s); + free_stream(xr_s); + return 0; #else - return 2; + return 2; #endif - } - else if (ci->v3_codec_id == ci->jpeg_codec_id) - { + } + else if (ci->v3_codec_id == ci->jpeg_codec_id) + { #if defined(XRDP_JPEG) - if (!xrdp_orders_send_as_jpeg(self, width, height, bpp, hints)) - { - LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg skipped")); - return 2; - } - LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg")); - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - make_stream(xr_s); - init_stream(xr_s, 16384); - make_stream(temp_s); - init_stream(temp_s, 16384); - quality = ci->jpeg_prop[0]; - xrdp_jpeg_compress(data, width, height, xr_s, bpp, 16384, - height - 1, temp_s, e, quality); - s_mark_end(xr_s); - bufsize = (int)(xr_s->end - xr_s->data); - xrdp_orders_out_v3(self, cache_id, cache_idx, (char*)(xr_s->data), bufsize, - width + e, height, bpp,ci->v3_codec_id); - free_stream(xr_s); - free_stream(temp_s); - return 0; + + if (!xrdp_orders_send_as_jpeg(self, width, height, bpp, hints)) + { + LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg skipped")); + return 2; + } + + LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg")); + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + make_stream(xr_s); + init_stream(xr_s, 16384); + make_stream(temp_s); + init_stream(temp_s, 16384); + quality = ci->jpeg_prop[0]; + xrdp_jpeg_compress(data, width, height, xr_s, bpp, 16384, + height - 1, temp_s, e, quality); + s_mark_end(xr_s); + bufsize = (int)(xr_s->end - xr_s->data); + xrdp_orders_out_v3(self, cache_id, cache_idx, (char *)(xr_s->data), bufsize, + width + e, height, bpp, ci->v3_codec_id); + free_stream(xr_s); + free_stream(temp_s); + return 0; #else - return 2; + return 2; #endif - } - else - { - g_writeln("xrdp_orders_send_bitmap3: todo unknown codec"); - return 1; - } - return 0; + } + else + { + g_writeln("xrdp_orders_send_bitmap3: todo unknown codec"); + return 1; + } + + return 0; } /*****************************************************************************/ /* returns error */ /* send a brush cache entry */ int APP_CC -xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height, - int bpp, int type, int size, char* data, int cache_id) +xrdp_orders_send_brush(struct xrdp_orders *self, int width, int height, + int bpp, int type, int size, char *data, int cache_id) { - int order_flags = 0; - int len = 0; + int order_flags = 0; + int len = 0; - xrdp_orders_check(self, size + 12); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (size + 6) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 0); /* flags */ - out_uint8(self->out_s, RDP_ORDER_BRUSHCACHE); /* type */ - out_uint8(self->out_s, cache_id); - out_uint8(self->out_s, bpp); - out_uint8(self->out_s, width); - out_uint8(self->out_s, height); - out_uint8(self->out_s, type); - out_uint8(self->out_s, size); - out_uint8a(self->out_s, data, size); - return 0; + xrdp_orders_check(self, size + 12); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (size + 6) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 0); /* flags */ + out_uint8(self->out_s, RDP_ORDER_BRUSHCACHE); /* type */ + out_uint8(self->out_s, cache_id); + out_uint8(self->out_s, bpp); + out_uint8(self->out_s, width); + out_uint8(self->out_s, height); + out_uint8(self->out_s, type); + out_uint8(self->out_s, size); + out_uint8a(self->out_s, data, size); + return 0; } /*****************************************************************************/ /* returns error */ /* send an off screen bitmap entry */ int APP_CC -xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id, +xrdp_orders_send_create_os_surface(struct xrdp_orders *self, int id, int width, int height, - struct list* del_list) + struct list *del_list) { - int order_flags; - int cache_id; - int flags; - int index; - int bytes; - int num_del_list; + int order_flags; + int cache_id; + int flags; + int index; + int bytes; + int num_del_list; - bytes = 7; - num_del_list = del_list->count; - if (num_del_list > 0) - { - bytes += 2; - bytes += num_del_list * 2; - } - xrdp_orders_check(self, bytes); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */ - out_uint8(self->out_s, order_flags); - cache_id = id & 0x7fff; - flags = cache_id; - if (num_del_list > 0) - { - flags |= 0x8000; - } - out_uint16_le(self->out_s, flags); - out_uint16_le(self->out_s, width); - out_uint16_le(self->out_s, height); - if (num_del_list > 0) - { - /* delete list */ - out_uint16_le(self->out_s, num_del_list); - for (index = 0; index < num_del_list; index++) + bytes = 7; + num_del_list = del_list->count; + + if (num_del_list > 0) { - cache_id = list_get_item(del_list, index) & 0x7fff; - out_uint16_le(self->out_s, cache_id); + bytes += 2; + bytes += num_del_list * 2; } - } - return 0; + + xrdp_orders_check(self, bytes); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */ + out_uint8(self->out_s, order_flags); + cache_id = id & 0x7fff; + flags = cache_id; + + if (num_del_list > 0) + { + flags |= 0x8000; + } + + out_uint16_le(self->out_s, flags); + out_uint16_le(self->out_s, width); + out_uint16_le(self->out_s, height); + + if (num_del_list > 0) + { + /* delete list */ + out_uint16_le(self->out_s, num_del_list); + + for (index = 0; index < num_del_list; index++) + { + cache_id = list_get_item(del_list, index) & 0x7fff; + out_uint16_le(self->out_s, cache_id); + } + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id) +xrdp_orders_send_switch_os_surface(struct xrdp_orders *self, int id) { - int order_flags; - int cache_id; + int order_flags; + int cache_id; - xrdp_orders_check(self, 3); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0 << 2; /* type RDP_ORDER_ALTSEC_SWITCH_SURFACE */ - out_uint8(self->out_s, order_flags); - cache_id = id & 0xffff; - out_uint16_le(self->out_s, cache_id); - return 0; + xrdp_orders_check(self, 3); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0 << 2; /* type RDP_ORDER_ALTSEC_SWITCH_SURFACE */ + out_uint8(self->out_s, order_flags); + cache_id = id & 0xffff; + out_uint16_le(self->out_s, cache_id); + return 0; } diff --git a/libxrdp/xrdp_orders_rail.c b/libxrdp/xrdp_orders_rail.c index 62f9b8ea..3ac0fd2a 100644 --- a/libxrdp/xrdp_orders_rail.c +++ b/libxrdp/xrdp_orders_rail.c @@ -27,26 +27,26 @@ /* RAIL */ /* returns error */ int APP_CC -xrdp_orders_send_window_delete(struct xrdp_orders* self, int window_id) +xrdp_orders_send_window_delete(struct xrdp_orders *self, int window_id) { - int order_size; - int order_flags; - int field_present_flags; + int order_size; + int order_flags; + int field_present_flags; - order_size = 11; - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - field_present_flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_DELETED; - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - return 0; + order_size = 11; + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_DELETED; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + return 0; } /*****************************************************************************/ @@ -55,69 +55,74 @@ xrdp_orders_send_window_delete(struct xrdp_orders* self, int window_id) /* flags can contain WINDOW_ORDER_STATE_NEW and/or WINDOW_ORDER_FIELD_ICON_BIG */ int APP_CC -xrdp_orders_send_window_cached_icon(struct xrdp_orders* self, +xrdp_orders_send_window_cached_icon(struct xrdp_orders *self, int window_id, int cache_entry, int cache_id, int flags) { - int order_size; - int order_flags; - int field_present_flags; + int order_size; + int order_flags; + int field_present_flags; - order_size = 14; - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | - WINDOW_ORDER_CACHED_ICON; - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - /* CacheEntry (2 bytes) */ - out_uint16_le(self->out_s, cache_entry); - /* CacheId (1 byte) */ - out_uint8(self->out_s, cache_id); - return 0; + order_size = 14; + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | + WINDOW_ORDER_CACHED_ICON; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + /* CacheEntry (2 bytes) */ + out_uint16_le(self->out_s, cache_entry); + /* CacheId (1 byte) */ + out_uint8(self->out_s, cache_id); + return 0; } /*****************************************************************************/ /* RAIL */ /* returns error */ static int APP_CC -xrdp_orders_send_ts_icon(struct stream* s, int cache_entry, int cache_id, - struct rail_icon_info* icon_info) +xrdp_orders_send_ts_icon(struct stream *s, int cache_entry, int cache_id, + struct rail_icon_info *icon_info) { - int use_cmap; + int use_cmap; - use_cmap = 0; - if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) - { - use_cmap = 1; - } + use_cmap = 0; - /* TS_ICON_INFO */ - out_uint16_le(s, cache_entry); - out_uint8(s, cache_id); - out_uint8(s, icon_info->bpp); - out_uint16_le(s, icon_info->width); - out_uint16_le(s, icon_info->height); - if (use_cmap) - { - out_uint16_le(s, icon_info->cmap_bytes); - } - out_uint16_le(s, icon_info->mask_bytes); - out_uint16_le(s, icon_info->data_bytes); - out_uint8p(s, icon_info->mask, icon_info->mask_bytes); - if (use_cmap) - { - out_uint8p(s, icon_info->cmap, icon_info->cmap_bytes); - } - out_uint8p(s, icon_info->data, icon_info->data_bytes); - return 0; + if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) + { + use_cmap = 1; + } + + /* TS_ICON_INFO */ + out_uint16_le(s, cache_entry); + out_uint8(s, cache_id); + out_uint8(s, icon_info->bpp); + out_uint16_le(s, icon_info->width); + out_uint16_le(s, icon_info->height); + + if (use_cmap) + { + out_uint16_le(s, icon_info->cmap_bytes); + } + + out_uint16_le(s, icon_info->mask_bytes); + out_uint16_le(s, icon_info->data_bytes); + out_uint8p(s, icon_info->mask, icon_info->mask_bytes); + + if (use_cmap) + { + out_uint8p(s, icon_info->cmap, icon_info->cmap_bytes); + } + + out_uint8p(s, icon_info->data, icon_info->data_bytes); + return 0; } /*****************************************************************************/ @@ -126,71 +131,78 @@ xrdp_orders_send_ts_icon(struct stream* s, int cache_entry, int cache_id, /* flags can contain WINDOW_ORDER_STATE_NEW and/or WINDOW_ORDER_FIELD_ICON_BIG */ int APP_CC -xrdp_orders_send_window_icon(struct xrdp_orders* self, +xrdp_orders_send_window_icon(struct xrdp_orders *self, int window_id, int cache_entry, int cache_id, - struct rail_icon_info* icon_info, + struct rail_icon_info *icon_info, int flags) { - int order_size; - int order_flags; - int field_present_flags; - int use_cmap; + int order_size; + int order_flags; + int field_present_flags; + int use_cmap; - use_cmap = 0; - if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) - { - use_cmap = 1; - } - order_size = 23 + icon_info->mask_bytes + icon_info->data_bytes; - if (use_cmap) - { - order_size += icon_info->cmap_bytes + 2; - } - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | - WINDOW_ORDER_ICON; - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); + use_cmap = 0; - xrdp_orders_send_ts_icon(self->out_s, cache_entry, cache_id, icon_info); + if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) + { + use_cmap = 1; + } - return 0; + order_size = 23 + icon_info->mask_bytes + icon_info->data_bytes; + + if (use_cmap) + { + order_size += icon_info->cmap_bytes + 2; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | + WINDOW_ORDER_ICON; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + + xrdp_orders_send_ts_icon(self->out_s, cache_entry, cache_id, icon_info); + + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_orders_send_as_unicode(struct stream* s, const char* text) +xrdp_orders_send_as_unicode(struct stream *s, const char *text) { - int str_chars; - int index; - int i32; - twchar wdst[256]; + int str_chars; + int index; + int i32; + twchar wdst[256]; - str_chars = g_mbstowcs(wdst, text, 255); - if (str_chars > 0) - { - i32 = str_chars * 2; - out_uint16_le(s, i32); - for (index = 0; index < str_chars; index++) + str_chars = g_mbstowcs(wdst, text, 255); + + if (str_chars > 0) { - i32 = wdst[index]; - out_uint16_le(s, i32); + i32 = str_chars * 2; + out_uint16_le(s, i32); + + for (index = 0; index < str_chars; index++) + { + i32 = wdst[index]; + out_uint16_le(s, i32); + } } - } - else - { - out_uint16_le(s, 0); - } - return 0; + else + { + out_uint16_le(s, 0); + } + + return 0; } /*****************************************************************************/ @@ -198,247 +210,276 @@ xrdp_orders_send_as_unicode(struct stream* s, const char* text) /* returns error */ /* flags can contain WINDOW_ORDER_STATE_NEW */ int APP_CC -xrdp_orders_send_window_new_update(struct xrdp_orders* self, int window_id, - struct rail_window_state_order* window_state, +xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id, + struct rail_window_state_order *window_state, int flags) { - int order_size; - int order_flags; - int field_present_flags; - int num_chars; - int index; + int order_size; + int order_flags; + int field_present_flags; + int num_chars; + int index; - order_size = 11; - field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW; - if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) - { - /* ownerWindowId (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) - { - /* style (4 bytes) */ - order_size += 4; - /* extendedStyle (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) - { - /* showState (1 byte) */ - order_size += 1; - } - if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) - { - /* titleInfo */ - num_chars = g_mbstowcs(0, window_state->title_info, 0); - order_size += 2 * num_chars + 2; - } - if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) - { - /* clientOffsetX (4 bytes) */ - order_size += 4; - /* clientOffsetY (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) - { - /* clientAreaWidth (4 bytes) */ - order_size += 4; - /* clientAreaHeight (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) - { - /* RPContent (1 byte) */ - order_size += 1; - } - if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) - { - /* rootParentHandle (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) - { - /* windowOffsetX (4 bytes) */ - order_size += 4; - /* windowOffsetY (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) - { - /* windowClientDeltaX (4 bytes) */ - order_size += 4; - /* windowClientDeltaY (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) - { - /* windowWidth (4 bytes) */ - order_size += 4; - /* windowHeight (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) - { - /* numWindowRects (2 bytes) */ - order_size += 2; - order_size += 8 * window_state->num_window_rects; - } - if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) - { - /* visibleOffsetX (4 bytes) */ - order_size += 4; - /* visibleOffsetY (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) - { - /* numVisibilityRects (2 bytes) */ - order_size += 2; - order_size += 8 * window_state->num_visibility_rects; - } + order_size = 11; + field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW; - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - - if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) - { - /* ownerWindowId (4 bytes) */ - out_uint32_le(self->out_s, window_state->owner_window_id); - } - if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) - { - /* style (4 bytes) */ - out_uint32_le(self->out_s, window_state->style); - /* extendedStyle (4 bytes) */ - out_uint32_le(self->out_s, window_state->extended_style); - } - if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) - { - /* showState (1 byte) */ - out_uint8(self->out_s, window_state->show_state); - } - if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) - { - /* titleInfo */ - xrdp_orders_send_as_unicode(self->out_s, window_state->title_info); - } - if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) - { - /* clientOffsetX (4 bytes) */ - out_uint32_le(self->out_s, window_state->client_offset_x); - /* clientOffsetY (4 bytes) */ - out_uint32_le(self->out_s, window_state->client_offset_y); - } - if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) - { - /* clientAreaWidth (4 bytes) */ - out_uint32_le(self->out_s, window_state->client_area_width); - /* clientAreaHeight (4 bytes) */ - out_uint32_le(self->out_s, window_state->client_area_height); - } - if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) - { - /* RPContent (1 byte) */ - out_uint8(self->out_s, window_state->rp_content); - } - if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) - { - /* rootParentHandle (4 bytes) */ - out_uint32_le(self->out_s, window_state->root_parent_handle); - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) - { - /* windowOffsetX (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_offset_x); - /* windowOffsetY (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_offset_y); - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) - { - /* windowClientDeltaX (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_client_delta_x); - /* windowClientDeltaY (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_client_delta_y); - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) - { - /* windowWidth (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_width); - /* windowHeight (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_height); - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) - { - /* numWindowRects (2 bytes) */ - out_uint16_le(self->out_s, window_state->num_window_rects); - for (index = 0; index < window_state->num_window_rects; index++) + if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) { - out_uint16_le(self->out_s, window_state->window_rects[index].left); - out_uint16_le(self->out_s, window_state->window_rects[index].top); - out_uint16_le(self->out_s, window_state->window_rects[index].right); - out_uint16_le(self->out_s, window_state->window_rects[index].bottom); + /* ownerWindowId (4 bytes) */ + order_size += 4; } - } - if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) - { - /* visibleOffsetX (4 bytes) */ - out_uint32_le(self->out_s, window_state->visible_offset_x); - /* visibleOffsetY (4 bytes) */ - out_uint32_le(self->out_s, window_state->visible_offset_y); - } - if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) - { - /* numVisibilityRects (2 bytes) */ - out_uint16_le(self->out_s, window_state->num_visibility_rects); - for (index = 0; index < window_state->num_visibility_rects; index++) - { - out_uint16_le(self->out_s, window_state->visibility_rects[index].left); - out_uint16_le(self->out_s, window_state->visibility_rects[index].top); - out_uint16_le(self->out_s, window_state->visibility_rects[index].right); - out_uint16_le(self->out_s, window_state->visibility_rects[index].bottom); - } - } - return 0; + if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) + { + /* style (4 bytes) */ + order_size += 4; + /* extendedStyle (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) + { + /* showState (1 byte) */ + order_size += 1; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) + { + /* titleInfo */ + num_chars = g_mbstowcs(0, window_state->title_info, 0); + order_size += 2 * num_chars + 2; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + /* clientOffsetX (4 bytes) */ + order_size += 4; + /* clientOffsetY (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + /* clientAreaWidth (4 bytes) */ + order_size += 4; + /* clientAreaHeight (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) + { + /* RPContent (1 byte) */ + order_size += 1; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) + { + /* rootParentHandle (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) + { + /* windowOffsetX (4 bytes) */ + order_size += 4; + /* windowOffsetY (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + /* windowClientDeltaX (4 bytes) */ + order_size += 4; + /* windowClientDeltaY (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) + { + /* windowWidth (4 bytes) */ + order_size += 4; + /* windowHeight (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) + { + /* numWindowRects (2 bytes) */ + order_size += 2; + order_size += 8 * window_state->num_window_rects; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + /* visibleOffsetX (4 bytes) */ + order_size += 4; + /* visibleOffsetY (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) + { + /* numVisibilityRects (2 bytes) */ + order_size += 2; + order_size += 8 * window_state->num_visibility_rects; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + + if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) + { + /* ownerWindowId (4 bytes) */ + out_uint32_le(self->out_s, window_state->owner_window_id); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) + { + /* style (4 bytes) */ + out_uint32_le(self->out_s, window_state->style); + /* extendedStyle (4 bytes) */ + out_uint32_le(self->out_s, window_state->extended_style); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) + { + /* showState (1 byte) */ + out_uint8(self->out_s, window_state->show_state); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) + { + /* titleInfo */ + xrdp_orders_send_as_unicode(self->out_s, window_state->title_info); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + /* clientOffsetX (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_offset_x); + /* clientOffsetY (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_offset_y); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + /* clientAreaWidth (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_area_width); + /* clientAreaHeight (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_area_height); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) + { + /* RPContent (1 byte) */ + out_uint8(self->out_s, window_state->rp_content); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) + { + /* rootParentHandle (4 bytes) */ + out_uint32_le(self->out_s, window_state->root_parent_handle); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) + { + /* windowOffsetX (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_offset_x); + /* windowOffsetY (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_offset_y); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + /* windowClientDeltaX (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_client_delta_x); + /* windowClientDeltaY (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_client_delta_y); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) + { + /* windowWidth (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_width); + /* windowHeight (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_height); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) + { + /* numWindowRects (2 bytes) */ + out_uint16_le(self->out_s, window_state->num_window_rects); + + for (index = 0; index < window_state->num_window_rects; index++) + { + out_uint16_le(self->out_s, window_state->window_rects[index].left); + out_uint16_le(self->out_s, window_state->window_rects[index].top); + out_uint16_le(self->out_s, window_state->window_rects[index].right); + out_uint16_le(self->out_s, window_state->window_rects[index].bottom); + } + } + + if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + /* visibleOffsetX (4 bytes) */ + out_uint32_le(self->out_s, window_state->visible_offset_x); + /* visibleOffsetY (4 bytes) */ + out_uint32_le(self->out_s, window_state->visible_offset_y); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) + { + /* numVisibilityRects (2 bytes) */ + out_uint16_le(self->out_s, window_state->num_visibility_rects); + + for (index = 0; index < window_state->num_visibility_rects; index++) + { + out_uint16_le(self->out_s, window_state->visibility_rects[index].left); + out_uint16_le(self->out_s, window_state->visibility_rects[index].top); + out_uint16_le(self->out_s, window_state->visibility_rects[index].right); + out_uint16_le(self->out_s, window_state->visibility_rects[index].bottom); + } + } + + return 0; } /*****************************************************************************/ /* RAIL */ /* returns error */ int APP_CC -xrdp_orders_send_notify_delete(struct xrdp_orders* self, int window_id, +xrdp_orders_send_notify_delete(struct xrdp_orders *self, int window_id, int notify_id) { - int order_size; - int order_flags; - int field_present_flags; + int order_size; + int order_flags; + int field_present_flags; - order_size = 15; - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - field_present_flags = WINDOW_ORDER_TYPE_NOTIFY | WINDOW_ORDER_STATE_DELETED; - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - /* notifyIconId (4 bytes) */ - out_uint32_le(self->out_s, notify_id); - return 0; + order_size = 15; + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = WINDOW_ORDER_TYPE_NOTIFY | WINDOW_ORDER_STATE_DELETED; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + /* notifyIconId (4 bytes) */ + out_uint32_le(self->out_s, notify_id); + return 0; } /*****************************************************************************/ @@ -446,123 +487,137 @@ xrdp_orders_send_notify_delete(struct xrdp_orders* self, int window_id, /* returns error */ /* flags can contain WINDOW_ORDER_STATE_NEW */ int APP_CC -xrdp_orders_send_notify_new_update(struct xrdp_orders* self, +xrdp_orders_send_notify_new_update(struct xrdp_orders *self, int window_id, int notify_id, - struct rail_notify_state_order* notify_state, + struct rail_notify_state_order *notify_state, int flags) { - int order_size; - int order_flags; - int field_present_flags; - int num_chars; - int use_cmap; + int order_size; + int order_flags; + int field_present_flags; + int num_chars; + int use_cmap; - order_size = 15; - field_present_flags = flags | WINDOW_ORDER_TYPE_NOTIFY; - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) - { - /* Version (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) - { - /* ToolTip (variable) UNICODE_STRING */ - num_chars = g_mbstowcs(0, notify_state->tool_tip, 0); - order_size += 2 * num_chars + 2; - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) - { - /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ - /* UNICODE_STRING */ - num_chars = g_mbstowcs(0, notify_state->infotip.title, 0); - order_size += 2 * num_chars + 2; - /* UNICODE_STRING */ - num_chars = g_mbstowcs(0, notify_state->infotip.text, 0); - order_size += 2 * num_chars + 2; - /* Timeout (4 bytes) */ - /* InfoFlags (4 bytes) */ - order_size += 8; - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) - { - /* State (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_ICON) - { - /* Icon (variable) */ - use_cmap = 0; - if ((notify_state->icon_info.bpp == 1) || (notify_state->icon_info.bpp == 2) || - (notify_state->icon_info.bpp == 4)) + order_size = 15; + field_present_flags = flags | WINDOW_ORDER_TYPE_NOTIFY; + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) { - use_cmap = 1; + /* Version (4 bytes) */ + order_size += 4; } - order_size += 12 + notify_state->icon_info.mask_bytes + - notify_state->icon_info.data_bytes; - if (use_cmap) + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) { - order_size += notify_state->icon_info.cmap_bytes + 2; + /* ToolTip (variable) UNICODE_STRING */ + num_chars = g_mbstowcs(0, notify_state->tool_tip, 0); + order_size += 2 * num_chars + 2; } - } - if (field_present_flags & WINDOW_ORDER_CACHED_ICON) - { - /* CachedIcon (3 bytes) */ - order_size += 3; - } - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - /* notifyIconId (4 bytes) */ - out_uint32_le(self->out_s, notify_id); + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) + { + /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ + /* UNICODE_STRING */ + num_chars = g_mbstowcs(0, notify_state->infotip.title, 0); + order_size += 2 * num_chars + 2; + /* UNICODE_STRING */ + num_chars = g_mbstowcs(0, notify_state->infotip.text, 0); + order_size += 2 * num_chars + 2; + /* Timeout (4 bytes) */ + /* InfoFlags (4 bytes) */ + order_size += 8; + } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) - { - /* Version (4 bytes) */ - out_uint32_le(self->out_s, notify_state->version); - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) - { - /* ToolTip (variable) UNICODE_STRING */ - xrdp_orders_send_as_unicode(self->out_s, notify_state->tool_tip); - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) - { - /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ - out_uint32_le(self->out_s, notify_state->infotip.timeout); - out_uint32_le(self->out_s, notify_state->infotip.flags); - xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.text); - xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.title); - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) - { - /* State (4 bytes) */ - out_uint32_le(self->out_s, notify_state->state); - } - if (field_present_flags & WINDOW_ORDER_ICON) - { - /* Icon (variable) */ - xrdp_orders_send_ts_icon(self->out_s, notify_state->icon_cache_entry, - notify_state->icon_cache_id, - ¬ify_state->icon_info); - } - if (field_present_flags & WINDOW_ORDER_CACHED_ICON) - { - /* CacheEntry (2 bytes) */ - out_uint16_le(self->out_s, notify_state->icon_cache_entry); - /* CacheId (1 byte) */ - out_uint8(self->out_s, notify_state->icon_cache_id); - } + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) + { + /* State (4 bytes) */ + order_size += 4; + } - return 0; + if (field_present_flags & WINDOW_ORDER_ICON) + { + /* Icon (variable) */ + use_cmap = 0; + + if ((notify_state->icon_info.bpp == 1) || (notify_state->icon_info.bpp == 2) || + (notify_state->icon_info.bpp == 4)) + { + use_cmap = 1; + } + + order_size += 12 + notify_state->icon_info.mask_bytes + + notify_state->icon_info.data_bytes; + + if (use_cmap) + { + order_size += notify_state->icon_info.cmap_bytes + 2; + } + } + + if (field_present_flags & WINDOW_ORDER_CACHED_ICON) + { + /* CachedIcon (3 bytes) */ + order_size += 3; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + /* notifyIconId (4 bytes) */ + out_uint32_le(self->out_s, notify_id); + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) + { + /* Version (4 bytes) */ + out_uint32_le(self->out_s, notify_state->version); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) + { + /* ToolTip (variable) UNICODE_STRING */ + xrdp_orders_send_as_unicode(self->out_s, notify_state->tool_tip); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) + { + /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ + out_uint32_le(self->out_s, notify_state->infotip.timeout); + out_uint32_le(self->out_s, notify_state->infotip.flags); + xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.text); + xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.title); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) + { + /* State (4 bytes) */ + out_uint32_le(self->out_s, notify_state->state); + } + + if (field_present_flags & WINDOW_ORDER_ICON) + { + /* Icon (variable) */ + xrdp_orders_send_ts_icon(self->out_s, notify_state->icon_cache_entry, + notify_state->icon_cache_id, + ¬ify_state->icon_info); + } + + if (field_present_flags & WINDOW_ORDER_CACHED_ICON) + { + /* CacheEntry (2 bytes) */ + out_uint16_le(self->out_s, notify_state->icon_cache_entry); + /* CacheId (1 byte) */ + out_uint8(self->out_s, notify_state->icon_cache_id); + } + + return 0; } /*****************************************************************************/ @@ -570,56 +625,59 @@ xrdp_orders_send_notify_new_update(struct xrdp_orders* self, /* returns error */ /* used for both Non-Monitored Desktop and Actively Monitored Desktop */ int APP_CC -xrdp_orders_send_monitored_desktop(struct xrdp_orders* self, - struct rail_monitored_desktop_order* mdo, +xrdp_orders_send_monitored_desktop(struct xrdp_orders *self, + struct rail_monitored_desktop_order *mdo, int flags) { - int order_size; - int order_flags; - int field_present_flags; - int index; + int order_size; + int order_flags; + int field_present_flags; + int index; - order_size = 7; - field_present_flags = flags | WINDOW_ORDER_TYPE_DESKTOP; + order_size = 7; + field_present_flags = flags | WINDOW_ORDER_TYPE_DESKTOP; - if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) - { - /* ActiveWindowId (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) - { - /* NumWindowIds (1 byte) */ - order_size += 1; - /* WindowIds (variable) */ - order_size += mdo->num_window_ids * 4; - } - - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - out_uint32_le(self->out_s, field_present_flags); - - if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) - { - /* ActiveWindowId (4 bytes) */ - out_uint32_le(self->out_s, mdo->active_window_id); - } - if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) - { - /* NumWindowIds (1 byte) */ - out_uint8(self->out_s, mdo->num_window_ids); - /* WindowIds (variable) */ - for (index = 0; index < mdo->num_window_ids; index++) + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) { - out_uint32_le(self->out_s, mdo->window_ids[index]); + /* ActiveWindowId (4 bytes) */ + order_size += 4; } - } - return 0; + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) + { + /* NumWindowIds (1 byte) */ + order_size += 1; + /* WindowIds (variable) */ + order_size += mdo->num_window_ids * 4; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + out_uint32_le(self->out_s, field_present_flags); + + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) + { + /* ActiveWindowId (4 bytes) */ + out_uint32_le(self->out_s, mdo->active_window_id); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) + { + /* NumWindowIds (1 byte) */ + out_uint8(self->out_s, mdo->num_window_ids); + + /* WindowIds (variable) */ + for (index = 0; index < mdo->num_window_ids; index++) + { + out_uint32_le(self->out_s, mdo->window_ids[index]); + } + } + + return 0; } diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 53e3ddc2..bf0f8f4e 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - rdp layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * rdp layer + */ #include "libxrdp.h" @@ -29,28 +27,30 @@ /* some compilers need unsigned char to avoid warnings */ static tui8 g_unknown1[172] = -{ 0xff, 0x02, 0xb6, 0x00, 0x28, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x27, 0x00, 0x03, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x26, 0x00, 0x01, 0x00, 0x1e, 0x00, - 0x02, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x1d, 0x00, - 0x04, 0x00, 0x27, 0x00, 0x05, 0x00, 0x0b, 0x00, - 0x06, 0x00, 0x28, 0x00, 0x08, 0x00, 0x21, 0x00, - 0x09, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x22, 0x00, - 0x0b, 0x00, 0x25, 0x00, 0x0c, 0x00, 0x24, 0x00, - 0x0d, 0x00, 0x23, 0x00, 0x0e, 0x00, 0x19, 0x00, - 0x0f, 0x00, 0x16, 0x00, 0x10, 0x00, 0x15, 0x00, - 0x11, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x1b, 0x00, - 0x13, 0x00, 0x1a, 0x00, 0x14, 0x00, 0x17, 0x00, - 0x15, 0x00, 0x18, 0x00, 0x16, 0x00, 0x0e, 0x00, - 0x18, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x0d, 0x00, - 0x1a, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x14, 0x00, - 0x1f, 0x00, 0x13, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x0a, 0x00, 0x22, 0x00, 0x06, 0x00, - 0x23, 0x00, 0x07, 0x00, 0x24, 0x00, 0x08, 0x00, - 0x25, 0x00, 0x09, 0x00, 0x26, 0x00, 0x04, 0x00, - 0x27, 0x00, 0x03, 0x00, 0x28, 0x00, 0x02, 0x00, - 0x29, 0x00, 0x01, 0x00, 0x2a, 0x00, 0x05, 0x00, - 0x2b, 0x00, 0x2a, 0x00 }; +{ + 0xff, 0x02, 0xb6, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x27, 0x00, 0x03, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x26, 0x00, 0x01, 0x00, 0x1e, 0x00, + 0x02, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x1d, 0x00, + 0x04, 0x00, 0x27, 0x00, 0x05, 0x00, 0x0b, 0x00, + 0x06, 0x00, 0x28, 0x00, 0x08, 0x00, 0x21, 0x00, + 0x09, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x22, 0x00, + 0x0b, 0x00, 0x25, 0x00, 0x0c, 0x00, 0x24, 0x00, + 0x0d, 0x00, 0x23, 0x00, 0x0e, 0x00, 0x19, 0x00, + 0x0f, 0x00, 0x16, 0x00, 0x10, 0x00, 0x15, 0x00, + 0x11, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x1b, 0x00, + 0x13, 0x00, 0x1a, 0x00, 0x14, 0x00, 0x17, 0x00, + 0x15, 0x00, 0x18, 0x00, 0x16, 0x00, 0x0e, 0x00, + 0x18, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x0d, 0x00, + 0x1a, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x14, 0x00, + 0x1f, 0x00, 0x13, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x0a, 0x00, 0x22, 0x00, 0x06, 0x00, + 0x23, 0x00, 0x07, 0x00, 0x24, 0x00, 0x08, 0x00, + 0x25, 0x00, 0x09, 0x00, 0x26, 0x00, 0x04, 0x00, + 0x27, 0x00, 0x03, 0x00, 0x28, 0x00, 0x02, 0x00, + 0x29, 0x00, 0x01, 0x00, 0x2a, 0x00, 0x05, 0x00, + 0x2b, 0x00, 0x2a, 0x00 +}; /* some compilers need unsigned char to avoid warnings */ /* @@ -60,113 +60,116 @@ static tui8 g_unknown2[8] = /*****************************************************************************/ static int APP_CC -xrdp_rdp_read_config(struct xrdp_client_info* client_info) +xrdp_rdp_read_config(struct xrdp_client_info *client_info) { - int index = 0; - struct list* items = (struct list *)NULL; - struct list* values = (struct list *)NULL; - char* item = (char *)NULL; - char* value = (char *)NULL; - char cfg_file[256]; + int index = 0; + struct list *items = (struct list *)NULL; + struct list *values = (struct list *)NULL; + char *item = (char *)NULL; + char *value = (char *)NULL; + char cfg_file[256]; - /* initialize (zero out) local variables: */ - g_memset(cfg_file,0,sizeof(char) * 256); + /* initialize (zero out) local variables: */ + g_memset(cfg_file, 0, sizeof(char) * 256); - items = list_create(); - items->auto_free = 1; - values = list_create(); - values->auto_free = 1; - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - file_by_name_read_section(cfg_file, "globals", items, values); - for (index = 0; index < items->count; index++) - { - item = (char*)list_get_item(items, index); - value = (char*)list_get_item(values, index); - if (g_strcasecmp(item, "bitmap_cache") == 0) + items = list_create(); + items->auto_free = 1; + values = list_create(); + values->auto_free = 1; + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + file_by_name_read_section(cfg_file, "globals", items, values); + + for (index = 0; index < items->count; index++) { - if ((g_strcasecmp(value, "yes") == 0) || - (g_strcasecmp(value, "true") == 0) || - (g_strcasecmp(value, "1") == 0)) - { - client_info->use_bitmap_cache = 1; - } + item = (char *)list_get_item(items, index); + value = (char *)list_get_item(values, index); + + if (g_strcasecmp(item, "bitmap_cache") == 0) + { + if ((g_strcasecmp(value, "yes") == 0) || + (g_strcasecmp(value, "true") == 0) || + (g_strcasecmp(value, "1") == 0)) + { + client_info->use_bitmap_cache = 1; + } + } + else if (g_strcasecmp(item, "bitmap_compression") == 0) + { + if (g_strcasecmp(value, "yes") == 0 || + g_strcasecmp(value, "true") == 0 || + g_strcasecmp(value, "1") == 0) + { + client_info->use_bitmap_comp = 1; + } + } + else if (g_strcasecmp(item, "crypt_level") == 0) + { + if (g_strcasecmp(value, "low") == 0) + { + client_info->crypt_level = 1; + } + else if (g_strcasecmp(value, "medium") == 0) + { + client_info->crypt_level = 2; + } + else if (g_strcasecmp(value, "high") == 0) + { + client_info->crypt_level = 3; + } + else + { + g_writeln("Warning: Your configured crypt level is" + "undefined 'high' will be used"); + client_info->crypt_level = 3; + } + } + else if (g_strcasecmp(item, "channel_code") == 0) + { + if ((g_strcasecmp(value, "yes") == 0) || + (g_strcasecmp(value, "1") == 0) || + (g_strcasecmp(value, "true") == 0)) + { + client_info->channel_code = 1; + } + else + { + g_writeln("Info: All channels are disabled"); + } + } + else if (g_strcasecmp(item, "max_bpp") == 0) + { + client_info->max_bpp = g_atoi(value); + } } - else if (g_strcasecmp(item, "bitmap_compression") == 0) - { - if (g_strcasecmp(value, "yes") == 0 || - g_strcasecmp(value, "true") == 0 || - g_strcasecmp(value, "1") == 0) - { - client_info->use_bitmap_comp = 1; - } - } - else if (g_strcasecmp(item, "crypt_level") == 0) - { - if (g_strcasecmp(value, "low") == 0) - { - client_info->crypt_level = 1; - } - else if (g_strcasecmp(value, "medium") == 0) - { - client_info->crypt_level = 2; - } - else if (g_strcasecmp(value, "high") == 0) - { - client_info->crypt_level = 3; - } - else - { - g_writeln("Warning: Your configured crypt level is" - "undefined 'high' will be used"); - client_info->crypt_level = 3; - } - } - else if (g_strcasecmp(item, "channel_code") == 0) - { - if ((g_strcasecmp(value, "yes") == 0) || - (g_strcasecmp(value, "1") == 0) || - (g_strcasecmp(value, "true") == 0)) - { - client_info->channel_code = 1; - } - else - { - g_writeln("Info: All channels are disabled"); - } - } - else if (g_strcasecmp(item, "max_bpp") == 0) - { - client_info->max_bpp = g_atoi(value); - } - } - list_delete(items); - list_delete(values); - return 0; + + list_delete(items); + list_delete(values); + return 0; } #if defined(XRDP_FREERDP1) /*****************************************************************************/ static void -cpuid(tui32 info, tui32* eax, tui32* ebx, tui32* ecx, tui32* edx) +cpuid(tui32 info, tui32 *eax, tui32 *ebx, tui32 *ecx, tui32 *edx) { #ifdef __GNUC__ #if defined(__i386__) || defined(__x86_64__) - __asm volatile - ( - /* The EBX (or RBX register on x86_64) is used for the PIC base address - and must not be corrupted by our inline assembly. */ + __asm volatile + ( + /* The EBX (or RBX register on x86_64) is used for the PIC base address + and must not be corrupted by our inline assembly. */ #if defined(__i386__) - "mov %%ebx, %%esi;" - "cpuid;" - "xchg %%ebx, %%esi;" + "mov %%ebx, %%esi;" + "cpuid;" + "xchg %%ebx, %%esi;" #else - "mov %%rbx, %%rsi;" - "cpuid;" - "xchg %%rbx, %%rsi;" + "mov %%rbx, %%rsi;" + "cpuid;" + "xchg %%rbx, %%rsi;" #endif - : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) - : "0" (info) - ); + : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (info) + ); #endif #endif } @@ -175,1379 +178,1457 @@ cpuid(tui32 info, tui32* eax, tui32* ebx, tui32* ecx, tui32* edx) static tui32 xrdp_rdp_detect_cpu(void) { - tui32 eax; - tui32 ebx; - tui32 ecx; - tui32 edx; - tui32 cpu_opt; + tui32 eax; + tui32 ebx; + tui32 ecx; + tui32 edx; + tui32 cpu_opt; - eax = 0; - ebx = 0; - ecx = 0; - edx = 0; - cpu_opt = 0; - cpuid(1, &eax, &ebx, &ecx, &edx); + eax = 0; + ebx = 0; + ecx = 0; + edx = 0; + cpu_opt = 0; + cpuid(1, &eax, &ebx, &ecx, &edx); - if (edx & (1 << 26)) - { - DEBUG("SSE2 detected"); - cpu_opt |= CPU_SSE2; - } + if (edx & (1 << 26)) + { + DEBUG("SSE2 detected"); + cpu_opt |= CPU_SSE2; + } - return cpu_opt; + return cpu_opt; } #endif /*****************************************************************************/ -struct xrdp_rdp* APP_CC -xrdp_rdp_create(struct xrdp_session* session, struct trans* trans) +struct xrdp_rdp *APP_CC +xrdp_rdp_create(struct xrdp_session *session, struct trans *trans) { - struct xrdp_rdp* self = (struct xrdp_rdp *)NULL; - int bytes; + struct xrdp_rdp *self = (struct xrdp_rdp *)NULL; + int bytes; - DEBUG(("in xrdp_rdp_create")); - self = (struct xrdp_rdp*)g_malloc(sizeof(struct xrdp_rdp), 1); - self->session = session; - self->share_id = 66538; - /* read ini settings */ - xrdp_rdp_read_config(&self->client_info); - /* create sec layer */ - self->sec_layer = xrdp_sec_create(self, trans, self->client_info.crypt_level, - self->client_info.channel_code); - /* default 8 bit v1 color bitmap cache entries and size */ - self->client_info.cache1_entries = 600; - self->client_info.cache1_size = 256; - self->client_info.cache2_entries = 300; - self->client_info.cache2_size = 1024; - self->client_info.cache3_entries = 262; - self->client_info.cache3_size = 4096; - /* load client ip info */ - bytes = sizeof(self->client_info.client_ip) - 1; - g_write_ip_address(trans->sck, self->client_info.client_ip, bytes); + DEBUG(("in xrdp_rdp_create")); + self = (struct xrdp_rdp *)g_malloc(sizeof(struct xrdp_rdp), 1); + self->session = session; + self->share_id = 66538; + /* read ini settings */ + xrdp_rdp_read_config(&self->client_info); + /* create sec layer */ + self->sec_layer = xrdp_sec_create(self, trans, self->client_info.crypt_level, + self->client_info.channel_code); + /* default 8 bit v1 color bitmap cache entries and size */ + self->client_info.cache1_entries = 600; + self->client_info.cache1_size = 256; + self->client_info.cache2_entries = 300; + self->client_info.cache2_size = 1024; + self->client_info.cache3_entries = 262; + self->client_info.cache3_size = 4096; + /* load client ip info */ + bytes = sizeof(self->client_info.client_ip) - 1; + g_write_ip_address(trans->sck, self->client_info.client_ip, bytes); #if defined(XRDP_FREERDP1) - self->mppc_enc = mppc_enc_new(PROTO_RDP_50); - self->rfx_enc = rfx_context_new(); - rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu()); + self->mppc_enc = mppc_enc_new(PROTO_RDP_50); + self->rfx_enc = rfx_context_new(); + rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu()); #endif - self->client_info.size = sizeof(self->client_info); - DEBUG(("out xrdp_rdp_create")); - return self; + self->client_info.size = sizeof(self->client_info); + DEBUG(("out xrdp_rdp_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_rdp_delete(struct xrdp_rdp* self) +xrdp_rdp_delete(struct xrdp_rdp *self) { - if (self == 0) - { - return; - } - xrdp_sec_delete(self->sec_layer); + if (self == 0) + { + return; + } + + xrdp_sec_delete(self->sec_layer); #if defined(XRDP_FREERDP1) - mppc_enc_free((struct rdp_mppc_enc*)(self->mppc_enc)); - rfx_context_free((RFX_CONTEXT*)(self->rfx_enc)); + mppc_enc_free((struct rdp_mppc_enc *)(self->mppc_enc)); + rfx_context_free((RFX_CONTEXT *)(self->rfx_enc)); #endif - g_free(self); + g_free(self); } /*****************************************************************************/ int APP_CC -xrdp_rdp_init(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_init(struct xrdp_rdp *self, struct stream *s) { - if (xrdp_sec_init(self->sec_layer, s) != 0) - { - return 1; - } - s_push_layer(s, rdp_hdr, 6); - return 0; + if (xrdp_sec_init(self->sec_layer, s) != 0) + { + return 1; + } + + s_push_layer(s, rdp_hdr, 6); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_init_data(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_init_data(struct xrdp_rdp *self, struct stream *s) { - if (xrdp_sec_init(self->sec_layer, s) != 0) - { - return 1; - } - s_push_layer(s, rdp_hdr, 18); - return 0; + if (xrdp_sec_init(self->sec_layer, s) != 0) + { + return 1; + } + + s_push_layer(s, rdp_hdr, 18); + return 0; } /*****************************************************************************/ /* returns erros */ int APP_CC -xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code) +xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) { - int error = 0; - int len = 0; - int pdu_code = 0; - int chan = 0; + int error = 0; + int len = 0; + int pdu_code = 0; + int chan = 0; - DEBUG(("in xrdp_rdp_recv")); - if (s->next_packet == 0 || s->next_packet >= s->end) - { - chan = 0; - error = xrdp_sec_recv(self->sec_layer, s, &chan); - if (error == -1) /* special code for send demand active */ + DEBUG(("in xrdp_rdp_recv")); + + if (s->next_packet == 0 || s->next_packet >= s->end) { - s->next_packet = 0; - *code = -1; - DEBUG(("out (1) xrdp_rdp_recv")); - return 0; - } - if (error != 0) - { - DEBUG(("out xrdp_rdp_recv error")); - return 1; - } - if ((chan != MCS_GLOBAL_CHANNEL) && (chan > 0)) - { - if (chan > MCS_GLOBAL_CHANNEL) - { - if(xrdp_channel_process(self->sec_layer->chan_layer, s, chan)!=0) + chan = 0; + error = xrdp_sec_recv(self->sec_layer, s, &chan); + + if (error == -1) /* special code for send demand active */ { - g_writeln("xrdp_channel_process returned unhandled error") ; + s->next_packet = 0; + *code = -1; + DEBUG(("out (1) xrdp_rdp_recv")); + return 0; } - } - else - { - g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d",chan); - } - s->next_packet = 0; - *code = 0; - DEBUG(("out (2) xrdp_rdp_recv")); - return 0; - } - s->next_packet = s->p; - } - else - { - DEBUG(("xrdp_rdp_recv stream not touched")) - s->p = s->next_packet; - } - if (!s_check_rem(s, 6)) - { - s->next_packet = 0; - *code = 0; - DEBUG(("out (3) xrdp_rdp_recv")); - len = (int)(s->end - s->p); - g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len); - return 0; - } - else - { - in_uint16_le(s, len); - /*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */ - in_uint16_le(s, pdu_code); - *code = pdu_code & 0xf; - in_uint8s(s, 2); /* mcs user id */ - s->next_packet += len; - DEBUG(("out (4) xrdp_rdp_recv")); - return 0; - } -} -/*****************************************************************************/ -int APP_CC -xrdp_rdp_send(struct xrdp_rdp* self, struct stream* s, int pdu_type) -{ - int len = 0; + if (error != 0) + { + DEBUG(("out xrdp_rdp_recv error")); + return 1; + } - DEBUG(("in xrdp_rdp_send")); - s_pop_layer(s, rdp_hdr); - len = s->end - s->p; - out_uint16_le(s, len); - out_uint16_le(s, 0x10 | pdu_type); - out_uint16_le(s, self->mcs_channel); - if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { - DEBUG(("out xrdp_rdp_send error")); - return 1; - } - DEBUG(("out xrdp_rdp_send")); - return 0; -} + if ((chan != MCS_GLOBAL_CHANNEL) && (chan > 0)) + { + if (chan > MCS_GLOBAL_CHANNEL) + { + if (xrdp_channel_process(self->sec_layer->chan_layer, s, chan) != 0) + { + g_writeln("xrdp_channel_process returned unhandled error") ; + } + } + else + { + g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d", chan); + } -/*****************************************************************************/ -int APP_CC -xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s, - int data_pdu_type) -{ - int len; - int ctype; - int clen; - int dlen; - int pdulen; - int pdutype; - int tocomplen; - int iso_offset; - int mcs_offset; - int sec_offset; - int rdp_offset; - struct stream ls; -#if defined(XRDP_FREERDP1) - struct rdp_mppc_enc* mppc_enc; -#endif + s->next_packet = 0; + *code = 0; + DEBUG(("out (2) xrdp_rdp_recv")); + return 0; + } - DEBUG(("in xrdp_rdp_send_data")); - s_pop_layer(s, rdp_hdr); - len = (int)(s->end - s->p); - pdutype = 0x10 | RDP_PDU_DATA; - pdulen = len; - dlen = len; - ctype = 0; - clen = len; - tocomplen = pdulen - 18; -#if defined(XRDP_FREERDP1) - if (self->client_info.rdp_compression && self->session->up_and_running) - { - mppc_enc = (struct rdp_mppc_enc*)(self->mppc_enc); - if (compress_rdp(mppc_enc, (tui8*)(s->p + 18), tocomplen)) - { - DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d " - "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb, - mppc_enc->historyOffset, tocomplen)); - if (mppc_enc->flags & RDP_MPPC_COMPRESSED) - { - clen = mppc_enc->bytes_in_opb + 18; - pdulen = clen; - ctype = mppc_enc->flags; - iso_offset = (int)(s->iso_hdr - s->data); - mcs_offset = (int)(s->mcs_hdr - s->data); - sec_offset = (int)(s->sec_hdr - s->data); - rdp_offset = (int)(s->rdp_hdr - s->data); - - /* outputBuffer has 64 bytes preceding it */ - ls.data = mppc_enc->outputBuffer - (rdp_offset + 18); - ls.p = ls.data + rdp_offset; - ls.end = ls.p + clen; - ls.size = clen; - ls.iso_hdr = ls.data + iso_offset; - ls.mcs_hdr = ls.data + mcs_offset; - ls.sec_hdr = ls.data + sec_offset; - ls.rdp_hdr = ls.data + rdp_offset; - ls.channel_hdr = 0; - ls.next_packet = 0; - s = &ls; - } + s->next_packet = s->p; } else { - g_writeln("mppc_encode not ok"); + DEBUG(("xrdp_rdp_recv stream not touched")) + s->p = s->next_packet; } - } -#endif - out_uint16_le(s, pdulen); - out_uint16_le(s, pdutype); - out_uint16_le(s, self->mcs_channel); - out_uint32_le(s, self->share_id); - out_uint8(s, 0); - out_uint8(s, 1); - out_uint16_le(s, dlen); - out_uint8(s, data_pdu_type); - out_uint8(s, ctype); - out_uint16_le(s, clen); - if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { - DEBUG(("out xrdp_rdp_send_data error")); - return 1; - } - DEBUG(("out xrdp_rdp_send_data")); - return 0; + if (!s_check_rem(s, 6)) + { + s->next_packet = 0; + *code = 0; + DEBUG(("out (3) xrdp_rdp_recv")); + len = (int)(s->end - s->p); + g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len); + return 0; + } + else + { + in_uint16_le(s, len); + /*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */ + in_uint16_le(s, pdu_code); + *code = pdu_code & 0xf; + in_uint8s(s, 2); /* mcs user id */ + s->next_packet += len; + DEBUG(("out (4) xrdp_rdp_recv")); + return 0; + } } /*****************************************************************************/ int APP_CC -xrdp_rdp_send_data_update_sync(struct xrdp_rdp* self) +xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type) { - struct stream * s = (struct stream *)NULL; + int len = 0; - make_stream(s); - init_stream(s, 8192); - DEBUG(("in xrdp_rdp_send_data_update_sync")); - if (xrdp_rdp_init_data(self, s) != 0) - { - DEBUG(("out xrdp_rdp_send_data_update_sync error")); + DEBUG(("in xrdp_rdp_send")); + s_pop_layer(s, rdp_hdr); + len = s->end - s->p; + out_uint16_le(s, len); + out_uint16_le(s, 0x10 | pdu_type); + out_uint16_le(s, self->mcs_channel); + + if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) + { + DEBUG(("out xrdp_rdp_send error")); + return 1; + } + + DEBUG(("out xrdp_rdp_send")); + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s, + int data_pdu_type) +{ + int len; + int ctype; + int clen; + int dlen; + int pdulen; + int pdutype; + int tocomplen; + int iso_offset; + int mcs_offset; + int sec_offset; + int rdp_offset; + struct stream ls; +#if defined(XRDP_FREERDP1) + struct rdp_mppc_enc *mppc_enc; +#endif + + DEBUG(("in xrdp_rdp_send_data")); + s_pop_layer(s, rdp_hdr); + len = (int)(s->end - s->p); + pdutype = 0x10 | RDP_PDU_DATA; + pdulen = len; + dlen = len; + ctype = 0; + clen = len; + tocomplen = pdulen - 18; +#if defined(XRDP_FREERDP1) + + if (self->client_info.rdp_compression && self->session->up_and_running) + { + mppc_enc = (struct rdp_mppc_enc *)(self->mppc_enc); + + if (compress_rdp(mppc_enc, (tui8 *)(s->p + 18), tocomplen)) + { + DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d " + "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb, + mppc_enc->historyOffset, tocomplen)); + + if (mppc_enc->flags & RDP_MPPC_COMPRESSED) + { + clen = mppc_enc->bytes_in_opb + 18; + pdulen = clen; + ctype = mppc_enc->flags; + iso_offset = (int)(s->iso_hdr - s->data); + mcs_offset = (int)(s->mcs_hdr - s->data); + sec_offset = (int)(s->sec_hdr - s->data); + rdp_offset = (int)(s->rdp_hdr - s->data); + + /* outputBuffer has 64 bytes preceding it */ + ls.data = mppc_enc->outputBuffer - (rdp_offset + 18); + ls.p = ls.data + rdp_offset; + ls.end = ls.p + clen; + ls.size = clen; + ls.iso_hdr = ls.data + iso_offset; + ls.mcs_hdr = ls.data + mcs_offset; + ls.sec_hdr = ls.data + sec_offset; + ls.rdp_hdr = ls.data + rdp_offset; + ls.channel_hdr = 0; + ls.next_packet = 0; + s = &ls; + } + } + else + { + g_writeln("mppc_encode not ok"); + } + } + +#endif + out_uint16_le(s, pdulen); + out_uint16_le(s, pdutype); + out_uint16_le(s, self->mcs_channel); + out_uint32_le(s, self->share_id); + out_uint8(s, 0); + out_uint8(s, 1); + out_uint16_le(s, dlen); + out_uint8(s, data_pdu_type); + out_uint8(s, ctype); + out_uint16_le(s, clen); + + if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) + { + DEBUG(("out xrdp_rdp_send_data error")); + return 1; + } + + DEBUG(("out xrdp_rdp_send_data")); + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self) +{ + struct stream *s = (struct stream *)NULL; + + make_stream(s); + init_stream(s, 8192); + DEBUG(("in xrdp_rdp_send_data_update_sync")); + + if (xrdp_rdp_init_data(self, s) != 0) + { + DEBUG(("out xrdp_rdp_send_data_update_sync error")); + free_stream(s); + return 1; + } + + out_uint16_le(s, RDP_UPDATE_SYNCHRONIZE); + out_uint8s(s, 2); + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_UPDATE) != 0) + { + DEBUG(("out xrdp_rdp_send_data_update_sync error")); + free_stream(s); + return 1; + } + + DEBUG(("out xrdp_rdp_send_data_update_sync")); free_stream(s); - return 1; - } - out_uint16_le(s, RDP_UPDATE_SYNCHRONIZE); - out_uint8s(s, 2); - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_UPDATE) != 0) - { - DEBUG(("out xrdp_rdp_send_data_update_sync error")); - free_stream(s); - return 1; - } - DEBUG(("out xrdp_rdp_send_data_update_sync")); - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp* self) +xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self) { - struct stream* p = (struct stream *)NULL; - int i = 0; + struct stream *p = (struct stream *)NULL; + int i = 0; - p = &(self->sec_layer->client_mcs_data); - p->p = p->data; - in_uint8s(p, 31); - in_uint16_le(p, self->client_info.width); - in_uint16_le(p, self->client_info.height); - in_uint8s(p, 120); - self->client_info.bpp = 8; - in_uint16_le(p, i); - switch (i) - { - case 0xca01: - in_uint8s(p, 6); - in_uint8(p, i); - if (i > 8) - { - self->client_info.bpp = i; - } - break; - case 0xca02: - self->client_info.bpp = 15; - break; - case 0xca03: - self->client_info.bpp = 16; - break; - case 0xca04: - self->client_info.bpp = 24; - break; - } - if (self->client_info.max_bpp > 0) - { - if (self->client_info.bpp > self->client_info.max_bpp) + p = &(self->sec_layer->client_mcs_data); + p->p = p->data; + in_uint8s(p, 31); + in_uint16_le(p, self->client_info.width); + in_uint16_le(p, self->client_info.height); + in_uint8s(p, 120); + self->client_info.bpp = 8; + in_uint16_le(p, i); + + switch (i) { - self->client_info.bpp = self->client_info.max_bpp; + case 0xca01: + in_uint8s(p, 6); + in_uint8(p, i); + + if (i > 8) + { + self->client_info.bpp = i; + } + + break; + case 0xca02: + self->client_info.bpp = 15; + break; + case 0xca03: + self->client_info.bpp = 16; + break; + case 0xca04: + self->client_info.bpp = 24; + break; } - } - p->p = p->data; - DEBUG(("client width %d, client height %d bpp %d", - self->client_info.width, self->client_info.height, - self->client_info.bpp)); - return 0; + + if (self->client_info.max_bpp > 0) + { + if (self->client_info.bpp > self->client_info.max_bpp) + { + self->client_info.bpp = self->client_info.max_bpp; + } + } + + p->p = p->data; + DEBUG(("client width %d, client height %d bpp %d", + self->client_info.width, self->client_info.height, + self->client_info.bpp)); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_incoming(struct xrdp_rdp* self) +xrdp_rdp_incoming(struct xrdp_rdp *self) { - DEBUG(("in xrdp_rdp_incoming")); - if (xrdp_sec_incoming(self->sec_layer) != 0) - { - return 1; - } - self->mcs_channel = self->sec_layer->mcs_layer->userid + - MCS_USERCHANNEL_BASE; - xrdp_rdp_parse_client_mcs_data(self); - DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel)); - return 0; + DEBUG(("in xrdp_rdp_incoming")); + + if (xrdp_sec_incoming(self->sec_layer) != 0) + { + return 1; + } + + self->mcs_channel = self->sec_layer->mcs_layer->userid + + MCS_USERCHANNEL_BASE; + xrdp_rdp_parse_client_mcs_data(self); + DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel)); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_send_demand_active(struct xrdp_rdp* self) +xrdp_rdp_send_demand_active(struct xrdp_rdp *self) { - struct stream* s; - int caps_count; - int caps_size; - int codec_caps_count; - int codec_caps_size; - char* caps_count_ptr; - char* caps_size_ptr; - char* caps_ptr; - char* codec_caps_count_ptr; - char* codec_caps_size_ptr; + struct stream *s; + int caps_count; + int caps_size; + int codec_caps_count; + int codec_caps_size; + char *caps_count_ptr; + char *caps_size_ptr; + char *caps_ptr; + char *codec_caps_count_ptr; + char *codec_caps_size_ptr; - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init(self, s) != 0) - { - free_stream(s); - return 1; - } + make_stream(s); + init_stream(s, 8192); - caps_count = 0; - out_uint32_le(s, self->share_id); - out_uint16_le(s, 4); /* 4 chars for RDP\0 */ - /* 2 bytes size after num caps, set later */ - caps_size_ptr = s->p; - out_uint8s(s, 2); - out_uint8a(s, "RDP", 4); - /* 4 byte num caps, set later */ - caps_count_ptr = s->p; - out_uint8s(s, 4); - caps_ptr = s->p; + if (xrdp_rdp_init(self, s) != 0) + { + free_stream(s); + return 1; + } - /* Output share capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_SHARE); - out_uint16_le(s, RDP_CAPLEN_SHARE); - out_uint16_le(s, self->mcs_channel); - out_uint16_be(s, 0xb5e2); /* 0x73e1 */ + caps_count = 0; + out_uint32_le(s, self->share_id); + out_uint16_le(s, 4); /* 4 chars for RDP\0 */ + /* 2 bytes size after num caps, set later */ + caps_size_ptr = s->p; + out_uint8s(s, 2); + out_uint8a(s, "RDP", 4); + /* 4 byte num caps, set later */ + caps_count_ptr = s->p; + out_uint8s(s, 4); + caps_ptr = s->p; - /* Output general capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_GENERAL); /* 1 */ - out_uint16_le(s, RDP_CAPLEN_GENERAL); /* 24(0x18) */ - out_uint16_le(s, 1); /* OS major type */ - out_uint16_le(s, 3); /* OS minor type */ - out_uint16_le(s, 0x200); /* Protocol version */ - out_uint16_le(s, 0); /* pad */ - out_uint16_le(s, 0); /* Compression types */ - //out_uint16_le(s, 0); /* pad use 0x40d for rdp packets, 0 for not */ - out_uint16_le(s, 0x40d); /* pad use 0x40d for rdp packets, 0 for not */ - out_uint16_le(s, 0); /* Update capability */ - out_uint16_le(s, 0); /* Remote unshare capability */ - out_uint16_le(s, 0); /* Compression level */ - out_uint16_le(s, 0); /* Pad */ + /* Output share capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_SHARE); + out_uint16_le(s, RDP_CAPLEN_SHARE); + out_uint16_le(s, self->mcs_channel); + out_uint16_be(s, 0xb5e2); /* 0x73e1 */ - /* Output bitmap capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_BITMAP); /* 2 */ - out_uint16_le(s, RDP_CAPLEN_BITMAP); /* 28(0x1c) */ - out_uint16_le(s, self->client_info.bpp); /* Preferred BPP */ - out_uint16_le(s, 1); /* Receive 1 BPP */ - out_uint16_le(s, 1); /* Receive 4 BPP */ - out_uint16_le(s, 1); /* Receive 8 BPP */ - out_uint16_le(s, self->client_info.width); /* width */ - out_uint16_le(s, self->client_info.height); /* height */ - out_uint16_le(s, 0); /* Pad */ - out_uint16_le(s, 1); /* Allow resize */ - out_uint16_le(s, 1); /* bitmap compression */ - out_uint16_le(s, 0); /* unknown */ - out_uint16_le(s, 0); /* unknown */ - out_uint16_le(s, 0); /* pad */ + /* Output general capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_GENERAL); /* 1 */ + out_uint16_le(s, RDP_CAPLEN_GENERAL); /* 24(0x18) */ + out_uint16_le(s, 1); /* OS major type */ + out_uint16_le(s, 3); /* OS minor type */ + out_uint16_le(s, 0x200); /* Protocol version */ + out_uint16_le(s, 0); /* pad */ + out_uint16_le(s, 0); /* Compression types */ + //out_uint16_le(s, 0); /* pad use 0x40d for rdp packets, 0 for not */ + out_uint16_le(s, 0x40d); /* pad use 0x40d for rdp packets, 0 for not */ + out_uint16_le(s, 0); /* Update capability */ + out_uint16_le(s, 0); /* Remote unshare capability */ + out_uint16_le(s, 0); /* Compression level */ + out_uint16_le(s, 0); /* Pad */ - /* Output font capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_FONT); /* 14 */ - out_uint16_le(s, RDP_CAPLEN_FONT); /* 4 */ + /* Output bitmap capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_BITMAP); /* 2 */ + out_uint16_le(s, RDP_CAPLEN_BITMAP); /* 28(0x1c) */ + out_uint16_le(s, self->client_info.bpp); /* Preferred BPP */ + out_uint16_le(s, 1); /* Receive 1 BPP */ + out_uint16_le(s, 1); /* Receive 4 BPP */ + out_uint16_le(s, 1); /* Receive 8 BPP */ + out_uint16_le(s, self->client_info.width); /* width */ + out_uint16_le(s, self->client_info.height); /* height */ + out_uint16_le(s, 0); /* Pad */ + out_uint16_le(s, 1); /* Allow resize */ + out_uint16_le(s, 1); /* bitmap compression */ + out_uint16_le(s, 0); /* unknown */ + out_uint16_le(s, 0); /* unknown */ + out_uint16_le(s, 0); /* pad */ - /* Output order capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_ORDER); /* 3 */ - out_uint16_le(s, RDP_CAPLEN_ORDER); /* 88(0x58) */ - out_uint8s(s, 16); - out_uint32_be(s, 0x40420f00); - out_uint16_le(s, 1); /* Cache X granularity */ - out_uint16_le(s, 20); /* Cache Y granularity */ - out_uint16_le(s, 0); /* Pad */ - out_uint16_le(s, 1); /* Max order level */ - out_uint16_le(s, 0x2f); /* Number of fonts */ - out_uint16_le(s, 0x22); /* Capability flags */ - /* caps */ - out_uint8(s, 1); /* dest blt */ - out_uint8(s, 1); /* pat blt */ - out_uint8(s, 1); /* screen blt */ - out_uint8(s, 1); /* mem blt */ - out_uint8(s, 0); /* tri blt */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* nine grid */ - out_uint8(s, 1); /* line to */ - out_uint8(s, 0); /* multi nine grid */ - out_uint8(s, 1); /* rect */ - out_uint8(s, 0); /* desk save */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* multi dest blt */ - out_uint8(s, 0); /* multi pat blt */ - out_uint8(s, 0); /* multi screen blt */ - out_uint8(s, 1); /* multi rect */ - out_uint8(s, 0); /* fast index */ - out_uint8(s, 0); /* polygonSC ([MS-RDPEGDI], 2.2.2.2.1.1.2.16) */ - out_uint8(s, 0); /* polygonCB ([MS-RDPEGDI], 2.2.2.2.1.1.2.17) */ - out_uint8(s, 0); /* polyline */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* fast glyph */ - out_uint8(s, 0); /* ellipse */ - out_uint8(s, 0); /* ellipse */ - out_uint8(s, 0); /* ? */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint16_le(s, 0x6a1); - /* declare support of bitmap cache rev3 */ - out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT); - out_uint32_le(s, 0x0f4240); /* desk save */ - out_uint32_le(s, 0x0f4240); /* desk save */ - out_uint32_le(s, 1); /* ? */ - out_uint32_le(s, 0); /* ? */ + /* Output font capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_FONT); /* 14 */ + out_uint16_le(s, RDP_CAPLEN_FONT); /* 4 */ - /* Output bmpcodecs capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_BMPCODECS); - codec_caps_size_ptr = s->p; - out_uint8s(s, 2); /* cap len set later */ - codec_caps_count = 0; - codec_caps_count_ptr = s->p; - out_uint8s(s, 1); /* bitmapCodecCount set later */ - /* nscodec */ - codec_caps_count++; - out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16); - out_uint8(s, 1); /* codec id, must be 1 */ - out_uint16_le(s, 3); - out_uint8(s, 0x01); /* fAllowDynamicFidelity */ - out_uint8(s, 0x01); /* fAllowSubsampling */ - out_uint8(s, 0x03); /* colorLossLevel */ - /* remotefx */ - codec_caps_count++; - out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16); - out_uint8(s, 0); /* codec id, client sets */ - out_uint16_le(s, 256); - out_uint8s(s, 256); - /* jpeg */ - codec_caps_count++; - out_uint8a(s, XR_CODEC_GUID_JPEG, 16); - out_uint8(s, 0); /* codec id, client sets */ - out_uint16_le(s, 1); /* ext length */ - out_uint8(s, 75); - /* calculate and set size and count */ - codec_caps_size = (int)(s->p - codec_caps_size_ptr); - codec_caps_size += 2; /* 2 bytes for RDP_CAPSET_BMPCODECS above */ - codec_caps_size_ptr[0] = codec_caps_size; - codec_caps_size_ptr[1] = codec_caps_size >> 8; - codec_caps_count_ptr[0] = codec_caps_count; + /* Output order capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_ORDER); /* 3 */ + out_uint16_le(s, RDP_CAPLEN_ORDER); /* 88(0x58) */ + out_uint8s(s, 16); + out_uint32_be(s, 0x40420f00); + out_uint16_le(s, 1); /* Cache X granularity */ + out_uint16_le(s, 20); /* Cache Y granularity */ + out_uint16_le(s, 0); /* Pad */ + out_uint16_le(s, 1); /* Max order level */ + out_uint16_le(s, 0x2f); /* Number of fonts */ + out_uint16_le(s, 0x22); /* Capability flags */ + /* caps */ + out_uint8(s, 1); /* dest blt */ + out_uint8(s, 1); /* pat blt */ + out_uint8(s, 1); /* screen blt */ + out_uint8(s, 1); /* mem blt */ + out_uint8(s, 0); /* tri blt */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* nine grid */ + out_uint8(s, 1); /* line to */ + out_uint8(s, 0); /* multi nine grid */ + out_uint8(s, 1); /* rect */ + out_uint8(s, 0); /* desk save */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* multi dest blt */ + out_uint8(s, 0); /* multi pat blt */ + out_uint8(s, 0); /* multi screen blt */ + out_uint8(s, 1); /* multi rect */ + out_uint8(s, 0); /* fast index */ + out_uint8(s, 0); /* polygonSC ([MS-RDPEGDI], 2.2.2.2.1.1.2.16) */ + out_uint8(s, 0); /* polygonCB ([MS-RDPEGDI], 2.2.2.2.1.1.2.17) */ + out_uint8(s, 0); /* polyline */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* fast glyph */ + out_uint8(s, 0); /* ellipse */ + out_uint8(s, 0); /* ellipse */ + out_uint8(s, 0); /* ? */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint16_le(s, 0x6a1); + /* declare support of bitmap cache rev3 */ + out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT); + out_uint32_le(s, 0x0f4240); /* desk save */ + out_uint32_le(s, 0x0f4240); /* desk save */ + out_uint32_le(s, 1); /* ? */ + out_uint32_le(s, 0); /* ? */ - /* Output color cache capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_COLCACHE); - out_uint16_le(s, RDP_CAPLEN_COLCACHE); - out_uint16_le(s, 6); /* cache size */ - out_uint16_le(s, 0); /* pad */ + /* Output bmpcodecs capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_BMPCODECS); + codec_caps_size_ptr = s->p; + out_uint8s(s, 2); /* cap len set later */ + codec_caps_count = 0; + codec_caps_count_ptr = s->p; + out_uint8s(s, 1); /* bitmapCodecCount set later */ + /* nscodec */ + codec_caps_count++; + out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16); + out_uint8(s, 1); /* codec id, must be 1 */ + out_uint16_le(s, 3); + out_uint8(s, 0x01); /* fAllowDynamicFidelity */ + out_uint8(s, 0x01); /* fAllowSubsampling */ + out_uint8(s, 0x03); /* colorLossLevel */ + /* remotefx */ + codec_caps_count++; + out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16); + out_uint8(s, 0); /* codec id, client sets */ + out_uint16_le(s, 256); + out_uint8s(s, 256); + /* jpeg */ + codec_caps_count++; + out_uint8a(s, XR_CODEC_GUID_JPEG, 16); + out_uint8(s, 0); /* codec id, client sets */ + out_uint16_le(s, 1); /* ext length */ + out_uint8(s, 75); + /* calculate and set size and count */ + codec_caps_size = (int)(s->p - codec_caps_size_ptr); + codec_caps_size += 2; /* 2 bytes for RDP_CAPSET_BMPCODECS above */ + codec_caps_size_ptr[0] = codec_caps_size; + codec_caps_size_ptr[1] = codec_caps_size >> 8; + codec_caps_count_ptr[0] = codec_caps_count; - /* Output pointer capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_POINTER); - out_uint16_le(s, RDP_CAPLEN_POINTER); - out_uint16_le(s, 1); /* Colour pointer */ - out_uint16_le(s, 0x19); /* Cache size */ - out_uint16_le(s, 0x19); /* Cache size */ + /* Output color cache capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_COLCACHE); + out_uint16_le(s, RDP_CAPLEN_COLCACHE); + out_uint16_le(s, 6); /* cache size */ + out_uint16_le(s, 0); /* pad */ - /* Output input capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_INPUT); /* 13(0xd) */ - out_uint16_le(s, RDP_CAPLEN_INPUT); /* 88(0x58) */ - out_uint8(s, 1); - out_uint8s(s, 83); + /* Output pointer capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_POINTER); + out_uint16_le(s, RDP_CAPLEN_POINTER); + out_uint16_le(s, 1); /* Colour pointer */ + out_uint16_le(s, 0x19); /* Cache size */ + out_uint16_le(s, 0x19); /* Cache size */ - /* Remote Programs Capability Set */ - caps_count++; - out_uint16_le(s, 0x0017); /* CAPSETTYPE_RAIL */ - out_uint16_le(s, 8); - out_uint32_le(s, 3); /* TS_RAIL_LEVEL_SUPPORTED + /* Output input capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_INPUT); /* 13(0xd) */ + out_uint16_le(s, RDP_CAPLEN_INPUT); /* 88(0x58) */ + out_uint8(s, 1); + out_uint8s(s, 83); + + /* Remote Programs Capability Set */ + caps_count++; + out_uint16_le(s, 0x0017); /* CAPSETTYPE_RAIL */ + out_uint16_le(s, 8); + out_uint32_le(s, 3); /* TS_RAIL_LEVEL_SUPPORTED TS_RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED */ - /* Window List Capability Set */ - caps_count++; - out_uint16_le(s, 0x0018); /* CAPSETTYPE_WINDOW */ - out_uint16_le(s, 11); - out_uint32_le(s, 2); /* TS_WINDOW_LEVEL_SUPPORTED_EX */ - out_uint8(s, 3); /* NumIconCaches */ - out_uint16_le(s, 12); /* NumIconCacheEntries */ + /* Window List Capability Set */ + caps_count++; + out_uint16_le(s, 0x0018); /* CAPSETTYPE_WINDOW */ + out_uint16_le(s, 11); + out_uint32_le(s, 2); /* TS_WINDOW_LEVEL_SUPPORTED_EX */ + out_uint8(s, 3); /* NumIconCaches */ + out_uint16_le(s, 12); /* NumIconCacheEntries */ - /* 6 - bitmap cache v3 codecid */ - caps_count++; - out_uint16_le(s, 0x0006); - out_uint16_le(s, 5); - out_uint8(s, 0); /* client sets */ + /* 6 - bitmap cache v3 codecid */ + caps_count++; + out_uint16_le(s, 0x0006); + out_uint16_le(s, 5); + out_uint8(s, 0); /* client sets */ - out_uint8s(s, 4); /* pad */ + out_uint8s(s, 4); /* pad */ - s_mark_end(s); + s_mark_end(s); - caps_size = (int)(s->end - caps_ptr); - caps_size_ptr[0] = caps_size; - caps_size_ptr[1] = caps_size >> 8; + caps_size = (int)(s->end - caps_ptr); + caps_size_ptr[0] = caps_size; + caps_size_ptr[1] = caps_size >> 8; - caps_count_ptr[0] = caps_count; - caps_count_ptr[1] = caps_count >> 8; - caps_count_ptr[2] = caps_count >> 16; - caps_count_ptr[3] = caps_count >> 24; + caps_count_ptr[0] = caps_count; + caps_count_ptr[1] = caps_count >> 8; + caps_count_ptr[2] = caps_count >> 16; + caps_count_ptr[3] = caps_count >> 24; + + if (xrdp_rdp_send(self, s, RDP_PDU_DEMAND_ACTIVE) != 0) + { + free_stream(s); + return 1; + } - if (xrdp_rdp_send(self, s, RDP_PDU_DEMAND_ACTIVE) != 0) - { free_stream(s); - return 1; - } - - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_general(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_general(struct xrdp_rdp *self, struct stream *s, int len) { - int i; + int i; - in_uint8s(s, 10); - in_uint16_le(s, i); - /* use_compact_packets is pretty much 'use rdp5' */ - self->client_info.use_compact_packets = (i != 0); - /* op2 is a boolean to use compact bitmap headers in bitmap cache */ - /* set it to same as 'use rdp5' boolean */ - self->client_info.op2 = self->client_info.use_compact_packets; - return 0; + in_uint8s(s, 10); + in_uint16_le(s, i); + /* use_compact_packets is pretty much 'use rdp5' */ + self->client_info.use_compact_packets = (i != 0); + /* op2 is a boolean to use compact bitmap headers in bitmap cache */ + /* set it to same as 'use rdp5' boolean */ + self->client_info.op2 = self->client_info.use_compact_packets; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_order(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_order(struct xrdp_rdp *self, struct stream *s, int len) { - int i; - char order_caps[32]; - int ex_flags; + int i; + char order_caps[32]; + int ex_flags; - DEBUG(("order capabilities")); - in_uint8s(s, 20); /* Terminal desc, pad */ - in_uint8s(s, 2); /* Cache X granularity */ - in_uint8s(s, 2); /* Cache Y granularity */ - in_uint8s(s, 2); /* Pad */ - in_uint8s(s, 2); /* Max order level */ - in_uint8s(s, 2); /* Number of fonts */ - in_uint8s(s, 2); /* Capability flags */ - in_uint8a(s, order_caps, 32); /* Orders supported */ - DEBUG(("dest blt-0 %d", order_caps[0])); - DEBUG(("pat blt-1 %d", order_caps[1])); - DEBUG(("screen blt-2 %d", order_caps[2])); - DEBUG(("memblt-3-13 %d %d", order_caps[3], order_caps[13])); - DEBUG(("triblt-4-14 %d %d", order_caps[4], order_caps[14])); - DEBUG(("line-8 %d", order_caps[8])); - DEBUG(("line-9 %d", order_caps[9])); - DEBUG(("rect-10 %d", order_caps[10])); - DEBUG(("desksave-11 %d", order_caps[11])); - DEBUG(("polygon-20 %d", order_caps[20])); - DEBUG(("polygon2-21 %d", order_caps[21])); - DEBUG(("polyline-22 %d", order_caps[22])); - DEBUG(("ellipse-25 %d", order_caps[25])); - DEBUG(("ellipse2-26 %d", order_caps[26])); - DEBUG(("text2-27 %d", order_caps[27])); - DEBUG(("order_caps dump")); + DEBUG(("order capabilities")); + in_uint8s(s, 20); /* Terminal desc, pad */ + in_uint8s(s, 2); /* Cache X granularity */ + in_uint8s(s, 2); /* Cache Y granularity */ + in_uint8s(s, 2); /* Pad */ + in_uint8s(s, 2); /* Max order level */ + in_uint8s(s, 2); /* Number of fonts */ + in_uint8s(s, 2); /* Capability flags */ + in_uint8a(s, order_caps, 32); /* Orders supported */ + DEBUG(("dest blt-0 %d", order_caps[0])); + DEBUG(("pat blt-1 %d", order_caps[1])); + DEBUG(("screen blt-2 %d", order_caps[2])); + DEBUG(("memblt-3-13 %d %d", order_caps[3], order_caps[13])); + DEBUG(("triblt-4-14 %d %d", order_caps[4], order_caps[14])); + DEBUG(("line-8 %d", order_caps[8])); + DEBUG(("line-9 %d", order_caps[9])); + DEBUG(("rect-10 %d", order_caps[10])); + DEBUG(("desksave-11 %d", order_caps[11])); + DEBUG(("polygon-20 %d", order_caps[20])); + DEBUG(("polygon2-21 %d", order_caps[21])); + DEBUG(("polyline-22 %d", order_caps[22])); + DEBUG(("ellipse-25 %d", order_caps[25])); + DEBUG(("ellipse2-26 %d", order_caps[26])); + DEBUG(("text2-27 %d", order_caps[27])); + DEBUG(("order_caps dump")); #if defined(XRDP_DEBUG) - g_hexdump(order_caps, 32); + g_hexdump(order_caps, 32); #endif - in_uint8s(s, 2); /* Text capability flags */ - /* read extended order support flags */ - in_uint16_le(s, ex_flags); /* Ex flags */ - if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT) - { - g_writeln("xrdp_process_capset_order: bitmap cache v3 supported"); - self->client_info.bitmap_cache_version |= 4; - } - in_uint8s(s, 4); /* Pad */ + in_uint8s(s, 2); /* Text capability flags */ + /* read extended order support flags */ + in_uint16_le(s, ex_flags); /* Ex flags */ - in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */ - self->client_info.desktop_cache = i; - DEBUG(("desktop cache size %d", i)); - in_uint8s(s, 4); /* Unknown */ - in_uint8s(s, 4); /* Unknown */ - return 0; + if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT) + { + g_writeln("xrdp_process_capset_order: bitmap cache v3 supported"); + self->client_info.bitmap_cache_version |= 4; + } + + in_uint8s(s, 4); /* Pad */ + + in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */ + self->client_info.desktop_cache = i; + DEBUG(("desktop cache size %d", i)); + in_uint8s(s, 4); /* Unknown */ + in_uint8s(s, 4); /* Unknown */ + return 0; } /*****************************************************************************/ /* get the bitmap cache size */ static int APP_CC -xrdp_process_capset_bmpcache(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_bmpcache(struct xrdp_rdp *self, struct stream *s, int len) { - self->client_info.bitmap_cache_version |= 1; - in_uint8s(s, 24); - in_uint16_le(s, self->client_info.cache1_entries); - in_uint16_le(s, self->client_info.cache1_size); - in_uint16_le(s, self->client_info.cache2_entries); - in_uint16_le(s, self->client_info.cache2_size); - in_uint16_le(s, self->client_info.cache3_entries); - in_uint16_le(s, self->client_info.cache3_size); - DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, - self->client_info.cache1_size)); - DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, - self->client_info.cache2_size)); - DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, - self->client_info.cache3_size)); - return 0; + self->client_info.bitmap_cache_version |= 1; + in_uint8s(s, 24); + in_uint16_le(s, self->client_info.cache1_entries); + in_uint16_le(s, self->client_info.cache1_size); + in_uint16_le(s, self->client_info.cache2_entries); + in_uint16_le(s, self->client_info.cache2_size); + in_uint16_le(s, self->client_info.cache3_entries); + in_uint16_le(s, self->client_info.cache3_size); + DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, + self->client_info.cache1_size)); + DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, + self->client_info.cache2_size)); + DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, + self->client_info.cache3_size)); + return 0; } /*****************************************************************************/ /* get the bitmap cache size */ static int APP_CC -xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_bmpcache2(struct xrdp_rdp *self, struct stream *s, int len) { - int Bpp = 0; - int i = 0; + int Bpp = 0; + int i = 0; - self->client_info.bitmap_cache_version |= 2; - Bpp = (self->client_info.bpp + 7) / 8; - in_uint16_le(s, i); /* cache flags */ - self->client_info.bitmap_cache_persist_enable = i; - in_uint8s(s, 2); /* number of caches in set, 3 */ - in_uint32_le(s, i); - i = MIN(i, 2000); - self->client_info.cache1_entries = i; - self->client_info.cache1_size = 256 * Bpp; - in_uint32_le(s, i); - i = MIN(i, 2000); - self->client_info.cache2_entries = i; - self->client_info.cache2_size = 1024 * Bpp; - in_uint32_le(s, i); - i = i & 0x7fffffff; - i = MIN(i, 2000); - self->client_info.cache3_entries = i; - self->client_info.cache3_size = 4096 * Bpp; - DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, - self->client_info.cache1_size)); - DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, - self->client_info.cache2_size)); - DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, - self->client_info.cache3_size)); - return 0; + self->client_info.bitmap_cache_version |= 2; + Bpp = (self->client_info.bpp + 7) / 8; + in_uint16_le(s, i); /* cache flags */ + self->client_info.bitmap_cache_persist_enable = i; + in_uint8s(s, 2); /* number of caches in set, 3 */ + in_uint32_le(s, i); + i = MIN(i, 2000); + self->client_info.cache1_entries = i; + self->client_info.cache1_size = 256 * Bpp; + in_uint32_le(s, i); + i = MIN(i, 2000); + self->client_info.cache2_entries = i; + self->client_info.cache2_size = 1024 * Bpp; + in_uint32_le(s, i); + i = i & 0x7fffffff; + i = MIN(i, 2000); + self->client_info.cache3_entries = i; + self->client_info.cache3_size = 4096 * Bpp; + DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, + self->client_info.cache1_size)); + DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, + self->client_info.cache2_size)); + DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, + self->client_info.cache3_size)); + return 0; } /*****************************************************************************/ static int -xrdp_process_capset_cache_v3_codec_id(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s, int len) { - int codec_id; + int codec_id; - in_uint8(s, codec_id); - g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d", - codec_id); - self->client_info.v3_codec_id = codec_id; - return 0; + in_uint8(s, codec_id); + g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d", + codec_id); + self->client_info.v3_codec_id = codec_id; + return 0; } /*****************************************************************************/ /* get the number of client cursor cache */ static int APP_CC -xrdp_process_capset_pointercache(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_pointercache(struct xrdp_rdp *self, struct stream *s, int len) { - int i; + int i; - in_uint8s(s, 2); /* color pointer */ - in_uint16_le(s, i); - i = MIN(i, 32); - self->client_info.pointer_cache_entries = i; - return 0; + in_uint8s(s, 2); /* color pointer */ + in_uint16_le(s, i); + i = MIN(i, 32); + self->client_info.pointer_cache_entries = i; + return 0; } /*****************************************************************************/ /* get the type of client brush cache */ static int APP_CC -xrdp_process_capset_brushcache(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_brushcache(struct xrdp_rdp *self, struct stream *s, int len) { - int code; + int code; - in_uint32_le(s, code); - self->client_info.brush_cache_code = code; - return 0; + in_uint32_le(s, code); + self->client_info.brush_cache_code = code; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_offscreen_bmpcache(struct xrdp_rdp* self, struct stream* s, +xrdp_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s, int len) { - int i32; + int i32; - if (len - 4 < 8) - { - g_writeln("xrdp_process_offscreen_bmpcache: bad len"); - return 1; - } - in_uint32_le(s, i32); - self->client_info.offscreen_support_level = i32; - in_uint16_le(s, i32); - self->client_info.offscreen_cache_size = i32 * 1024; - in_uint16_le(s, i32); - self->client_info.offscreen_cache_entries = i32; - g_writeln("xrdp_process_offscreen_bmpcache: support level %d " - "cache size %d MB cache entries %d", - self->client_info.offscreen_support_level, - self->client_info.offscreen_cache_size, - self->client_info.offscreen_cache_entries); - return 0; + if (len - 4 < 8) + { + g_writeln("xrdp_process_offscreen_bmpcache: bad len"); + return 1; + } + + in_uint32_le(s, i32); + self->client_info.offscreen_support_level = i32; + in_uint16_le(s, i32); + self->client_info.offscreen_cache_size = i32 * 1024; + in_uint16_le(s, i32); + self->client_info.offscreen_cache_entries = i32; + g_writeln("xrdp_process_offscreen_bmpcache: support level %d " + "cache size %d MB cache entries %d", + self->client_info.offscreen_support_level, + self->client_info.offscreen_cache_size, + self->client_info.offscreen_cache_entries); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_rail(struct xrdp_rdp* self, struct stream* s, int len) +xrdp_process_capset_rail(struct xrdp_rdp *self, struct stream *s, int len) { - int i32; + int i32; - if (len - 4 < 4) - { - g_writeln("xrdp_process_capset_rail: bad len"); - return 1; - } - in_uint32_le(s, i32); - self->client_info.rail_support_level = i32; - g_writeln("xrdp_process_capset_rail: rail_support_level %d", - self->client_info.rail_support_level); - return 0; + if (len - 4 < 4) + { + g_writeln("xrdp_process_capset_rail: bad len"); + return 1; + } + + in_uint32_le(s, i32); + self->client_info.rail_support_level = i32; + g_writeln("xrdp_process_capset_rail: rail_support_level %d", + self->client_info.rail_support_level); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_window(struct xrdp_rdp* self, struct stream* s, int len) +xrdp_process_capset_window(struct xrdp_rdp *self, struct stream *s, int len) { - int i32; + int i32; - if (len - 4 < 7) - { - g_writeln("xrdp_process_capset_window: bad len"); - return 1; - } - in_uint32_le(s, i32); - self->client_info.wnd_support_level = i32; - in_uint8(s, i32); - self->client_info.wnd_num_icon_caches = i32; - in_uint16_le(s, i32); - self->client_info.wnd_num_icon_cache_entries = i32; - g_writeln("xrdp_process_capset_window wnd_support_level %d " - "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d", - self->client_info.wnd_support_level, - self->client_info.wnd_num_icon_caches, - self->client_info.wnd_num_icon_cache_entries); - return 0; + if (len - 4 < 7) + { + g_writeln("xrdp_process_capset_window: bad len"); + return 1; + } + + in_uint32_le(s, i32); + self->client_info.wnd_support_level = i32; + in_uint8(s, i32); + self->client_info.wnd_num_icon_caches = i32; + in_uint16_le(s, i32); + self->client_info.wnd_num_icon_cache_entries = i32; + g_writeln("xrdp_process_capset_window wnd_support_level %d " + "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d", + self->client_info.wnd_support_level, + self->client_info.wnd_num_icon_caches, + self->client_info.wnd_num_icon_cache_entries); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_codecs(struct xrdp_rdp* self, struct stream* s, int len) +xrdp_process_capset_codecs(struct xrdp_rdp *self, struct stream *s, int len) { - int codec_id; - int codec_count; - int index; - int codec_properties_length; - int i1; - char* codec_guid; - char* next_guid; + int codec_id; + int codec_count; + int index; + int codec_properties_length; + int i1; + char *codec_guid; + char *next_guid; - in_uint8(s, codec_count); - for (index = 0; index < codec_count; index++) - { - codec_guid = s->p; - in_uint8s(s, 16); - in_uint8(s, codec_id); - in_uint16_le(s, codec_properties_length); - next_guid = s->p + codec_properties_length; - if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0) + in_uint8(s, codec_count); + + for (index = 0; index < codec_count; index++) { - g_writeln("xrdp_process_capset_codecs: nscodec codec id %d prop len %d", - codec_id, codec_properties_length); - self->client_info.ns_codec_id = codec_id; - i1 = MIN(64, codec_properties_length); - g_memcpy(self->client_info.ns_prop, s->p, i1); - self->client_info.ns_prop_len = i1; + codec_guid = s->p; + in_uint8s(s, 16); + in_uint8(s, codec_id); + in_uint16_le(s, codec_properties_length); + next_guid = s->p + codec_properties_length; + + if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0) + { + g_writeln("xrdp_process_capset_codecs: nscodec codec id %d prop len %d", + codec_id, codec_properties_length); + self->client_info.ns_codec_id = codec_id; + i1 = MIN(64, codec_properties_length); + g_memcpy(self->client_info.ns_prop, s->p, i1); + self->client_info.ns_prop_len = i1; + } + else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0) + { + g_writeln("xrdp_process_capset_codecs: rfx codec id %d prop len %d", + codec_id, codec_properties_length); + self->client_info.rfx_codec_id = codec_id; + i1 = MIN(64, codec_properties_length); + g_memcpy(self->client_info.rfx_prop, s->p, i1); + self->client_info.rfx_prop_len = i1; + } + else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0) + { + g_writeln("xrdp_process_capset_codecs: jpeg codec id %d prop len %d", + codec_id, codec_properties_length); + self->client_info.jpeg_codec_id = codec_id; + i1 = MIN(64, codec_properties_length); + g_memcpy(self->client_info.jpeg_prop, s->p, i1); + self->client_info.jpeg_prop_len = i1; + g_writeln(" jpeg quality %d", self->client_info.jpeg_prop[0]); + } + else + { + g_writeln("xrdp_process_capset_codecs: unknown codec id %d", codec_id); + } + + s->p = next_guid; } - else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0) - { - g_writeln("xrdp_process_capset_codecs: rfx codec id %d prop len %d", - codec_id, codec_properties_length); - self->client_info.rfx_codec_id = codec_id; - i1 = MIN(64, codec_properties_length); - g_memcpy(self->client_info.rfx_prop, s->p, i1); - self->client_info.rfx_prop_len = i1; - } - else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0) - { - g_writeln("xrdp_process_capset_codecs: jpeg codec id %d prop len %d", - codec_id, codec_properties_length); - self->client_info.jpeg_codec_id = codec_id; - i1 = MIN(64, codec_properties_length); - g_memcpy(self->client_info.jpeg_prop, s->p, i1); - self->client_info.jpeg_prop_len = i1; - g_writeln(" jpeg quality %d", self->client_info.jpeg_prop[0]); - } - else - { - g_writeln("xrdp_process_capset_codecs: unknown codec id %d", codec_id); - } - s->p = next_guid; - } - return 0; + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_confirm_active(struct xrdp_rdp *self, struct stream *s) { - int cap_len; - int source_len; - int num_caps; - int index; - int type; - int len; - char* p; + int cap_len; + int source_len; + int num_caps; + int index; + int type; + int len; + char *p; - DEBUG(("in xrdp_rdp_process_confirm_active")); - in_uint8s(s, 4); /* rdp_shareid */ - in_uint8s(s, 2); /* userid */ - in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */ - in_uint16_le(s, cap_len); - in_uint8s(s, source_len); - in_uint16_le(s, num_caps); - in_uint8s(s, 2); /* pad */ - for (index = 0; index < num_caps; index++) - { - p = s->p; - in_uint16_le(s, type); - in_uint16_le(s, len); - switch (type) + DEBUG(("in xrdp_rdp_process_confirm_active")); + in_uint8s(s, 4); /* rdp_shareid */ + in_uint8s(s, 2); /* userid */ + in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */ + in_uint16_le(s, cap_len); + in_uint8s(s, source_len); + in_uint16_le(s, num_caps); + in_uint8s(s, 2); /* pad */ + + for (index = 0; index < num_caps; index++) { - case RDP_CAPSET_GENERAL: /* 1 */ - DEBUG(("RDP_CAPSET_GENERAL")); - xrdp_process_capset_general(self, s, len); - break; - case RDP_CAPSET_BITMAP: /* 2 */ - DEBUG(("RDP_CAPSET_BITMAP")); - break; - case RDP_CAPSET_ORDER: /* 3 */ - DEBUG(("RDP_CAPSET_ORDER")); - xrdp_process_capset_order(self, s, len); - break; - case RDP_CAPSET_BMPCACHE: /* 4 */ - DEBUG(("RDP_CAPSET_BMPCACHE")); - xrdp_process_capset_bmpcache(self, s, len); - break; - case RDP_CAPSET_CONTROL: /* 5 */ - DEBUG(("RDP_CAPSET_CONTROL")); - break; - case 6: - xrdp_process_capset_cache_v3_codec_id(self, s, len); - break; - case RDP_CAPSET_ACTIVATE: /* 7 */ - DEBUG(("RDP_CAPSET_ACTIVATE")); - break; - case RDP_CAPSET_POINTER: /* 8 */ - DEBUG(("RDP_CAPSET_POINTER")); - xrdp_process_capset_pointercache(self, s, len); - break; - case RDP_CAPSET_SHARE: /* 9 */ - DEBUG(("RDP_CAPSET_SHARE")); - break; - case RDP_CAPSET_COLCACHE: /* 10 */ - DEBUG(("RDP_CAPSET_COLCACHE")); - break; - case 12: /* 12 */ - DEBUG(("--12")); - break; - case 13: /* 13 */ - DEBUG(("--13")); - break; - case 14: /* 14 */ - DEBUG(("--14")); - break; - case RDP_CAPSET_BRUSHCACHE: /* 15 */ - xrdp_process_capset_brushcache(self, s, len); - break; - case 16: /* 16 */ - DEBUG(("--16")); - break; - case 17: /* 17 */ - DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE")); - xrdp_process_offscreen_bmpcache(self, s, len); - break; - case RDP_CAPSET_BMPCACHE2: /* 19 */ - DEBUG(("RDP_CAPSET_BMPCACHE2")); - xrdp_process_capset_bmpcache2(self, s, len); - break; - case 20: /* 20 */ - DEBUG(("--20")); - break; - case 21: /* 21 */ - DEBUG(("--21")); - break; - case 22: /* 22 */ - DEBUG(("--22")); - break; - case 0x0017: /* 23 CAPSETTYPE_RAIL */ - xrdp_process_capset_rail(self, s, len); - break; - case 0x0018: /* 24 CAPSETTYPE_WINDOW */ - xrdp_process_capset_window(self, s, len); - break; - case 26: /* 26 */ - DEBUG(("--26")); - break; - case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */ - xrdp_process_capset_codecs(self, s, len); - break; - default: - g_writeln("unknown in xrdp_rdp_process_confirm_active %d", type); - break; + p = s->p; + in_uint16_le(s, type); + in_uint16_le(s, len); + + switch (type) + { + case RDP_CAPSET_GENERAL: /* 1 */ + DEBUG(("RDP_CAPSET_GENERAL")); + xrdp_process_capset_general(self, s, len); + break; + case RDP_CAPSET_BITMAP: /* 2 */ + DEBUG(("RDP_CAPSET_BITMAP")); + break; + case RDP_CAPSET_ORDER: /* 3 */ + DEBUG(("RDP_CAPSET_ORDER")); + xrdp_process_capset_order(self, s, len); + break; + case RDP_CAPSET_BMPCACHE: /* 4 */ + DEBUG(("RDP_CAPSET_BMPCACHE")); + xrdp_process_capset_bmpcache(self, s, len); + break; + case RDP_CAPSET_CONTROL: /* 5 */ + DEBUG(("RDP_CAPSET_CONTROL")); + break; + case 6: + xrdp_process_capset_cache_v3_codec_id(self, s, len); + break; + case RDP_CAPSET_ACTIVATE: /* 7 */ + DEBUG(("RDP_CAPSET_ACTIVATE")); + break; + case RDP_CAPSET_POINTER: /* 8 */ + DEBUG(("RDP_CAPSET_POINTER")); + xrdp_process_capset_pointercache(self, s, len); + break; + case RDP_CAPSET_SHARE: /* 9 */ + DEBUG(("RDP_CAPSET_SHARE")); + break; + case RDP_CAPSET_COLCACHE: /* 10 */ + DEBUG(("RDP_CAPSET_COLCACHE")); + break; + case 12: /* 12 */ + DEBUG(("--12")); + break; + case 13: /* 13 */ + DEBUG(("--13")); + break; + case 14: /* 14 */ + DEBUG(("--14")); + break; + case RDP_CAPSET_BRUSHCACHE: /* 15 */ + xrdp_process_capset_brushcache(self, s, len); + break; + case 16: /* 16 */ + DEBUG(("--16")); + break; + case 17: /* 17 */ + DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE")); + xrdp_process_offscreen_bmpcache(self, s, len); + break; + case RDP_CAPSET_BMPCACHE2: /* 19 */ + DEBUG(("RDP_CAPSET_BMPCACHE2")); + xrdp_process_capset_bmpcache2(self, s, len); + break; + case 20: /* 20 */ + DEBUG(("--20")); + break; + case 21: /* 21 */ + DEBUG(("--21")); + break; + case 22: /* 22 */ + DEBUG(("--22")); + break; + case 0x0017: /* 23 CAPSETTYPE_RAIL */ + xrdp_process_capset_rail(self, s, len); + break; + case 0x0018: /* 24 CAPSETTYPE_WINDOW */ + xrdp_process_capset_window(self, s, len); + break; + case 26: /* 26 */ + DEBUG(("--26")); + break; + case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */ + xrdp_process_capset_codecs(self, s, len); + break; + default: + g_writeln("unknown in xrdp_rdp_process_confirm_active %d", type); + break; + } + + s->p = p + len; } - s->p = p + len; - } - DEBUG(("out xrdp_rdp_process_confirm_active")); - return 0; + + DEBUG(("out xrdp_rdp_process_confirm_active")); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_process_data_pointer(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_data_pointer(struct xrdp_rdp *self, struct stream *s) { - return 0; + return 0; } /*****************************************************************************/ /* RDP_DATA_PDU_INPUT */ static int APP_CC -xrdp_rdp_process_data_input(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s) { - int num_events; - int index; - int msg_type; - int device_flags; - int param1; - int param2; - int time; + int num_events; + int index; + int msg_type; + int device_flags; + int param1; + int param2; + int time; - in_uint16_le(s, num_events); - in_uint8s(s, 2); /* pad */ - DEBUG(("in xrdp_rdp_process_data_input %d events", num_events)); - for (index = 0; index < num_events; index++) - { - in_uint32_le(s, time); - in_uint16_le(s, msg_type); - in_uint16_le(s, device_flags); - in_sint16_le(s, param1); - in_sint16_le(s, param2); - DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d \ + in_uint16_le(s, num_events); + in_uint8s(s, 2); /* pad */ + DEBUG(("in xrdp_rdp_process_data_input %d events", num_events)); + + for (index = 0; index < num_events; index++) + { + in_uint32_le(s, time); + in_uint16_le(s, msg_type); + in_uint16_le(s, device_flags); + in_sint16_le(s, param1); + in_sint16_le(s, param2); + DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d \ param2 %d time %d", msg_type, device_flags, param1, param2, time)); + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, msg_type, param1, param2, + device_flags, time); + } + } + + DEBUG(("out xrdp_rdp_process_data_input")); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_rdp_send_synchronise(struct xrdp_rdp *self) +{ + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint16_le(s, 1); + out_uint16_le(s, 1002); + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_SYNCHRONISE) != 0) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_rdp_send_control(struct xrdp_rdp *self, int action) +{ + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint16_le(s, action); + out_uint16_le(s, 0); /* userid */ + out_uint32_le(s, 1002); /* control id */ + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_CONTROL) != 0) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_rdp_process_data_control(struct xrdp_rdp *self, struct stream *s) +{ + int action; + + DEBUG(("xrdp_rdp_process_data_control")); + in_uint16_le(s, action); + in_uint8s(s, 2); /* user id */ + in_uint8s(s, 4); /* control id */ + + if (action == RDP_CTL_REQUEST_CONTROL) + { + DEBUG(("xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL")); + DEBUG(("xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise")); + xrdp_rdp_send_synchronise(self); + DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE")); + xrdp_rdp_send_control(self, RDP_CTL_COOPERATE); + DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL")); + xrdp_rdp_send_control(self, RDP_CTL_GRANT_CONTROL); + } + else + { + DEBUG(("xrdp_rdp_process_data_control unknown action")); + } + + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_rdp_process_data_sync(struct xrdp_rdp *self) +{ + DEBUG(("xrdp_rdp_process_data_sync")); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s) +{ + int op; + int left; + int top; + int right; + int bottom; + int cx; + int cy; + + in_uint32_le(s, op); + in_uint16_le(s, left); + in_uint16_le(s, top); + in_uint16_le(s, right); + in_uint16_le(s, bottom); + cx = (right - left) + 1; + cy = (bottom - top) + 1; + if (self->session->callback != 0) { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, msg_type, param1, param2, - device_flags, time); + self->session->callback(self->session->id, 0x4444, left, top, cx, cy); } - } - DEBUG(("out xrdp_rdp_process_data_input")); - return 0; + + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_send_synchronise(struct xrdp_rdp* self) +xrdp_rdp_send_unknown1(struct xrdp_rdp *self) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8a(s, g_unknown1, 172); + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, 0x28) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { free_stream(s); - return 1; - } - out_uint16_le(s, 1); - out_uint16_le(s, 1002); - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_SYNCHRONISE) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_send_control(struct xrdp_rdp* self, int action) +xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s) { - struct stream* s; + int seq; - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { - free_stream(s); - return 1; - } - out_uint16_le(s, action); - out_uint16_le(s, 0); /* userid */ - out_uint32_le(s, 1002); /* control id */ - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_CONTROL) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} + DEBUG(("in xrdp_rdp_process_data_font")); + in_uint8s(s, 2); /* num of fonts */ + in_uint8s(s, 2); /* unknown */ + in_uint16_le(s, seq); -/*****************************************************************************/ -static int APP_CC -xrdp_rdp_process_data_control(struct xrdp_rdp* self, struct stream* s) -{ - int action; + /* 419 client sends Seq 1, then 2 */ + /* 2600 clients sends only Seq 3 */ + if (seq == 2 || seq == 3) /* after second font message, we are up and */ + { + /* running */ + DEBUG(("sending unknown1")); + xrdp_rdp_send_unknown1(self); + self->session->up_and_running = 1; + DEBUG(("up_and_running set")); + xrdp_rdp_send_data_update_sync(self); + } - DEBUG(("xrdp_rdp_process_data_control")); - in_uint16_le(s, action); - in_uint8s(s, 2); /* user id */ - in_uint8s(s, 4); /* control id */ - if (action == RDP_CTL_REQUEST_CONTROL) - { - DEBUG(("xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL")); - DEBUG(("xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise")); - xrdp_rdp_send_synchronise(self); - DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE")); - xrdp_rdp_send_control(self, RDP_CTL_COOPERATE); - DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL")); - xrdp_rdp_send_control(self, RDP_CTL_GRANT_CONTROL); - } - else - { - DEBUG(("xrdp_rdp_process_data_control unknown action")); - } - return 0; -} - -/*****************************************************************************/ -static int APP_CC -xrdp_rdp_process_data_sync(struct xrdp_rdp* self) -{ - DEBUG(("xrdp_rdp_process_data_sync")); - return 0; -} - -/*****************************************************************************/ -static int APP_CC -xrdp_rdp_process_screen_update(struct xrdp_rdp* self, struct stream* s) -{ - int op; - int left; - int top; - int right; - int bottom; - int cx; - int cy; - - in_uint32_le(s, op); - in_uint16_le(s, left); - in_uint16_le(s, top); - in_uint16_le(s, right); - in_uint16_le(s, bottom); - cx = (right - left) + 1; - cy = (bottom - top) + 1; - if (self->session->callback != 0) - { - self->session->callback(self->session->id, 0x4444, left, top, cx, cy); - } - return 0; -} - -/*****************************************************************************/ -static int APP_CC -xrdp_rdp_send_unknown1(struct xrdp_rdp* self) -{ - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8a(s, g_unknown1, 172); - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, 0x28) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} - -/*****************************************************************************/ -static int APP_CC -xrdp_rdp_process_data_font(struct xrdp_rdp* self, struct stream* s) -{ - int seq; - - DEBUG(("in xrdp_rdp_process_data_font")); - in_uint8s(s, 2); /* num of fonts */ - in_uint8s(s, 2); /* unknown */ - in_uint16_le(s, seq); - /* 419 client sends Seq 1, then 2 */ - /* 2600 clients sends only Seq 3 */ - if (seq == 2 || seq == 3) /* after second font message, we are up and */ - { /* running */ - DEBUG(("sending unknown1")); - xrdp_rdp_send_unknown1(self); - self->session->up_and_running = 1; - DEBUG(("up_and_running set")); - xrdp_rdp_send_data_update_sync(self); - } - DEBUG(("out xrdp_rdp_process_data_font")); - return 0; + DEBUG(("out xrdp_rdp_process_data_font")); + return 0; } /*****************************************************************************/ /* sent 37 pdu */ static int APP_CC -xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp* self) +xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp *self) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, 37) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { free_stream(s); - return 1; - } - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, 37) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } #if 0 /* not used */ /*****************************************************************************/ /* sent RDP_DATA_PDU_DISCONNECT 47 pdu */ static int APP_CC -xrdp_rdp_send_disconnect_reason(struct xrdp_rdp* self, int reason) +xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint32_le(s, reason); + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_DISCONNECT) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { free_stream(s); - return 1; - } - out_uint32_le(s, reason); - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_DISCONNECT) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } #endif /*****************************************************************************/ /* RDP_PDU_DATA */ int APP_CC -xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s) { - int len; - int data_type; - int ctype; - int clen; + int len; + int data_type; + int ctype; + int clen; - in_uint8s(s, 6); - in_uint16_le(s, len); - in_uint8(s, data_type); - in_uint8(s, ctype); - in_uint16_le(s, clen); - DEBUG(("xrdp_rdp_process_data code %d", data_type)); - switch (data_type) - { - case RDP_DATA_PDU_POINTER: /* 27(0x1b) */ - xrdp_rdp_process_data_pointer(self, s); - break; - case RDP_DATA_PDU_INPUT: /* 28(0x1c) */ - xrdp_rdp_process_data_input(self, s); - break; - case RDP_DATA_PDU_CONTROL: /* 20(0x14) */ - xrdp_rdp_process_data_control(self, s); - break; - case RDP_DATA_PDU_SYNCHRONISE: /* 31(0x1f) */ - xrdp_rdp_process_data_sync(self); - break; - case 33: /* 33(0x21) ?? Invalidate an area I think */ - xrdp_rdp_process_screen_update(self, s); - break; - case 35: /* 35(0x23) */ - /* 35 ?? this comes when minimuzing a full screen mstsc.exe 2600 */ - /* I think this is saying the client no longer wants screen */ - /* updates and it will issue a 33 above to catch up */ - /* so minimized apps don't take bandwidth */ - break; - case 36: /* 36(0x24) ?? disconnect query? */ - /* when this message comes, send a 37 back so the client */ - /* is sure the connection is alive and it can ask if user */ - /* really wants to disconnect */ - xrdp_rdp_send_disconnect_query_response(self); /* send a 37 back */ - break; - case RDP_DATA_PDU_FONT2: /* 39(0x27) */ - xrdp_rdp_process_data_font(self, s); - break; - default: - g_writeln("unknown in xrdp_rdp_process_data %d", data_type); - break; - } - return 0; + in_uint8s(s, 6); + in_uint16_le(s, len); + in_uint8(s, data_type); + in_uint8(s, ctype); + in_uint16_le(s, clen); + DEBUG(("xrdp_rdp_process_data code %d", data_type)); + + switch (data_type) + { + case RDP_DATA_PDU_POINTER: /* 27(0x1b) */ + xrdp_rdp_process_data_pointer(self, s); + break; + case RDP_DATA_PDU_INPUT: /* 28(0x1c) */ + xrdp_rdp_process_data_input(self, s); + break; + case RDP_DATA_PDU_CONTROL: /* 20(0x14) */ + xrdp_rdp_process_data_control(self, s); + break; + case RDP_DATA_PDU_SYNCHRONISE: /* 31(0x1f) */ + xrdp_rdp_process_data_sync(self); + break; + case 33: /* 33(0x21) ?? Invalidate an area I think */ + xrdp_rdp_process_screen_update(self, s); + break; + case 35: /* 35(0x23) */ + /* 35 ?? this comes when minimuzing a full screen mstsc.exe 2600 */ + /* I think this is saying the client no longer wants screen */ + /* updates and it will issue a 33 above to catch up */ + /* so minimized apps don't take bandwidth */ + break; + case 36: /* 36(0x24) ?? disconnect query? */ + /* when this message comes, send a 37 back so the client */ + /* is sure the connection is alive and it can ask if user */ + /* really wants to disconnect */ + xrdp_rdp_send_disconnect_query_response(self); /* send a 37 back */ + break; + case RDP_DATA_PDU_FONT2: /* 39(0x27) */ + xrdp_rdp_process_data_font(self, s); + break; + default: + g_writeln("unknown in xrdp_rdp_process_data %d", data_type); + break; + } + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_disconnect(struct xrdp_rdp* self) +xrdp_rdp_disconnect(struct xrdp_rdp *self) { - int rv; + int rv; - DEBUG(("in xrdp_rdp_disconnect")); - rv = xrdp_sec_disconnect(self->sec_layer); - DEBUG(("out xrdp_rdp_disconnect")); - return rv; + DEBUG(("in xrdp_rdp_disconnect")); + rv = xrdp_sec_disconnect(self->sec_layer); + DEBUG(("out xrdp_rdp_disconnect")); + return rv; } /*****************************************************************************/ int APP_CC -xrdp_rdp_send_deactive(struct xrdp_rdp* self) +xrdp_rdp_send_deactive(struct xrdp_rdp *self) { - struct stream* s; + struct stream *s; + + DEBUG(("in xrdp_rdp_send_deactive")); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init(self, s) != 0) + { + free_stream(s); + DEBUG(("out xrdp_rdp_send_deactive error")); + return 1; + } + + s_mark_end(s); + + if (xrdp_rdp_send(self, s, RDP_PDU_DEACTIVATE) != 0) + { + free_stream(s); + DEBUG(("out xrdp_rdp_send_deactive error")); + return 1; + } - DEBUG(("in xrdp_rdp_send_deactive")); - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init(self, s) != 0) - { free_stream(s); - DEBUG(("out xrdp_rdp_send_deactive error")); - return 1; - } - s_mark_end(s); - if (xrdp_rdp_send(self, s, RDP_PDU_DEACTIVATE) != 0) - { - free_stream(s); - DEBUG(("out xrdp_rdp_send_deactive error")); - return 1; - } - free_stream(s); - DEBUG(("out xrdp_rdp_send_deactive")); - return 0; + DEBUG(("out xrdp_rdp_send_deactive")); + return 0; } diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 381e8435..66b66264 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -1,1008 +1,1111 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - secure layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * secure layer + */ #include "libxrdp.h" /* some compilers need unsigned char to avoid warnings */ static tui8 g_pad_54[40] = -{ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54 }; +{ + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54 +}; /* some compilers need unsigned char to avoid warnings */ static tui8 g_pad_92[48] = -{ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92 }; +{ + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92 +}; /* some compilers need unsigned char to avoid warnings */ static tui8 g_lic1[322] = -{ 0x80, 0x00, 0x3e, 0x01, 0x01, 0x02, 0x3e, 0x01, - 0x7b, 0x3c, 0x31, 0xa6, 0xae, 0xe8, 0x74, 0xf6, - 0xb4, 0xa5, 0x03, 0x90, 0xe7, 0xc2, 0xc7, 0x39, - 0xba, 0x53, 0x1c, 0x30, 0x54, 0x6e, 0x90, 0x05, - 0xd0, 0x05, 0xce, 0x44, 0x18, 0x91, 0x83, 0x81, - 0x00, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, - 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, - 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, - 0x74, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, - 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, - 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x33, 0x00, 0x36, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x03, 0x00, 0xb8, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x5c, 0x00, 0x52, 0x53, 0x41, 0x31, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, - 0x01, 0xc7, 0xc9, 0xf7, 0x8e, 0x5a, 0x38, 0xe4, - 0x29, 0xc3, 0x00, 0x95, 0x2d, 0xdd, 0x4c, 0x3e, - 0x50, 0x45, 0x0b, 0x0d, 0x9e, 0x2a, 0x5d, 0x18, - 0x63, 0x64, 0xc4, 0x2c, 0xf7, 0x8f, 0x29, 0xd5, - 0x3f, 0xc5, 0x35, 0x22, 0x34, 0xff, 0xad, 0x3a, - 0xe6, 0xe3, 0x95, 0x06, 0xae, 0x55, 0x82, 0xe3, - 0xc8, 0xc7, 0xb4, 0xa8, 0x47, 0xc8, 0x50, 0x71, - 0x74, 0x29, 0x53, 0x89, 0x6d, 0x9c, 0xed, 0x70, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x48, 0x00, 0xa8, 0xf4, 0x31, 0xb9, - 0xab, 0x4b, 0xe6, 0xb4, 0xf4, 0x39, 0x89, 0xd6, - 0xb1, 0xda, 0xf6, 0x1e, 0xec, 0xb1, 0xf0, 0x54, - 0x3b, 0x5e, 0x3e, 0x6a, 0x71, 0xb4, 0xf7, 0x75, - 0xc8, 0x16, 0x2f, 0x24, 0x00, 0xde, 0xe9, 0x82, - 0x99, 0x5f, 0x33, 0x0b, 0xa9, 0xa6, 0x94, 0xaf, - 0xcb, 0x11, 0xc3, 0xf2, 0xdb, 0x09, 0x42, 0x68, - 0x29, 0x56, 0x58, 0x01, 0x56, 0xdb, 0x59, 0x03, - 0x69, 0xdb, 0x7d, 0x37, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x0e, 0x00, 0x6d, 0x69, 0x63, 0x72, - 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x00 }; +{ + 0x80, 0x00, 0x3e, 0x01, 0x01, 0x02, 0x3e, 0x01, + 0x7b, 0x3c, 0x31, 0xa6, 0xae, 0xe8, 0x74, 0xf6, + 0xb4, 0xa5, 0x03, 0x90, 0xe7, 0xc2, 0xc7, 0x39, + 0xba, 0x53, 0x1c, 0x30, 0x54, 0x6e, 0x90, 0x05, + 0xd0, 0x05, 0xce, 0x44, 0x18, 0x91, 0x83, 0x81, + 0x00, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, + 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, + 0x74, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, + 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, + 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x33, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0xb8, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x5c, 0x00, 0x52, 0x53, 0x41, 0x31, + 0x48, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0xc7, 0xc9, 0xf7, 0x8e, 0x5a, 0x38, 0xe4, + 0x29, 0xc3, 0x00, 0x95, 0x2d, 0xdd, 0x4c, 0x3e, + 0x50, 0x45, 0x0b, 0x0d, 0x9e, 0x2a, 0x5d, 0x18, + 0x63, 0x64, 0xc4, 0x2c, 0xf7, 0x8f, 0x29, 0xd5, + 0x3f, 0xc5, 0x35, 0x22, 0x34, 0xff, 0xad, 0x3a, + 0xe6, 0xe3, 0x95, 0x06, 0xae, 0x55, 0x82, 0xe3, + 0xc8, 0xc7, 0xb4, 0xa8, 0x47, 0xc8, 0x50, 0x71, + 0x74, 0x29, 0x53, 0x89, 0x6d, 0x9c, 0xed, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x48, 0x00, 0xa8, 0xf4, 0x31, 0xb9, + 0xab, 0x4b, 0xe6, 0xb4, 0xf4, 0x39, 0x89, 0xd6, + 0xb1, 0xda, 0xf6, 0x1e, 0xec, 0xb1, 0xf0, 0x54, + 0x3b, 0x5e, 0x3e, 0x6a, 0x71, 0xb4, 0xf7, 0x75, + 0xc8, 0x16, 0x2f, 0x24, 0x00, 0xde, 0xe9, 0x82, + 0x99, 0x5f, 0x33, 0x0b, 0xa9, 0xa6, 0x94, 0xaf, + 0xcb, 0x11, 0xc3, 0xf2, 0xdb, 0x09, 0x42, 0x68, + 0x29, 0x56, 0x58, 0x01, 0x56, 0xdb, 0x59, 0x03, + 0x69, 0xdb, 0x7d, 0x37, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x0e, 0x00, 0x6d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x00 +}; /* some compilers need unsigned char to avoid warnings */ static tui8 g_lic2[20] = -{ 0x80, 0x00, 0x10, 0x00, 0xff, 0x02, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x28, 0x14, 0x00, 0x00 }; +{ + 0x80, 0x00, 0x10, 0x00, 0xff, 0x02, 0x10, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x28, 0x14, 0x00, 0x00 +}; /* mce */ /* some compilers need unsigned char to avoid warnings */ static tui8 g_lic3[20] = -{ 0x80, 0x02, 0x10, 0x00, 0xff, 0x03, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0xf3, 0x99, 0x00, 0x00 }; +{ + 0x80, 0x02, 0x10, 0x00, 0xff, 0x03, 0x10, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xf3, 0x99, 0x00, 0x00 +}; /*****************************************************************************/ static void APP_CC -hex_str_to_bin(char* in, char* out, int out_len) +hex_str_to_bin(char *in, char *out, int out_len) { - int in_index; - int in_len; - int out_index; - int val; - char hex[16]; + int in_index; + int in_len; + int out_index; + int val; + char hex[16]; - in_len = g_strlen(in); - out_index = 0; - in_index = 0; - while (in_index <= (in_len - 4)) - { - if ((in[in_index] == '0') && (in[in_index + 1] == 'x')) + in_len = g_strlen(in); + out_index = 0; + in_index = 0; + + while (in_index <= (in_len - 4)) { - hex[0] = in[in_index + 2]; - hex[1] = in[in_index + 3]; - hex[2] = 0; - if (out_index < out_len) - { - val = g_htoi(hex); - out[out_index] = val; - } - out_index++; + if ((in[in_index] == '0') && (in[in_index + 1] == 'x')) + { + hex[0] = in[in_index + 2]; + hex[1] = in[in_index + 3]; + hex[2] = 0; + + if (out_index < out_len) + { + val = g_htoi(hex); + out[out_index] = val; + } + + out_index++; + } + + in_index++; } - in_index++; - } } /*****************************************************************************/ -struct xrdp_sec* APP_CC -xrdp_sec_create(struct xrdp_rdp* owner, struct trans* trans, int crypt_level, +struct xrdp_sec *APP_CC +xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level, int channel_code) { - struct xrdp_sec* self; + struct xrdp_sec *self; - DEBUG((" in xrdp_sec_create")); - self = (struct xrdp_sec*)g_malloc(sizeof(struct xrdp_sec), 1); - self->rdp_layer = owner; - self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */ - self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */ - switch (crypt_level) - { - case 1: - self->rc4_key_size = 1; - self->crypt_level = 1; - break; - case 2: - self->rc4_key_size = 1; - self->crypt_level = 2; - break; - case 3: - self->rc4_key_size = 2; - self->crypt_level = 3; - break; - default: - g_writeln("Fatal : Illegal crypt_level"); - break ; - } - self->channel_code = channel_code; - if(self->decrypt_rc4_info!=NULL) - { - g_writeln("xrdp_sec_create - decrypt_rc4_info already created !!!"); - } - self->decrypt_rc4_info = ssl_rc4_info_create(); - if(self->encrypt_rc4_info!=NULL) - { - g_writeln("xrdp_sec_create - encrypt_rc4_info already created !!!"); - } - self->encrypt_rc4_info = ssl_rc4_info_create(); - self->mcs_layer = xrdp_mcs_create(self, trans, &self->client_mcs_data, - &self->server_mcs_data); - self->chan_layer = xrdp_channel_create(self, self->mcs_layer); - DEBUG((" out xrdp_sec_create")); - return self; + DEBUG((" in xrdp_sec_create")); + self = (struct xrdp_sec *)g_malloc(sizeof(struct xrdp_sec), 1); + self->rdp_layer = owner; + self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */ + self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */ + + switch (crypt_level) + { + case 1: + self->rc4_key_size = 1; + self->crypt_level = 1; + break; + case 2: + self->rc4_key_size = 1; + self->crypt_level = 2; + break; + case 3: + self->rc4_key_size = 2; + self->crypt_level = 3; + break; + default: + g_writeln("Fatal : Illegal crypt_level"); + break ; + } + + self->channel_code = channel_code; + + if (self->decrypt_rc4_info != NULL) + { + g_writeln("xrdp_sec_create - decrypt_rc4_info already created !!!"); + } + + self->decrypt_rc4_info = ssl_rc4_info_create(); + + if (self->encrypt_rc4_info != NULL) + { + g_writeln("xrdp_sec_create - encrypt_rc4_info already created !!!"); + } + + self->encrypt_rc4_info = ssl_rc4_info_create(); + self->mcs_layer = xrdp_mcs_create(self, trans, &self->client_mcs_data, + &self->server_mcs_data); + self->chan_layer = xrdp_channel_create(self, self->mcs_layer); + DEBUG((" out xrdp_sec_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_sec_delete(struct xrdp_sec* self) +xrdp_sec_delete(struct xrdp_sec *self) { - if (self == 0) - { - g_writeln("xrdp_sec_delete: indata is null"); - return; - } - xrdp_channel_delete(self->chan_layer); - xrdp_mcs_delete(self->mcs_layer); - ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */ - ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */ - g_free(self->client_mcs_data.data); - g_free(self->server_mcs_data.data); - /* Crypto information must always be cleared */ - g_memset(self,0,sizeof(struct xrdp_sec)); - g_free(self); + if (self == 0) + { + g_writeln("xrdp_sec_delete: indata is null"); + return; + } + + xrdp_channel_delete(self->chan_layer); + xrdp_mcs_delete(self->mcs_layer); + ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */ + ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */ + g_free(self->client_mcs_data.data); + g_free(self->server_mcs_data.data); + /* Crypto information must always be cleared */ + g_memset(self, 0, sizeof(struct xrdp_sec)); + g_free(self); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_sec_init(struct xrdp_sec* self, struct stream* s) +xrdp_sec_init(struct xrdp_sec *self, struct stream *s) { - if (xrdp_mcs_init(self->mcs_layer, s) != 0) - { - return 1; - } - if (self->crypt_level > 1) - { - s_push_layer(s, sec_hdr, 4 + 8); - } - else - { - s_push_layer(s, sec_hdr, 4); - } - return 0; + if (xrdp_mcs_init(self->mcs_layer, s) != 0) + { + return 1; + } + + if (self->crypt_level > 1) + { + s_push_layer(s, sec_hdr, 4 + 8); + } + else + { + s_push_layer(s, sec_hdr, 4); + } + + return 0; } /*****************************************************************************/ /* Reduce key entropy from 64 to 40 bits */ static void APP_CC -xrdp_sec_make_40bit(char* key) +xrdp_sec_make_40bit(char *key) { - key[0] = 0xd1; - key[1] = 0x26; - key[2] = 0x9e; + key[0] = 0xd1; + key[1] = 0x26; + key[2] = 0x9e; } /*****************************************************************************/ /* returns error */ /* update an encryption key */ static int APP_CC -xrdp_sec_update(char* key, char* update_key, int key_len) +xrdp_sec_update(char *key, char *update_key, int key_len) { - char shasig[20]; - void* sha1_info; - void* md5_info; - void* rc4_info; + char shasig[20]; + void *sha1_info; + void *md5_info; + void *rc4_info; - sha1_info = ssl_sha1_info_create(); - md5_info = ssl_md5_info_create(); - rc4_info = ssl_rc4_info_create(); - ssl_sha1_clear(sha1_info); - ssl_sha1_transform(sha1_info, update_key, key_len); - ssl_sha1_transform(sha1_info, (char*)g_pad_54, 40); - ssl_sha1_transform(sha1_info, key, key_len); - ssl_sha1_complete(sha1_info, shasig); - ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, update_key, key_len); - ssl_md5_transform(md5_info, (char*)g_pad_92, 48); - ssl_md5_transform(md5_info, shasig, 20); - ssl_md5_complete(md5_info, key); - ssl_rc4_set_key(rc4_info, key, key_len); - ssl_rc4_crypt(rc4_info, key, key_len); - if (key_len == 8) - { - xrdp_sec_make_40bit(key); - } - ssl_sha1_info_delete(sha1_info); - ssl_md5_info_delete(md5_info); - ssl_rc4_info_delete(rc4_info); - return 0; -} - -/*****************************************************************************/ -static void APP_CC -xrdp_sec_decrypt(struct xrdp_sec* self, char* data, int len) -{ - if (self->decrypt_use_count == 4096) - { - xrdp_sec_update(self->decrypt_key, self->decrypt_update_key, - self->rc4_key_len); - ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, - self->rc4_key_len); - self->decrypt_use_count = 0; - } - ssl_rc4_crypt(self->decrypt_rc4_info, data, len); - self->decrypt_use_count++; -} - -/*****************************************************************************/ -static void APP_CC -xrdp_sec_encrypt(struct xrdp_sec* self, char* data, int len) -{ - if (self->encrypt_use_count == 4096) - { - xrdp_sec_update(self->encrypt_key, self->encrypt_update_key, - self->rc4_key_len); - ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, - self->rc4_key_len); - self->encrypt_use_count = 0; - } - ssl_rc4_crypt(self->encrypt_rc4_info, data, len); - self->encrypt_use_count++; -} - -/*****************************************************************************/ -static int APP_CC -unicode_in(struct stream* s, int uni_len, char* dst, int dst_len) -{ - int dst_index; - int src_index; - - dst_index = 0; - src_index = 0; - while (src_index < uni_len) - { - if (dst_index >= dst_len || src_index > 512) - { - break; - } - in_uint8(s, dst[dst_index]); - in_uint8s(s, 1); - dst_index++; - src_index += 2; - } - in_uint8s(s, 2); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -xrdp_sec_process_logon_info(struct xrdp_sec* self, struct stream* s) -{ - int flags = 0; - int len_domain = 0; - int len_user = 0; - int len_password = 0; - int len_program = 0; - int len_directory = 0; - int len_ip = 0; - int len_dll = 0; - int tzone = 0; - char tmpdata[256]; - - /* initialize (zero out) local variables */ - g_memset(tmpdata,0,sizeof(char)*256); - in_uint8s(s, 4); - in_uint32_le(s, flags); - DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags)); - /* this is the first test that the decrypt is working */ - if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */ - { /* must be or error */ - DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error")); - return 1; - } - if (flags & RDP_LOGON_LEAVE_AUDIO) - { - self->rdp_layer->client_info.sound_code = 1; - DEBUG(("flag RDP_LOGON_LEAVE_AUDIO found")); - } - if ((flags & RDP_LOGON_AUTO) && (!self->rdp_layer->client_info.is_mce)) - /* todo, for now not allowing autologon and mce both */ - { - self->rdp_layer->client_info.rdp_autologin = 1; - DEBUG(("flag RDP_LOGON_AUTO found")); - } - if (flags & RDP_COMPRESSION) - { - self->rdp_layer->client_info.rdp_compression = 1; - DEBUG(("flag RDP_COMPRESSION found")); - } - in_uint16_le(s, len_domain); - if (len_domain > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain > 511")); - return 1; - } - in_uint16_le(s, len_user); - if (len_user > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_user > 511")); - return 1; - } - in_uint16_le(s, len_password); - if (len_password > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_password > 511")); - return 1; - } - in_uint16_le(s, len_program); - if (len_program > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_program > 511")); - return 1; - } - in_uint16_le(s, len_directory); - if (len_directory > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_directory > 511")); - return 1; - } - unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255); - DEBUG(("domain %s", self->rdp_layer->client_info.domain)); - unicode_in(s, len_user, self->rdp_layer->client_info.username, 255); - DEBUG(("username %s", self->rdp_layer->client_info.username)); - if (flags & RDP_LOGON_AUTO) - { - unicode_in(s, len_password, self->rdp_layer->client_info.password, 255); - DEBUG(("flag RDP_LOGON_AUTO found")); - } - else - { - in_uint8s(s, len_password + 2); - } - unicode_in(s, len_program, self->rdp_layer->client_info.program, 255); - DEBUG(("program %s", self->rdp_layer->client_info.program)); - unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255); - DEBUG(("directory %s", self->rdp_layer->client_info.directory)); - if (flags & RDP_LOGON_BLOB) - { - in_uint8s(s, 2); /* unknown */ - in_uint16_le(s, len_ip); - unicode_in(s, len_ip - 2, tmpdata, 255); - in_uint16_le(s, len_dll); - unicode_in(s, len_dll - 2, tmpdata, 255); - in_uint32_le(s, tzone); /* len of timetone */ - in_uint8s(s, 62); /* skip */ - in_uint8s(s, 22); /* skip misc. */ - in_uint8s(s, 62); /* skip */ - in_uint8s(s, 26); /* skip stuff */ - in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags); - } - DEBUG(("out xrdp_sec_process_logon_info")); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -xrdp_sec_send_lic_initial(struct xrdp_sec* self) -{ - struct stream* s = (struct stream *)NULL; - - make_stream(s); - init_stream(s, 8192); - if (xrdp_mcs_init(self->mcs_layer, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8a(s, g_lic1, 322); - s_mark_end(s); - if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -xrdp_sec_send_lic_response(struct xrdp_sec* self) -{ - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (xrdp_mcs_init(self->mcs_layer, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8a(s, g_lic2, 20); - s_mark_end(s); - if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -xrdp_sec_send_media_lic_response(struct xrdp_sec* self) -{ - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (xrdp_mcs_init(self->mcs_layer, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8a(s, g_lic3, sizeof(g_lic3)); - s_mark_end(s); - if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} - -/*****************************************************************************/ -static void APP_CC -xrdp_sec_rsa_op(char* out, char* in, char* mod, char* exp) -{ - ssl_mod_exp(out, 64, in, 64, mod, 64, exp, 64); -} - -/*****************************************************************************/ -static void APP_CC -xrdp_sec_hash_48(char* out, char* in, char* salt1, char* salt2, int salt) -{ - int i; - void* sha1_info; - void* md5_info; - char pad[4]; - char sha1_sig[20]; - char md5_sig[16]; - - sha1_info = ssl_sha1_info_create(); - md5_info = ssl_md5_info_create(); - for (i = 0; i < 3; i++) - { - g_memset(pad, salt + i, 4); + sha1_info = ssl_sha1_info_create(); + md5_info = ssl_md5_info_create(); + rc4_info = ssl_rc4_info_create(); ssl_sha1_clear(sha1_info); - ssl_sha1_transform(sha1_info, pad, i + 1); - ssl_sha1_transform(sha1_info, in, 48); - ssl_sha1_transform(sha1_info, salt1, 32); - ssl_sha1_transform(sha1_info, salt2, 32); - ssl_sha1_complete(sha1_info, sha1_sig); + ssl_sha1_transform(sha1_info, update_key, key_len); + ssl_sha1_transform(sha1_info, (char *)g_pad_54, 40); + ssl_sha1_transform(sha1_info, key, key_len); + ssl_sha1_complete(sha1_info, shasig); ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, in, 48); - ssl_md5_transform(md5_info, sha1_sig, 20); - ssl_md5_complete(md5_info, md5_sig); - g_memcpy(out + i * 16, md5_sig, 16); - } - ssl_sha1_info_delete(sha1_info); - ssl_md5_info_delete(md5_info); + ssl_md5_transform(md5_info, update_key, key_len); + ssl_md5_transform(md5_info, (char *)g_pad_92, 48); + ssl_md5_transform(md5_info, shasig, 20); + ssl_md5_complete(md5_info, key); + ssl_rc4_set_key(rc4_info, key, key_len); + ssl_rc4_crypt(rc4_info, key, key_len); + + if (key_len == 8) + { + xrdp_sec_make_40bit(key); + } + + ssl_sha1_info_delete(sha1_info); + ssl_md5_info_delete(md5_info); + ssl_rc4_info_delete(rc4_info); + return 0; } /*****************************************************************************/ static void APP_CC -xrdp_sec_hash_16(char* out, char* in, char* salt1, char* salt2) +xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len) { - void* md5_info; + if (self->decrypt_use_count == 4096) + { + xrdp_sec_update(self->decrypt_key, self->decrypt_update_key, + self->rc4_key_len); + ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, + self->rc4_key_len); + self->decrypt_use_count = 0; + } - md5_info = ssl_md5_info_create(); - ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, in, 16); - ssl_md5_transform(md5_info, salt1, 32); - ssl_md5_transform(md5_info, salt2, 32); - ssl_md5_complete(md5_info, out); - ssl_md5_info_delete(md5_info); + ssl_rc4_crypt(self->decrypt_rc4_info, data, len); + self->decrypt_use_count++; } /*****************************************************************************/ static void APP_CC -xrdp_sec_establish_keys(struct xrdp_sec* self) +xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len) { - char session_key[48]; - char temp_hash[48]; - char input[48]; + if (self->encrypt_use_count == 4096) + { + xrdp_sec_update(self->encrypt_key, self->encrypt_update_key, + self->rc4_key_len); + ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, + self->rc4_key_len); + self->encrypt_use_count = 0; + } - g_memcpy(input, self->client_random, 24); - g_memcpy(input + 24, self->server_random, 24); - xrdp_sec_hash_48(temp_hash, input, self->client_random, - self->server_random, 65); - xrdp_sec_hash_48(session_key, temp_hash, self->client_random, - self->server_random, 88); - g_memcpy(self->sign_key, session_key, 16); - xrdp_sec_hash_16(self->encrypt_key, session_key + 16, self->client_random, - self->server_random); - xrdp_sec_hash_16(self->decrypt_key, session_key + 32, self->client_random, - self->server_random); - if (self->rc4_key_size == 1) - { - xrdp_sec_make_40bit(self->sign_key); - xrdp_sec_make_40bit(self->encrypt_key); - xrdp_sec_make_40bit(self->decrypt_key); - self->rc4_key_len = 8; - } - else - { - self->rc4_key_len = 16; - } - g_memcpy(self->decrypt_update_key, self->decrypt_key, 16); - g_memcpy(self->encrypt_update_key, self->encrypt_key, 16); - ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, self->rc4_key_len); - ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, self->rc4_key_len); + ssl_rc4_crypt(self->encrypt_rc4_info, data, len); + self->encrypt_use_count++; +} + +/*****************************************************************************/ +static int APP_CC +unicode_in(struct stream *s, int uni_len, char *dst, int dst_len) +{ + int dst_index; + int src_index; + + dst_index = 0; + src_index = 0; + + while (src_index < uni_len) + { + if (dst_index >= dst_len || src_index > 512) + { + break; + } + + in_uint8(s, dst[dst_index]); + in_uint8s(s, 1); + dst_index++; + src_index += 2; + } + + in_uint8s(s, 2); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s) +{ + int flags = 0; + int len_domain = 0; + int len_user = 0; + int len_password = 0; + int len_program = 0; + int len_directory = 0; + int len_ip = 0; + int len_dll = 0; + int tzone = 0; + char tmpdata[256]; + + /* initialize (zero out) local variables */ + g_memset(tmpdata, 0, sizeof(char) * 256); + in_uint8s(s, 4); + in_uint32_le(s, flags); + DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags)); + + /* this is the first test that the decrypt is working */ + if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */ + { + /* must be or error */ + DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error")); + return 1; + } + + if (flags & RDP_LOGON_LEAVE_AUDIO) + { + self->rdp_layer->client_info.sound_code = 1; + DEBUG(("flag RDP_LOGON_LEAVE_AUDIO found")); + } + + if ((flags & RDP_LOGON_AUTO) && (!self->rdp_layer->client_info.is_mce)) + /* todo, for now not allowing autologon and mce both */ + { + self->rdp_layer->client_info.rdp_autologin = 1; + DEBUG(("flag RDP_LOGON_AUTO found")); + } + + if (flags & RDP_COMPRESSION) + { + self->rdp_layer->client_info.rdp_compression = 1; + DEBUG(("flag RDP_COMPRESSION found")); + } + + in_uint16_le(s, len_domain); + + if (len_domain > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain > 511")); + return 1; + } + + in_uint16_le(s, len_user); + + if (len_user > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_user > 511")); + return 1; + } + + in_uint16_le(s, len_password); + + if (len_password > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_password > 511")); + return 1; + } + + in_uint16_le(s, len_program); + + if (len_program > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_program > 511")); + return 1; + } + + in_uint16_le(s, len_directory); + + if (len_directory > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_directory > 511")); + return 1; + } + + unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255); + DEBUG(("domain %s", self->rdp_layer->client_info.domain)); + unicode_in(s, len_user, self->rdp_layer->client_info.username, 255); + DEBUG(("username %s", self->rdp_layer->client_info.username)); + + if (flags & RDP_LOGON_AUTO) + { + unicode_in(s, len_password, self->rdp_layer->client_info.password, 255); + DEBUG(("flag RDP_LOGON_AUTO found")); + } + else + { + in_uint8s(s, len_password + 2); + } + + unicode_in(s, len_program, self->rdp_layer->client_info.program, 255); + DEBUG(("program %s", self->rdp_layer->client_info.program)); + unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255); + DEBUG(("directory %s", self->rdp_layer->client_info.directory)); + + if (flags & RDP_LOGON_BLOB) + { + in_uint8s(s, 2); /* unknown */ + in_uint16_le(s, len_ip); + unicode_in(s, len_ip - 2, tmpdata, 255); + in_uint16_le(s, len_dll); + unicode_in(s, len_dll - 2, tmpdata, 255); + in_uint32_le(s, tzone); /* len of timetone */ + in_uint8s(s, 62); /* skip */ + in_uint8s(s, 22); /* skip misc. */ + in_uint8s(s, 62); /* skip */ + in_uint8s(s, 26); /* skip stuff */ + in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags); + } + + DEBUG(("out xrdp_sec_process_logon_info")); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_sec_send_lic_initial(struct xrdp_sec *self) +{ + struct stream *s = (struct stream *)NULL; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_mcs_init(self->mcs_layer, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8a(s, g_lic1, 322); + s_mark_end(s); + + if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_sec_send_lic_response(struct xrdp_sec *self) +{ + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_mcs_init(self->mcs_layer, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8a(s, g_lic2, 20); + s_mark_end(s); + + if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_sec_send_media_lic_response(struct xrdp_sec *self) +{ + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_mcs_init(self->mcs_layer, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8a(s, g_lic3, sizeof(g_lic3)); + s_mark_end(s); + + if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +static void APP_CC +xrdp_sec_rsa_op(char *out, char *in, char *mod, char *exp) +{ + ssl_mod_exp(out, 64, in, 64, mod, 64, exp, 64); +} + +/*****************************************************************************/ +static void APP_CC +xrdp_sec_hash_48(char *out, char *in, char *salt1, char *salt2, int salt) +{ + int i; + void *sha1_info; + void *md5_info; + char pad[4]; + char sha1_sig[20]; + char md5_sig[16]; + + sha1_info = ssl_sha1_info_create(); + md5_info = ssl_md5_info_create(); + + for (i = 0; i < 3; i++) + { + g_memset(pad, salt + i, 4); + ssl_sha1_clear(sha1_info); + ssl_sha1_transform(sha1_info, pad, i + 1); + ssl_sha1_transform(sha1_info, in, 48); + ssl_sha1_transform(sha1_info, salt1, 32); + ssl_sha1_transform(sha1_info, salt2, 32); + ssl_sha1_complete(sha1_info, sha1_sig); + ssl_md5_clear(md5_info); + ssl_md5_transform(md5_info, in, 48); + ssl_md5_transform(md5_info, sha1_sig, 20); + ssl_md5_complete(md5_info, md5_sig); + g_memcpy(out + i * 16, md5_sig, 16); + } + + ssl_sha1_info_delete(sha1_info); + ssl_md5_info_delete(md5_info); +} + +/*****************************************************************************/ +static void APP_CC +xrdp_sec_hash_16(char *out, char *in, char *salt1, char *salt2) +{ + void *md5_info; + + md5_info = ssl_md5_info_create(); + ssl_md5_clear(md5_info); + ssl_md5_transform(md5_info, in, 16); + ssl_md5_transform(md5_info, salt1, 32); + ssl_md5_transform(md5_info, salt2, 32); + ssl_md5_complete(md5_info, out); + ssl_md5_info_delete(md5_info); +} + +/*****************************************************************************/ +static void APP_CC +xrdp_sec_establish_keys(struct xrdp_sec *self) +{ + char session_key[48]; + char temp_hash[48]; + char input[48]; + + g_memcpy(input, self->client_random, 24); + g_memcpy(input + 24, self->server_random, 24); + xrdp_sec_hash_48(temp_hash, input, self->client_random, + self->server_random, 65); + xrdp_sec_hash_48(session_key, temp_hash, self->client_random, + self->server_random, 88); + g_memcpy(self->sign_key, session_key, 16); + xrdp_sec_hash_16(self->encrypt_key, session_key + 16, self->client_random, + self->server_random); + xrdp_sec_hash_16(self->decrypt_key, session_key + 32, self->client_random, + self->server_random); + + if (self->rc4_key_size == 1) + { + xrdp_sec_make_40bit(self->sign_key); + xrdp_sec_make_40bit(self->encrypt_key); + xrdp_sec_make_40bit(self->decrypt_key); + self->rc4_key_len = 8; + } + else + { + self->rc4_key_len = 16; + } + + g_memcpy(self->decrypt_update_key, self->decrypt_key, 16); + g_memcpy(self->encrypt_update_key, self->encrypt_key, 16); + ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, self->rc4_key_len); + ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, self->rc4_key_len); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_sec_recv(struct xrdp_sec* self, struct stream* s, int* chan) +xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan) { - int flags; - int len; + int flags; + int len; - DEBUG((" in xrdp_sec_recv")); - if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0) - { - DEBUG((" out xrdp_sec_recv error")); - return 1; - } - in_uint32_le(s, flags); - DEBUG((" in xrdp_sec_recv flags $%x", flags)); - if (flags & SEC_ENCRYPT) /* 0x08 */ - { - in_uint8s(s, 8); /* signature */ - xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p)); - } - if (flags & SEC_CLIENT_RANDOM) /* 0x01 */ - { - in_uint32_le(s, len); - in_uint8a(s, self->client_crypt_random, 64); - xrdp_sec_rsa_op(self->client_random, self->client_crypt_random, - self->pub_mod, self->pri_exp); - xrdp_sec_establish_keys(self); - *chan = 1; /* just set a non existing channel and exit */ - DEBUG((" out xrdp_sec_recv")); - return 0; - } - if (flags & SEC_LOGON_INFO) /* 0x40 */ - { - if (xrdp_sec_process_logon_info(self, s) != 0) + DEBUG((" in xrdp_sec_recv")); + + if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0) { - DEBUG((" out xrdp_sec_recv error")); - return 1; - } - if (self->rdp_layer->client_info.is_mce) - { - if (xrdp_sec_send_media_lic_response(self) != 0) - { DEBUG((" out xrdp_sec_recv error")); return 1; - } - DEBUG((" out xrdp_sec_recv")); - return -1; /* special error that means send demand active */ } - if (xrdp_sec_send_lic_initial(self) != 0) + + in_uint32_le(s, flags); + DEBUG((" in xrdp_sec_recv flags $%x", flags)); + + if (flags & SEC_ENCRYPT) /* 0x08 */ { - DEBUG((" out xrdp_sec_recv error")); - return 1; + in_uint8s(s, 8); /* signature */ + xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p)); } - *chan = 1; /* just set a non existing channel and exit */ + + if (flags & SEC_CLIENT_RANDOM) /* 0x01 */ + { + in_uint32_le(s, len); + in_uint8a(s, self->client_crypt_random, 64); + xrdp_sec_rsa_op(self->client_random, self->client_crypt_random, + self->pub_mod, self->pri_exp); + xrdp_sec_establish_keys(self); + *chan = 1; /* just set a non existing channel and exit */ + DEBUG((" out xrdp_sec_recv")); + return 0; + } + + if (flags & SEC_LOGON_INFO) /* 0x40 */ + { + if (xrdp_sec_process_logon_info(self, s) != 0) + { + DEBUG((" out xrdp_sec_recv error")); + return 1; + } + + if (self->rdp_layer->client_info.is_mce) + { + if (xrdp_sec_send_media_lic_response(self) != 0) + { + DEBUG((" out xrdp_sec_recv error")); + return 1; + } + + DEBUG((" out xrdp_sec_recv")); + return -1; /* special error that means send demand active */ + } + + if (xrdp_sec_send_lic_initial(self) != 0) + { + DEBUG((" out xrdp_sec_recv error")); + return 1; + } + + *chan = 1; /* just set a non existing channel and exit */ + DEBUG((" out xrdp_sec_recv")); + return 0; + } + + if (flags & SEC_LICENCE_NEG) /* 0x80 */ + { + if (xrdp_sec_send_lic_response(self) != 0) + { + DEBUG((" out xrdp_sec_recv error")); + return 1; + } + + DEBUG((" out xrdp_sec_recv")); + return -1; /* special error that means send demand active */ + } + DEBUG((" out xrdp_sec_recv")); return 0; - } - if (flags & SEC_LICENCE_NEG) /* 0x80 */ - { - if (xrdp_sec_send_lic_response(self) != 0) - { - DEBUG((" out xrdp_sec_recv error")); - return 1; - } - DEBUG((" out xrdp_sec_recv")); - return -1; /* special error that means send demand active */ - } - DEBUG((" out xrdp_sec_recv")); - return 0; } /*****************************************************************************/ /* Output a uint32 into a buffer (little-endian) */ static void -buf_out_uint32(char* buffer, int value) +buf_out_uint32(char *buffer, int value) { - buffer[0] = (value) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[3] = (value >> 24) & 0xff; + buffer[0] = (value) & 0xff; + buffer[1] = (value >> 8) & 0xff; + buffer[2] = (value >> 16) & 0xff; + buffer[3] = (value >> 24) & 0xff; } /*****************************************************************************/ /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */ static void APP_CC -xrdp_sec_sign(struct xrdp_sec* self, char* out, int out_len, - char* data, int data_len) +xrdp_sec_sign(struct xrdp_sec *self, char *out, int out_len, + char *data, int data_len) { - char shasig[20]; - char md5sig[16]; - char lenhdr[4]; - void* sha1_info; - void* md5_info; + char shasig[20]; + char md5sig[16]; + char lenhdr[4]; + void *sha1_info; + void *md5_info; - buf_out_uint32(lenhdr, data_len); - sha1_info = ssl_sha1_info_create(); - md5_info = ssl_md5_info_create(); - ssl_sha1_clear(sha1_info); - ssl_sha1_transform(sha1_info, self->sign_key, self->rc4_key_len); - ssl_sha1_transform(sha1_info, (char*)g_pad_54, 40); - ssl_sha1_transform(sha1_info, lenhdr, 4); - ssl_sha1_transform(sha1_info, data, data_len); - ssl_sha1_complete(sha1_info, shasig); - ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, self->sign_key, self->rc4_key_len); - ssl_md5_transform(md5_info, (char*)g_pad_92, 48); - ssl_md5_transform(md5_info, shasig, 20); - ssl_md5_complete(md5_info, md5sig); - g_memcpy(out, md5sig, out_len); - ssl_sha1_info_delete(sha1_info); - ssl_md5_info_delete(md5_info); + buf_out_uint32(lenhdr, data_len); + sha1_info = ssl_sha1_info_create(); + md5_info = ssl_md5_info_create(); + ssl_sha1_clear(sha1_info); + ssl_sha1_transform(sha1_info, self->sign_key, self->rc4_key_len); + ssl_sha1_transform(sha1_info, (char *)g_pad_54, 40); + ssl_sha1_transform(sha1_info, lenhdr, 4); + ssl_sha1_transform(sha1_info, data, data_len); + ssl_sha1_complete(sha1_info, shasig); + ssl_md5_clear(md5_info); + ssl_md5_transform(md5_info, self->sign_key, self->rc4_key_len); + ssl_md5_transform(md5_info, (char *)g_pad_92, 48); + ssl_md5_transform(md5_info, shasig, 20); + ssl_md5_complete(md5_info, md5sig); + g_memcpy(out, md5sig, out_len); + ssl_sha1_info_delete(sha1_info); + ssl_md5_info_delete(md5_info); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_sec_send(struct xrdp_sec* self, struct stream* s, int chan) +xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan) { - int datalen; + int datalen; - DEBUG((" in xrdp_sec_send")); - s_pop_layer(s, sec_hdr); - if (self->crypt_level > 1) - { - out_uint32_le(s, SEC_ENCRYPT); - datalen = (int)((s->end - s->p) - 8); - xrdp_sec_sign(self, s->p, 8, s->p + 8, datalen); - xrdp_sec_encrypt(self, s->p + 8, datalen); - } - else - { - out_uint32_le(s, 0); - } - if (xrdp_mcs_send(self->mcs_layer, s, chan) != 0) - { - return 1; - } - DEBUG((" out xrdp_sec_send")); - return 0; + DEBUG((" in xrdp_sec_send")); + s_pop_layer(s, sec_hdr); + + if (self->crypt_level > 1) + { + out_uint32_le(s, SEC_ENCRYPT); + datalen = (int)((s->end - s->p) - 8); + xrdp_sec_sign(self, s->p, 8, s->p + 8, datalen); + xrdp_sec_encrypt(self, s->p + 8, datalen); + } + else + { + out_uint32_le(s, 0); + } + + if (xrdp_mcs_send(self->mcs_layer, s, chan) != 0) + { + return 1; + } + + DEBUG((" out xrdp_sec_send")); + return 0; } /*****************************************************************************/ /* this adds the mcs channels in the list of channels to be used when creating the server mcs data */ static int APP_CC -xrdp_sec_process_mcs_data_channels(struct xrdp_sec* self, struct stream* s) +xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s) { - int num_channels; - int index; - struct mcs_channel_item* channel_item; + int num_channels; + int index; + struct mcs_channel_item *channel_item; + + DEBUG(("processing channels, channel_code is %d", self->channel_code)); + + /* this is an option set in xrdp.ini */ + if (self->channel_code != 1) /* are channels on? */ + { + g_writeln("Processing channel data from client - The channel is off"); + return 0; + } + + in_uint32_le(s, num_channels); + + for (index = 0; index < num_channels; index++) + { + channel_item = (struct mcs_channel_item *) + g_malloc(sizeof(struct mcs_channel_item), 1); + in_uint8a(s, channel_item->name, 8); + in_uint32_le(s, channel_item->flags); + channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1); + list_add_item(self->mcs_layer->channel_list, (long)channel_item); + DEBUG(("got channel flags %8.8x name %s", channel_item->flags, + channel_item->name)); + } - DEBUG(("processing channels, channel_code is %d", self->channel_code)); - /* this is an option set in xrdp.ini */ - if (self->channel_code != 1) /* are channels on? */ - { - g_writeln("Processing channel data from client - The channel is off"); return 0; - } - in_uint32_le(s, num_channels); - for (index = 0; index < num_channels; index++) - { - channel_item = (struct mcs_channel_item*) - g_malloc(sizeof(struct mcs_channel_item), 1); - in_uint8a(s, channel_item->name, 8); - in_uint32_le(s, channel_item->flags); - channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1); - list_add_item(self->mcs_layer->channel_list, (long)channel_item); - DEBUG(("got channel flags %8.8x name %s", channel_item->flags, - channel_item->name)); - } - return 0; } /*****************************************************************************/ /* process client mcs data, we need some things in here to create the server mcs data */ int APP_CC -xrdp_sec_process_mcs_data(struct xrdp_sec* self) +xrdp_sec_process_mcs_data(struct xrdp_sec *self) { - struct stream* s = (struct stream *)NULL; - char* hold_p = (char *)NULL; - int tag = 0; - int size = 0; + struct stream *s = (struct stream *)NULL; + char *hold_p = (char *)NULL; + int tag = 0; + int size = 0; - s = &self->client_mcs_data; - /* set p to beginning */ - s->p = s->data; - /* skip header */ - in_uint8s(s, 23); - while (s_check_rem(s, 4)) - { - hold_p = s->p; - in_uint16_le(s, tag); - in_uint16_le(s, size); - if (size < 4 || !s_check_rem(s, size - 4)) + s = &self->client_mcs_data; + /* set p to beginning */ + s->p = s->data; + /* skip header */ + in_uint8s(s, 23); + + while (s_check_rem(s, 4)) { - g_writeln("error in xrdp_sec_process_mcs_data tag %d size %d", - tag, size); - break; + hold_p = s->p; + in_uint16_le(s, tag); + in_uint16_le(s, size); + + if (size < 4 || !s_check_rem(s, size - 4)) + { + g_writeln("error in xrdp_sec_process_mcs_data tag %d size %d", + tag, size); + break; + } + + switch (tag) + { + case SEC_TAG_CLI_INFO: + break; + case SEC_TAG_CLI_CRYPT: + break; + case SEC_TAG_CLI_CHANNELS: + xrdp_sec_process_mcs_data_channels(self, s); + break; + case SEC_TAG_CLI_4: + break; + default: + g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d", + tag, size); + break; + } + + s->p = hold_p + size; } - switch (tag) - { - case SEC_TAG_CLI_INFO: - break; - case SEC_TAG_CLI_CRYPT: - break; - case SEC_TAG_CLI_CHANNELS: - xrdp_sec_process_mcs_data_channels(self, s); - break; - case SEC_TAG_CLI_4: - break; - default: - g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d", - tag, size); - break; - } - s->p = hold_p + size; - } - /* set p to beginning */ - s->p = s->data; - return 0; + + /* set p to beginning */ + s->p = s->data; + return 0; } /*****************************************************************************/ /* prepare server mcs data to send in mcs layer */ int APP_CC -xrdp_sec_out_mcs_data(struct xrdp_sec* self) +xrdp_sec_out_mcs_data(struct xrdp_sec *self) { - struct stream* s; - int num_channels_even; - int num_channels; - int index; - int channel; + struct stream *s; + int num_channels_even; + int num_channels; + int index; + int channel; - num_channels = self->mcs_layer->channel_list->count; - num_channels_even = num_channels + (num_channels & 1); - s = &self->server_mcs_data; - init_stream(s, 512); - out_uint16_be(s, 5); - out_uint16_be(s, 0x14); - out_uint8(s, 0x7c); - out_uint16_be(s, 1); - out_uint8(s, 0x2a); - out_uint8(s, 0x14); - out_uint8(s, 0x76); - out_uint8(s, 0x0a); - out_uint8(s, 1); - out_uint8(s, 1); - out_uint8(s, 0); - out_uint16_le(s, 0xc001); - out_uint8(s, 0); - out_uint8(s, 0x4d); /* M */ - out_uint8(s, 0x63); /* c */ - out_uint8(s, 0x44); /* D */ - out_uint8(s, 0x6e); /* n */ - out_uint16_be(s, 0x80fc + (num_channels_even * 2)); - out_uint16_le(s, SEC_TAG_SRV_INFO); - out_uint16_le(s, 8); /* len */ - out_uint8(s, 4); /* 4 = rdp5 1 = rdp4 */ - out_uint8(s, 0); - out_uint8(s, 8); - out_uint8(s, 0); - out_uint16_le(s, SEC_TAG_SRV_CHANNELS); - out_uint16_le(s, 8 + (num_channels_even * 2)); /* len */ - out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel */ - out_uint16_le(s, num_channels); /* number of other channels */ - for (index = 0; index < num_channels_even; index++) - { - if (index < num_channels) + num_channels = self->mcs_layer->channel_list->count; + num_channels_even = num_channels + (num_channels & 1); + s = &self->server_mcs_data; + init_stream(s, 512); + out_uint16_be(s, 5); + out_uint16_be(s, 0x14); + out_uint8(s, 0x7c); + out_uint16_be(s, 1); + out_uint8(s, 0x2a); + out_uint8(s, 0x14); + out_uint8(s, 0x76); + out_uint8(s, 0x0a); + out_uint8(s, 1); + out_uint8(s, 1); + out_uint8(s, 0); + out_uint16_le(s, 0xc001); + out_uint8(s, 0); + out_uint8(s, 0x4d); /* M */ + out_uint8(s, 0x63); /* c */ + out_uint8(s, 0x44); /* D */ + out_uint8(s, 0x6e); /* n */ + out_uint16_be(s, 0x80fc + (num_channels_even * 2)); + out_uint16_le(s, SEC_TAG_SRV_INFO); + out_uint16_le(s, 8); /* len */ + out_uint8(s, 4); /* 4 = rdp5 1 = rdp4 */ + out_uint8(s, 0); + out_uint8(s, 8); + out_uint8(s, 0); + out_uint16_le(s, SEC_TAG_SRV_CHANNELS); + out_uint16_le(s, 8 + (num_channels_even * 2)); /* len */ + out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel */ + out_uint16_le(s, num_channels); /* number of other channels */ + + for (index = 0; index < num_channels_even; index++) { - channel = MCS_GLOBAL_CHANNEL + (index + 1); - out_uint16_le(s, channel); + if (index < num_channels) + { + channel = MCS_GLOBAL_CHANNEL + (index + 1); + out_uint16_le(s, channel); + } + else + { + out_uint16_le(s, 0); + } } - else - { - out_uint16_le(s, 0); - } - } - out_uint16_le(s, SEC_TAG_SRV_CRYPT); - out_uint16_le(s, 0x00ec); /* len is 236 */ - out_uint32_le(s, self->rc4_key_size); /* key len 1 = 40 bit 2 = 128 bit */ - out_uint32_le(s, self->crypt_level); /* crypt level 1 = low 2 = medium */ - /* 3 = high */ - out_uint32_le(s, 32); /* 32 bytes random len */ - out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */ - out_uint8a(s, self->server_random, 32); - /* here to end is certificate */ - /* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ */ - /* TermService\Parameters\Certificate */ - out_uint32_le(s, 1); - out_uint32_le(s, 1); - out_uint32_le(s, 1); - out_uint16_le(s, SEC_TAG_PUBKEY); - out_uint16_le(s, 0x005c); /* 92 bytes length of SEC_TAG_PUBKEY */ - out_uint32_le(s, SEC_RSA_MAGIC); - out_uint32_le(s, 0x48); /* 72 bytes modulus len */ - out_uint32_be(s, 0x00020000); - out_uint32_be(s, 0x3f000000); - out_uint8a(s, self->pub_exp, 4); /* pub exp */ - out_uint8a(s, self->pub_mod, 64); /* pub mod */ - out_uint8s(s, 8); /* pad */ - out_uint16_le(s, SEC_TAG_KEYSIG); - out_uint16_le(s, 72); /* len */ - out_uint8a(s, self->pub_sig, 64); /* pub sig */ - out_uint8s(s, 8); /* pad */ - /* end certificate */ - s_mark_end(s); - return 0; + + out_uint16_le(s, SEC_TAG_SRV_CRYPT); + out_uint16_le(s, 0x00ec); /* len is 236 */ + out_uint32_le(s, self->rc4_key_size); /* key len 1 = 40 bit 2 = 128 bit */ + out_uint32_le(s, self->crypt_level); /* crypt level 1 = low 2 = medium */ + /* 3 = high */ + out_uint32_le(s, 32); /* 32 bytes random len */ + out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */ + out_uint8a(s, self->server_random, 32); + /* here to end is certificate */ + /* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ */ + /* TermService\Parameters\Certificate */ + out_uint32_le(s, 1); + out_uint32_le(s, 1); + out_uint32_le(s, 1); + out_uint16_le(s, SEC_TAG_PUBKEY); + out_uint16_le(s, 0x005c); /* 92 bytes length of SEC_TAG_PUBKEY */ + out_uint32_le(s, SEC_RSA_MAGIC); + out_uint32_le(s, 0x48); /* 72 bytes modulus len */ + out_uint32_be(s, 0x00020000); + out_uint32_be(s, 0x3f000000); + out_uint8a(s, self->pub_exp, 4); /* pub exp */ + out_uint8a(s, self->pub_mod, 64); /* pub mod */ + out_uint8s(s, 8); /* pad */ + out_uint16_le(s, SEC_TAG_KEYSIG); + out_uint16_le(s, 72); /* len */ + out_uint8a(s, self->pub_sig, 64); /* pub sig */ + out_uint8s(s, 8); /* pad */ + /* end certificate */ + s_mark_end(s); + return 0; } /*****************************************************************************/ /* process the mcs client data we received from the mcs layer */ static void APP_CC -xrdp_sec_in_mcs_data(struct xrdp_sec* self) +xrdp_sec_in_mcs_data(struct xrdp_sec *self) { - struct stream* s = (struct stream *)NULL; - struct xrdp_client_info* client_info = (struct xrdp_client_info *)NULL; - int index = 0; - char c = 0; + struct stream *s = (struct stream *)NULL; + struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL; + int index = 0; + char c = 0; - client_info = &(self->rdp_layer->client_info); - s = &(self->client_mcs_data); - /* get hostname, its unicode */ - s->p = s->data; - in_uint8s(s, 47); - g_memset(client_info->hostname, 0, 32); - c = 1; - index = 0; - while (index < 16 && c != 0) - { - in_uint8(s, c); - in_uint8s(s, 1); - client_info->hostname[index] = c; - index++; - } - /* get build */ - s->p = s->data; - in_uint8s(s, 43); - in_uint32_le(s, client_info->build); - /* get keylayout */ - s->p = s->data; - in_uint8s(s, 39); - in_uint32_le(s, client_info->keylayout); - s->p = s->data; + client_info = &(self->rdp_layer->client_info); + s = &(self->client_mcs_data); + /* get hostname, its unicode */ + s->p = s->data; + in_uint8s(s, 47); + g_memset(client_info->hostname, 0, 32); + c = 1; + index = 0; + + while (index < 16 && c != 0) + { + in_uint8(s, c); + in_uint8s(s, 1); + client_info->hostname[index] = c; + index++; + } + + /* get build */ + s->p = s->data; + in_uint8s(s, 43); + in_uint32_le(s, client_info->build); + /* get keylayout */ + s->p = s->data; + in_uint8s(s, 39); + in_uint32_le(s, client_info->keylayout); + s->p = s->data; } /*****************************************************************************/ int APP_CC -xrdp_sec_incoming(struct xrdp_sec* self) +xrdp_sec_incoming(struct xrdp_sec *self) { - struct list* items = NULL; - struct list* values = NULL; - int index = 0; - char* item = NULL; - char* value = NULL; - char key_file[256]; + struct list *items = NULL; + struct list *values = NULL; + int index = 0; + char *item = NULL; + char *value = NULL; + char key_file[256]; - g_memset(key_file,0,sizeof(char)*256); + g_memset(key_file, 0, sizeof(char) * 256); + + DEBUG((" in xrdp_sec_incoming")); + g_random(self->server_random, 32); + items = list_create(); + items->auto_free = 1; + values = list_create(); + values->auto_free = 1; + g_snprintf(key_file, 255, "%s/rsakeys.ini", XRDP_CFG_PATH); + + if (file_by_name_read_section(key_file, "keys", items, values) != 0) + { + /* this is a show stopper */ + g_writeln("xrdp_sec_incoming: error reading %s file", key_file); + list_delete(items); + list_delete(values); + return 1; + } + + for (index = 0; index < items->count; index++) + { + item = (char *)list_get_item(items, index); + value = (char *)list_get_item(values, index); + + if (g_strcasecmp(item, "pub_exp") == 0) + { + hex_str_to_bin(value, self->pub_exp, 4); + } + else if (g_strcasecmp(item, "pub_mod") == 0) + { + hex_str_to_bin(value, self->pub_mod, 64); + } + else if (g_strcasecmp(item, "pub_sig") == 0) + { + hex_str_to_bin(value, self->pub_sig, 64); + } + else if (g_strcasecmp(item, "pri_exp") == 0) + { + hex_str_to_bin(value, self->pri_exp, 64); + } + } - DEBUG((" in xrdp_sec_incoming")); - g_random(self->server_random, 32); - items = list_create(); - items->auto_free = 1; - values = list_create(); - values->auto_free = 1; - g_snprintf(key_file, 255, "%s/rsakeys.ini", XRDP_CFG_PATH); - if (file_by_name_read_section(key_file, "keys", items, values) != 0) - { - /* this is a show stopper */ - g_writeln("xrdp_sec_incoming: error reading %s file", key_file); list_delete(items); list_delete(values); - return 1; - } - for (index = 0; index < items->count; index++) - { - item = (char*)list_get_item(items, index); - value = (char*)list_get_item(values, index); - if (g_strcasecmp(item, "pub_exp") == 0) + + if (xrdp_mcs_incoming(self->mcs_layer) != 0) { - hex_str_to_bin(value, self->pub_exp, 4); + return 1; } - else if (g_strcasecmp(item, "pub_mod") == 0) - { - hex_str_to_bin(value, self->pub_mod, 64); - } - else if (g_strcasecmp(item, "pub_sig") == 0) - { - hex_str_to_bin(value, self->pub_sig, 64); - } - else if (g_strcasecmp(item, "pri_exp") == 0) - { - hex_str_to_bin(value, self->pri_exp, 64); - } - } - list_delete(items); - list_delete(values); - if (xrdp_mcs_incoming(self->mcs_layer) != 0) - { - return 1; - } + #ifdef XRDP_DEBUG - g_writeln("client mcs data received"); - g_hexdump(self->client_mcs_data.data, - (int)(self->client_mcs_data.end - self->client_mcs_data.data)); - g_writeln("server mcs data sent"); - g_hexdump(self->server_mcs_data.data, - (int)(self->server_mcs_data.end - self->server_mcs_data.data)); + g_writeln("client mcs data received"); + g_hexdump(self->client_mcs_data.data, + (int)(self->client_mcs_data.end - self->client_mcs_data.data)); + g_writeln("server mcs data sent"); + g_hexdump(self->server_mcs_data.data, + (int)(self->server_mcs_data.end - self->server_mcs_data.data)); #endif - DEBUG((" out xrdp_sec_incoming")); - xrdp_sec_in_mcs_data(self); - return 0; + DEBUG((" out xrdp_sec_incoming")); + xrdp_sec_in_mcs_data(self); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_sec_disconnect(struct xrdp_sec* self) +xrdp_sec_disconnect(struct xrdp_sec *self) { - int rv; + int rv; - DEBUG((" in xrdp_sec_disconnect")); - rv = xrdp_mcs_disconnect(self->mcs_layer); - DEBUG((" out xrdp_sec_disconnect")); - return rv; + DEBUG((" in xrdp_sec_disconnect")); + rv = xrdp_mcs_disconnect(self->mcs_layer); + DEBUG((" out xrdp_sec_disconnect")); + return rv; } diff --git a/libxrdp/xrdp_surface.c b/libxrdp/xrdp_surface.c index efc640ee..34ab9f48 100644 --- a/libxrdp/xrdp_surface.c +++ b/libxrdp/xrdp_surface.c @@ -21,141 +21,144 @@ #include "freerdp/codec/rfx.h" /*****************************************************************************/ -struct xrdp_surface* APP_CC -xrdp_surface_create(struct xrdp_session* session, struct xrdp_fastpath* fastpath) +struct xrdp_surface *APP_CC +xrdp_surface_create(struct xrdp_session *session, struct xrdp_fastpath *fastpath) { - struct xrdp_surface* self; + struct xrdp_surface *self; - self = (struct xrdp_surface*)g_malloc(sizeof(struct xrdp_surface), 1); - self->session = session; - self->fastpath = fastpath; - self->rfx_context = rfx_context_new(); - self->s = stream_new(16384); - return self; + self = (struct xrdp_surface *)g_malloc(sizeof(struct xrdp_surface), 1); + self->session = session; + self->fastpath = fastpath; + self->rfx_context = rfx_context_new(); + self->s = stream_new(16384); + return self; } /*****************************************************************************/ void APP_CC -xrdp_surface_delete(struct xrdp_surface* self) +xrdp_surface_delete(struct xrdp_surface *self) { - STREAM* s; - RFX_CONTEXT* rfx_context; + STREAM *s; + RFX_CONTEXT *rfx_context; - if (self == 0) - { - return; - } - s = (STREAM*)(self->s); - rfx_context = (RFX_CONTEXT*)(self->rfx_context); - free_stream(self->out_s); - stream_free(s); - rfx_context_free(rfx_context); - g_free(self); + if (self == 0) + { + return; + } + + s = (STREAM *)(self->s); + rfx_context = (RFX_CONTEXT *)(self->rfx_context); + free_stream(self->out_s); + stream_free(s); + rfx_context_free(rfx_context); + g_free(self); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_surface_reset(struct xrdp_surface* self) +xrdp_surface_reset(struct xrdp_surface *self) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -xrdp_surface_init(struct xrdp_surface* self) +xrdp_surface_init(struct xrdp_surface *self) { - int width; - int height; - RFX_CONTEXT* rfx_context; + int width; + int height; + RFX_CONTEXT *rfx_context; - rfx_context = (RFX_CONTEXT*)(self->rfx_context); - width = self->session->client_info->width; - height= self->session->client_info->height; + rfx_context = (RFX_CONTEXT *)(self->rfx_context); + width = self->session->client_info->width; + height = self->session->client_info->height; - rfx_context->mode = self->session->client_info->rfx_entropy; - rfx_context->width = width; - rfx_context->height= height; + rfx_context->mode = self->session->client_info->rfx_entropy; + rfx_context->width = width; + rfx_context->height = height; - make_stream(self->out_s); - init_stream(self->out_s, 2 * 3 * width * height + 22); + make_stream(self->out_s); + init_stream(self->out_s, 2 * 3 * width * height + 22); - return 0; + return 0; } /*****************************************************************************/ int APP_CC -xrdp_surface_send_surface_bits(struct xrdp_surface* self,int bpp, char* data, +xrdp_surface_send_surface_bits(struct xrdp_surface *self, int bpp, char *data, int x, int y, int cx, int cy) { - RFX_RECT rect; - char* buf; - int Bpp; - int i; - int j; - int codecId; - uint32 bitmapDataLength; - STREAM* s; - RFX_CONTEXT* rfx_context; + RFX_RECT rect; + char *buf; + int Bpp; + int i; + int j; + int codecId; + uint32 bitmapDataLength; + STREAM *s; + RFX_CONTEXT *rfx_context; - s = (STREAM*)(self->s); - rfx_context = (RFX_CONTEXT*)(self->rfx_context); - if ((bpp == 24) || (bpp == 32)) - { - } - else - { - g_writeln("bpp = %d is not supported\n", bpp); - return 1; - } - Bpp = 4; + s = (STREAM *)(self->s); + rfx_context = (RFX_CONTEXT *)(self->rfx_context); - rect.x = 0; - rect.y = 0; - rect.width = cx; - rect.height = cy; + if ((bpp == 24) || (bpp == 32)) + { + } + else + { + g_writeln("bpp = %d is not supported\n", bpp); + return 1; + } - init_stream(self->out_s, 0); + Bpp = 4; - stream_set_pos(s, 0); - rfx_compose_message(rfx_context, s, &rect, 1, data, cx, cy, Bpp * cx); + rect.x = 0; + rect.y = 0; + rect.width = cx; + rect.height = cy; - codecId = self->session->client_info->rfx_codecId; - /* surface_bits_command */ - out_uint16_le(self->out_s, CMDTYPE_STREAM_SURFACE_BITS); /* cmdType */ - out_uint16_le(self->out_s, x); /* destLeft */ - out_uint16_le(self->out_s, y); /* destTop */ - out_uint16_le(self->out_s, x + cx); /* destRight */ - out_uint16_le(self->out_s, y + cy); /* destBottom */ - out_uint8(self->out_s, 32); /* bpp */ - out_uint8(self->out_s, 0); /* reserved1 */ - out_uint8(self->out_s, 0); /* reserved2 */ - out_uint8(self->out_s, codecId); /* codecId */ - out_uint16_le(self->out_s, cx); /* width */ - out_uint16_le(self->out_s, cy); /* height */ - bitmapDataLength = stream_get_length(s); - out_uint32_le(self->out_s, bitmapDataLength); /* bitmapDataLength */ + init_stream(self->out_s, 0); - /* rfx bit stream */ - out_uint8p(self->out_s, s->data, bitmapDataLength); + stream_set_pos(s, 0); + rfx_compose_message(rfx_context, s, &rect, 1, data, cx, cy, Bpp * cx); - s_mark_end(self->out_s); - return xrdp_fastpath_send_update_pdu(self->fastpath, - FASTPATH_UPDATETYPE_SURFCMDS, - self->out_s); + codecId = self->session->client_info->rfx_codecId; + /* surface_bits_command */ + out_uint16_le(self->out_s, CMDTYPE_STREAM_SURFACE_BITS); /* cmdType */ + out_uint16_le(self->out_s, x); /* destLeft */ + out_uint16_le(self->out_s, y); /* destTop */ + out_uint16_le(self->out_s, x + cx); /* destRight */ + out_uint16_le(self->out_s, y + cy); /* destBottom */ + out_uint8(self->out_s, 32); /* bpp */ + out_uint8(self->out_s, 0); /* reserved1 */ + out_uint8(self->out_s, 0); /* reserved2 */ + out_uint8(self->out_s, codecId); /* codecId */ + out_uint16_le(self->out_s, cx); /* width */ + out_uint16_le(self->out_s, cy); /* height */ + bitmapDataLength = stream_get_length(s); + out_uint32_le(self->out_s, bitmapDataLength); /* bitmapDataLength */ + + /* rfx bit stream */ + out_uint8p(self->out_s, s->data, bitmapDataLength); + + s_mark_end(self->out_s); + return xrdp_fastpath_send_update_pdu(self->fastpath, + FASTPATH_UPDATETYPE_SURFCMDS, + self->out_s); } /*****************************************************************************/ int APP_CC -xrdp_surface_send_frame_marker(struct xrdp_surface* self, +xrdp_surface_send_frame_marker(struct xrdp_surface *self, uint16 frameAction, uint32 frameId) { - init_stream(self->out_s, 0); - out_uint16_le(self->out_s, CMDTYPE_FRAME_MARKER); - out_uint16_le(self->out_s, frameAction); - out_uint32_le(self->out_s, frameId); - s_mark_end(self->out_s); - return xrdp_fastpath_send_update_pdu(self->fastpath, - FASTPATH_UPDATETYPE_SURFCMDS, - self->out_s); + init_stream(self->out_s, 0); + out_uint16_le(self->out_s, CMDTYPE_FRAME_MARKER); + out_uint16_le(self->out_s, frameAction); + out_uint32_le(self->out_s, frameId); + s_mark_end(self->out_s); + return xrdp_fastpath_send_update_pdu(self->fastpath, + FASTPATH_UPDATETYPE_SURFCMDS, + self->out_s); } diff --git a/libxrdp/xrdp_tcp.c b/libxrdp/xrdp_tcp.c index e4755ad6..807797a1 100644 --- a/libxrdp/xrdp_tcp.c +++ b/libxrdp/xrdp_tcp.c @@ -1,87 +1,89 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - tcp layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004 - 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * tcp layer + */ #include "libxrdp.h" /*****************************************************************************/ -struct xrdp_tcp* APP_CC -xrdp_tcp_create(struct xrdp_iso* owner, struct trans* trans) +struct xrdp_tcp *APP_CC +xrdp_tcp_create(struct xrdp_iso *owner, struct trans *trans) { - struct xrdp_tcp* self; + struct xrdp_tcp *self; - DEBUG((" in xrdp_tcp_create")); - self = (struct xrdp_tcp*)g_malloc(sizeof(struct xrdp_tcp), 1); - self->iso_layer = owner; - self->trans = trans; - DEBUG((" out xrdp_tcp_create")); - return self; + DEBUG((" in xrdp_tcp_create")); + self = (struct xrdp_tcp *)g_malloc(sizeof(struct xrdp_tcp), 1); + self->iso_layer = owner; + self->trans = trans; + DEBUG((" out xrdp_tcp_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_tcp_delete(struct xrdp_tcp* self) +xrdp_tcp_delete(struct xrdp_tcp *self) { - g_free(self); + g_free(self); } /*****************************************************************************/ /* get out stream ready for data */ /* returns error */ int APP_CC -xrdp_tcp_init(struct xrdp_tcp* self, struct stream* s) +xrdp_tcp_init(struct xrdp_tcp *self, struct stream *s) { - init_stream(s, 8192); - return 0; + init_stream(s, 8192); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_tcp_recv(struct xrdp_tcp* self, struct stream* s, int len) +xrdp_tcp_recv(struct xrdp_tcp *self, struct stream *s, int len) { - DEBUG((" in xrdp_tcp_recv, gota get %d bytes", len)); - init_stream(s, len); - if (trans_force_read_s(self->trans, s, len) != 0) - { - DEBUG((" error in trans_force_read_s")); - return 1; - } - DEBUG((" out xrdp_tcp_recv")); - return 0; + DEBUG((" in xrdp_tcp_recv, gota get %d bytes", len)); + init_stream(s, len); + + if (trans_force_read_s(self->trans, s, len) != 0) + { + DEBUG((" error in trans_force_read_s")); + return 1; + } + + DEBUG((" out xrdp_tcp_recv")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_tcp_send(struct xrdp_tcp* self, struct stream* s) +xrdp_tcp_send(struct xrdp_tcp *self, struct stream *s) { - int len; - len = s->end - s->data; - DEBUG((" in xrdp_tcp_send, gota send %d bytes", len)); - if (trans_force_write_s(self->trans, s) != 0) - { - DEBUG((" error in trans_force_write_s")); - return 1; - } - DEBUG((" out xrdp_tcp_send, sent %d bytes ok", len)); - return 0; + int len; + len = s->end - s->data; + DEBUG((" in xrdp_tcp_send, gota send %d bytes", len)); + + if (trans_force_write_s(self->trans, s) != 0) + { + DEBUG((" error in trans_force_write_s")); + return 1; + } + + DEBUG((" out xrdp_tcp_send, sent %d bytes ok", len)); + return 0; } diff --git a/mc/mc.c b/mc/mc.c index 21c797d3..b585915c 100644 --- a/mc/mc.c +++ b/mc/mc.c @@ -1,114 +1,113 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2007-2010 - - media center - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * media center + */ #include "mc.h" /*****************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_start(struct mod* mod, int w, int h, int bpp) +lib_mod_start(struct mod *mod, int w, int h, int bpp) { - LIB_DEBUG(mod, "in lib_mod_start"); - mod->width = w; - mod->height = h; - mod->bpp = bpp; - LIB_DEBUG(mod, "out lib_mod_start"); - return 0; + LIB_DEBUG(mod, "in lib_mod_start"); + mod->width = w; + mod->height = h; + mod->bpp = bpp; + LIB_DEBUG(mod, "out lib_mod_start"); + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_connect(struct mod* mod) +lib_mod_connect(struct mod *mod) { - LIB_DEBUG(mod, "in lib_mod_connect"); - LIB_DEBUG(mod, "out lib_mod_connect"); - return 0; + LIB_DEBUG(mod, "in lib_mod_connect"); + LIB_DEBUG(mod, "out lib_mod_connect"); + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_event(struct mod* mod, int msg, long param1, long param2, +lib_mod_event(struct mod *mod, int msg, long param1, long param2, long param3, long param4) { - LIB_DEBUG(mod, "in lib_mod_event"); - LIB_DEBUG(mod, "out lib_mod_event"); - return 0; + LIB_DEBUG(mod, "in lib_mod_event"); + LIB_DEBUG(mod, "out lib_mod_event"); + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_signal(struct mod* mod) +lib_mod_signal(struct mod *mod) { - LIB_DEBUG(mod, "in lib_mod_signal"); - LIB_DEBUG(mod, "out lib_mod_signal"); - return 0; + LIB_DEBUG(mod, "in lib_mod_signal"); + LIB_DEBUG(mod, "out lib_mod_signal"); + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_end(struct mod* mod) +lib_mod_end(struct mod *mod) { - return 0; + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_set_param(struct mod* mod, char* name, char* value) +lib_mod_set_param(struct mod *mod, char *name, char *value) { - return 0; + return 0; } /******************************************************************************/ -struct mod* EXPORT_CC +struct mod *EXPORT_CC mod_init(void) { - struct mod* mod; + struct mod *mod; - mod = (struct mod*)g_malloc(sizeof(struct mod), 1); - mod->size = sizeof(struct mod); - mod->version = CURRENT_MOD_VER; - mod->handle = (long)mod; - mod->mod_connect = lib_mod_connect; - mod->mod_start = lib_mod_start; - mod->mod_event = lib_mod_event; - mod->mod_signal = lib_mod_signal; - mod->mod_end = lib_mod_end; - mod->mod_set_param = lib_mod_set_param; - return mod; + mod = (struct mod *)g_malloc(sizeof(struct mod), 1); + mod->size = sizeof(struct mod); + mod->version = CURRENT_MOD_VER; + mod->handle = (long)mod; + mod->mod_connect = lib_mod_connect; + mod->mod_start = lib_mod_start; + mod->mod_event = lib_mod_event; + mod->mod_signal = lib_mod_signal; + mod->mod_end = lib_mod_end; + mod->mod_set_param = lib_mod_set_param; + return mod; } /******************************************************************************/ int EXPORT_CC -mod_exit(struct mod* mod) +mod_exit(struct mod *mod) { - if (mod == 0) - { + if (mod == 0) + { + return 0; + } + + g_free(mod); return 0; - } - g_free(mod); - return 0; } diff --git a/mc/mc.h b/mc/mc.h index b1802727..1246326d 100644 --- a/mc/mc.h +++ b/mc/mc.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2007-2010 - - media center - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * media center + */ /* include other h files */ #include "arch.h" diff --git a/rdp/rdp.c b/rdp/rdp.c index 78d7cd93..f10b2760 100644 --- a/rdp/rdp.c +++ b/rdp/rdp.c @@ -1,333 +1,352 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - librdp main file - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * librdp main file + */ #include "rdp.h" /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_start(struct mod* mod, int w, int h, int bpp) +lib_mod_start(struct mod *mod, int w, int h, int bpp) { - DEBUG(("in lib_mod_start")); - mod->width = w; - mod->height = h; - mod->rdp_bpp = bpp; - mod->xrdp_bpp = bpp; - mod->keylayout = 0x409; - g_strncpy(mod->port, "3389", 255); /* default */ - DEBUG(("out lib_mod_start")); - return 0; -} - -/******************************************************************************/ -/* return error */ -int DEFAULT_CC -lib_mod_connect(struct mod* mod) -{ - DEBUG(("in lib_mod_connect")); - /* clear screen */ - mod->server_begin_update(mod); - mod->server_set_fgcolor(mod, 0); - mod->server_fill_rect(mod, 0, 0, mod->width, mod->height); - mod->server_end_update(mod); - /* connect */ - if (rdp_rdp_connect(mod->rdp_layer, mod->ip, mod->port) == 0) - { - mod->sck = mod->rdp_layer->sec_layer->mcs_layer->iso_layer->tcp_layer->sck; - g_tcp_set_non_blocking(mod->sck); - g_tcp_set_no_delay(mod->sck); - mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0); - DEBUG(("out lib_mod_connect")); + DEBUG(("in lib_mod_start")); + mod->width = w; + mod->height = h; + mod->rdp_bpp = bpp; + mod->xrdp_bpp = bpp; + mod->keylayout = 0x409; + g_strncpy(mod->port, "3389", 255); /* default */ + DEBUG(("out lib_mod_start")); return 0; - } - DEBUG(("out lib_mod_connect error")); - return 1; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_event(struct mod* mod, int msg, long param1, long param2, +lib_mod_connect(struct mod *mod) +{ + DEBUG(("in lib_mod_connect")); + /* clear screen */ + mod->server_begin_update(mod); + mod->server_set_fgcolor(mod, 0); + mod->server_fill_rect(mod, 0, 0, mod->width, mod->height); + mod->server_end_update(mod); + + /* connect */ + if (rdp_rdp_connect(mod->rdp_layer, mod->ip, mod->port) == 0) + { + mod->sck = mod->rdp_layer->sec_layer->mcs_layer->iso_layer->tcp_layer->sck; + g_tcp_set_non_blocking(mod->sck); + g_tcp_set_no_delay(mod->sck); + mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0); + DEBUG(("out lib_mod_connect")); + return 0; + } + + DEBUG(("out lib_mod_connect error")); + return 1; +} + +/******************************************************************************/ +/* return error */ +int DEFAULT_CC +lib_mod_event(struct mod *mod, int msg, long param1, long param2, long param3, long param4) { - struct stream* s; + struct stream *s; - if (!mod->up_and_running) - { + if (!mod->up_and_running) + { + return 0; + } + + DEBUG(("in lib_mod_event")); + make_stream(s); + init_stream(s, 8192 * 2); + + switch (msg) + { + case 15: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_SCANCODE, + param4, param3, 0); + break; + case 16: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_SCANCODE, + param4, param3, 0); + break; + case 17: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_SYNCHRONIZE, + param4, param3, 0); + break; + case 100: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_MOVE, param1, param2); + break; + case 101: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON1, param1, param2); + break; + case 102: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON1 | MOUSE_FLAG_DOWN, + param1, param2); + break; + case 103: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON2, param1, param2); + break; + case 104: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON2 | MOUSE_FLAG_DOWN, + param1, param2); + break; + case 105: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON3, param1, param2); + break; + case 106: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON3 | MOUSE_FLAG_DOWN, + param1, param2); + break; + case 107: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON4, param1, param2); + break; + case 108: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON4 | MOUSE_FLAG_DOWN, + param1, param2); + break; + case 109: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON5, param1, param2); + break; + case 110: + rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, + MOUSE_FLAG_BUTTON5 | MOUSE_FLAG_DOWN, + param1, param2); + break; + case 200: + rdp_rdp_send_invalidate(mod->rdp_layer, s, + (param1 >> 16) & 0xffff, param1 & 0xffff, + (param2 >> 16) & 0xffff, param2 & 0xffff); + break; + } + + free_stream(s); + DEBUG(("out lib_mod_event")); return 0; - } - DEBUG(("in lib_mod_event")); - make_stream(s); - init_stream(s, 8192 * 2); - switch (msg) - { - case 15: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_SCANCODE, - param4, param3, 0); - break; - case 16: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_SCANCODE, - param4, param3, 0); - break; - case 17: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_SYNCHRONIZE, - param4, param3, 0); - break; - case 100: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_MOVE, param1, param2); - break; - case 101: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON1, param1, param2); - break; - case 102: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON1 | MOUSE_FLAG_DOWN, - param1, param2); - break; - case 103: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON2, param1, param2); - break; - case 104: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON2 | MOUSE_FLAG_DOWN, - param1, param2); - break; - case 105: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON3, param1, param2); - break; - case 106: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON3 | MOUSE_FLAG_DOWN, - param1, param2); - break; - case 107: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON4, param1, param2); - break; - case 108: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON4 | MOUSE_FLAG_DOWN, - param1, param2); - break; - case 109: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON5, param1, param2); - break; - case 110: - rdp_rdp_send_input(mod->rdp_layer, s, 0, RDP_INPUT_MOUSE, - MOUSE_FLAG_BUTTON5 | MOUSE_FLAG_DOWN, - param1, param2); - break; - case 200: - rdp_rdp_send_invalidate(mod->rdp_layer, s, - (param1 >> 16) & 0xffff, param1 & 0xffff, - (param2 >> 16) & 0xffff, param2 & 0xffff); - break; - } - free_stream(s); - DEBUG(("out lib_mod_event")); - return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_signal(struct mod* mod) +lib_mod_signal(struct mod *mod) { - int type; - int cont; - struct stream* s; + int type; + int cont; + struct stream *s; - DEBUG(("in lib_mod_signal")); - if (mod->in_s == 0) - { - make_stream(mod->in_s); - } - s = mod->in_s; - init_stream(s, 8192 * 2); - cont = 1; - while (cont) - { - type = 0; - if (rdp_rdp_recv(mod->rdp_layer, s, &type) != 0) + DEBUG(("in lib_mod_signal")); + + if (mod->in_s == 0) { - DEBUG(("out lib_mod_signal error rdp_rdp_recv failed")); - return 1; + make_stream(mod->in_s); } - DEBUG(("lib_mod_signal type %d", type)); - switch (type) + + s = mod->in_s; + init_stream(s, 8192 * 2); + cont = 1; + + while (cont) { - case RDP_PDU_DATA: - rdp_rdp_process_data_pdu(mod->rdp_layer, s); - break; - case RDP_PDU_DEMAND_ACTIVE: - rdp_rdp_process_demand_active(mod->rdp_layer, s); - mod->up_and_running = 1; - break; - case RDP_PDU_DEACTIVATE: - mod->up_and_running = 0; - break; - case RDP_PDU_REDIRECT: - break; - case 0: - break; - default: - break; + type = 0; + + if (rdp_rdp_recv(mod->rdp_layer, s, &type) != 0) + { + DEBUG(("out lib_mod_signal error rdp_rdp_recv failed")); + return 1; + } + + DEBUG(("lib_mod_signal type %d", type)); + + switch (type) + { + case RDP_PDU_DATA: + rdp_rdp_process_data_pdu(mod->rdp_layer, s); + break; + case RDP_PDU_DEMAND_ACTIVE: + rdp_rdp_process_demand_active(mod->rdp_layer, s); + mod->up_and_running = 1; + break; + case RDP_PDU_DEACTIVATE: + mod->up_and_running = 0; + break; + case RDP_PDU_REDIRECT: + break; + case 0: + break; + default: + break; + } + + cont = s->next_packet < s->end; } - cont = s->next_packet < s->end; - } - DEBUG(("out lib_mod_signal")); - return 0; + + DEBUG(("out lib_mod_signal")); + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_end(struct mod* mod) +lib_mod_end(struct mod *mod) { - rdp_rdp_delete(mod->rdp_layer); - mod->rdp_layer = 0; - free_stream(mod->in_s); - mod->in_s = 0; - if (mod->sck_obj != 0) - { - g_delete_wait_obj_from_socket(mod->sck_obj); - mod->sck_obj = 0; - } - if (mod->sck != 0) - { - g_tcp_close(mod->sck); - mod->sck = 0; - } - return 0; -} + rdp_rdp_delete(mod->rdp_layer); + mod->rdp_layer = 0; + free_stream(mod->in_s); + mod->in_s = 0; -/******************************************************************************/ -/* return error */ -int DEFAULT_CC -lib_mod_set_param(struct mod* mod, char* name, char* value) -{ - if (g_strncasecmp(name, "ip", 255) == 0) - { - g_strncpy(mod->ip, value, 255); - } - else if (g_strncasecmp(name, "port", 255) == 0) - { - g_strncpy(mod->port, value, 255); - } - else if (g_strncasecmp(name, "username", 255) == 0) - { - g_strncpy(mod->username, value, 255); - } - else if (g_strncasecmp(name, "password", 255) == 0) - { - g_strncpy(mod->password, value, 255); - } - else if (g_strncasecmp(name, "hostname", 255) == 0) - { - g_strncpy(mod->hostname, value, 255); - } - else if (g_strncasecmp(name, "keylayout", 255) == 0) - { - mod->keylayout = g_atoi(value); - } - return 0; -} - -/******************************************************************************/ -/* return error */ -int DEFAULT_CC -lib_mod_get_wait_objs(struct mod* mod, tbus* read_objs, int* rcount, - tbus* write_objs, int* wcount, int* timeout) -{ - int i; - - i = *rcount; - if (mod != 0) - { if (mod->sck_obj != 0) { - read_objs[i++] = mod->sck_obj; + g_delete_wait_obj_from_socket(mod->sck_obj); + mod->sck_obj = 0; } - } - *rcount = i; - return 0; + + if (mod->sck != 0) + { + g_tcp_close(mod->sck); + mod->sck = 0; + } + + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_check_wait_objs(struct mod* mod) +lib_mod_set_param(struct mod *mod, char *name, char *value) { - int rv; - - rv = 0; - if (mod != 0) - { - if (mod->sck_obj != 0) + if (g_strncasecmp(name, "ip", 255) == 0) { - if (g_is_wait_obj_set(mod->sck_obj)) - { - rv = lib_mod_signal(mod); - } + g_strncpy(mod->ip, value, 255); } - } - return rv; + else if (g_strncasecmp(name, "port", 255) == 0) + { + g_strncpy(mod->port, value, 255); + } + else if (g_strncasecmp(name, "username", 255) == 0) + { + g_strncpy(mod->username, value, 255); + } + else if (g_strncasecmp(name, "password", 255) == 0) + { + g_strncpy(mod->password, value, 255); + } + else if (g_strncasecmp(name, "hostname", 255) == 0) + { + g_strncpy(mod->hostname, value, 255); + } + else if (g_strncasecmp(name, "keylayout", 255) == 0) + { + mod->keylayout = g_atoi(value); + } + + return 0; } /******************************************************************************/ -struct mod* EXPORT_CC +/* return error */ +int DEFAULT_CC +lib_mod_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount, + tbus *write_objs, int *wcount, int *timeout) +{ + int i; + + i = *rcount; + + if (mod != 0) + { + if (mod->sck_obj != 0) + { + read_objs[i++] = mod->sck_obj; + } + } + + *rcount = i; + return 0; +} + +/******************************************************************************/ +/* return error */ +int DEFAULT_CC +lib_mod_check_wait_objs(struct mod *mod) +{ + int rv; + + rv = 0; + + if (mod != 0) + { + if (mod->sck_obj != 0) + { + if (g_is_wait_obj_set(mod->sck_obj)) + { + rv = lib_mod_signal(mod); + } + } + } + + return rv; +} + +/******************************************************************************/ +struct mod *EXPORT_CC mod_init(void) { - struct mod* mod; + struct mod *mod; - DEBUG(("in mod_init")); - mod = (struct mod*)g_malloc(sizeof(struct mod), 1); - mod->size = sizeof(struct mod); - mod->version = CURRENT_MOD_VER; - mod->handle = (long)mod; - mod->mod_connect = lib_mod_connect; - mod->mod_start = lib_mod_start; - mod->mod_event = lib_mod_event; - mod->mod_signal = lib_mod_signal; - mod->mod_end = lib_mod_end; - mod->mod_set_param = lib_mod_set_param; - mod->mod_get_wait_objs = lib_mod_get_wait_objs; - mod->mod_check_wait_objs = lib_mod_check_wait_objs; - mod->rdp_layer = rdp_rdp_create(mod); - DEBUG(("out mod_init")); - return mod; + DEBUG(("in mod_init")); + mod = (struct mod *)g_malloc(sizeof(struct mod), 1); + mod->size = sizeof(struct mod); + mod->version = CURRENT_MOD_VER; + mod->handle = (long)mod; + mod->mod_connect = lib_mod_connect; + mod->mod_start = lib_mod_start; + mod->mod_event = lib_mod_event; + mod->mod_signal = lib_mod_signal; + mod->mod_end = lib_mod_end; + mod->mod_set_param = lib_mod_set_param; + mod->mod_get_wait_objs = lib_mod_get_wait_objs; + mod->mod_check_wait_objs = lib_mod_check_wait_objs; + mod->rdp_layer = rdp_rdp_create(mod); + DEBUG(("out mod_init")); + return mod; } /******************************************************************************/ int EXPORT_CC -mod_exit(struct mod* mod) +mod_exit(struct mod *mod) { - DEBUG(("in mod_exit")); - g_free(mod); - DEBUG(("out mod_exit")); - return 0; + DEBUG(("in mod_exit")); + g_free(mod); + DEBUG(("out mod_exit")); + return 0; } diff --git a/rdp/rdp.h b/rdp/rdp.h index 66a72c7f..727d6c3e 100644 --- a/rdp/rdp.h +++ b/rdp/rdp.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - librdp main header file - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * librdp main header file + */ /* include other h files */ #include "arch.h" @@ -269,7 +267,7 @@ struct mod int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount, tbus* write_objs, int* wcount, int* timeout); int (*mod_check_wait_objs)(struct mod* v); - long mod_dumby[100 - 9]; /* align, 100 minus the number of mod + long mod_dumby[100 - 9]; /* align, 100 minus the number of mod functions above */ /* server functions */ int (*server_begin_update)(struct mod* v); diff --git a/rdp/rdp_bitmap.c b/rdp/rdp_bitmap.c index f2d31dae..adba5f6f 100644 --- a/rdp/rdp_bitmap.c +++ b/rdp/rdp_bitmap.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - librdp bitmap routines - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * librdp bitmap routines + */ #include "rdp.h" @@ -35,891 +33,964 @@ /******************************************************************************/ #define REPEAT(statement) \ -{ \ - while ((count > 0) && (x < width)) \ - { \ - statement; \ - count--; \ - x++; \ - } \ -} + { \ + while ((count > 0) && (x < width)) \ + { \ + statement; \ + count--; \ + x++; \ + } \ + } /******************************************************************************/ #define MASK_UPDATE \ -{ \ - mixmask <<= 1; \ - if ((mixmask & 0xff) == 0) \ - { \ - mask = fom_mask ? fom_mask : CVAL(input); \ - mixmask = 1; \ - } \ -} + { \ + mixmask <<= 1; \ + if ((mixmask & 0xff) == 0) \ + { \ + mask = fom_mask ? fom_mask : CVAL(input); \ + mixmask = 1; \ + } \ + } /******************************************************************************/ /* 1 byte bitmap decompress */ /* returns boolean */ static int APP_CC -bitmap_decompress1(char* output, int width, int height, char* input, int size) +bitmap_decompress1(char *output, int width, int height, char *input, int size) { - char* prevline; - char* line; - char* end; - char color1; - char color2; - char mix; - int code; - int mixmask; - int mask; - int opcode; - int count; - int offset; - int isfillormix; - int x; - int lastopcode; - int insertmix; - int bicolor; - int fom_mask; + char *prevline; + char *line; + char *end; + char color1; + char color2; + char mix; + int code; + int mixmask; + int mask; + int opcode; + int count; + int offset; + int isfillormix; + int x; + int lastopcode; + int insertmix; + int bicolor; + int fom_mask; - end = input + size; - prevline = 0; - line = 0; - x = width; - lastopcode = -1; - insertmix = 0; - bicolor = 0; - color1 = 0; - color2 = 0; - mix = 0xff; - mask = 0; - fom_mask = 0; - - while (input < end) - { + end = input + size; + prevline = 0; + line = 0; + x = width; + lastopcode = -1; + insertmix = 0; + bicolor = 0; + color1 = 0; + color2 = 0; + mix = 0xff; + mask = 0; fom_mask = 0; - code = CVAL(input); - opcode = code >> 4; - /* Handle different opcode forms */ - switch (opcode) + + while (input < end) { - case 0xc: - case 0xd: - case 0xe: - opcode -= 6; - count = code & 0xf; - offset = 16; - break; - case 0xf: - opcode = code & 0xf; - if (opcode < 9) + fom_mask = 0; + code = CVAL(input); + opcode = code >> 4; + + /* Handle different opcode forms */ + switch (opcode) { - count = CVAL(input); - count |= CVAL(input) << 8; + case 0xc: + case 0xd: + case 0xe: + opcode -= 6; + count = code & 0xf; + offset = 16; + break; + case 0xf: + opcode = code & 0xf; + + if (opcode < 9) + { + count = CVAL(input); + count |= CVAL(input) << 8; + } + else + { + count = (opcode < 0xb) ? 8 : 1; + } + + offset = 0; + break; + default: + opcode >>= 1; + count = code & 0x1f; + offset = 32; + break; } - else + + /* Handle strange cases for counts */ + if (offset != 0) { - count = (opcode < 0xb) ? 8 : 1; - } - offset = 0; - break; - default: - opcode >>= 1; - count = code & 0x1f; - offset = 32; - break; - } - /* Handle strange cases for counts */ - if (offset != 0) - { - isfillormix = ((opcode == 2) || (opcode == 7)); - if (count == 0) - { - if (isfillormix) - { - count = CVAL(input) + 1; - } - else - { - count = CVAL(input) + offset; - } - } - else if (isfillormix) - { - count <<= 3; - } - } - /* Read preliminary data */ - switch (opcode) - { - case 0: /* Fill */ - if ((lastopcode == opcode) && !((x == width) && (prevline == 0))) - { - insertmix = 1; - } - break; - case 8: /* Bicolor */ - color1 = CVAL(input); - case 3: /* Color */ - color2 = CVAL(input); - break; - case 6: /* SetMix/Mix */ - case 7: /* SetMix/FillOrMix */ - mix = CVAL(input); - opcode -= 5; - break; - case 9: /* FillOrMix_1 */ - mask = 0x03; - opcode = 0x02; - fom_mask = 3; - break; - case 0x0a: /* FillOrMix_2 */ - mask = 0x05; - opcode = 0x02; - fom_mask = 5; - break; - } - lastopcode = opcode; - mixmask = 0; - /* Output body */ - while (count > 0) - { - if (x >= width) - { - if (height <= 0) - { - return 0; - } - x = 0; - height--; - prevline = line; - line = output + height * width; - } - switch (opcode) - { - case 0: /* Fill */ - if (insertmix) - { - if (prevline == 0) + isfillormix = ((opcode == 2) || (opcode == 7)); + + if (count == 0) { - line[x] = mix; + if (isfillormix) + { + count = CVAL(input) + 1; + } + else + { + count = CVAL(input) + offset; + } } - else + else if (isfillormix) { - line[x] = prevline[x] ^ mix; + count <<= 3; } - insertmix = 0; - count--; - x++; - } - if (prevline == 0) - { - REPEAT(line[x] = 0) - } - else - { - REPEAT(line[x] = prevline[x]) - } - break; - case 1: /* Mix */ - if (prevline == 0) - { - REPEAT(line[x] = mix) - } - else - { - REPEAT(line[x] = prevline[x] ^ mix) - } - break; - case 2: /* Fill or Mix */ - if (prevline == 0) - { - REPEAT - ( - MASK_UPDATE; - if (mask & mixmask) - { - line[x] = mix; - } - else - { - line[x] = 0; - } - ) - } - else - { - REPEAT - ( - MASK_UPDATE; - if (mask & mixmask) - { - line[x] = prevline[x] ^ mix; - } - else - { - line[x] = prevline[x]; - } - ) - } - break; - case 3: /* Color */ - REPEAT(line[x] = color2) - break; - case 4: /* Copy */ - REPEAT(line[x] = CVAL(input)) - break; - case 8: /* Bicolor */ - REPEAT - ( - if (bicolor) + } + + /* Read preliminary data */ + switch (opcode) + { + case 0: /* Fill */ + + if ((lastopcode == opcode) && !((x == width) && (prevline == 0))) + { + insertmix = 1; + } + + break; + case 8: /* Bicolor */ + color1 = CVAL(input); + case 3: /* Color */ + color2 = CVAL(input); + break; + case 6: /* SetMix/Mix */ + case 7: /* SetMix/FillOrMix */ + mix = CVAL(input); + opcode -= 5; + break; + case 9: /* FillOrMix_1 */ + mask = 0x03; + opcode = 0x02; + fom_mask = 3; + break; + case 0x0a: /* FillOrMix_2 */ + mask = 0x05; + opcode = 0x02; + fom_mask = 5; + break; + } + + lastopcode = opcode; + mixmask = 0; + + /* Output body */ + while (count > 0) + { + if (x >= width) { - line[x] = color2; - bicolor = 0; + if (height <= 0) + { + return 0; + } + + x = 0; + height--; + prevline = line; + line = output + height * width; } - else + + switch (opcode) { - line[x] = color1; - bicolor = 1; - count++; + case 0: /* Fill */ + + if (insertmix) + { + if (prevline == 0) + { + line[x] = mix; + } + else + { + line[x] = prevline[x] ^ mix; + } + + insertmix = 0; + count--; + x++; + } + + if (prevline == 0) + { + REPEAT(line[x] = 0) + } + else + { + REPEAT(line[x] = prevline[x]) + } + + break; + case 1: /* Mix */ + + if (prevline == 0) + { + REPEAT(line[x] = mix) + } + else + { + REPEAT(line[x] = prevline[x] ^ mix) + } + + break; + case 2: /* Fill or Mix */ + + if (prevline == 0) + { + REPEAT + ( + MASK_UPDATE; + + if (mask & mixmask) + { + line[x] = mix; + } + else + { + line[x] = 0; + } + ) + } + else + { + REPEAT + ( + MASK_UPDATE; + + if (mask & mixmask) + { + line[x] = prevline[x] ^ mix; + } + else + { + line[x] = prevline[x]; + } + ) + } + + break; + case 3: /* Color */ + REPEAT(line[x] = color2) + break; + case 4: /* Copy */ + REPEAT(line[x] = CVAL(input)) + break; + case 8: /* Bicolor */ + REPEAT + ( + + if (bicolor) + { + line[x] = color2; + bicolor = 0; + } + else + { + line[x] = color1; + bicolor = 1; + count++; + } + ) + break; + case 0xd: /* White */ + REPEAT(line[x] = 0xff) + break; + case 0xe: /* Black */ + REPEAT(line[x] = 0) + break; + default: + return 0; + break; } - ) - break; - case 0xd: /* White */ - REPEAT(line[x] = 0xff) - break; - case 0xe: /* Black */ - REPEAT(line[x] = 0) - break; - default: - return 0; - break; - } + } } - } - return 1; + + return 1; } /******************************************************************************/ /* 2 byte bitmap decompress */ /* returns boolean */ static int APP_CC -bitmap_decompress2(char* output, int width, int height, char* input, int size) +bitmap_decompress2(char *output, int width, int height, char *input, int size) { - char* prevline; - char* line; - char* end; - char color1[2]; - char color2[2]; - char mix[2]; - int code; - int mixmask; - int mask; - int opcode; - int count; - int offset; - int isfillormix; - int x; - int lastopcode; - int insertmix; - int bicolor; - int fom_mask; + char *prevline; + char *line; + char *end; + char color1[2]; + char color2[2]; + char mix[2]; + int code; + int mixmask; + int mask; + int opcode; + int count; + int offset; + int isfillormix; + int x; + int lastopcode; + int insertmix; + int bicolor; + int fom_mask; - end = input + size; - prevline = 0; - line = 0; - x = width; - lastopcode = -1; - insertmix = 0; - bicolor = 0; - color1[0] = 0; - color1[1] = 0; - color2[0] = 0; - color2[1] = 0; - mix[0] = 0xff; - mix[1] = 0xff; - mask = 0; - fom_mask = 0; - - while (input < end) - { + end = input + size; + prevline = 0; + line = 0; + x = width; + lastopcode = -1; + insertmix = 0; + bicolor = 0; + color1[0] = 0; + color1[1] = 0; + color2[0] = 0; + color2[1] = 0; + mix[0] = 0xff; + mix[1] = 0xff; + mask = 0; fom_mask = 0; - code = CVAL(input); - opcode = code >> 4; - /* Handle different opcode forms */ - switch (opcode) + + while (input < end) { - case 0xc: - case 0xd: - case 0xe: - opcode -= 6; - count = code & 0xf; - offset = 16; - break; - case 0xf: - opcode = code & 0xf; - if (opcode < 9) + fom_mask = 0; + code = CVAL(input); + opcode = code >> 4; + + /* Handle different opcode forms */ + switch (opcode) { - count = CVAL(input); - count |= CVAL(input) << 8; + case 0xc: + case 0xd: + case 0xe: + opcode -= 6; + count = code & 0xf; + offset = 16; + break; + case 0xf: + opcode = code & 0xf; + + if (opcode < 9) + { + count = CVAL(input); + count |= CVAL(input) << 8; + } + else + { + count = (opcode < 0xb) ? 8 : 1; + } + + offset = 0; + break; + default: + opcode >>= 1; + count = code & 0x1f; + offset = 32; + break; } - else + + /* Handle strange cases for counts */ + if (offset != 0) { - count = (opcode < 0xb) ? 8 : 1; - } - offset = 0; - break; - default: - opcode >>= 1; - count = code & 0x1f; - offset = 32; - break; - } - /* Handle strange cases for counts */ - if (offset != 0) - { - isfillormix = ((opcode == 2) || (opcode == 7)); - if (count == 0) - { - if (isfillormix) - { - count = CVAL(input) + 1; - } - else - { - count = CVAL(input) + offset; - } - } - else if (isfillormix) - { - count <<= 3; - } - } - /* Read preliminary data */ - switch (opcode) - { - case 0: /* Fill */ - if ((lastopcode == opcode) && !((x == width) && (prevline == 0))) - { - insertmix = 1; - } - break; - case 8: /* Bicolor */ - color1[EIK0] = CVAL(input); - color1[EIK1] = CVAL(input); - case 3: /* Color */ - color2[EIK0] = CVAL(input); - color2[EIK1] = CVAL(input); - break; - case 6: /* SetMix/Mix */ - case 7: /* SetMix/FillOrMix */ - mix[EIK0] = CVAL(input); - mix[EIK1] = CVAL(input); - opcode -= 5; - break; - case 9: /* FillOrMix_1 */ - mask = 0x03; - opcode = 0x02; - fom_mask = 3; - break; - case 0x0a: /* FillOrMix_2 */ - mask = 0x05; - opcode = 0x02; - fom_mask = 5; - break; - } - lastopcode = opcode; - mixmask = 0; - /* Output body */ - while (count > 0) - { - if (x >= width) - { - if (height <= 0) - { - return 0; - } - x = 0; - height--; - prevline = line; - line = output + height * (width * 2); - } - switch (opcode) - { - case 0: /* Fill */ - if (insertmix) - { - if (prevline == 0) + isfillormix = ((opcode == 2) || (opcode == 7)); + + if (count == 0) { - line[x * 2 + 0] = mix[0]; - line[x * 2 + 1] = mix[1]; + if (isfillormix) + { + count = CVAL(input) + 1; + } + else + { + count = CVAL(input) + offset; + } } - else + else if (isfillormix) { - line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0]; - line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1]; + count <<= 3; } - insertmix = 0; - count--; - x++; - } - if (prevline == 0) - { - REPEAT - ( - line[x * 2 + 0] = 0; - line[x * 2 + 1] = 0; - ) - } - else - { - REPEAT - ( - line[x * 2 + 0] = prevline[x * 2 + 0]; - line[x * 2 + 1] = prevline[x * 2 + 1]; - ) - } - break; - case 1: /* Mix */ - if (prevline == 0) - { - REPEAT - ( - line[x * 2 + 0] = mix[0]; - line[x * 2 + 1] = mix[1]; - ) - } - else - { - REPEAT - ( - line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0]; - line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1]; - ) - } - break; - case 2: /* Fill or Mix */ - if (prevline == 0) - { - REPEAT - ( - MASK_UPDATE; - if (mask & mixmask) - { - line[x * 2 + 0] = mix[0]; - line[x * 2 + 1] = mix[1]; - } - else - { - line[x * 2 + 0] = 0; - line[x * 2 + 1] = 0; - } - ) - } - else - { - REPEAT - ( - MASK_UPDATE; - if (mask & mixmask) - { - line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0]; - line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1]; - } - else - { - line[x * 2 + 0] = prevline[x * 2 + 0]; - line[x * 2 + 1] = prevline[x * 2 + 1]; - } - ) - } - break; - case 3: /* Color */ - REPEAT - ( - line[x * 2 + 0] = color2[0]; - line[x * 2 + 1] = color2[1]; - ) - break; - case 4: /* Copy */ - REPEAT - ( - line[x * 2 + EIK0] = CVAL(input); - line[x * 2 + EIK1] = CVAL(input); - ) - break; - case 8: /* Bicolor */ - REPEAT - ( - if (bicolor) + } + + /* Read preliminary data */ + switch (opcode) + { + case 0: /* Fill */ + + if ((lastopcode == opcode) && !((x == width) && (prevline == 0))) + { + insertmix = 1; + } + + break; + case 8: /* Bicolor */ + color1[EIK0] = CVAL(input); + color1[EIK1] = CVAL(input); + case 3: /* Color */ + color2[EIK0] = CVAL(input); + color2[EIK1] = CVAL(input); + break; + case 6: /* SetMix/Mix */ + case 7: /* SetMix/FillOrMix */ + mix[EIK0] = CVAL(input); + mix[EIK1] = CVAL(input); + opcode -= 5; + break; + case 9: /* FillOrMix_1 */ + mask = 0x03; + opcode = 0x02; + fom_mask = 3; + break; + case 0x0a: /* FillOrMix_2 */ + mask = 0x05; + opcode = 0x02; + fom_mask = 5; + break; + } + + lastopcode = opcode; + mixmask = 0; + + /* Output body */ + while (count > 0) + { + if (x >= width) { - line[x * 2 + 0] = color2[0]; - line[x * 2 + 1] = color2[1]; - bicolor = 0; + if (height <= 0) + { + return 0; + } + + x = 0; + height--; + prevline = line; + line = output + height * (width * 2); } - else + + switch (opcode) { - line[x * 2 + 0] = color1[0]; - line[x * 2 + 1] = color1[1]; - bicolor = 1; - count++; + case 0: /* Fill */ + + if (insertmix) + { + if (prevline == 0) + { + line[x * 2 + 0] = mix[0]; + line[x * 2 + 1] = mix[1]; + } + else + { + line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0]; + line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1]; + } + + insertmix = 0; + count--; + x++; + } + + if (prevline == 0) + { + REPEAT + ( + line[x * 2 + 0] = 0; + line[x * 2 + 1] = 0; + ) + } + else + { + REPEAT + ( + line[x * 2 + 0] = prevline[x * 2 + 0]; + line[x * 2 + 1] = prevline[x * 2 + 1]; + ) + } + + break; + case 1: /* Mix */ + + if (prevline == 0) + { + REPEAT + ( + line[x * 2 + 0] = mix[0]; + line[x * 2 + 1] = mix[1]; + ) + } + else + { + REPEAT + ( + line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0]; + line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1]; + ) + } + + break; + case 2: /* Fill or Mix */ + + if (prevline == 0) + { + REPEAT + ( + MASK_UPDATE; + + if (mask & mixmask) + { + line[x * 2 + 0] = mix[0]; + line[x * 2 + 1] = mix[1]; + } + else + { + line[x * 2 + 0] = 0; + line[x * 2 + 1] = 0; + } + ) + } + else + { + REPEAT + ( + MASK_UPDATE; + + if (mask & mixmask) + { + line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0]; + line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1]; + } + else + { + line[x * 2 + 0] = prevline[x * 2 + 0]; + line[x * 2 + 1] = prevline[x * 2 + 1]; + } + ) + } + + break; + case 3: /* Color */ + REPEAT + ( + line[x * 2 + 0] = color2[0]; + line[x * 2 + 1] = color2[1]; + ) + break; + case 4: /* Copy */ + REPEAT + ( + line[x * 2 + EIK0] = CVAL(input); + line[x * 2 + EIK1] = CVAL(input); + ) + break; + case 8: /* Bicolor */ + REPEAT + ( + + if (bicolor) + { + line[x * 2 + 0] = color2[0]; + line[x * 2 + 1] = color2[1]; + bicolor = 0; + } + else + { + line[x * 2 + 0] = color1[0]; + line[x * 2 + 1] = color1[1]; + bicolor = 1; + count++; + } + ) + break; + case 0xd: /* White */ + REPEAT + ( + line[x * 2 + 0] = 0xff; + line[x * 2 + 1] = 0xff; + ) + break; + case 0xe: /* Black */ + REPEAT + ( + line[x * 2 + 0] = 0; + line[x * 2 + 1] = 0; + ) + break; + default: + return 0; + break; } - ) - break; - case 0xd: /* White */ - REPEAT - ( - line[x * 2 + 0] = 0xff; - line[x * 2 + 1] = 0xff; - ) - break; - case 0xe: /* Black */ - REPEAT - ( - line[x * 2 + 0] = 0; - line[x * 2 + 1] = 0; - ) - break; - default: - return 0; - break; - } + } } - } - return 1; + + return 1; } /******************************************************************************/ /* 3 byte bitmap decompress */ /* returns boolean */ static int APP_CC -bitmap_decompress3(char* output, int width, int height, char* input, int size) +bitmap_decompress3(char *output, int width, int height, char *input, int size) { - char* prevline; - char* line; - char* end; - char color1[3]; - char color2[3]; - char mix[3]; - int code; - int mixmask; - int mask; - int opcode; - int count; - int offset; - int isfillormix; - int x; - int lastopcode; - int insertmix; - int bicolor; - int fom_mask; + char *prevline; + char *line; + char *end; + char color1[3]; + char color2[3]; + char mix[3]; + int code; + int mixmask; + int mask; + int opcode; + int count; + int offset; + int isfillormix; + int x; + int lastopcode; + int insertmix; + int bicolor; + int fom_mask; - end = input + size; - prevline = 0; - line = 0; - x = width; - lastopcode = -1; - insertmix = 0; - bicolor = 0; - color1[0] = 0; - color1[1] = 0; - color1[2] = 0; - color2[0] = 0; - color2[1] = 0; - color2[2] = 0; - mix[0] = 0xff; - mix[1] = 0xff; - mix[2] = 0xff; - mask = 0; - fom_mask = 0; - - while (input < end) - { + end = input + size; + prevline = 0; + line = 0; + x = width; + lastopcode = -1; + insertmix = 0; + bicolor = 0; + color1[0] = 0; + color1[1] = 0; + color1[2] = 0; + color2[0] = 0; + color2[1] = 0; + color2[2] = 0; + mix[0] = 0xff; + mix[1] = 0xff; + mix[2] = 0xff; + mask = 0; fom_mask = 0; - code = CVAL(input); - opcode = code >> 4; - /* Handle different opcode forms */ - switch (opcode) + + while (input < end) { - case 0xc: - case 0xd: - case 0xe: - opcode -= 6; - count = code & 0xf; - offset = 16; - break; - case 0xf: - opcode = code & 0xf; - if (opcode < 9) + fom_mask = 0; + code = CVAL(input); + opcode = code >> 4; + + /* Handle different opcode forms */ + switch (opcode) { - count = CVAL(input); - count |= CVAL(input) << 8; + case 0xc: + case 0xd: + case 0xe: + opcode -= 6; + count = code & 0xf; + offset = 16; + break; + case 0xf: + opcode = code & 0xf; + + if (opcode < 9) + { + count = CVAL(input); + count |= CVAL(input) << 8; + } + else + { + count = (opcode < 0xb) ? 8 : 1; + } + + offset = 0; + break; + default: + opcode >>= 1; + count = code & 0x1f; + offset = 32; + break; } - else + + /* Handle strange cases for counts */ + if (offset != 0) { - count = (opcode < 0xb) ? 8 : 1; - } - offset = 0; - break; - default: - opcode >>= 1; - count = code & 0x1f; - offset = 32; - break; - } - /* Handle strange cases for counts */ - if (offset != 0) - { - isfillormix = ((opcode == 2) || (opcode == 7)); - if (count == 0) - { - if (isfillormix) - { - count = CVAL(input) + 1; - } - else - { - count = CVAL(input) + offset; - } - } - else if (isfillormix) - { - count <<= 3; - } - } - /* Read preliminary data */ - switch (opcode) - { - case 0: /* Fill */ - if ((lastopcode == opcode) && !((x == width) && (prevline == 0))) - { - insertmix = 1; - } - break; - case 8: /* Bicolor */ - color1[0] = CVAL(input); - color1[1] = CVAL(input); - color1[2] = CVAL(input); - case 3: /* Color */ - color2[0] = CVAL(input); - color2[1] = CVAL(input); - color2[2] = CVAL(input); - break; - case 6: /* SetMix/Mix */ - case 7: /* SetMix/FillOrMix */ - mix[0] = CVAL(input); - mix[1] = CVAL(input); - mix[2] = CVAL(input); - opcode -= 5; - break; - case 9: /* FillOrMix_1 */ - mask = 0x03; - opcode = 0x02; - fom_mask = 3; - break; - case 0x0a: /* FillOrMix_2 */ - mask = 0x05; - opcode = 0x02; - fom_mask = 5; - break; - } - lastopcode = opcode; - mixmask = 0; - /* Output body */ - while (count > 0) - { - if (x >= width) - { - if (height <= 0) - { - return 0; - } - x = 0; - height--; - prevline = line; - line = output + height * (width * 3); - } - switch (opcode) - { - case 0: /* Fill */ - if (insertmix) - { - if (prevline == 0) + isfillormix = ((opcode == 2) || (opcode == 7)); + + if (count == 0) { - line[x * 3 + 0] = mix[0]; - line[x * 3 + 1] = mix[1]; - line[x * 3 + 2] = mix[2]; + if (isfillormix) + { + count = CVAL(input) + 1; + } + else + { + count = CVAL(input) + offset; + } } - else + else if (isfillormix) { - line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0]; - line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1]; - line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2]; + count <<= 3; } - insertmix = 0; - count--; - x++; - } - if (prevline == 0) - { - REPEAT - ( - line[x * 3 + 0] = 0; - line[x * 3 + 1] = 0; - line[x * 3 + 2] = 0; - ) - } - else - { - REPEAT - ( - line[x * 3 + 0] = prevline[x * 3 + 0]; - line[x * 3 + 1] = prevline[x * 3 + 1]; - line[x * 3 + 2] = prevline[x * 3 + 2]; - ) - } - break; - case 1: /* Mix */ - if (prevline == 0) - { - REPEAT - ( - line[x * 3 + 0] = mix[0]; - line[x * 3 + 1] = mix[1]; - line[x * 3 + 2] = mix[2]; - ) - } - else - { - REPEAT - ( - line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0]; - line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1]; - line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2]; - ) - } - break; - case 2: /* Fill or Mix */ - if (prevline == 0) - { - REPEAT - ( - MASK_UPDATE; - if (mask & mixmask) - { - line[x * 3 + 0] = mix[0]; - line[x * 3 + 1] = mix[1]; - line[x * 3 + 2] = mix[2]; - } - else - { - line[x * 3 + 0] = 0; - line[x * 3 + 1] = 0; - line[x * 3 + 2] = 0; - } - ) - } - else - { - REPEAT - ( - MASK_UPDATE; - if (mask & mixmask) - { - line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0]; - line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1]; - line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2]; - } - else - { - line[x * 3 + 0] = prevline[x * 3 + 0]; - line[x * 3 + 1] = prevline[x * 3 + 1]; - line[x * 3 + 2] = prevline[x * 3 + 2]; - } - ) - } - break; - case 3: /* Color */ - REPEAT - ( - line[x * 3 + 0] = color2[0]; - line[x * 3 + 1] = color2[1]; - line[x * 3 + 2] = color2[2]; - ) - break; - case 4: /* Copy */ - REPEAT - ( - line[x * 3 + 0] = CVAL(input); - line[x * 3 + 1] = CVAL(input); - line[x * 3 + 2] = CVAL(input); - ) - break; - case 8: /* Bicolor */ - REPEAT - ( - if (bicolor) + } + + /* Read preliminary data */ + switch (opcode) + { + case 0: /* Fill */ + + if ((lastopcode == opcode) && !((x == width) && (prevline == 0))) + { + insertmix = 1; + } + + break; + case 8: /* Bicolor */ + color1[0] = CVAL(input); + color1[1] = CVAL(input); + color1[2] = CVAL(input); + case 3: /* Color */ + color2[0] = CVAL(input); + color2[1] = CVAL(input); + color2[2] = CVAL(input); + break; + case 6: /* SetMix/Mix */ + case 7: /* SetMix/FillOrMix */ + mix[0] = CVAL(input); + mix[1] = CVAL(input); + mix[2] = CVAL(input); + opcode -= 5; + break; + case 9: /* FillOrMix_1 */ + mask = 0x03; + opcode = 0x02; + fom_mask = 3; + break; + case 0x0a: /* FillOrMix_2 */ + mask = 0x05; + opcode = 0x02; + fom_mask = 5; + break; + } + + lastopcode = opcode; + mixmask = 0; + + /* Output body */ + while (count > 0) + { + if (x >= width) { - line[x * 3 + 0] = color2[0]; - line[x * 3 + 1] = color2[1]; - line[x * 3 + 2] = color2[2]; - bicolor = 0; + if (height <= 0) + { + return 0; + } + + x = 0; + height--; + prevline = line; + line = output + height * (width * 3); } - else + + switch (opcode) { - line[x * 3 + 0] = color1[0]; - line[x * 3 + 1] = color1[1]; - line[x * 3 + 2] = color1[2]; - bicolor = 1; - count++; + case 0: /* Fill */ + + if (insertmix) + { + if (prevline == 0) + { + line[x * 3 + 0] = mix[0]; + line[x * 3 + 1] = mix[1]; + line[x * 3 + 2] = mix[2]; + } + else + { + line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0]; + line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1]; + line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2]; + } + + insertmix = 0; + count--; + x++; + } + + if (prevline == 0) + { + REPEAT + ( + line[x * 3 + 0] = 0; + line[x * 3 + 1] = 0; + line[x * 3 + 2] = 0; + ) + } + else + { + REPEAT + ( + line[x * 3 + 0] = prevline[x * 3 + 0]; + line[x * 3 + 1] = prevline[x * 3 + 1]; + line[x * 3 + 2] = prevline[x * 3 + 2]; + ) + } + + break; + case 1: /* Mix */ + + if (prevline == 0) + { + REPEAT + ( + line[x * 3 + 0] = mix[0]; + line[x * 3 + 1] = mix[1]; + line[x * 3 + 2] = mix[2]; + ) + } + else + { + REPEAT + ( + line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0]; + line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1]; + line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2]; + ) + } + + break; + case 2: /* Fill or Mix */ + + if (prevline == 0) + { + REPEAT + ( + MASK_UPDATE; + + if (mask & mixmask) + { + line[x * 3 + 0] = mix[0]; + line[x * 3 + 1] = mix[1]; + line[x * 3 + 2] = mix[2]; + } + else + { + line[x * 3 + 0] = 0; + line[x * 3 + 1] = 0; + line[x * 3 + 2] = 0; + } + ) + } + else + { + REPEAT + ( + MASK_UPDATE; + + if (mask & mixmask) + { + line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0]; + line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1]; + line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2]; + } + else + { + line[x * 3 + 0] = prevline[x * 3 + 0]; + line[x * 3 + 1] = prevline[x * 3 + 1]; + line[x * 3 + 2] = prevline[x * 3 + 2]; + } + ) + } + + break; + case 3: /* Color */ + REPEAT + ( + line[x * 3 + 0] = color2[0]; + line[x * 3 + 1] = color2[1]; + line[x * 3 + 2] = color2[2]; + ) + break; + case 4: /* Copy */ + REPEAT + ( + line[x * 3 + 0] = CVAL(input); + line[x * 3 + 1] = CVAL(input); + line[x * 3 + 2] = CVAL(input); + ) + break; + case 8: /* Bicolor */ + REPEAT + ( + + if (bicolor) + { + line[x * 3 + 0] = color2[0]; + line[x * 3 + 1] = color2[1]; + line[x * 3 + 2] = color2[2]; + bicolor = 0; + } + else + { + line[x * 3 + 0] = color1[0]; + line[x * 3 + 1] = color1[1]; + line[x * 3 + 2] = color1[2]; + bicolor = 1; + count++; + } + ) + break; + case 0xd: /* White */ + REPEAT + ( + line[x * 3 + 0] = 0xff; + line[x * 3 + 1] = 0xff; + line[x * 3 + 2] = 0xff; + ) + break; + case 0xe: /* Black */ + REPEAT + ( + line[x * 3 + 0] = 0; + line[x * 3 + 1] = 0; + line[x * 3 + 2] = 0; + ) + break; + default: + return 0; + break; } - ) - break; - case 0xd: /* White */ - REPEAT - ( - line[x * 3 + 0] = 0xff; - line[x * 3 + 1] = 0xff; - line[x * 3 + 2] = 0xff; - ) - break; - case 0xe: /* Black */ - REPEAT - ( - line[x * 3 + 0] = 0; - line[x * 3 + 1] = 0; - line[x * 3 + 2] = 0; - ) - break; - default: - return 0; - break; - } + } } - } - return 1; + + return 1; } /*****************************************************************************/ /* returns boolean */ int APP_CC -rdp_bitmap_decompress(char* output, int width, int height, char* input, +rdp_bitmap_decompress(char *output, int width, int height, char *input, int size, int Bpp) { - int rv; + int rv; - switch (Bpp) - { - case 1: - rv = bitmap_decompress1(output, width, height, input, size); - break; - case 2: - rv = bitmap_decompress2(output, width, height, input, size); - break; - case 3: - rv = bitmap_decompress3(output, width, height, input, size); - break; - default: - rv = 0; - break; - } - return rv; + switch (Bpp) + { + case 1: + rv = bitmap_decompress1(output, width, height, input, size); + break; + case 2: + rv = bitmap_decompress2(output, width, height, input, size); + break; + case 3: + rv = bitmap_decompress3(output, width, height, input, size); + break; + default: + rv = 0; + break; + } + + return rv; } diff --git a/rdp/rdp_iso.c b/rdp/rdp_iso.c index 3db99dd4..09c874b6 100644 --- a/rdp/rdp_iso.c +++ b/rdp/rdp_iso.c @@ -1,219 +1,239 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - librdp iso layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * librdp iso layer + */ #include "rdp.h" /*****************************************************************************/ -struct rdp_iso* APP_CC -rdp_iso_create(struct rdp_mcs* owner) +struct rdp_iso *APP_CC +rdp_iso_create(struct rdp_mcs *owner) { - struct rdp_iso* self; + struct rdp_iso *self; - self = (struct rdp_iso*)g_malloc(sizeof(struct rdp_iso), 1); - self->mcs_layer = owner; - self->tcp_layer = rdp_tcp_create(self); - return self; + self = (struct rdp_iso *)g_malloc(sizeof(struct rdp_iso), 1); + self->mcs_layer = owner; + self->tcp_layer = rdp_tcp_create(self); + return self; } /*****************************************************************************/ void APP_CC -rdp_iso_delete(struct rdp_iso* self) +rdp_iso_delete(struct rdp_iso *self) { - if (self == 0) - { - return; - } - rdp_tcp_delete(self->tcp_layer); - g_free(self); + if (self == 0) + { + return; + } + + rdp_tcp_delete(self->tcp_layer); + g_free(self); } /*****************************************************************************/ /* returns error */ static int APP_CC -rdp_iso_recv_msg(struct rdp_iso* self, struct stream* s, int* code) +rdp_iso_recv_msg(struct rdp_iso *self, struct stream *s, int *code) { - int ver; - int len; + int ver; + int len; + + *code = 0; + + if (rdp_tcp_recv(self->tcp_layer, s, 4) != 0) + { + DEBUG((" out rdp_iso_recv_msg error rdp_tcp_recv 1 failed")); + return 1; + } + + in_uint8(s, ver); + + if (ver != 3) + { + DEBUG((" out rdp_iso_recv_msg error ver != 3")); + return 1; + } - *code = 0; - if (rdp_tcp_recv(self->tcp_layer, s, 4) != 0) - { - DEBUG((" out rdp_iso_recv_msg error rdp_tcp_recv 1 failed")); - return 1; - } - in_uint8(s, ver); - if (ver != 3) - { - DEBUG((" out rdp_iso_recv_msg error ver != 3")); - return 1; - } - in_uint8s(s, 1); - in_uint16_be(s, len); - if (rdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) - { - DEBUG((" out rdp_iso_recv_msg error rdp_tcp_recv 2 failed")); - return 1; - } - in_uint8s(s, 1); - in_uint8(s, *code); - if (*code == ISO_PDU_DT) - { in_uint8s(s, 1); - } - else - { - in_uint8s(s, 5); - } - return 0; + in_uint16_be(s, len); + + if (rdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) + { + DEBUG((" out rdp_iso_recv_msg error rdp_tcp_recv 2 failed")); + return 1; + } + + in_uint8s(s, 1); + in_uint8(s, *code); + + if (*code == ISO_PDU_DT) + { + in_uint8s(s, 1); + } + else + { + in_uint8s(s, 5); + } + + return 0; } /*****************************************************************************/ static int APP_CC -rdp_iso_send_msg(struct rdp_iso* self, struct stream* s, int code) +rdp_iso_send_msg(struct rdp_iso *self, struct stream *s, int code) { - if (rdp_tcp_init(self->tcp_layer, s) != 0) - { - return 1; - } - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, 11); /* length */ - out_uint8(s, 6); - out_uint8(s, code); - out_uint16_le(s, 0); - out_uint16_le(s, 0); - out_uint8(s, 0); - s_mark_end(s); - if (rdp_tcp_send(self->tcp_layer, s) != 0) - { - return 1; - } - return 0; + if (rdp_tcp_init(self->tcp_layer, s) != 0) + { + return 1; + } + + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, 11); /* length */ + out_uint8(s, 6); + out_uint8(s, code); + out_uint16_le(s, 0); + out_uint16_le(s, 0); + out_uint8(s, 0); + s_mark_end(s); + + if (rdp_tcp_send(self->tcp_layer, s) != 0) + { + return 1; + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_iso_recv(struct rdp_iso* self, struct stream* s) +rdp_iso_recv(struct rdp_iso *self, struct stream *s) { - int code; + int code; - if (rdp_iso_recv_msg(self, s, &code) != 0) - { - return 1; - } - if (code != ISO_PDU_DT) - { - return 1; - } - return 0; + if (rdp_iso_recv_msg(self, s, &code) != 0) + { + return 1; + } + + if (code != ISO_PDU_DT) + { + return 1; + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_iso_init(struct rdp_iso* self, struct stream* s) +rdp_iso_init(struct rdp_iso *self, struct stream *s) { - rdp_tcp_init(self->tcp_layer, s); - s_push_layer(s, iso_hdr, 7); - return 0; + rdp_tcp_init(self->tcp_layer, s); + s_push_layer(s, iso_hdr, 7); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_iso_send(struct rdp_iso* self, struct stream* s) +rdp_iso_send(struct rdp_iso *self, struct stream *s) { - int len; + int len; - s_pop_layer(s, iso_hdr); - len = s->end - s->p; - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, len); - out_uint8(s, 2); - out_uint8(s, ISO_PDU_DT); - out_uint8(s, 0x80); - if (rdp_tcp_send(self->tcp_layer, s) != 0) - { - return 1; - } - return 0; + s_pop_layer(s, iso_hdr); + len = s->end - s->p; + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, len); + out_uint8(s, 2); + out_uint8(s, ISO_PDU_DT); + out_uint8(s, 0x80); + + if (rdp_tcp_send(self->tcp_layer, s) != 0) + { + return 1; + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_iso_connect(struct rdp_iso* self, char* ip, char* port) +rdp_iso_connect(struct rdp_iso *self, char *ip, char *port) { - int code; - struct stream* s; + int code; + struct stream *s; + + DEBUG((" in rdp_iso_connect")); + make_stream(s); + init_stream(s, 8192); + + if (rdp_tcp_connect(self->tcp_layer, ip, port) != 0) + { + free_stream(s); + DEBUG((" out rdp_iso_connect error rdp_tcp_connect failed")); + return 1; + } + + if (rdp_iso_send_msg(self, s, ISO_PDU_CR) != 0) + { + free_stream(s); + rdp_tcp_disconnect(self->tcp_layer); + DEBUG((" out rdp_iso_connect error rdp_iso_send_msg failed")); + return 1; + } + + init_stream(s, 8192); + + if (rdp_iso_recv_msg(self, s, &code) != 0) + { + free_stream(s); + rdp_tcp_disconnect(self->tcp_layer); + DEBUG((" out rdp_iso_connect error rdp_iso_recv_msg failed")); + return 1; + } + + if (code != ISO_PDU_CC) + { + free_stream(s); + rdp_tcp_disconnect(self->tcp_layer); + DEBUG((" out rdp_iso_connect error code != ISO_PDU_CC")); + return 1; + } - DEBUG((" in rdp_iso_connect")); - make_stream(s); - init_stream(s, 8192); - if (rdp_tcp_connect(self->tcp_layer, ip, port) != 0) - { - free_stream(s); - DEBUG((" out rdp_iso_connect error rdp_tcp_connect failed")); - return 1; - } - if (rdp_iso_send_msg(self, s, ISO_PDU_CR) != 0) - { free_stream(s); + DEBUG((" out rdp_iso_connect")); + return 0; +} + +/*****************************************************************************/ +int APP_CC +rdp_iso_disconnect(struct rdp_iso *self) +{ + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + rdp_iso_send_msg(self, s, ISO_PDU_DR); rdp_tcp_disconnect(self->tcp_layer); - DEBUG((" out rdp_iso_connect error rdp_iso_send_msg failed")); - return 1; - } - init_stream(s, 8192); - if (rdp_iso_recv_msg(self, s, &code) != 0) - { free_stream(s); - rdp_tcp_disconnect(self->tcp_layer); - DEBUG((" out rdp_iso_connect error rdp_iso_recv_msg failed")); - return 1; - } - if (code != ISO_PDU_CC) - { - free_stream(s); - rdp_tcp_disconnect(self->tcp_layer); - DEBUG((" out rdp_iso_connect error code != ISO_PDU_CC")); - return 1; - } - free_stream(s); - DEBUG((" out rdp_iso_connect")); - return 0; -} - -/*****************************************************************************/ -int APP_CC -rdp_iso_disconnect(struct rdp_iso* self) -{ - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - rdp_iso_send_msg(self, s, ISO_PDU_DR); - rdp_tcp_disconnect(self->tcp_layer); - free_stream(s); - return 0; + return 0; } diff --git a/rdp/rdp_lic.c b/rdp/rdp_lic.c index a729a7bc..ce9a0624 100644 --- a/rdp/rdp_lic.c +++ b/rdp/rdp_lic.c @@ -1,358 +1,369 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - licence - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * licence + */ #include "rdp.h" /*****************************************************************************/ -struct rdp_lic* APP_CC -rdp_lic_create(struct rdp_sec* owner) +struct rdp_lic *APP_CC +rdp_lic_create(struct rdp_sec *owner) { - struct rdp_lic* self; + struct rdp_lic *self; - self = (struct rdp_lic*)g_malloc(sizeof(struct rdp_lic), 1); - self->sec_layer = owner; - return self; + self = (struct rdp_lic *)g_malloc(sizeof(struct rdp_lic), 1); + self->sec_layer = owner; + return self; } /*****************************************************************************/ void APP_CC -rdp_lic_delete(struct rdp_lic* self) +rdp_lic_delete(struct rdp_lic *self) { - if (self == 0) - { - return; - } - g_free(self); + if (self == 0) + { + return; + } + + g_free(self); } /*****************************************************************************/ /* Generate a session key and RC4 keys, given client and server randoms */ static void APP_CC -rdp_lic_generate_keys(struct rdp_lic* self, char* client_random, - char* server_random, char* pre_master_secret) +rdp_lic_generate_keys(struct rdp_lic *self, char *client_random, + char *server_random, char *pre_master_secret) { - char master_secret[48]; - char key_block[48]; + char master_secret[48]; + char key_block[48]; - /* Generate master secret and then key material */ - rdp_sec_hash_48(master_secret, pre_master_secret, client_random, - server_random, 65); - rdp_sec_hash_48(key_block, master_secret, server_random, - client_random, 65); - /* Store first 16 bytes of session key as MAC secret */ - g_memcpy(self->licence_sign_key, key_block, 16); - /* Generate RC4 key from next 16 bytes */ - rdp_sec_hash_16(self->licence_key, key_block + 16, client_random, - server_random); + /* Generate master secret and then key material */ + rdp_sec_hash_48(master_secret, pre_master_secret, client_random, + server_random, 65); + rdp_sec_hash_48(key_block, master_secret, server_random, + client_random, 65); + /* Store first 16 bytes of session key as MAC secret */ + g_memcpy(self->licence_sign_key, key_block, 16); + /* Generate RC4 key from next 16 bytes */ + rdp_sec_hash_16(self->licence_key, key_block + 16, client_random, + server_random); } /*****************************************************************************/ static void APP_CC -rdp_lic_generate_hwid(struct rdp_lic* self, char* hwid) +rdp_lic_generate_hwid(struct rdp_lic *self, char *hwid) { - rdp_sec_buf_out_uint32(hwid, 2); - g_strncpy(hwid + 4, self->sec_layer->rdp_layer->mod->hostname, - LICENCE_HWID_SIZE - 4); + rdp_sec_buf_out_uint32(hwid, 2); + g_strncpy(hwid + 4, self->sec_layer->rdp_layer->mod->hostname, + LICENCE_HWID_SIZE - 4); } /*****************************************************************************/ /* Present an existing licence to the server */ static void APP_CC -rdp_lic_present(struct rdp_lic* self, char* client_random, char* rsa_data, - char* licence_data, int licence_size, char* hwid, - char* signature) +rdp_lic_present(struct rdp_lic *self, char *client_random, char *rsa_data, + char *licence_data, int licence_size, char *hwid, + char *signature) { - int sec_flags; - int length; - struct stream* s; + int sec_flags; + int length; + struct stream *s; - sec_flags = SEC_LICENCE_NEG; - length = 16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + - licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE; - make_stream(s); - init_stream(s, 8192); - rdp_sec_init(self->sec_layer, s, sec_flags); - out_uint8(s, LICENCE_TAG_PRESENT); - out_uint8(s, 2); /* version */ - out_uint16_le(s, length); - out_uint32_le(s, 1); - out_uint16_le(s, 0); - out_uint16_le(s, 0x0201); - out_uint8p(s, client_random, SEC_RANDOM_SIZE); - out_uint16_le(s, 0); - out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); - out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); - out_uint8s(s, SEC_PADDING_SIZE); - out_uint16_le(s, 1); - out_uint16_le(s, licence_size); - out_uint8p(s, licence_data, licence_size); - out_uint16_le(s, 1); - out_uint16_le(s, LICENCE_HWID_SIZE); - out_uint8p(s, hwid, LICENCE_HWID_SIZE); - out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); - s_mark_end(s); - rdp_sec_send(self->sec_layer, s, sec_flags); - free_stream(s); + sec_flags = SEC_LICENCE_NEG; + length = 16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + + licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE; + make_stream(s); + init_stream(s, 8192); + rdp_sec_init(self->sec_layer, s, sec_flags); + out_uint8(s, LICENCE_TAG_PRESENT); + out_uint8(s, 2); /* version */ + out_uint16_le(s, length); + out_uint32_le(s, 1); + out_uint16_le(s, 0); + out_uint16_le(s, 0x0201); + out_uint8p(s, client_random, SEC_RANDOM_SIZE); + out_uint16_le(s, 0); + out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); + out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); + out_uint8s(s, SEC_PADDING_SIZE); + out_uint16_le(s, 1); + out_uint16_le(s, licence_size); + out_uint8p(s, licence_data, licence_size); + out_uint16_le(s, 1); + out_uint16_le(s, LICENCE_HWID_SIZE); + out_uint8p(s, hwid, LICENCE_HWID_SIZE); + out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); + s_mark_end(s); + rdp_sec_send(self->sec_layer, s, sec_flags); + free_stream(s); } /*****************************************************************************/ /* Send a licence request packet */ static void APP_CC -rdp_lic_send_request(struct rdp_lic* self, char* client_random, - char* rsa_data, char* user, char* host) +rdp_lic_send_request(struct rdp_lic *self, char *client_random, + char *rsa_data, char *user, char *host) { - int sec_flags; - int userlen; - int hostlen; - int length; - struct stream* s; + int sec_flags; + int userlen; + int hostlen; + int length; + struct stream *s; - sec_flags = SEC_LICENCE_NEG; - userlen = g_strlen(user) + 1; - hostlen = g_strlen(host) + 1; - length = 128 + userlen + hostlen; - make_stream(s); - init_stream(s, 8192); - rdp_sec_init(self->sec_layer, s, sec_flags); - out_uint8(s, LICENCE_TAG_REQUEST); - out_uint8(s, 2); /* version */ - out_uint16_le(s, length); - out_uint32_le(s, 1); - out_uint16_le(s, 0); - out_uint16_le(s, 0xff01); - out_uint8p(s, client_random, SEC_RANDOM_SIZE); - out_uint16_le(s, 0); - out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); - out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); - out_uint8s(s, SEC_PADDING_SIZE); - out_uint16_le(s, LICENCE_TAG_USER); - out_uint16_le(s, userlen); - out_uint8p(s, user, userlen); - out_uint16_le(s, LICENCE_TAG_HOST); - out_uint16_le(s, hostlen); - out_uint8p(s, host, hostlen); - s_mark_end(s); - rdp_sec_send(self->sec_layer, s, sec_flags); - free_stream(s); + sec_flags = SEC_LICENCE_NEG; + userlen = g_strlen(user) + 1; + hostlen = g_strlen(host) + 1; + length = 128 + userlen + hostlen; + make_stream(s); + init_stream(s, 8192); + rdp_sec_init(self->sec_layer, s, sec_flags); + out_uint8(s, LICENCE_TAG_REQUEST); + out_uint8(s, 2); /* version */ + out_uint16_le(s, length); + out_uint32_le(s, 1); + out_uint16_le(s, 0); + out_uint16_le(s, 0xff01); + out_uint8p(s, client_random, SEC_RANDOM_SIZE); + out_uint16_le(s, 0); + out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); + out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); + out_uint8s(s, SEC_PADDING_SIZE); + out_uint16_le(s, LICENCE_TAG_USER); + out_uint16_le(s, userlen); + out_uint8p(s, user, userlen); + out_uint16_le(s, LICENCE_TAG_HOST); + out_uint16_le(s, hostlen); + out_uint8p(s, host, hostlen); + s_mark_end(s); + rdp_sec_send(self->sec_layer, s, sec_flags); + free_stream(s); } /*****************************************************************************/ /* Process a licence demand packet */ static void APP_CC -rdp_lic_process_demand(struct rdp_lic* self, struct stream* s) +rdp_lic_process_demand(struct rdp_lic *self, struct stream *s) { - char null_data[SEC_MODULUS_SIZE]; - char* server_random; - char signature[LICENCE_SIGNATURE_SIZE]; - char hwid[LICENCE_HWID_SIZE]; - char* licence_data; - int licence_size; - void* crypt_key; + char null_data[SEC_MODULUS_SIZE]; + char *server_random; + char signature[LICENCE_SIGNATURE_SIZE]; + char hwid[LICENCE_HWID_SIZE]; + char *licence_data; + int licence_size; + void *crypt_key; - licence_data = 0; - /* Retrieve the server random from the incoming packet */ - in_uint8p(s, server_random, SEC_RANDOM_SIZE); - /* We currently use null client keys. This is a bit naughty but, hey, - the security of licence negotiation isn't exactly paramount. */ - g_memset(null_data, 0, sizeof(null_data)); - rdp_lic_generate_keys(self, null_data, server_random, null_data); - licence_size = 0; /* todo load_licence(&licence_data); */ - if (licence_size > 0) - { - /* Generate a signature for the HWID buffer */ - rdp_lic_generate_hwid(self, hwid); - rdp_sec_sign(signature, 16, self->licence_sign_key, 16, - hwid, sizeof(hwid)); - /* Now encrypt the HWID */ - crypt_key = ssl_rc4_info_create(); - ssl_rc4_set_key(crypt_key, self->licence_key, 16); - ssl_rc4_crypt(crypt_key, hwid, sizeof(hwid)); - ssl_rc4_info_delete(crypt_key); - rdp_lic_present(self, null_data, null_data, licence_data, - licence_size, hwid, signature); - g_free(licence_data); - return; - } - rdp_lic_send_request(self, null_data, null_data, - self->sec_layer->rdp_layer->mod->username, - self->sec_layer->rdp_layer->mod->hostname); + licence_data = 0; + /* Retrieve the server random from the incoming packet */ + in_uint8p(s, server_random, SEC_RANDOM_SIZE); + /* We currently use null client keys. This is a bit naughty but, hey, + the security of licence negotiation isn't exactly paramount. */ + g_memset(null_data, 0, sizeof(null_data)); + rdp_lic_generate_keys(self, null_data, server_random, null_data); + licence_size = 0; /* todo load_licence(&licence_data); */ + + if (licence_size > 0) + { + /* Generate a signature for the HWID buffer */ + rdp_lic_generate_hwid(self, hwid); + rdp_sec_sign(signature, 16, self->licence_sign_key, 16, + hwid, sizeof(hwid)); + /* Now encrypt the HWID */ + crypt_key = ssl_rc4_info_create(); + ssl_rc4_set_key(crypt_key, self->licence_key, 16); + ssl_rc4_crypt(crypt_key, hwid, sizeof(hwid)); + ssl_rc4_info_delete(crypt_key); + rdp_lic_present(self, null_data, null_data, licence_data, + licence_size, hwid, signature); + g_free(licence_data); + return; + } + + rdp_lic_send_request(self, null_data, null_data, + self->sec_layer->rdp_layer->mod->username, + self->sec_layer->rdp_layer->mod->hostname); } /*****************************************************************************/ /* Send an authentication response packet */ static void APP_CC -rdp_lic_send_authresp(struct rdp_lic* self, char* token, char* crypt_hwid, - char* signature) +rdp_lic_send_authresp(struct rdp_lic *self, char *token, char *crypt_hwid, + char *signature) { - int sec_flags; - int length; - struct stream* s; + int sec_flags; + int length; + struct stream *s; - sec_flags = SEC_LICENCE_NEG; - length = 58; - make_stream(s); - init_stream(s, 8192); - rdp_sec_init(self->sec_layer, s, sec_flags); - out_uint8(s, LICENCE_TAG_AUTHRESP); - out_uint8(s, 2); /* version */ - out_uint16_le(s, length); - out_uint16_le(s, 1); - out_uint16_le(s, LICENCE_TOKEN_SIZE); - out_uint8p(s, token, LICENCE_TOKEN_SIZE); - out_uint16_le(s, 1); - out_uint16_le(s, LICENCE_HWID_SIZE); - out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE); - out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); - s_mark_end(s); - rdp_sec_send(self->sec_layer, s, sec_flags); - free_stream(s); + sec_flags = SEC_LICENCE_NEG; + length = 58; + make_stream(s); + init_stream(s, 8192); + rdp_sec_init(self->sec_layer, s, sec_flags); + out_uint8(s, LICENCE_TAG_AUTHRESP); + out_uint8(s, 2); /* version */ + out_uint16_le(s, length); + out_uint16_le(s, 1); + out_uint16_le(s, LICENCE_TOKEN_SIZE); + out_uint8p(s, token, LICENCE_TOKEN_SIZE); + out_uint16_le(s, 1); + out_uint16_le(s, LICENCE_HWID_SIZE); + out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE); + out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); + s_mark_end(s); + rdp_sec_send(self->sec_layer, s, sec_flags); + free_stream(s); } /*****************************************************************************/ /* Parse an authentication request packet */ /* returns boolean */ static int APP_CC -rdp_lic_parse_authreq(struct rdp_lic* self, struct stream* s, - char** token, char** signature) +rdp_lic_parse_authreq(struct rdp_lic *self, struct stream *s, + char **token, char **signature) { - int tokenlen; + int tokenlen; - in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */ - in_uint16_le(s, tokenlen); - if (tokenlen != LICENCE_TOKEN_SIZE) - { - /* error("token len %d\n", tokenlen); */ - return 0; - } - in_uint8p(s, *token, tokenlen); - in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE); - return s_check_end(s); + in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */ + in_uint16_le(s, tokenlen); + + if (tokenlen != LICENCE_TOKEN_SIZE) + { + /* error("token len %d\n", tokenlen); */ + return 0; + } + + in_uint8p(s, *token, tokenlen); + in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE); + return s_check_end(s); } /*****************************************************************************/ /* Process an authentication request packet */ static void APP_CC -rdp_lic_process_authreq(struct rdp_lic* self, struct stream* s) +rdp_lic_process_authreq(struct rdp_lic *self, struct stream *s) { - char* in_token; - char* in_sig; - char out_token[LICENCE_TOKEN_SIZE]; - char decrypt_token[LICENCE_TOKEN_SIZE]; - char hwid[LICENCE_HWID_SIZE]; - char crypt_hwid[LICENCE_HWID_SIZE]; - char sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE]; - char out_sig[LICENCE_SIGNATURE_SIZE]; - void* crypt_key; + char *in_token; + char *in_sig; + char out_token[LICENCE_TOKEN_SIZE]; + char decrypt_token[LICENCE_TOKEN_SIZE]; + char hwid[LICENCE_HWID_SIZE]; + char crypt_hwid[LICENCE_HWID_SIZE]; + char sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE]; + char out_sig[LICENCE_SIGNATURE_SIZE]; + void *crypt_key; - in_token = 0; - in_sig = 0; - /* Parse incoming packet and save the encrypted token */ - rdp_lic_parse_authreq(self, s, &in_token, &in_sig); - g_memcpy(out_token, in_token, LICENCE_TOKEN_SIZE); - /* Decrypt the token. It should read TEST in Unicode. */ - crypt_key = ssl_rc4_info_create(); - ssl_rc4_set_key(crypt_key, self->licence_key, 16); - g_memcpy(decrypt_token, in_token, LICENCE_TOKEN_SIZE); - ssl_rc4_crypt(crypt_key, decrypt_token, LICENCE_TOKEN_SIZE); - /* Generate a signature for a buffer of token and HWID */ - rdp_lic_generate_hwid(self, hwid); - g_memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE); - g_memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE); - rdp_sec_sign(out_sig, 16, self->licence_sign_key, 16, sealed_buffer, - sizeof(sealed_buffer)); - /* Now encrypt the HWID */ - ssl_rc4_set_key(crypt_key, self->licence_key, 16); - g_memcpy(crypt_hwid, hwid, LICENCE_HWID_SIZE); - ssl_rc4_crypt(crypt_key, crypt_hwid, LICENCE_HWID_SIZE); - rdp_lic_send_authresp(self, out_token, crypt_hwid, out_sig); - ssl_rc4_info_delete(crypt_key); + in_token = 0; + in_sig = 0; + /* Parse incoming packet and save the encrypted token */ + rdp_lic_parse_authreq(self, s, &in_token, &in_sig); + g_memcpy(out_token, in_token, LICENCE_TOKEN_SIZE); + /* Decrypt the token. It should read TEST in Unicode. */ + crypt_key = ssl_rc4_info_create(); + ssl_rc4_set_key(crypt_key, self->licence_key, 16); + g_memcpy(decrypt_token, in_token, LICENCE_TOKEN_SIZE); + ssl_rc4_crypt(crypt_key, decrypt_token, LICENCE_TOKEN_SIZE); + /* Generate a signature for a buffer of token and HWID */ + rdp_lic_generate_hwid(self, hwid); + g_memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE); + g_memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE); + rdp_sec_sign(out_sig, 16, self->licence_sign_key, 16, sealed_buffer, + sizeof(sealed_buffer)); + /* Now encrypt the HWID */ + ssl_rc4_set_key(crypt_key, self->licence_key, 16); + g_memcpy(crypt_hwid, hwid, LICENCE_HWID_SIZE); + ssl_rc4_crypt(crypt_key, crypt_hwid, LICENCE_HWID_SIZE); + rdp_lic_send_authresp(self, out_token, crypt_hwid, out_sig); + ssl_rc4_info_delete(crypt_key); } /*****************************************************************************/ /* Process an licence issue packet */ static void APP_CC -rdp_lic_process_issue(struct rdp_lic* self, struct stream* s) +rdp_lic_process_issue(struct rdp_lic *self, struct stream *s) { - void* crypt_key; - int length; - int check; - int i; + void *crypt_key; + int length; + int check; + int i; + + in_uint8s(s, 2); /* 3d 45 - unknown */ + in_uint16_le(s, length); - in_uint8s(s, 2); /* 3d 45 - unknown */ - in_uint16_le(s, length); - if (!s_check_rem(s, length)) - { - return; - } - crypt_key = ssl_rc4_info_create(); - ssl_rc4_set_key(crypt_key, self->licence_key, 16); - ssl_rc4_crypt(crypt_key, s->p, length); - ssl_rc4_info_delete(crypt_key); - in_uint16_le(s, check); - if (check != 0) - { - return; - } - self->licence_issued = 1; - in_uint8s(s, 2); /* pad */ - /* advance to fourth string */ - length = 0; - for (i = 0; i < 4; i++) - { - in_uint8s(s, length); - in_uint32_le(s, length); if (!s_check_rem(s, length)) { - return; + return; } - } - /* todo save_licence(s->p, length); */ + + crypt_key = ssl_rc4_info_create(); + ssl_rc4_set_key(crypt_key, self->licence_key, 16); + ssl_rc4_crypt(crypt_key, s->p, length); + ssl_rc4_info_delete(crypt_key); + in_uint16_le(s, check); + + if (check != 0) + { + return; + } + + self->licence_issued = 1; + in_uint8s(s, 2); /* pad */ + /* advance to fourth string */ + length = 0; + + for (i = 0; i < 4; i++) + { + in_uint8s(s, length); + in_uint32_le(s, length); + + if (!s_check_rem(s, length)) + { + return; + } + } + + /* todo save_licence(s->p, length); */ } /******************************************************************************/ /* Process a licence packet */ void APP_CC -rdp_lic_process(struct rdp_lic* self, struct stream* s) +rdp_lic_process(struct rdp_lic *self, struct stream *s) { - int tag; + int tag; - in_uint8(s, tag); - in_uint8s(s, 3); /* version, length */ - switch (tag) - { - case LICENCE_TAG_DEMAND: - rdp_lic_process_demand(self, s); - break; - case LICENCE_TAG_AUTHREQ: - rdp_lic_process_authreq(self, s); - break; - case LICENCE_TAG_ISSUE: - rdp_lic_process_issue(self, s); - break; - case LICENCE_TAG_REISSUE: - case LICENCE_TAG_RESULT: - break; - default: - break; - /* todo unimpl("licence tag 0x%x\n", tag); */ - } + in_uint8(s, tag); + in_uint8s(s, 3); /* version, length */ + + switch (tag) + { + case LICENCE_TAG_DEMAND: + rdp_lic_process_demand(self, s); + break; + case LICENCE_TAG_AUTHREQ: + rdp_lic_process_authreq(self, s); + break; + case LICENCE_TAG_ISSUE: + rdp_lic_process_issue(self, s); + break; + case LICENCE_TAG_REISSUE: + case LICENCE_TAG_RESULT: + break; + default: + break; + /* todo unimpl("licence tag 0x%x\n", tag); */ + } } diff --git a/rdp/rdp_mcs.c b/rdp/rdp_mcs.c index 4b8993da..3f5162f3 100644 --- a/rdp/rdp_mcs.c +++ b/rdp/rdp_mcs.c @@ -1,562 +1,628 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - librdp mcs layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * librdp mcs layer + */ #include "rdp.h" /*****************************************************************************/ -struct rdp_mcs* APP_CC -rdp_mcs_create(struct rdp_sec* owner, - struct stream* client_mcs_data, - struct stream* server_mcs_data) +struct rdp_mcs *APP_CC +rdp_mcs_create(struct rdp_sec *owner, + struct stream *client_mcs_data, + struct stream *server_mcs_data) { - struct rdp_mcs* self; + struct rdp_mcs *self; - self = (struct rdp_mcs*)g_malloc(sizeof(struct rdp_mcs), 1); - self->sec_layer = owner; - self->userid = 1; - self->client_mcs_data = client_mcs_data; - self->server_mcs_data = server_mcs_data; - self->iso_layer = rdp_iso_create(self); - return self; + self = (struct rdp_mcs *)g_malloc(sizeof(struct rdp_mcs), 1); + self->sec_layer = owner; + self->userid = 1; + self->client_mcs_data = client_mcs_data; + self->server_mcs_data = server_mcs_data; + self->iso_layer = rdp_iso_create(self); + return self; } /*****************************************************************************/ void APP_CC -rdp_mcs_delete(struct rdp_mcs* self) +rdp_mcs_delete(struct rdp_mcs *self) { - if (self == 0) - { - return; - } - rdp_iso_delete(self->iso_layer); - g_free(self); -} - -/*****************************************************************************/ -/* returns error */ -int APP_CC -rdp_mcs_recv(struct rdp_mcs* self, struct stream* s, int* chan) -{ - int appid; - int opcode; - int len; - - DEBUG((" in rdp_mcs_recv")); - if (rdp_iso_recv(self->iso_layer, s) != 0) - { - return 1; - } - in_uint8(s, opcode); - appid = opcode >> 2; - if (appid != MCS_SDIN) - { - DEBUG((" out rdp_mcs_recv error")); - return 1; - } - in_uint8s(s, 2); - in_uint16_be(s, *chan); - in_uint8s(s, 1); - in_uint8(s, len); - if (len & 0x80) - { - in_uint8s(s, 1); - } - DEBUG((" out rdp_mcs_recv")); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_ber_out_header(struct rdp_mcs* self, struct stream* s, - int tag_val, int len) -{ - if (tag_val > 0xff) - { - out_uint16_be(s, tag_val); - } - else - { - out_uint8(s, tag_val); - } - if (len >= 0x80) - { - out_uint8(s, 0x82); - out_uint16_be(s, len); - } - else - { - out_uint8(s, len); - } - return 0; -} - -#if 0 -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_ber_out_int8(struct rdp_mcs* self, struct stream* s, int value) -{ - rdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); - out_uint8(s, value); - return 0; -} -#endif - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_ber_out_int16(struct rdp_mcs* self, struct stream* s, int value) -{ - rdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 2); - out_uint8(s, (value >> 8)); - out_uint8(s, value); - return 0; -} - -#if 0 -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_ber_out_int24(struct rdp_mcs* self, struct stream* s, int value) -{ - rdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 3); - out_uint8(s, (value >> 16)); - out_uint8(s, (value >> 8)); - out_uint8(s, value); - return 0; -} -#endif - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_out_domain_params(struct rdp_mcs* self, struct stream* s, - int max_channels, - int max_users, int max_tokens, - int max_pdu_size) -{ - rdp_mcs_ber_out_header(self, s, MCS_TAG_DOMAIN_PARAMS, 32); - rdp_mcs_ber_out_int16(self, s, max_channels); - rdp_mcs_ber_out_int16(self, s, max_users); - rdp_mcs_ber_out_int16(self, s, max_tokens); - rdp_mcs_ber_out_int16(self, s, 1); - rdp_mcs_ber_out_int16(self, s, 0); - rdp_mcs_ber_out_int16(self, s, 1); - rdp_mcs_ber_out_int16(self, s, max_pdu_size); - rdp_mcs_ber_out_int16(self, s, 2); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_send_connection_initial(struct rdp_mcs* self) -{ - int data_len; - int len; - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - data_len = self->client_mcs_data->end - self->client_mcs_data->data; - len = 7 + 3 * 34 + 4 + data_len; - if (rdp_iso_init(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - rdp_mcs_ber_out_header(self, s, MCS_CONNECT_INITIAL, len); - rdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, 0); /* calling domain */ - rdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, 0); /* called domain */ - rdp_mcs_ber_out_header(self, s, BER_TAG_BOOLEAN, 1); - out_uint8(s, 0xff); /* upward flag */ - rdp_mcs_out_domain_params(self, s, 2, 2, 0, 0xffff); /* target params */ - rdp_mcs_out_domain_params(self, s, 1, 1, 1, 0x420); /* min params */ - rdp_mcs_out_domain_params(self, s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */ - rdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, data_len); - out_uint8p(s, self->client_mcs_data->data, data_len); - s_mark_end(s); - if (rdp_iso_send(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_ber_parse_header(struct rdp_mcs* self, struct stream* s, - int tag_val, int* len) -{ - int tag; - int l; - int i; - - if (tag_val > 0xff) - { - in_uint16_be(s, tag); - } - else - { - in_uint8(s, tag); - } - if (tag != tag_val) - { - return 1; - } - in_uint8(s, l); - if (l & 0x80) - { - l = l & ~0x80; - *len = 0; - while (l > 0) + if (self == 0) { - in_uint8(s, i); - *len = (*len << 8) | i; - l--; + return; } - } - else - { - *len = l; - } - if (s_check(s)) - { - return 0; - } - else - { - return 1; - } -} -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_parse_domain_params(struct rdp_mcs* self, struct stream* s) -{ - int len; - - if (rdp_mcs_ber_parse_header(self, s, MCS_TAG_DOMAIN_PARAMS, &len) != 0) - { - return 1; - } - in_uint8s(s, len); - if (s_check(s)) - { - return 0; - } - else - { - return 1; - } -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_recv_connection_response(struct rdp_mcs* self) -{ - int len; - int res; - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (rdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - rdp_mcs_ber_parse_header(self, s, MCS_CONNECT_RESPONSE, &len); - rdp_mcs_ber_parse_header(self, s, BER_TAG_RESULT, &len); - in_uint8(s, res); - if (res != 0) - { - free_stream(s); - return 1; - } - rdp_mcs_ber_parse_header(self, s, BER_TAG_INTEGER, &len); - in_uint8s(s, len); /* connect id */ - rdp_mcs_parse_domain_params(self, s); - rdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len); - if (len > self->server_mcs_data->size) - { - len = self->server_mcs_data->size; - } - in_uint8a(s, self->server_mcs_data->data, len); - self->server_mcs_data->p = self->server_mcs_data->data; - self->server_mcs_data->end = self->server_mcs_data->data + len; - if (s_check_end(s)) - { - free_stream(s); - return 0; - } - else - { - free_stream(s); - return 1; - } -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_send_edrq(struct rdp_mcs* self) -{ - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (rdp_iso_init(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8(s, (MCS_EDRQ << 2)); - out_uint16_be(s, 0x100); /* height */ - out_uint16_be(s, 0x100); /* interval */ - s_mark_end(s); - if (rdp_iso_send(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_send_aurq(struct rdp_mcs* self) -{ - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (rdp_iso_init(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8(s, (MCS_AURQ << 2)); - s_mark_end(s); - if (rdp_iso_send(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_recv_aucf(struct rdp_mcs* self) -{ - int opcode; - int res; - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (rdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_AUCF) - { - free_stream(s); - return 1; - } - in_uint8(s, res); - if (res != 0) - { - free_stream(s); - return 1; - } - if (opcode & 2) - { - in_uint16_be(s, self->userid); - } - if (!(s_check_end(s))) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_send_cjrq(struct rdp_mcs* self, int chanid) -{ - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (rdp_iso_init(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8(s, (MCS_CJRQ << 2)); - out_uint16_be(s, self->userid); - out_uint16_be(s, chanid); - s_mark_end(s); - if (rdp_iso_send(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; -} - -/*****************************************************************************/ -/* returns error */ -static int APP_CC -rdp_mcs_recv_cjcf(struct rdp_mcs* self) -{ - int opcode; - int res; - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - if (rdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_CJCF) - { - free_stream(s); - return 1; - } - in_uint8(s, res); - if (res != 0) - { - free_stream(s); - return 1; - } - in_uint8s(s, 4); /* mcs_userid, req_chanid */ - if (opcode & 2) - { - in_uint8s(s, 2); /* join_chanid */ - } - if (!(s_check_end(s))) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; + rdp_iso_delete(self->iso_layer); + g_free(self); } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_mcs_connect(struct rdp_mcs* self, char* ip, char* port) +rdp_mcs_recv(struct rdp_mcs *self, struct stream *s, int *chan) { - DEBUG((" in rdp_mcs_connect")); - if (rdp_iso_connect(self->iso_layer, ip, port) != 0) - { - DEBUG((" out rdp_mcs_connect error rdp_iso_connect failed")); - return 1; - } - rdp_mcs_send_connection_initial(self); - if (rdp_mcs_recv_connection_response(self) != 0) - { - rdp_iso_disconnect(self->iso_layer); - DEBUG((" out rdp_mcs_connect error rdp_mcs_recv_connection_response \ + int appid; + int opcode; + int len; + + DEBUG((" in rdp_mcs_recv")); + + if (rdp_iso_recv(self->iso_layer, s) != 0) + { + return 1; + } + + in_uint8(s, opcode); + appid = opcode >> 2; + + if (appid != MCS_SDIN) + { + DEBUG((" out rdp_mcs_recv error")); + return 1; + } + + in_uint8s(s, 2); + in_uint16_be(s, *chan); + in_uint8s(s, 1); + in_uint8(s, len); + + if (len & 0x80) + { + in_uint8s(s, 1); + } + + DEBUG((" out rdp_mcs_recv")); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_ber_out_header(struct rdp_mcs *self, struct stream *s, + int tag_val, int len) +{ + if (tag_val > 0xff) + { + out_uint16_be(s, tag_val); + } + else + { + out_uint8(s, tag_val); + } + + if (len >= 0x80) + { + out_uint8(s, 0x82); + out_uint16_be(s, len); + } + else + { + out_uint8(s, len); + } + + return 0; +} + +#if 0 +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_ber_out_int8(struct rdp_mcs *self, struct stream *s, int value) +{ + rdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); + out_uint8(s, value); + return 0; +} +#endif + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_ber_out_int16(struct rdp_mcs *self, struct stream *s, int value) +{ + rdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 2); + out_uint8(s, (value >> 8)); + out_uint8(s, value); + return 0; +} + +#if 0 +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_ber_out_int24(struct rdp_mcs *self, struct stream *s, int value) +{ + rdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 3); + out_uint8(s, (value >> 16)); + out_uint8(s, (value >> 8)); + out_uint8(s, value); + return 0; +} +#endif + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_out_domain_params(struct rdp_mcs *self, struct stream *s, + int max_channels, + int max_users, int max_tokens, + int max_pdu_size) +{ + rdp_mcs_ber_out_header(self, s, MCS_TAG_DOMAIN_PARAMS, 32); + rdp_mcs_ber_out_int16(self, s, max_channels); + rdp_mcs_ber_out_int16(self, s, max_users); + rdp_mcs_ber_out_int16(self, s, max_tokens); + rdp_mcs_ber_out_int16(self, s, 1); + rdp_mcs_ber_out_int16(self, s, 0); + rdp_mcs_ber_out_int16(self, s, 1); + rdp_mcs_ber_out_int16(self, s, max_pdu_size); + rdp_mcs_ber_out_int16(self, s, 2); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_send_connection_initial(struct rdp_mcs *self) +{ + int data_len; + int len; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + data_len = self->client_mcs_data->end - self->client_mcs_data->data; + len = 7 + 3 * 34 + 4 + data_len; + + if (rdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + rdp_mcs_ber_out_header(self, s, MCS_CONNECT_INITIAL, len); + rdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, 0); /* calling domain */ + rdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, 0); /* called domain */ + rdp_mcs_ber_out_header(self, s, BER_TAG_BOOLEAN, 1); + out_uint8(s, 0xff); /* upward flag */ + rdp_mcs_out_domain_params(self, s, 2, 2, 0, 0xffff); /* target params */ + rdp_mcs_out_domain_params(self, s, 1, 1, 1, 0x420); /* min params */ + rdp_mcs_out_domain_params(self, s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */ + rdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, data_len); + out_uint8p(s, self->client_mcs_data->data, data_len); + s_mark_end(s); + + if (rdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_ber_parse_header(struct rdp_mcs *self, struct stream *s, + int tag_val, int *len) +{ + int tag; + int l; + int i; + + if (tag_val > 0xff) + { + in_uint16_be(s, tag); + } + else + { + in_uint8(s, tag); + } + + if (tag != tag_val) + { + return 1; + } + + in_uint8(s, l); + + if (l & 0x80) + { + l = l & ~0x80; + *len = 0; + + while (l > 0) + { + in_uint8(s, i); + *len = (*len << 8) | i; + l--; + } + } + else + { + *len = l; + } + + if (s_check(s)) + { + return 0; + } + else + { + return 1; + } +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_parse_domain_params(struct rdp_mcs *self, struct stream *s) +{ + int len; + + if (rdp_mcs_ber_parse_header(self, s, MCS_TAG_DOMAIN_PARAMS, &len) != 0) + { + return 1; + } + + in_uint8s(s, len); + + if (s_check(s)) + { + return 0; + } + else + { + return 1; + } +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_recv_connection_response(struct rdp_mcs *self) +{ + int len; + int res; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (rdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + rdp_mcs_ber_parse_header(self, s, MCS_CONNECT_RESPONSE, &len); + rdp_mcs_ber_parse_header(self, s, BER_TAG_RESULT, &len); + in_uint8(s, res); + + if (res != 0) + { + free_stream(s); + return 1; + } + + rdp_mcs_ber_parse_header(self, s, BER_TAG_INTEGER, &len); + in_uint8s(s, len); /* connect id */ + rdp_mcs_parse_domain_params(self, s); + rdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len); + + if (len > self->server_mcs_data->size) + { + len = self->server_mcs_data->size; + } + + in_uint8a(s, self->server_mcs_data->data, len); + self->server_mcs_data->p = self->server_mcs_data->data; + self->server_mcs_data->end = self->server_mcs_data->data + len; + + if (s_check_end(s)) + { + free_stream(s); + return 0; + } + else + { + free_stream(s); + return 1; + } +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_send_edrq(struct rdp_mcs *self) +{ + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (rdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8(s, (MCS_EDRQ << 2)); + out_uint16_be(s, 0x100); /* height */ + out_uint16_be(s, 0x100); /* interval */ + s_mark_end(s); + + if (rdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_send_aurq(struct rdp_mcs *self) +{ + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (rdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8(s, (MCS_AURQ << 2)); + s_mark_end(s); + + if (rdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_recv_aucf(struct rdp_mcs *self) +{ + int opcode; + int res; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (rdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + in_uint8(s, opcode); + + if ((opcode >> 2) != MCS_AUCF) + { + free_stream(s); + return 1; + } + + in_uint8(s, res); + + if (res != 0) + { + free_stream(s); + return 1; + } + + if (opcode & 2) + { + in_uint16_be(s, self->userid); + } + + if (!(s_check_end(s))) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_send_cjrq(struct rdp_mcs *self, int chanid) +{ + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (rdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8(s, (MCS_CJRQ << 2)); + out_uint16_be(s, self->userid); + out_uint16_be(s, chanid); + s_mark_end(s); + + if (rdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_mcs_recv_cjcf(struct rdp_mcs *self) +{ + int opcode; + int res; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (rdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + in_uint8(s, opcode); + + if ((opcode >> 2) != MCS_CJCF) + { + free_stream(s); + return 1; + } + + in_uint8(s, res); + + if (res != 0) + { + free_stream(s); + return 1; + } + + in_uint8s(s, 4); /* mcs_userid, req_chanid */ + + if (opcode & 2) + { + in_uint8s(s, 2); /* join_chanid */ + } + + if (!(s_check_end(s))) + { + free_stream(s); + return 1; + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +rdp_mcs_connect(struct rdp_mcs *self, char *ip, char *port) +{ + DEBUG((" in rdp_mcs_connect")); + + if (rdp_iso_connect(self->iso_layer, ip, port) != 0) + { + DEBUG((" out rdp_mcs_connect error rdp_iso_connect failed")); + return 1; + } + + rdp_mcs_send_connection_initial(self); + + if (rdp_mcs_recv_connection_response(self) != 0) + { + rdp_iso_disconnect(self->iso_layer); + DEBUG((" out rdp_mcs_connect error rdp_mcs_recv_connection_response \ failed")); - return 1; - } - rdp_mcs_send_edrq(self); - rdp_mcs_send_aurq(self); - if (rdp_mcs_recv_aucf(self) != 0) - { - rdp_iso_disconnect(self->iso_layer); - DEBUG((" out rdp_mcs_connect error rdp_mcs_recv_aucf failed")); - return 1; - } - rdp_mcs_send_cjrq(self, self->userid + 1001); - if (rdp_mcs_recv_cjcf(self) != 0) - { - rdp_iso_disconnect(self->iso_layer); - DEBUG((" out rdp_mcs_connect error rdp_mcs_recv_cjcf 1 failed")); - return 1; - } - rdp_mcs_send_cjrq(self, MCS_GLOBAL_CHANNEL); - if (rdp_mcs_recv_cjcf(self) != 0) - { - rdp_iso_disconnect(self->iso_layer); - DEBUG((" out rdp_mcs_connect error rdp_mcs_recv_cjcf 2 failed")); - return 1; - } - DEBUG((" out rdp_mcs_connect")); - return 0; + return 1; + } + + rdp_mcs_send_edrq(self); + rdp_mcs_send_aurq(self); + + if (rdp_mcs_recv_aucf(self) != 0) + { + rdp_iso_disconnect(self->iso_layer); + DEBUG((" out rdp_mcs_connect error rdp_mcs_recv_aucf failed")); + return 1; + } + + rdp_mcs_send_cjrq(self, self->userid + 1001); + + if (rdp_mcs_recv_cjcf(self) != 0) + { + rdp_iso_disconnect(self->iso_layer); + DEBUG((" out rdp_mcs_connect error rdp_mcs_recv_cjcf 1 failed")); + return 1; + } + + rdp_mcs_send_cjrq(self, MCS_GLOBAL_CHANNEL); + + if (rdp_mcs_recv_cjcf(self) != 0) + { + rdp_iso_disconnect(self->iso_layer); + DEBUG((" out rdp_mcs_connect error rdp_mcs_recv_cjcf 2 failed")); + return 1; + } + + DEBUG((" out rdp_mcs_connect")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_mcs_init(struct rdp_mcs* self, struct stream* s) +rdp_mcs_init(struct rdp_mcs *self, struct stream *s) { - rdp_iso_init(self->iso_layer, s); - s_push_layer(s, mcs_hdr, 8); - return 0; + rdp_iso_init(self->iso_layer, s); + s_push_layer(s, mcs_hdr, 8); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_mcs_send(struct rdp_mcs* self, struct stream* s) +rdp_mcs_send(struct rdp_mcs *self, struct stream *s) { - int len; + int len; - s_pop_layer(s, mcs_hdr); - len = (s->end - s->p) - 8; - len = len | 0x8000; - out_uint8(s, MCS_SDRQ << 2); - out_uint16_be(s, self->userid); - out_uint16_be(s, MCS_GLOBAL_CHANNEL); - out_uint8(s, 0x70); - out_uint16_be(s, len); - if (rdp_iso_send(self->iso_layer, s) != 0) - { - return 1; - } - return 0; + s_pop_layer(s, mcs_hdr); + len = (s->end - s->p) - 8; + len = len | 0x8000; + out_uint8(s, MCS_SDRQ << 2); + out_uint16_be(s, self->userid); + out_uint16_be(s, MCS_GLOBAL_CHANNEL); + out_uint8(s, 0x70); + out_uint16_be(s, len); + + if (rdp_iso_send(self->iso_layer, s) != 0) + { + return 1; + } + + return 0; } diff --git a/rdp/rdp_orders.c b/rdp/rdp_orders.c index c0da6c35..b686c925 100644 --- a/rdp/rdp_orders.c +++ b/rdp/rdp_orders.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - librdp orders - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ibrdp orders + */ #include "rdp.h" @@ -27,1506 +25,1668 @@ #endif /*****************************************************************************/ -struct rdp_orders* APP_CC -rdp_orders_create(struct rdp_rdp* owner) +struct rdp_orders *APP_CC +rdp_orders_create(struct rdp_rdp *owner) { - struct rdp_orders* self = (struct rdp_orders *)NULL; + struct rdp_orders *self = (struct rdp_orders *)NULL; - self = (struct rdp_orders*)g_malloc(sizeof(struct rdp_orders), 1); - self->rdp_layer = owner; - return self; + self = (struct rdp_orders *)g_malloc(sizeof(struct rdp_orders), 1); + self->rdp_layer = owner; + return self; } /*****************************************************************************/ void APP_CC -rdp_orders_delete(struct rdp_orders* self) +rdp_orders_delete(struct rdp_orders *self) { - int i = 0; - int j = 0; + int i = 0; + int j = 0; - if (self == 0) - { - return; - } - /* free the colormap cache */ - for (i = 0; i < 6; i++) - { - g_free(self->cache_colormap[i]); - } - /* free the bitmap cache */ - for (i = 0; i < 3; i++) - { - for (j = 0; j < 600; j++) + if (self == 0) { - if (self->cache_bitmap[i][j] != 0) - { - g_free(self->cache_bitmap[i][j]->data); - } - g_free(self->cache_bitmap[i][j]); + return; } - } - g_free(self); + + /* free the colormap cache */ + for (i = 0; i < 6; i++) + { + g_free(self->cache_colormap[i]); + } + + /* free the bitmap cache */ + for (i = 0; i < 3; i++) + { + for (j = 0; j < 600; j++) + { + if (self->cache_bitmap[i][j] != 0) + { + g_free(self->cache_bitmap[i][j]->data); + } + + g_free(self->cache_bitmap[i][j]); + } + } + + g_free(self); } /*****************************************************************************/ void APP_CC -rdp_orders_reset_state(struct rdp_orders* self) +rdp_orders_reset_state(struct rdp_orders *self) { - g_memset(&self->state, 0, sizeof(self->state)); + g_memset(&self->state, 0, sizeof(self->state)); } /*****************************************************************************/ /* Read field indicating which parameters are present */ static void APP_CC -rdp_orders_in_present(struct stream* s, int* present, +rdp_orders_in_present(struct stream *s, int *present, int flags, int size) { - int bits = 0; - int i = 0; + int bits = 0; + int i = 0; - if (flags & RDP_ORDER_SMALL) - { - size--; - } - if (flags & RDP_ORDER_TINY) - { - if (size < 2) + if (flags & RDP_ORDER_SMALL) { - size = 0; + size--; } - else + + if (flags & RDP_ORDER_TINY) { - size -= 2; + if (size < 2) + { + size = 0; + } + else + { + size -= 2; + } + } + + *present = 0; + + for (i = 0; i < size; i++) + { + in_uint8(s, bits); + *present |= bits << (i * 8); } - } - *present = 0; - for (i = 0; i < size; i++) - { - in_uint8(s, bits); - *present |= bits << (i * 8); - } } /*****************************************************************************/ /* Read a co-ordinate (16-bit, or 8-bit delta) */ static void APP_CC -rdp_orders_in_coord(struct stream* s, int* coord, int delta) +rdp_orders_in_coord(struct stream *s, int *coord, int delta) { - int change = 0; + int change = 0; - if (delta) - { - in_sint8(s, change); - *coord += change; - } - else - { - in_sint16_le(s, *coord); - } + if (delta) + { + in_sint8(s, change); + *coord += change; + } + else + { + in_sint16_le(s, *coord); + } } /*****************************************************************************/ /* Parse bounds information */ static void APP_CC -rdp_orders_parse_bounds(struct rdp_orders* self, struct stream* s) +rdp_orders_parse_bounds(struct rdp_orders *self, struct stream *s) { - int present = 0; + int present = 0; - in_uint8(s, present); - if (present & 1) - { - rdp_orders_in_coord(s, &self->state.clip_left, 0); - } - else if (present & 16) - { - rdp_orders_in_coord(s, &self->state.clip_left, 1); - } - if (present & 2) - { - rdp_orders_in_coord(s, &self->state.clip_top, 0); - } - else if (present & 32) - { - rdp_orders_in_coord(s, &self->state.clip_top, 1); - } - if (present & 4) - { - rdp_orders_in_coord(s, &self->state.clip_right, 0); - } - else if (present & 64) - { - rdp_orders_in_coord(s, &self->state.clip_right, 1); - } - if (present & 8) - { - rdp_orders_in_coord(s, &self->state.clip_bottom, 0); - } - else if (present & 128) - { - rdp_orders_in_coord(s, &self->state.clip_bottom, 1); - } + in_uint8(s, present); + + if (present & 1) + { + rdp_orders_in_coord(s, &self->state.clip_left, 0); + } + else if (present & 16) + { + rdp_orders_in_coord(s, &self->state.clip_left, 1); + } + + if (present & 2) + { + rdp_orders_in_coord(s, &self->state.clip_top, 0); + } + else if (present & 32) + { + rdp_orders_in_coord(s, &self->state.clip_top, 1); + } + + if (present & 4) + { + rdp_orders_in_coord(s, &self->state.clip_right, 0); + } + else if (present & 64) + { + rdp_orders_in_coord(s, &self->state.clip_right, 1); + } + + if (present & 8) + { + rdp_orders_in_coord(s, &self->state.clip_bottom, 0); + } + else if (present & 128) + { + rdp_orders_in_coord(s, &self->state.clip_bottom, 1); + } } /*****************************************************************************/ /* Process a colormap cache order */ static void APP_CC -rdp_orders_process_colcache(struct rdp_orders* self, struct stream* s, +rdp_orders_process_colcache(struct rdp_orders *self, struct stream *s, int flags) { - struct rdp_colormap* colormap = (struct rdp_colormap *)NULL; - struct stream* rec_s = (struct stream *)NULL; - int cache_id = 0; - int i = 0; + struct rdp_colormap *colormap = (struct rdp_colormap *)NULL; + struct stream *rec_s = (struct stream *)NULL; + int cache_id = 0; + int i = 0; - colormap = (struct rdp_colormap*)g_malloc(sizeof(struct rdp_colormap), 1); - in_uint8(s, cache_id); - in_uint16_le(s, colormap->ncolors); - for (i = 0; i < colormap->ncolors; i++) - { - in_uint32_le(s, colormap->colors[i]); - } - g_free(self->cache_colormap[cache_id]); - self->cache_colormap[cache_id] = colormap; - if (self->rdp_layer->rec_mode) - { - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, 4096); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 10); - out_uint8(rec_s, cache_id); - for (i = 0; i < 256; i++) + colormap = (struct rdp_colormap *)g_malloc(sizeof(struct rdp_colormap), 1); + in_uint8(s, cache_id); + in_uint16_le(s, colormap->ncolors); + + for (i = 0; i < colormap->ncolors; i++) { - out_uint32_le(rec_s, colormap->colors[i]); + in_uint32_le(s, colormap->colors[i]); + } + + g_free(self->cache_colormap[cache_id]); + self->cache_colormap[cache_id] = colormap; + + if (self->rdp_layer->rec_mode) + { + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, 4096); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 10); + out_uint8(rec_s, cache_id); + + for (i = 0; i < 256; i++) + { + out_uint32_le(rec_s, colormap->colors[i]); + } + + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); } - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); - } } /*****************************************************************************/ /* Process a raw bitmap cache order */ static void APP_CC -rdp_orders_process_raw_bmpcache(struct rdp_orders* self, struct stream* s, +rdp_orders_process_raw_bmpcache(struct rdp_orders *self, struct stream *s, int flags) { - int cache_idx = 0; - int bufsize = 0; - int cache_id = 0; - int width = 0; - int height = 0; - int bpp = 0; - int Bpp = 0; - int x = 0; - int y = 0; - char* inverted = (char *)NULL; - char* dst = (char *)NULL; - struct rdp_bitmap* bitmap = (struct rdp_bitmap *)NULL; - struct stream* rec_s = (struct stream *)NULL; + int cache_idx = 0; + int bufsize = 0; + int cache_id = 0; + int width = 0; + int height = 0; + int bpp = 0; + int Bpp = 0; + int x = 0; + int y = 0; + char *inverted = (char *)NULL; + char *dst = (char *)NULL; + struct rdp_bitmap *bitmap = (struct rdp_bitmap *)NULL; + struct stream *rec_s = (struct stream *)NULL; - in_uint8(s, cache_id); - in_uint8s(s, 1); - in_uint8(s, width); - in_uint8(s, height); - in_uint8(s, bpp); - Bpp = (bpp + 7) / 8; - in_uint16_le(s, bufsize); - in_uint16_le(s, cache_idx); - inverted = (char*)g_malloc(width * height * Bpp, 0); - for (y = 0; y < height; y++) - { - dst = inverted + (((height - y) - 1) * (width * Bpp)); - if (Bpp == 1) + in_uint8(s, cache_id); + in_uint8s(s, 1); + in_uint8(s, width); + in_uint8(s, height); + in_uint8(s, bpp); + Bpp = (bpp + 7) / 8; + in_uint16_le(s, bufsize); + in_uint16_le(s, cache_idx); + inverted = (char *)g_malloc(width * height * Bpp, 0); + + for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) - { - in_uint8(s, dst[x]); - } + dst = inverted + (((height - y) - 1) * (width * Bpp)); + + if (Bpp == 1) + { + for (x = 0; x < width; x++) + { + in_uint8(s, dst[x]); + } + } + else if (Bpp == 2) + { + for (x = 0; x < width; x++) + { + in_uint16_le(s, ((tui16 *)dst)[x]); + } + } + else if (Bpp == 3) + { + for (x = 0; x < width; x++) + { + in_uint8(s, dst[x * 3 + 0]); + in_uint8(s, dst[x * 3 + 1]); + in_uint8(s, dst[x * 3 + 2]); + } + } } - else if (Bpp == 2) + + bitmap = (struct rdp_bitmap *)g_malloc(sizeof(struct rdp_bitmap), 0); + bitmap->width = width; + bitmap->height = height; + bitmap->bpp = bpp; + bitmap->data = inverted; + + if (self->cache_bitmap[cache_id][cache_idx] != 0) { - for (x = 0; x < width; x++) - { - in_uint16_le(s, ((tui16*)dst)[x]); - } + g_free(self->cache_bitmap[cache_id][cache_idx]->data); } - else if (Bpp == 3) + + g_free(self->cache_bitmap[cache_id][cache_idx]); + self->cache_bitmap[cache_id][cache_idx] = bitmap; + + if (self->rdp_layer->rec_mode) { - for (x = 0; x < width; x++) - { - in_uint8(s, dst[x * 3 + 0]); - in_uint8(s, dst[x * 3 + 1]); - in_uint8(s, dst[x * 3 + 2]); - } + y = width * height * Bpp; + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, y + 256); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 8); + out_uint8(rec_s, cache_id); + out_uint16_le(rec_s, cache_idx); + out_uint16_le(rec_s, width); + out_uint16_le(rec_s, height); + out_uint16_le(rec_s, y); + out_uint8a(rec_s, inverted, y); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); } - } - bitmap = (struct rdp_bitmap*)g_malloc(sizeof(struct rdp_bitmap), 0); - bitmap->width = width; - bitmap->height = height; - bitmap->bpp = bpp; - bitmap->data = inverted; - if (self->cache_bitmap[cache_id][cache_idx] != 0) - { - g_free(self->cache_bitmap[cache_id][cache_idx]->data); - } - g_free(self->cache_bitmap[cache_id][cache_idx]); - self->cache_bitmap[cache_id][cache_idx] = bitmap; - if (self->rdp_layer->rec_mode) - { - y = width * height * Bpp; - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, y + 256); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 8); - out_uint8(rec_s, cache_id); - out_uint16_le(rec_s, cache_idx); - out_uint16_le(rec_s, width); - out_uint16_le(rec_s, height); - out_uint16_le(rec_s, y); - out_uint8a(rec_s, inverted, y); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); - } } /*****************************************************************************/ /* Process a bitmap cache order */ static void APP_CC -rdp_orders_process_bmpcache(struct rdp_orders* self, struct stream* s, +rdp_orders_process_bmpcache(struct rdp_orders *self, struct stream *s, int flags) { - char* data = (char *)NULL; - char* bmpdata = (char *)NULL; - int cache_idx = 0; - int size = 0; - int cache_id = 0; - int width = 0; - int height = 0; - int bpp = 0; - int Bpp = 0; - int bufsize = 0; - int pad1 = 0; - int pad2 = 0; - int row_size = 0; - int final_size = 0; - struct rdp_bitmap* bitmap = (struct rdp_bitmap *)NULL; - struct stream* rec_s = (struct stream *)NULL; + char *data = (char *)NULL; + char *bmpdata = (char *)NULL; + int cache_idx = 0; + int size = 0; + int cache_id = 0; + int width = 0; + int height = 0; + int bpp = 0; + int Bpp = 0; + int bufsize = 0; + int pad1 = 0; + int pad2 = 0; + int row_size = 0; + int final_size = 0; + struct rdp_bitmap *bitmap = (struct rdp_bitmap *)NULL; + struct stream *rec_s = (struct stream *)NULL; - in_uint8(s, cache_id); - in_uint8(s, pad1); - in_uint8(s, width); - in_uint8(s, height); - in_uint8(s, bpp); - Bpp = (bpp + 7) / 8; - in_uint16_le(s, bufsize); - in_uint16_le(s, cache_idx); - if (flags & 1024) - { - size = bufsize; - } - else - { - in_uint16_le(s, pad2); - in_uint16_le(s, size); - in_uint16_le(s, row_size); - in_uint16_le(s, final_size); - } - in_uint8p(s, data, size); - bmpdata = (char*)g_malloc(width * height * Bpp, 0); - if (rdp_bitmap_decompress(bmpdata, width, height, data, size, Bpp)) - { - } - else - { - /* error */ - } - bitmap = (struct rdp_bitmap*)g_malloc(sizeof(struct rdp_bitmap), 0); - bitmap->width = width; - bitmap->height = height; - bitmap->bpp = bpp; - bitmap->data = bmpdata; - if (self->cache_bitmap[cache_id][cache_idx] != 0) - { - g_free(self->cache_bitmap[cache_id][cache_idx]->data); - } - g_free(self->cache_bitmap[cache_id][cache_idx]); - self->cache_bitmap[cache_id][cache_idx] = bitmap; - if (self->rdp_layer->rec_mode) - { - size = width * height * Bpp; - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, size + 256); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 8); - out_uint8(rec_s, cache_id); - out_uint16_le(rec_s, cache_idx); - out_uint16_le(rec_s, width); - out_uint16_le(rec_s, height); - out_uint16_le(rec_s, size); - out_uint8a(rec_s, bmpdata, size); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); - } + in_uint8(s, cache_id); + in_uint8(s, pad1); + in_uint8(s, width); + in_uint8(s, height); + in_uint8(s, bpp); + Bpp = (bpp + 7) / 8; + in_uint16_le(s, bufsize); + in_uint16_le(s, cache_idx); + + if (flags & 1024) + { + size = bufsize; + } + else + { + in_uint16_le(s, pad2); + in_uint16_le(s, size); + in_uint16_le(s, row_size); + in_uint16_le(s, final_size); + } + + in_uint8p(s, data, size); + bmpdata = (char *)g_malloc(width * height * Bpp, 0); + + if (rdp_bitmap_decompress(bmpdata, width, height, data, size, Bpp)) + { + } + else + { + /* error */ + } + + bitmap = (struct rdp_bitmap *)g_malloc(sizeof(struct rdp_bitmap), 0); + bitmap->width = width; + bitmap->height = height; + bitmap->bpp = bpp; + bitmap->data = bmpdata; + + if (self->cache_bitmap[cache_id][cache_idx] != 0) + { + g_free(self->cache_bitmap[cache_id][cache_idx]->data); + } + + g_free(self->cache_bitmap[cache_id][cache_idx]); + self->cache_bitmap[cache_id][cache_idx] = bitmap; + + if (self->rdp_layer->rec_mode) + { + size = width * height * Bpp; + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, size + 256); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 8); + out_uint8(rec_s, cache_id); + out_uint16_le(rec_s, cache_idx); + out_uint16_le(rec_s, width); + out_uint16_le(rec_s, height); + out_uint16_le(rec_s, size); + out_uint8a(rec_s, bmpdata, size); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); + } } /*****************************************************************************/ /* Process a font cache order */ static void APP_CC -rdp_orders_process_fontcache(struct rdp_orders* self, struct stream* s, +rdp_orders_process_fontcache(struct rdp_orders *self, struct stream *s, int flags) { - struct stream* rec_s = (struct stream *)NULL; - int font = 0; - int nglyphs = 0; - int character = 0; - int offset = 0; - int baseline = 0; - int width = 0; - int height = 0; - int i = 0; - int datasize = 0; - char* data = (char *)NULL; + struct stream *rec_s = (struct stream *)NULL; + int font = 0; + int nglyphs = 0; + int character = 0; + int offset = 0; + int baseline = 0; + int width = 0; + int height = 0; + int i = 0; + int datasize = 0; + char *data = (char *)NULL; - in_uint8(s, font); - in_uint8(s, nglyphs); - for (i = 0; i < nglyphs; i++) - { - in_uint16_le(s, character); - in_uint16_le(s, offset); - in_uint16_le(s, baseline); - in_uint16_le(s, width); - in_uint16_le(s, height); - datasize = (height * ((width + 7) / 8) + 3) & ~3; - in_uint8p(s, data, datasize); - self->rdp_layer->mod->server_add_char(self->rdp_layer->mod, font, - character, offset, baseline, - width, height, data); - if (self->rdp_layer->rec_mode) + in_uint8(s, font); + in_uint8(s, nglyphs); + + for (i = 0; i < nglyphs; i++) { - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, datasize + 256); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 9); - out_uint8(rec_s, font); - out_uint16_le(rec_s, character); - out_uint16_le(rec_s, offset); - out_uint16_le(rec_s, baseline); - out_uint16_le(rec_s, width); - out_uint16_le(rec_s, height); - out_uint16_le(rec_s, datasize); - out_uint8a(rec_s, data, datasize); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); + in_uint16_le(s, character); + in_uint16_le(s, offset); + in_uint16_le(s, baseline); + in_uint16_le(s, width); + in_uint16_le(s, height); + datasize = (height * ((width + 7) / 8) + 3) & ~3; + in_uint8p(s, data, datasize); + self->rdp_layer->mod->server_add_char(self->rdp_layer->mod, font, + character, offset, baseline, + width, height, data); + + if (self->rdp_layer->rec_mode) + { + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, datasize + 256); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 9); + out_uint8(rec_s, font); + out_uint16_le(rec_s, character); + out_uint16_le(rec_s, offset); + out_uint16_le(rec_s, baseline); + out_uint16_le(rec_s, width); + out_uint16_le(rec_s, height); + out_uint16_le(rec_s, datasize); + out_uint8a(rec_s, data, datasize); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); + } } - } } /*****************************************************************************/ /* Process a secondary order */ static int APP_CC -rdp_orders_process_secondary_order(struct rdp_orders* self, struct stream* s) +rdp_orders_process_secondary_order(struct rdp_orders *self, struct stream *s) { - short length = 0; - int flags = 0; - int type = 0; - char* next_order = (char *)NULL; + short length = 0; + int flags = 0; + int type = 0; + char *next_order = (char *)NULL; - in_uint16_le(s, length); - in_uint16_le(s, flags); - in_uint8(s, type); - next_order = s->p + length + 7; - switch (type) - { - case RDP_ORDER_COLCACHE: - rdp_orders_process_colcache(self, s, flags); - break; - case RDP_ORDER_RAW_BMPCACHE: - rdp_orders_process_raw_bmpcache(self, s, flags); - break; - case RDP_ORDER_BMPCACHE: - rdp_orders_process_bmpcache(self, s, flags); - break; - case RDP_ORDER_FONTCACHE: - rdp_orders_process_fontcache(self, s, flags); - break; - default: - /* error, unknown order */ - break; - } - s->p = next_order; - return 0; + in_uint16_le(s, length); + in_uint16_le(s, flags); + in_uint8(s, type); + next_order = s->p + length + 7; + + switch (type) + { + case RDP_ORDER_COLCACHE: + rdp_orders_process_colcache(self, s, flags); + break; + case RDP_ORDER_RAW_BMPCACHE: + rdp_orders_process_raw_bmpcache(self, s, flags); + break; + case RDP_ORDER_BMPCACHE: + rdp_orders_process_bmpcache(self, s, flags); + break; + case RDP_ORDER_FONTCACHE: + rdp_orders_process_fontcache(self, s, flags); + break; + default: + /* error, unknown order */ + break; + } + + s->p = next_order; + return 0; } /*****************************************************************************/ /* Read a color entry */ static void APP_CC -rdp_orders_in_color(struct stream* s, int* color) +rdp_orders_in_color(struct stream *s, int *color) { - int i = 0; + int i = 0; - in_uint8(s, i); - *color = i; - in_uint8(s, i); - *color |= i << 8; - in_uint8(s, i); - *color |= i << 16; + in_uint8(s, i); + *color = i; + in_uint8(s, i); + *color |= i << 8; + in_uint8(s, i); + *color |= i << 16; } /*****************************************************************************/ /* Parse a brush */ static void APP_CC -rdp_orders_parse_brush(struct stream* s, struct rdp_brush* brush, int present) +rdp_orders_parse_brush(struct stream *s, struct rdp_brush *brush, int present) { - if (present & 1) - { - in_uint8(s, brush->xorigin); - } - if (present & 2) - { - in_uint8(s, brush->yorigin); - } - if (present & 4) - { - in_uint8(s, brush->style); - } - if (present & 8) - { - in_uint8(s, brush->pattern[0]); - } - if (present & 16) - { - in_uint8a(s, brush->pattern + 1, 7); - } + if (present & 1) + { + in_uint8(s, brush->xorigin); + } + + if (present & 2) + { + in_uint8(s, brush->yorigin); + } + + if (present & 4) + { + in_uint8(s, brush->style); + } + + if (present & 8) + { + in_uint8(s, brush->pattern[0]); + } + + if (present & 16) + { + in_uint8a(s, brush->pattern + 1, 7); + } } /*****************************************************************************/ /* Parse a pen */ static void APP_CC -rdp_orders_parse_pen(struct stream* s, struct rdp_pen* pen, int present) +rdp_orders_parse_pen(struct stream *s, struct rdp_pen *pen, int present) { - if (present & 1) - { - in_uint8(s, pen->style); - } - if (present & 2) - { - in_uint8(s, pen->width); - } - if (present & 4) - { - rdp_orders_in_color(s, &pen->color); - } + if (present & 1) + { + in_uint8(s, pen->style); + } + + if (present & 2) + { + in_uint8(s, pen->width); + } + + if (present & 4) + { + rdp_orders_in_color(s, &pen->color); + } } /*****************************************************************************/ /* Process a text order */ static void APP_CC -rdp_orders_process_text2(struct rdp_orders* self, struct stream* s, +rdp_orders_process_text2(struct rdp_orders *self, struct stream *s, int present, int delta) { - int fgcolor = 0; - int bgcolor = 0; - struct stream* rec_s = (struct stream *)NULL; + int fgcolor = 0; + int bgcolor = 0; + struct stream *rec_s = (struct stream *)NULL; - if (present & 0x000001) - { - in_uint8(s, self->state.text_font); - } - if (present & 0x000002) - { - in_uint8(s, self->state.text_flags); - } - if (present & 0x000004) - { - in_uint8(s, self->state.text_opcode); - } - if (present & 0x000008) - { - in_uint8(s, self->state.text_mixmode); - } - if (present & 0x000010) - { - rdp_orders_in_color(s, &self->state.text_fgcolor); - } - if (present & 0x000020) - { - rdp_orders_in_color(s, &self->state.text_bgcolor); - } - if (present & 0x000040) - { - in_sint16_le(s, self->state.text_clipleft); - } - if (present & 0x000080) - { - in_sint16_le(s, self->state.text_cliptop); - } - if (present & 0x000100) - { - in_sint16_le(s, self->state.text_clipright); - } - if (present & 0x000200) - { - in_sint16_le(s, self->state.text_clipbottom); - } - if (present & 0x000400) - { - in_sint16_le(s, self->state.text_boxleft); - } - if (present & 0x000800) - { - in_sint16_le(s, self->state.text_boxtop); - } - if (present & 0x001000) - { - in_sint16_le(s, self->state.text_boxright); - } - if (present & 0x002000) - { - in_sint16_le(s, self->state.text_boxbottom); - } - rdp_orders_parse_brush(s, &self->state.text_brush, present >> 14); - if (present & 0x080000) - { - in_sint16_le(s, self->state.text_x); - } - if (present & 0x100000) - { - in_sint16_le(s, self->state.text_y); - } - if (present & 0x200000) - { - in_uint8(s, self->state.text_length); - in_uint8a(s, self->state.text_text, self->state.text_length); - } - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, - self->state.text_opcode); - fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, - self->rdp_layer->mod->xrdp_bpp, - self->state.text_fgcolor, - self->rdp_layer->colormap.colors); - self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); - bgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, - self->rdp_layer->mod->xrdp_bpp, - self->state.text_bgcolor, - self->rdp_layer->colormap.colors); - self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, bgcolor); - self->rdp_layer->mod->server_draw_text(self->rdp_layer->mod, - self->state.text_font, - self->state.text_flags, - self->state.text_mixmode, - self->state.text_clipleft, - self->state.text_cliptop, - self->state.text_clipright, - self->state.text_clipbottom, - self->state.text_boxleft, - self->state.text_boxtop, - self->state.text_boxright, - self->state.text_boxbottom, - self->state.text_x, - self->state.text_y, - self->state.text_text, - self->state.text_length); - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); - if (self->rdp_layer->rec_mode) - { - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, 512); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 7); - out_uint8(rec_s, self->state.text_font); - out_uint8(rec_s, self->state.text_flags); - out_uint8(rec_s, self->state.text_opcode); - out_uint8(rec_s, self->state.text_mixmode); - out_uint32_le(rec_s, self->state.text_fgcolor); - out_uint32_le(rec_s, self->state.text_bgcolor); - out_uint16_le(rec_s, self->state.text_clipleft); - out_uint16_le(rec_s, self->state.text_cliptop); - out_uint16_le(rec_s, self->state.text_clipright); - out_uint16_le(rec_s, self->state.text_clipbottom); - out_uint16_le(rec_s, self->state.text_boxleft); - out_uint16_le(rec_s, self->state.text_boxtop); - out_uint16_le(rec_s, self->state.text_boxright); - out_uint16_le(rec_s, self->state.text_boxbottom); - out_uint16_le(rec_s, self->state.text_x); - out_uint16_le(rec_s, self->state.text_y); - out_uint16_le(rec_s, self->state.text_length); - out_uint8a(rec_s, self->state.text_text, self->state.text_length); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); - } + if (present & 0x000001) + { + in_uint8(s, self->state.text_font); + } + + if (present & 0x000002) + { + in_uint8(s, self->state.text_flags); + } + + if (present & 0x000004) + { + in_uint8(s, self->state.text_opcode); + } + + if (present & 0x000008) + { + in_uint8(s, self->state.text_mixmode); + } + + if (present & 0x000010) + { + rdp_orders_in_color(s, &self->state.text_fgcolor); + } + + if (present & 0x000020) + { + rdp_orders_in_color(s, &self->state.text_bgcolor); + } + + if (present & 0x000040) + { + in_sint16_le(s, self->state.text_clipleft); + } + + if (present & 0x000080) + { + in_sint16_le(s, self->state.text_cliptop); + } + + if (present & 0x000100) + { + in_sint16_le(s, self->state.text_clipright); + } + + if (present & 0x000200) + { + in_sint16_le(s, self->state.text_clipbottom); + } + + if (present & 0x000400) + { + in_sint16_le(s, self->state.text_boxleft); + } + + if (present & 0x000800) + { + in_sint16_le(s, self->state.text_boxtop); + } + + if (present & 0x001000) + { + in_sint16_le(s, self->state.text_boxright); + } + + if (present & 0x002000) + { + in_sint16_le(s, self->state.text_boxbottom); + } + + rdp_orders_parse_brush(s, &self->state.text_brush, present >> 14); + + if (present & 0x080000) + { + in_sint16_le(s, self->state.text_x); + } + + if (present & 0x100000) + { + in_sint16_le(s, self->state.text_y); + } + + if (present & 0x200000) + { + in_uint8(s, self->state.text_length); + in_uint8a(s, self->state.text_text, self->state.text_length); + } + + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, + self->state.text_opcode); + fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.text_fgcolor, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); + bgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.text_bgcolor, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, bgcolor); + self->rdp_layer->mod->server_draw_text(self->rdp_layer->mod, + self->state.text_font, + self->state.text_flags, + self->state.text_mixmode, + self->state.text_clipleft, + self->state.text_cliptop, + self->state.text_clipright, + self->state.text_clipbottom, + self->state.text_boxleft, + self->state.text_boxtop, + self->state.text_boxright, + self->state.text_boxbottom, + self->state.text_x, + self->state.text_y, + self->state.text_text, + self->state.text_length); + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); + + if (self->rdp_layer->rec_mode) + { + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, 512); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 7); + out_uint8(rec_s, self->state.text_font); + out_uint8(rec_s, self->state.text_flags); + out_uint8(rec_s, self->state.text_opcode); + out_uint8(rec_s, self->state.text_mixmode); + out_uint32_le(rec_s, self->state.text_fgcolor); + out_uint32_le(rec_s, self->state.text_bgcolor); + out_uint16_le(rec_s, self->state.text_clipleft); + out_uint16_le(rec_s, self->state.text_cliptop); + out_uint16_le(rec_s, self->state.text_clipright); + out_uint16_le(rec_s, self->state.text_clipbottom); + out_uint16_le(rec_s, self->state.text_boxleft); + out_uint16_le(rec_s, self->state.text_boxtop); + out_uint16_le(rec_s, self->state.text_boxright); + out_uint16_le(rec_s, self->state.text_boxbottom); + out_uint16_le(rec_s, self->state.text_x); + out_uint16_le(rec_s, self->state.text_y); + out_uint16_le(rec_s, self->state.text_length); + out_uint8a(rec_s, self->state.text_text, self->state.text_length); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); + } } /*****************************************************************************/ /* Process a destination blt order */ static void APP_CC -rdp_orders_process_destblt(struct rdp_orders* self, struct stream* s, +rdp_orders_process_destblt(struct rdp_orders *self, struct stream *s, int present, int delta) { - struct stream* rec_s = (struct stream *)NULL; + struct stream *rec_s = (struct stream *)NULL; - if (present & 0x01) - { - rdp_orders_in_coord(s, &self->state.dest_x, delta); - } - if (present & 0x02) - { - rdp_orders_in_coord(s, &self->state.dest_y, delta); - } - if (present & 0x04) - { - rdp_orders_in_coord(s, &self->state.dest_cx, delta); - } - if (present & 0x08) - { - rdp_orders_in_coord(s, &self->state.dest_cy, delta); - } - if (present & 0x10) - { - in_uint8(s, self->state.dest_opcode); - } - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, - self->state.dest_opcode); - self->rdp_layer->mod->server_fill_rect(self->rdp_layer->mod, - self->state.dest_x, - self->state.dest_y, - self->state.dest_cx, - self->state.dest_cy); - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); - if (self->rdp_layer->rec_mode) - { - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, 512); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 6); - out_uint16_le(rec_s, self->state.dest_x); - out_uint16_le(rec_s, self->state.dest_y); - out_uint16_le(rec_s, self->state.dest_cx); - out_uint16_le(rec_s, self->state.dest_cy); - out_uint8(rec_s, self->state.dest_opcode); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); - } + if (present & 0x01) + { + rdp_orders_in_coord(s, &self->state.dest_x, delta); + } + + if (present & 0x02) + { + rdp_orders_in_coord(s, &self->state.dest_y, delta); + } + + if (present & 0x04) + { + rdp_orders_in_coord(s, &self->state.dest_cx, delta); + } + + if (present & 0x08) + { + rdp_orders_in_coord(s, &self->state.dest_cy, delta); + } + + if (present & 0x10) + { + in_uint8(s, self->state.dest_opcode); + } + + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, + self->state.dest_opcode); + self->rdp_layer->mod->server_fill_rect(self->rdp_layer->mod, + self->state.dest_x, + self->state.dest_y, + self->state.dest_cx, + self->state.dest_cy); + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); + + if (self->rdp_layer->rec_mode) + { + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, 512); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 6); + out_uint16_le(rec_s, self->state.dest_x); + out_uint16_le(rec_s, self->state.dest_y); + out_uint16_le(rec_s, self->state.dest_cx); + out_uint16_le(rec_s, self->state.dest_cy); + out_uint8(rec_s, self->state.dest_opcode); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); + } } /*****************************************************************************/ /* Process a pattern blt order */ static void APP_CC -rdp_orders_process_patblt(struct rdp_orders* self, struct stream* s, +rdp_orders_process_patblt(struct rdp_orders *self, struct stream *s, int present, int delta) { - int fgcolor = 0; - int bgcolor = 0; - struct stream* rec_s = (struct stream *)NULL; + int fgcolor = 0; + int bgcolor = 0; + struct stream *rec_s = (struct stream *)NULL; - if (present & 0x0001) - { - rdp_orders_in_coord(s, &self->state.pat_x, delta); - } - if (present & 0x0002) - { - rdp_orders_in_coord(s, &self->state.pat_y, delta); - } - if (present & 0x0004) - { - rdp_orders_in_coord(s, &self->state.pat_cx, delta); - } - if (present & 0x0008) - { - rdp_orders_in_coord(s, &self->state.pat_cy, delta); - } - if (present & 0x0010) - { - in_uint8(s, self->state.pat_opcode); - } - if (present & 0x0020) - { - rdp_orders_in_color(s, &self->state.pat_bgcolor); - } - if (present & 0x0040) - { - rdp_orders_in_color(s, &self->state.pat_fgcolor); - } - rdp_orders_parse_brush(s, &self->state.pat_brush, present >> 7); - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, - self->state.pat_opcode); - self->rdp_layer->mod->server_set_mixmode(self->rdp_layer->mod, 1); - fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, - self->rdp_layer->mod->xrdp_bpp, - self->state.pat_fgcolor, - self->rdp_layer->colormap.colors); - self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); - bgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, - self->rdp_layer->mod->xrdp_bpp, - self->state.pat_bgcolor, - self->rdp_layer->colormap.colors); - self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, bgcolor); - self->rdp_layer->mod->server_set_brush(self->rdp_layer->mod, - self->state.pat_brush.xorigin, - self->state.pat_brush.yorigin, - self->state.pat_brush.style, - self->state.pat_brush.pattern); - self->rdp_layer->mod->server_fill_rect(self->rdp_layer->mod, - self->state.pat_x, - self->state.pat_y, - self->state.pat_cx, - self->state.pat_cy); - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); - self->rdp_layer->mod->server_set_mixmode(self->rdp_layer->mod, 0); - if (self->rdp_layer->rec_mode) - { - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, 512); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 5); - out_uint16_le(rec_s, self->state.pat_x); - out_uint16_le(rec_s, self->state.pat_y); - out_uint16_le(rec_s, self->state.pat_cx); - out_uint16_le(rec_s, self->state.pat_cy); - out_uint8(rec_s, self->state.pat_opcode); - out_uint32_le(rec_s, self->state.pat_fgcolor); - out_uint32_le(rec_s, self->state.pat_bgcolor); - out_uint8(rec_s, self->state.pat_brush.xorigin); - out_uint8(rec_s, self->state.pat_brush.yorigin); - out_uint8(rec_s, self->state.pat_brush.style); - out_uint8a(rec_s, self->state.pat_brush.pattern, 8); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); - } + if (present & 0x0001) + { + rdp_orders_in_coord(s, &self->state.pat_x, delta); + } + + if (present & 0x0002) + { + rdp_orders_in_coord(s, &self->state.pat_y, delta); + } + + if (present & 0x0004) + { + rdp_orders_in_coord(s, &self->state.pat_cx, delta); + } + + if (present & 0x0008) + { + rdp_orders_in_coord(s, &self->state.pat_cy, delta); + } + + if (present & 0x0010) + { + in_uint8(s, self->state.pat_opcode); + } + + if (present & 0x0020) + { + rdp_orders_in_color(s, &self->state.pat_bgcolor); + } + + if (present & 0x0040) + { + rdp_orders_in_color(s, &self->state.pat_fgcolor); + } + + rdp_orders_parse_brush(s, &self->state.pat_brush, present >> 7); + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, + self->state.pat_opcode); + self->rdp_layer->mod->server_set_mixmode(self->rdp_layer->mod, 1); + fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.pat_fgcolor, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); + bgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.pat_bgcolor, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, bgcolor); + self->rdp_layer->mod->server_set_brush(self->rdp_layer->mod, + self->state.pat_brush.xorigin, + self->state.pat_brush.yorigin, + self->state.pat_brush.style, + self->state.pat_brush.pattern); + self->rdp_layer->mod->server_fill_rect(self->rdp_layer->mod, + self->state.pat_x, + self->state.pat_y, + self->state.pat_cx, + self->state.pat_cy); + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); + self->rdp_layer->mod->server_set_mixmode(self->rdp_layer->mod, 0); + + if (self->rdp_layer->rec_mode) + { + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, 512); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 5); + out_uint16_le(rec_s, self->state.pat_x); + out_uint16_le(rec_s, self->state.pat_y); + out_uint16_le(rec_s, self->state.pat_cx); + out_uint16_le(rec_s, self->state.pat_cy); + out_uint8(rec_s, self->state.pat_opcode); + out_uint32_le(rec_s, self->state.pat_fgcolor); + out_uint32_le(rec_s, self->state.pat_bgcolor); + out_uint8(rec_s, self->state.pat_brush.xorigin); + out_uint8(rec_s, self->state.pat_brush.yorigin); + out_uint8(rec_s, self->state.pat_brush.style); + out_uint8a(rec_s, self->state.pat_brush.pattern, 8); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); + } } /*****************************************************************************/ /* Process a screen blt order */ static void APP_CC -rdp_orders_process_screenblt(struct rdp_orders* self, struct stream* s, +rdp_orders_process_screenblt(struct rdp_orders *self, struct stream *s, int present, int delta) { - struct stream* rec_s; + struct stream *rec_s; - if (present & 0x0001) - { - rdp_orders_in_coord(s, &self->state.screenblt_x, delta); - } - if (present & 0x0002) - { - rdp_orders_in_coord(s, &self->state.screenblt_y, delta); - } - if (present & 0x0004) - { - rdp_orders_in_coord(s, &self->state.screenblt_cx, delta); - } - if (present & 0x0008) - { - rdp_orders_in_coord(s, &self->state.screenblt_cy, delta); - } - if (present & 0x0010) - { - in_uint8(s, self->state.screenblt_opcode); - } - if (present & 0x0020) - { - rdp_orders_in_coord(s, &self->state.screenblt_srcx, delta); - } - if (present & 0x0040) - { - rdp_orders_in_coord(s, &self->state.screenblt_srcy, delta); - } - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, - self->state.screenblt_opcode); - self->rdp_layer->mod->server_screen_blt(self->rdp_layer->mod, - self->state.screenblt_x, - self->state.screenblt_y, - self->state.screenblt_cx, - self->state.screenblt_cy, - self->state.screenblt_srcx, - self->state.screenblt_srcy); - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); - if (self->rdp_layer->rec_mode) - { - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, 512); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 4); - out_uint16_le(rec_s, self->state.screenblt_x); - out_uint16_le(rec_s, self->state.screenblt_y); - out_uint16_le(rec_s, self->state.screenblt_cx); - out_uint16_le(rec_s, self->state.screenblt_cy); - out_uint16_le(rec_s, self->state.screenblt_srcx); - out_uint16_le(rec_s, self->state.screenblt_srcy); - out_uint8(rec_s, self->state.screenblt_opcode); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); - } + if (present & 0x0001) + { + rdp_orders_in_coord(s, &self->state.screenblt_x, delta); + } + + if (present & 0x0002) + { + rdp_orders_in_coord(s, &self->state.screenblt_y, delta); + } + + if (present & 0x0004) + { + rdp_orders_in_coord(s, &self->state.screenblt_cx, delta); + } + + if (present & 0x0008) + { + rdp_orders_in_coord(s, &self->state.screenblt_cy, delta); + } + + if (present & 0x0010) + { + in_uint8(s, self->state.screenblt_opcode); + } + + if (present & 0x0020) + { + rdp_orders_in_coord(s, &self->state.screenblt_srcx, delta); + } + + if (present & 0x0040) + { + rdp_orders_in_coord(s, &self->state.screenblt_srcy, delta); + } + + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, + self->state.screenblt_opcode); + self->rdp_layer->mod->server_screen_blt(self->rdp_layer->mod, + self->state.screenblt_x, + self->state.screenblt_y, + self->state.screenblt_cx, + self->state.screenblt_cy, + self->state.screenblt_srcx, + self->state.screenblt_srcy); + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); + + if (self->rdp_layer->rec_mode) + { + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, 512); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 4); + out_uint16_le(rec_s, self->state.screenblt_x); + out_uint16_le(rec_s, self->state.screenblt_y); + out_uint16_le(rec_s, self->state.screenblt_cx); + out_uint16_le(rec_s, self->state.screenblt_cy); + out_uint16_le(rec_s, self->state.screenblt_srcx); + out_uint16_le(rec_s, self->state.screenblt_srcy); + out_uint8(rec_s, self->state.screenblt_opcode); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); + } } /*****************************************************************************/ /* Process a line order */ static void APP_CC -rdp_orders_process_line(struct rdp_orders* self, struct stream* s, +rdp_orders_process_line(struct rdp_orders *self, struct stream *s, int present, int delta) { - int bgcolor = 0; - int fgcolor = 0; - struct stream* rec_s = (struct stream *)NULL; + int bgcolor = 0; + int fgcolor = 0; + struct stream *rec_s = (struct stream *)NULL; - if (present & 0x0001) - { - in_uint16_le(s, self->state.line_mixmode); - } - if (present & 0x0002) - { - rdp_orders_in_coord(s, &self->state.line_startx, delta); - } - if (present & 0x0004) - { - rdp_orders_in_coord(s, &self->state.line_starty, delta); - } - if (present & 0x0008) - { - rdp_orders_in_coord(s, &self->state.line_endx, delta); - } - if (present & 0x0010) - { - rdp_orders_in_coord(s, &self->state.line_endy, delta); - } - if (present & 0x0020) - { - rdp_orders_in_color(s, &self->state.line_bgcolor); - } - if (present & 0x0040) - { - in_uint8(s, self->state.line_opcode); - } - rdp_orders_parse_pen(s, &self->state.line_pen, present >> 7); - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, - self->state.line_opcode); - bgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, - self->rdp_layer->mod->xrdp_bpp, - self->state.line_bgcolor, - self->rdp_layer->colormap.colors); - fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, - self->rdp_layer->mod->xrdp_bpp, - self->state.line_pen.color, - self->rdp_layer->colormap.colors); - self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); - self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, bgcolor); - self->rdp_layer->mod->server_set_pen(self->rdp_layer->mod, - self->state.line_pen.style, - self->state.line_pen.width); - self->rdp_layer->mod->server_draw_line(self->rdp_layer->mod, - self->state.line_startx, - self->state.line_starty, - self->state.line_endx, - self->state.line_endy); - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); - if (self->rdp_layer->rec_mode) - { - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, 512); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 3); - out_uint16_le(rec_s, self->state.line_mixmode); - out_uint16_le(rec_s, self->state.line_startx); - out_uint16_le(rec_s, self->state.line_starty); - out_uint16_le(rec_s, self->state.line_endx); - out_uint16_le(rec_s, self->state.line_endy); - out_uint32_le(rec_s, self->state.line_bgcolor); - out_uint8(rec_s, self->state.line_opcode); - out_uint8(rec_s, self->state.line_pen.style); - out_uint8(rec_s, self->state.line_pen.width); - out_uint32_le(rec_s, self->state.line_pen.color); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); - } + if (present & 0x0001) + { + in_uint16_le(s, self->state.line_mixmode); + } + + if (present & 0x0002) + { + rdp_orders_in_coord(s, &self->state.line_startx, delta); + } + + if (present & 0x0004) + { + rdp_orders_in_coord(s, &self->state.line_starty, delta); + } + + if (present & 0x0008) + { + rdp_orders_in_coord(s, &self->state.line_endx, delta); + } + + if (present & 0x0010) + { + rdp_orders_in_coord(s, &self->state.line_endy, delta); + } + + if (present & 0x0020) + { + rdp_orders_in_color(s, &self->state.line_bgcolor); + } + + if (present & 0x0040) + { + in_uint8(s, self->state.line_opcode); + } + + rdp_orders_parse_pen(s, &self->state.line_pen, present >> 7); + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, + self->state.line_opcode); + bgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.line_bgcolor, + self->rdp_layer->colormap.colors); + fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.line_pen.color, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); + self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, bgcolor); + self->rdp_layer->mod->server_set_pen(self->rdp_layer->mod, + self->state.line_pen.style, + self->state.line_pen.width); + self->rdp_layer->mod->server_draw_line(self->rdp_layer->mod, + self->state.line_startx, + self->state.line_starty, + self->state.line_endx, + self->state.line_endy); + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); + + if (self->rdp_layer->rec_mode) + { + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, 512); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 3); + out_uint16_le(rec_s, self->state.line_mixmode); + out_uint16_le(rec_s, self->state.line_startx); + out_uint16_le(rec_s, self->state.line_starty); + out_uint16_le(rec_s, self->state.line_endx); + out_uint16_le(rec_s, self->state.line_endy); + out_uint32_le(rec_s, self->state.line_bgcolor); + out_uint8(rec_s, self->state.line_opcode); + out_uint8(rec_s, self->state.line_pen.style); + out_uint8(rec_s, self->state.line_pen.width); + out_uint32_le(rec_s, self->state.line_pen.color); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); + } } /*****************************************************************************/ /* Process an opaque rectangle order */ static void APP_CC -rdp_orders_process_rect(struct rdp_orders* self, struct stream* s, +rdp_orders_process_rect(struct rdp_orders *self, struct stream *s, int present, int delta) { - int i = 0; - int fgcolor = 0; - struct stream* rec_s = (struct stream *)NULL; + int i = 0; + int fgcolor = 0; + struct stream *rec_s = (struct stream *)NULL; - if (present & 0x01) - { - rdp_orders_in_coord(s, &self->state.rect_x, delta); - } - if (present & 0x02) - { - rdp_orders_in_coord(s, &self->state.rect_y, delta); - } - if (present & 0x04) - { - rdp_orders_in_coord(s, &self->state.rect_cx, delta); - } - if (present & 0x08) - { - rdp_orders_in_coord(s, &self->state.rect_cy, delta); - } - if (present & 0x10) - { - in_uint8(s, i); - self->state.rect_color = (self->state.rect_color & 0xffffff00) | i; - } - if (present & 0x20) - { - in_uint8(s, i); - self->state.rect_color = (self->state.rect_color & 0xffff00ff) | (i << 8); - } - if (present & 0x40) - { - in_uint8(s, i); - self->state.rect_color = (self->state.rect_color & 0xff00ffff) | (i << 16); - } - fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, - self->rdp_layer->mod->xrdp_bpp, - self->state.rect_color, - self->rdp_layer->colormap.colors); - self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); - self->rdp_layer->mod->server_fill_rect(self->rdp_layer->mod, - self->state.rect_x, - self->state.rect_y, - self->state.rect_cx, - self->state.rect_cy); - if (self->rdp_layer->rec_mode) - { - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, 512); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 1); - out_uint16_le(rec_s, self->state.rect_x); - out_uint16_le(rec_s, self->state.rect_y); - out_uint16_le(rec_s, self->state.rect_cx); - out_uint16_le(rec_s, self->state.rect_cy); - out_uint32_le(rec_s, self->state.rect_color); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); - } + if (present & 0x01) + { + rdp_orders_in_coord(s, &self->state.rect_x, delta); + } + + if (present & 0x02) + { + rdp_orders_in_coord(s, &self->state.rect_y, delta); + } + + if (present & 0x04) + { + rdp_orders_in_coord(s, &self->state.rect_cx, delta); + } + + if (present & 0x08) + { + rdp_orders_in_coord(s, &self->state.rect_cy, delta); + } + + if (present & 0x10) + { + in_uint8(s, i); + self->state.rect_color = (self->state.rect_color & 0xffffff00) | i; + } + + if (present & 0x20) + { + in_uint8(s, i); + self->state.rect_color = (self->state.rect_color & 0xffff00ff) | (i << 8); + } + + if (present & 0x40) + { + in_uint8(s, i); + self->state.rect_color = (self->state.rect_color & 0xff00ffff) | (i << 16); + } + + fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.rect_color, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); + self->rdp_layer->mod->server_fill_rect(self->rdp_layer->mod, + self->state.rect_x, + self->state.rect_y, + self->state.rect_cx, + self->state.rect_cy); + + if (self->rdp_layer->rec_mode) + { + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, 512); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 1); + out_uint16_le(rec_s, self->state.rect_x); + out_uint16_le(rec_s, self->state.rect_y); + out_uint16_le(rec_s, self->state.rect_cx); + out_uint16_le(rec_s, self->state.rect_cy); + out_uint32_le(rec_s, self->state.rect_color); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); + } } /*****************************************************************************/ /* Process a desktop save order */ static void APP_CC -rdp_orders_process_desksave(struct rdp_orders* self, struct stream* s, +rdp_orders_process_desksave(struct rdp_orders *self, struct stream *s, int present, int delta) { - int width = 0; - int height = 0; + int width = 0; + int height = 0; - if (present & 0x01) - { - in_uint32_le(s, self->state.desksave_offset); - } - if (present & 0x02) - { - rdp_orders_in_coord(s, &self->state.desksave_left, delta); - } - if (present & 0x04) - { - rdp_orders_in_coord(s, &self->state.desksave_top, delta); - } - if (present & 0x08) - { - rdp_orders_in_coord(s, &self->state.desksave_right, delta); - } - if (present & 0x10) - { - rdp_orders_in_coord(s, &self->state.desksave_bottom, delta); - } - if (present & 0x20) - { - in_uint8(s, self->state.desksave_action); - } -// width = (self->state.desksave_right - self->state.desksave_left) + 1; -// height = (self->state.desksave_bottom - self->state.desksave_top) + 1; - if (self->state.desksave_action == 0) - { -// ui_desktop_save(os->offset, os->left, os->top, width, height); - } - else - { -// ui_desktop_restore(os->offset, os->left, os->top, width, height); - } + if (present & 0x01) + { + in_uint32_le(s, self->state.desksave_offset); + } + + if (present & 0x02) + { + rdp_orders_in_coord(s, &self->state.desksave_left, delta); + } + + if (present & 0x04) + { + rdp_orders_in_coord(s, &self->state.desksave_top, delta); + } + + if (present & 0x08) + { + rdp_orders_in_coord(s, &self->state.desksave_right, delta); + } + + if (present & 0x10) + { + rdp_orders_in_coord(s, &self->state.desksave_bottom, delta); + } + + if (present & 0x20) + { + in_uint8(s, self->state.desksave_action); + } + + // width = (self->state.desksave_right - self->state.desksave_left) + 1; + // height = (self->state.desksave_bottom - self->state.desksave_top) + 1; + if (self->state.desksave_action == 0) + { + // ui_desktop_save(os->offset, os->left, os->top, width, height); + } + else + { + // ui_desktop_restore(os->offset, os->left, os->top, width, height); + } } /*****************************************************************************/ /* Process a memory blt order */ static void APP_CC -rdp_orders_process_memblt(struct rdp_orders* self, struct stream* s, +rdp_orders_process_memblt(struct rdp_orders *self, struct stream *s, int present, int delta) { - struct rdp_bitmap* bitmap = (struct rdp_bitmap *)NULL; - struct stream* rec_s = (struct stream *)NULL; - char* bmpdata = (char *)NULL; + struct rdp_bitmap *bitmap = (struct rdp_bitmap *)NULL; + struct stream *rec_s = (struct stream *)NULL; + char *bmpdata = (char *)NULL; - if (present & 0x0001) - { - in_uint8(s, self->state.memblt_cache_id); - in_uint8(s, self->state.memblt_color_table); - } - if (present & 0x0002) - { - rdp_orders_in_coord(s, &self->state.memblt_x, delta); - } - if (present & 0x0004) - { - rdp_orders_in_coord(s, &self->state.memblt_y, delta); - } - if (present & 0x0008) - { - rdp_orders_in_coord(s, &self->state.memblt_cx, delta); - } - if (present & 0x0010) - { - rdp_orders_in_coord(s, &self->state.memblt_cy, delta); - } - if (present & 0x0020) - { - in_uint8(s, self->state.memblt_opcode); - } - if (present & 0x0040) - { - rdp_orders_in_coord(s, &self->state.memblt_srcx, delta); - } - if (present & 0x0080) - { - rdp_orders_in_coord(s, &self->state.memblt_srcy, delta); - } - if (present & 0x0100) - { - in_uint16_le(s, self->state.memblt_cache_idx); - } - bitmap = self->cache_bitmap[self->state.memblt_cache_id] - [self->state.memblt_cache_idx]; - if (bitmap != 0) - { - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, - self->state.memblt_opcode); - bmpdata = rdp_orders_convert_bitmap(self->rdp_layer->mod->rdp_bpp, - self->rdp_layer->mod->xrdp_bpp, - bitmap->data, bitmap->width, - bitmap->height, - self->cache_colormap - [self->state.memblt_color_table]->colors); - self->rdp_layer->mod->server_paint_rect(self->rdp_layer->mod, - self->state.memblt_x, - self->state.memblt_y, - self->state.memblt_cx, - self->state.memblt_cy, - bmpdata, - bitmap->width, + if (present & 0x0001) + { + in_uint8(s, self->state.memblt_cache_id); + in_uint8(s, self->state.memblt_color_table); + } + + if (present & 0x0002) + { + rdp_orders_in_coord(s, &self->state.memblt_x, delta); + } + + if (present & 0x0004) + { + rdp_orders_in_coord(s, &self->state.memblt_y, delta); + } + + if (present & 0x0008) + { + rdp_orders_in_coord(s, &self->state.memblt_cx, delta); + } + + if (present & 0x0010) + { + rdp_orders_in_coord(s, &self->state.memblt_cy, delta); + } + + if (present & 0x0020) + { + in_uint8(s, self->state.memblt_opcode); + } + + if (present & 0x0040) + { + rdp_orders_in_coord(s, &self->state.memblt_srcx, delta); + } + + if (present & 0x0080) + { + rdp_orders_in_coord(s, &self->state.memblt_srcy, delta); + } + + if (present & 0x0100) + { + in_uint16_le(s, self->state.memblt_cache_idx); + } + + bitmap = self->cache_bitmap[self->state.memblt_cache_id] + [self->state.memblt_cache_idx]; + + if (bitmap != 0) + { + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, + self->state.memblt_opcode); + bmpdata = rdp_orders_convert_bitmap(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + bitmap->data, bitmap->width, bitmap->height, - self->state.memblt_srcx, - self->state.memblt_srcy); - self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); - if (self->rdp_layer->rec_mode) - { - rdp_rec_check_file(self->rdp_layer); - make_stream(rec_s); - init_stream(rec_s, 512); - s_push_layer(rec_s, iso_hdr, 4); - out_uint8(rec_s, 2); - out_uint8(rec_s, self->state.memblt_opcode); - out_uint16_le(rec_s, self->state.memblt_x); - out_uint16_le(rec_s, self->state.memblt_y); - out_uint16_le(rec_s, self->state.memblt_cx); - out_uint16_le(rec_s, self->state.memblt_cy); - out_uint16_le(rec_s, self->state.memblt_cache_id); - out_uint16_le(rec_s, self->state.memblt_cache_idx); - out_uint16_le(rec_s, self->state.memblt_srcx); - out_uint16_le(rec_s, self->state.memblt_srcy); - rdp_rec_write_item(self->rdp_layer, rec_s); - free_stream(rec_s); + self->cache_colormap + [self->state.memblt_color_table]->colors); + self->rdp_layer->mod->server_paint_rect(self->rdp_layer->mod, + self->state.memblt_x, + self->state.memblt_y, + self->state.memblt_cx, + self->state.memblt_cy, + bmpdata, + bitmap->width, + bitmap->height, + self->state.memblt_srcx, + self->state.memblt_srcy); + self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); + + if (self->rdp_layer->rec_mode) + { + rdp_rec_check_file(self->rdp_layer); + make_stream(rec_s); + init_stream(rec_s, 512); + s_push_layer(rec_s, iso_hdr, 4); + out_uint8(rec_s, 2); + out_uint8(rec_s, self->state.memblt_opcode); + out_uint16_le(rec_s, self->state.memblt_x); + out_uint16_le(rec_s, self->state.memblt_y); + out_uint16_le(rec_s, self->state.memblt_cx); + out_uint16_le(rec_s, self->state.memblt_cy); + out_uint16_le(rec_s, self->state.memblt_cache_id); + out_uint16_le(rec_s, self->state.memblt_cache_idx); + out_uint16_le(rec_s, self->state.memblt_srcx); + out_uint16_le(rec_s, self->state.memblt_srcy); + rdp_rec_write_item(self->rdp_layer, rec_s); + free_stream(rec_s); + } + + if (bmpdata != bitmap->data) + { + g_free(bmpdata); + } } - if (bmpdata != bitmap->data) - { - g_free(bmpdata); - } - } } /*****************************************************************************/ /* Process a 3-way blt order */ static void APP_CC -rdp_orders_process_triblt(struct rdp_orders* self, struct stream* s, +rdp_orders_process_triblt(struct rdp_orders *self, struct stream *s, int present, int delta) { - /* not used */ + /* not used */ } /*****************************************************************************/ /* Process a polyline order */ static void APP_CC -rdp_orders_process_polyline(struct rdp_orders* self, struct stream* s, +rdp_orders_process_polyline(struct rdp_orders *self, struct stream *s, int present, int delta) { - if (present & 0x01) - { - rdp_orders_in_coord(s, &self->state.polyline_x, delta); - } - if (present & 0x02) - { - rdp_orders_in_coord(s, &self->state.polyline_y, delta); - } - if (present & 0x04) - { - in_uint8(s, self->state.polyline_opcode); - } - if (present & 0x10) - { - rdp_orders_in_color(s, &self->state.polyline_fgcolor); - } - if (present & 0x20) - { - in_uint8(s, self->state.polyline_lines); - } - if (present & 0x40) - { - in_uint8(s, self->state.polyline_datasize); - in_uint8a(s, self->state.polyline_data, self->state.polyline_datasize); - } - /* todo */ + if (present & 0x01) + { + rdp_orders_in_coord(s, &self->state.polyline_x, delta); + } + + if (present & 0x02) + { + rdp_orders_in_coord(s, &self->state.polyline_y, delta); + } + + if (present & 0x04) + { + in_uint8(s, self->state.polyline_opcode); + } + + if (present & 0x10) + { + rdp_orders_in_color(s, &self->state.polyline_fgcolor); + } + + if (present & 0x20) + { + in_uint8(s, self->state.polyline_lines); + } + + if (present & 0x40) + { + in_uint8(s, self->state.polyline_datasize); + in_uint8a(s, self->state.polyline_data, self->state.polyline_datasize); + } + + /* todo */ } /*****************************************************************************/ int APP_CC -rdp_orders_process_orders(struct rdp_orders* self, struct stream* s, +rdp_orders_process_orders(struct rdp_orders *self, struct stream *s, int num_orders) { - int processed = 0; - int order_flags = 0; - int size = 0; - int present = 0; - int delta = 0; + int processed = 0; + int order_flags = 0; + int size = 0; + int present = 0; + int delta = 0; - processed = 0; - while (processed < num_orders) - { - in_uint8(s, order_flags); - if (!(order_flags & RDP_ORDER_STANDARD)) + processed = 0; + + while (processed < num_orders) { - /* error, this should always be set */ - break; - } - if (order_flags & RDP_ORDER_SECONDARY) - { - rdp_orders_process_secondary_order(self, s); - } - else - { - if (order_flags & RDP_ORDER_CHANGE) - { - in_uint8(s, self->state.order_type); - } - switch (self->state.order_type) - { - case RDP_ORDER_TRIBLT: - case RDP_ORDER_TEXT2: - size = 3; - break; - case RDP_ORDER_PATBLT: - case RDP_ORDER_MEMBLT: - case RDP_ORDER_LINE: - size = 2; - break; - default: - size = 1; - break; - } - rdp_orders_in_present(s, &present, order_flags, size); - if (order_flags & RDP_ORDER_BOUNDS) - { - if (!(order_flags & RDP_ORDER_LASTBOUNDS)) + in_uint8(s, order_flags); + + if (!(order_flags & RDP_ORDER_STANDARD)) { - rdp_orders_parse_bounds(self, s); + /* error, this should always be set */ + break; } - self->rdp_layer->mod->server_set_clip(self->rdp_layer->mod, - self->state.clip_left, - self->state.clip_top, - (self->state.clip_right - self->state.clip_left) + 1, - (self->state.clip_bottom - self->state.clip_top) + 1); - } - delta = order_flags & RDP_ORDER_DELTA; - switch (self->state.order_type) - { - case RDP_ORDER_TEXT2: - rdp_orders_process_text2(self, s, present, delta); - break; - case RDP_ORDER_DESTBLT: - rdp_orders_process_destblt(self, s, present, delta); - break; - case RDP_ORDER_PATBLT: - rdp_orders_process_patblt(self, s, present, delta); - break; - case RDP_ORDER_SCREENBLT: - rdp_orders_process_screenblt(self, s, present, delta); - break; - case RDP_ORDER_LINE: - rdp_orders_process_line(self, s, present, delta); - break; - case RDP_ORDER_RECT: - rdp_orders_process_rect(self, s, present, delta); - break; - case RDP_ORDER_DESKSAVE: - rdp_orders_process_desksave(self, s, present, delta); - break; - case RDP_ORDER_MEMBLT: - rdp_orders_process_memblt(self, s, present, delta); - break; - case RDP_ORDER_TRIBLT: - rdp_orders_process_triblt(self, s, present, delta); - break; - case RDP_ORDER_POLYLINE: - rdp_orders_process_polyline(self, s, present, delta); - break; - default: - /* error unknown order */ - break; - } - if (order_flags & RDP_ORDER_BOUNDS) - { - self->rdp_layer->mod->server_reset_clip(self->rdp_layer->mod); - } + + if (order_flags & RDP_ORDER_SECONDARY) + { + rdp_orders_process_secondary_order(self, s); + } + else + { + if (order_flags & RDP_ORDER_CHANGE) + { + in_uint8(s, self->state.order_type); + } + + switch (self->state.order_type) + { + case RDP_ORDER_TRIBLT: + case RDP_ORDER_TEXT2: + size = 3; + break; + case RDP_ORDER_PATBLT: + case RDP_ORDER_MEMBLT: + case RDP_ORDER_LINE: + size = 2; + break; + default: + size = 1; + break; + } + + rdp_orders_in_present(s, &present, order_flags, size); + + if (order_flags & RDP_ORDER_BOUNDS) + { + if (!(order_flags & RDP_ORDER_LASTBOUNDS)) + { + rdp_orders_parse_bounds(self, s); + } + + self->rdp_layer->mod->server_set_clip(self->rdp_layer->mod, + self->state.clip_left, + self->state.clip_top, + (self->state.clip_right - self->state.clip_left) + 1, + (self->state.clip_bottom - self->state.clip_top) + 1); + } + + delta = order_flags & RDP_ORDER_DELTA; + + switch (self->state.order_type) + { + case RDP_ORDER_TEXT2: + rdp_orders_process_text2(self, s, present, delta); + break; + case RDP_ORDER_DESTBLT: + rdp_orders_process_destblt(self, s, present, delta); + break; + case RDP_ORDER_PATBLT: + rdp_orders_process_patblt(self, s, present, delta); + break; + case RDP_ORDER_SCREENBLT: + rdp_orders_process_screenblt(self, s, present, delta); + break; + case RDP_ORDER_LINE: + rdp_orders_process_line(self, s, present, delta); + break; + case RDP_ORDER_RECT: + rdp_orders_process_rect(self, s, present, delta); + break; + case RDP_ORDER_DESKSAVE: + rdp_orders_process_desksave(self, s, present, delta); + break; + case RDP_ORDER_MEMBLT: + rdp_orders_process_memblt(self, s, present, delta); + break; + case RDP_ORDER_TRIBLT: + rdp_orders_process_triblt(self, s, present, delta); + break; + case RDP_ORDER_POLYLINE: + rdp_orders_process_polyline(self, s, present, delta); + break; + default: + /* error unknown order */ + break; + } + + if (order_flags & RDP_ORDER_BOUNDS) + { + self->rdp_layer->mod->server_reset_clip(self->rdp_layer->mod); + } + } + + processed++; } - processed++; - } - return 0; + + return 0; } /*****************************************************************************/ /* returns pointer, it might return bmpdata if the data dosen't need to be converted, else it mallocs it. The calling function must free it if needed */ -char* APP_CC -rdp_orders_convert_bitmap(int in_bpp, int out_bpp, char* bmpdata, - int width, int height, int* palette) +char *APP_CC +rdp_orders_convert_bitmap(int in_bpp, int out_bpp, char *bmpdata, + int width, int height, int *palette) { - char* out = (char *)NULL; - char* src = (char *)NULL; - char* dst = (char *)NULL; - int i = 0; - int j = 0; - int red = 0; - int green = 0; - int blue = 0; - int pixel = 0; + char *out = (char *)NULL; + char *src = (char *)NULL; + char *dst = (char *)NULL; + int i = 0; + int j = 0; + int red = 0; + int green = 0; + int blue = 0; + int pixel = 0; - if ((in_bpp == 8) && (out_bpp == 8)) - { - out = (char*)g_malloc(width * height, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + if ((in_bpp == 8) && (out_bpp == 8)) { - for (j = 0; j < width; j++) - { - pixel = *((tui8*)src); - pixel = palette[pixel]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR8(red, green, blue); - *dst = pixel; - src++; - dst++; - } + out = (char *)g_malloc(width * height, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui8 *)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + *dst = pixel; + src++; + dst++; + } + } + + return out; } - return out; - } - if ((in_bpp == 8) && (out_bpp == 16)) - { - out = (char*)g_malloc(width * height * 2, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 8) && (out_bpp == 16)) { - for (j = 0; j < width; j++) - { - pixel = *((tui8*)src); - pixel = palette[pixel]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - *((tui16*)dst) = pixel; - src++; - dst += 2; - } + out = (char *)g_malloc(width * height * 2, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui8 *)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + *((tui16 *)dst) = pixel; + src++; + dst += 2; + } + } + + return out; } - return out; - } - if ((in_bpp == 8) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 8) && (out_bpp == 24)) { - for (j = 0; j < width; j++) - { - pixel = *((tui8*)src); - pixel = palette[pixel]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - src++; - dst += 4; - } + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui8 *)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + src++; + dst += 4; + } + } + + return out; } - return out; - } - if ((in_bpp == 15) && (out_bpp == 16)) - { - out = (char*)g_malloc(width * height * 2, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 15) && (out_bpp == 16)) { - for (j = 0; j < width; j++) - { - pixel = *((tui16*)src); - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - *((tui16*)dst) = pixel; - src += 2; - dst += 2; - } + out = (char *)g_malloc(width * height * 2, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui16 *)src); + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + *((tui16 *)dst) = pixel; + src += 2; + dst += 2; + } + } + + return out; } - return out; - } - if ((in_bpp == 15) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 15) && (out_bpp == 24)) { - for (j = 0; j < width; j++) - { - pixel = *((tui16*)src); - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - src += 2; - dst += 4; - } + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui16 *)src); + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + src += 2; + dst += 4; + } + } + + return out; } - return out; - } - if ((in_bpp == 16) && (out_bpp == 16)) - { - return bmpdata; - } - if ((in_bpp == 16) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 16) && (out_bpp == 16)) { - for (j = 0; j < width; j++) - { - pixel = *((tui16*)src); - SPLITCOLOR16(red, green, blue, pixel); - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - src += 2; - dst += 4; - } + return bmpdata; } - return out; - } - if ((in_bpp == 24) && (out_bpp == 24)) - { - out = (char*)g_malloc(width * height * 4, 0); - src = bmpdata; - dst = out; - for (i = 0; i < height; i++) + + if ((in_bpp == 16) && (out_bpp == 24)) { - for (j = 0; j < width; j++) - { - blue = *((tui8*)src); - src++; - green = *((tui8*)src); - src++; - red = *((tui8*)src); - src++; - pixel = COLOR24RGB(red, green, blue); - *((tui32*)dst) = pixel; - dst += 4; - } + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((tui16 *)src); + SPLITCOLOR16(red, green, blue, pixel); + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + src += 2; + dst += 4; + } + } + + return out; } - return out; - } - return 0; + + if ((in_bpp == 24) && (out_bpp == 24)) + { + out = (char *)g_malloc(width * height * 4, 0); + src = bmpdata; + dst = out; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + blue = *((tui8 *)src); + src++; + green = *((tui8 *)src); + src++; + red = *((tui8 *)src); + src++; + pixel = COLOR24RGB(red, green, blue); + *((tui32 *)dst) = pixel; + dst += 4; + } + } + + return out; + } + + return 0; } /*****************************************************************************/ /* returns color or 0 */ int APP_CC -rdp_orders_convert_color(int in_bpp, int out_bpp, int in_color, int* palette) +rdp_orders_convert_color(int in_bpp, int out_bpp, int in_color, int *palette) { - int pixel = 0; - int red = 0; - int green = 0; - int blue = 0; + int pixel = 0; + int red = 0; + int green = 0; + int blue = 0; - if ((in_bpp == 8) && (out_bpp == 8)) - { - pixel = palette[in_color]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR8(red, green, blue); - return pixel; - } - if ((in_bpp == 8) && (out_bpp == 16)) - { - pixel = palette[in_color]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - return pixel; - } - if ((in_bpp == 8) && (out_bpp == 24)) - { - pixel = palette[in_color]; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR24BGR(red, green, blue); - return pixel; - } - if ((in_bpp == 15) && (out_bpp == 16)) - { - pixel = in_color; - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - return pixel; - } - if ((in_bpp == 15) && (out_bpp == 24)) - { - pixel = in_color; - SPLITCOLOR15(red, green, blue, pixel); - pixel = COLOR24BGR(red, green, blue); - return pixel; - } - if ((in_bpp == 16) && (out_bpp == 16)) - { - return in_color; - } - if ((in_bpp == 16) && (out_bpp == 24)) - { - pixel = in_color; - SPLITCOLOR16(red, green, blue, pixel); - pixel = COLOR24BGR(red, green, blue); - return pixel; - } - if ((in_bpp == 24) && (out_bpp == 24)) - { - return in_color; - } - return 0; + if ((in_bpp == 8) && (out_bpp == 8)) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + return pixel; + } + + if ((in_bpp == 8) && (out_bpp == 16)) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + return pixel; + } + + if ((in_bpp == 8) && (out_bpp == 24)) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR24BGR(red, green, blue); + return pixel; + } + + if ((in_bpp == 15) && (out_bpp == 16)) + { + pixel = in_color; + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + return pixel; + } + + if ((in_bpp == 15) && (out_bpp == 24)) + { + pixel = in_color; + SPLITCOLOR15(red, green, blue, pixel); + pixel = COLOR24BGR(red, green, blue); + return pixel; + } + + if ((in_bpp == 16) && (out_bpp == 16)) + { + return in_color; + } + + if ((in_bpp == 16) && (out_bpp == 24)) + { + pixel = in_color; + SPLITCOLOR16(red, green, blue, pixel); + pixel = COLOR24BGR(red, green, blue); + return pixel; + } + + if ((in_bpp == 24) && (out_bpp == 24)) + { + return in_color; + } + + return 0; } diff --git a/rdp/rdp_rdp.c b/rdp/rdp_rdp.c index b3c6d42a..c42d6e5f 100644 --- a/rdp/rdp_rdp.c +++ b/rdp/rdp_rdp.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - librdp rdp layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * librdp rdp layer + */ #include "rdp.h" @@ -27,321 +25,332 @@ #endif /*****************************************************************************/ -struct rdp_rdp* APP_CC -rdp_rdp_create(struct mod* owner) +struct rdp_rdp *APP_CC +rdp_rdp_create(struct mod *owner) { - struct rdp_rdp* self; + struct rdp_rdp *self; - self = (struct rdp_rdp*)g_malloc(sizeof(struct rdp_rdp), 1); - self->mod = owner; - self->sec_layer = rdp_sec_create(self); - self->bitmap_compression = 1; - self->bitmap_cache = 1; - self->desktop_save = 0; - self->orders = rdp_orders_create(self); - self->rec_mode = 0; - return self; + self = (struct rdp_rdp *)g_malloc(sizeof(struct rdp_rdp), 1); + self->mod = owner; + self->sec_layer = rdp_sec_create(self); + self->bitmap_compression = 1; + self->bitmap_cache = 1; + self->desktop_save = 0; + self->orders = rdp_orders_create(self); + self->rec_mode = 0; + return self; } /*****************************************************************************/ void APP_CC -rdp_rdp_delete(struct rdp_rdp* self) +rdp_rdp_delete(struct rdp_rdp *self) { - if (self == 0) - { - return; - } - rdp_orders_delete(self->orders); - rdp_sec_delete(self->sec_layer); - if (self->rec_fd != 0) - { - g_file_close(self->rec_fd); - self->rec_fd = 0; - } - g_free(self); + if (self == 0) + { + return; + } + + rdp_orders_delete(self->orders); + rdp_sec_delete(self->sec_layer); + + if (self->rec_fd != 0) + { + g_file_close(self->rec_fd); + self->rec_fd = 0; + } + + g_free(self); } /******************************************************************************/ /* Initialise an RDP packet */ int APP_CC -rdp_rdp_init(struct rdp_rdp* self, struct stream* s) +rdp_rdp_init(struct rdp_rdp *self, struct stream *s) { - if (rdp_sec_init(self->sec_layer, s, SEC_ENCRYPT) != 0) - { - return 1; - } - s_push_layer(s, rdp_hdr, 6); - return 0; + if (rdp_sec_init(self->sec_layer, s, SEC_ENCRYPT) != 0) + { + return 1; + } + + s_push_layer(s, rdp_hdr, 6); + return 0; } /******************************************************************************/ /* Send an RDP packet */ int APP_CC -rdp_rdp_send(struct rdp_rdp* self, struct stream* s, int pdu_type) +rdp_rdp_send(struct rdp_rdp *self, struct stream *s, int pdu_type) { - int len; - int sec_flags; + int len; + int sec_flags; - s_pop_layer(s, rdp_hdr); - len = s->end - s->p; - out_uint16_le(s, len); - out_uint16_le(s, pdu_type | 0x10); - out_uint16_le(s, self->sec_layer->mcs_layer->userid); - sec_flags = SEC_ENCRYPT; - if (rdp_sec_send(self->sec_layer, s, sec_flags) != 0) - { - return 1; - } - return 0; + s_pop_layer(s, rdp_hdr); + len = s->end - s->p; + out_uint16_le(s, len); + out_uint16_le(s, pdu_type | 0x10); + out_uint16_le(s, self->sec_layer->mcs_layer->userid); + sec_flags = SEC_ENCRYPT; + + if (rdp_sec_send(self->sec_layer, s, sec_flags) != 0) + { + return 1; + } + + return 0; } /******************************************************************************/ /* Initialise an RDP data packet */ int APP_CC -rdp_rdp_init_data(struct rdp_rdp* self, struct stream* s) +rdp_rdp_init_data(struct rdp_rdp *self, struct stream *s) { - if (rdp_sec_init(self->sec_layer, s, SEC_ENCRYPT) != 0) - { - return 1; - } - s_push_layer(s, rdp_hdr, 18); - return 0; + if (rdp_sec_init(self->sec_layer, s, SEC_ENCRYPT) != 0) + { + return 1; + } + + s_push_layer(s, rdp_hdr, 18); + return 0; } /******************************************************************************/ /* Send an RDP data packet */ int APP_CC -rdp_rdp_send_data(struct rdp_rdp* self, struct stream* s, int pdu_data_type) +rdp_rdp_send_data(struct rdp_rdp *self, struct stream *s, int pdu_data_type) { - int len; - int sec_flags; + int len; + int sec_flags; - s_pop_layer(s, rdp_hdr); - len = s->end - s->p; - out_uint16_le(s, len); - out_uint16_le(s, RDP_PDU_DATA | 0x10); - out_uint16_le(s, self->sec_layer->mcs_layer->userid); - out_uint32_le(s, self->share_id); - out_uint8(s, 0); - out_uint8(s, 1); - out_uint16_le(s, len - 14); - out_uint8(s, pdu_data_type); - out_uint8(s, 0); /* compress type */ - out_uint16_le(s, 0); /* compress len */ - sec_flags = SEC_ENCRYPT; - if (rdp_sec_send(self->sec_layer, s, sec_flags) != 0) - { - return 1; - } - return 0; + s_pop_layer(s, rdp_hdr); + len = s->end - s->p; + out_uint16_le(s, len); + out_uint16_le(s, RDP_PDU_DATA | 0x10); + out_uint16_le(s, self->sec_layer->mcs_layer->userid); + out_uint32_le(s, self->share_id); + out_uint8(s, 0); + out_uint8(s, 1); + out_uint16_le(s, len - 14); + out_uint8(s, pdu_data_type); + out_uint8(s, 0); /* compress type */ + out_uint16_le(s, 0); /* compress len */ + sec_flags = SEC_ENCRYPT; + + if (rdp_sec_send(self->sec_layer, s, sec_flags) != 0) + { + return 1; + } + + return 0; } /******************************************************************************/ /* Output general capability set */ static int APP_CC -rdp_rdp_out_general_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_out_general_caps(struct rdp_rdp *self, struct stream *s) { - out_uint16_le(s, RDP_CAPSET_GENERAL); - out_uint16_le(s, RDP_CAPLEN_GENERAL); - out_uint16_le(s, 1); /* OS major type */ - out_uint16_le(s, 3); /* OS minor type */ - out_uint16_le(s, 0x200); /* Protocol version */ - out_uint16_le(s, 0); /* Pad */ - out_uint16_le(s, 0); /* Compression types */ - out_uint16_le(s, self->use_rdp5 ? 0x40d : 0); - out_uint16_le(s, 0); /* Update capability */ - out_uint16_le(s, 0); /* Remote unshare capability */ - out_uint16_le(s, 0); /* Compression level */ - out_uint16_le(s, 0); /* Pad */ - return 0; + out_uint16_le(s, RDP_CAPSET_GENERAL); + out_uint16_le(s, RDP_CAPLEN_GENERAL); + out_uint16_le(s, 1); /* OS major type */ + out_uint16_le(s, 3); /* OS minor type */ + out_uint16_le(s, 0x200); /* Protocol version */ + out_uint16_le(s, 0); /* Pad */ + out_uint16_le(s, 0); /* Compression types */ + out_uint16_le(s, self->use_rdp5 ? 0x40d : 0); + out_uint16_le(s, 0); /* Update capability */ + out_uint16_le(s, 0); /* Remote unshare capability */ + out_uint16_le(s, 0); /* Compression level */ + out_uint16_le(s, 0); /* Pad */ + return 0; } /******************************************************************************/ /* Output bitmap capability set */ static int APP_CC -rdp_rdp_out_bitmap_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_out_bitmap_caps(struct rdp_rdp *self, struct stream *s) { - out_uint16_le(s, RDP_CAPSET_BITMAP); - out_uint16_le(s, RDP_CAPLEN_BITMAP); - out_uint16_le(s, self->mod->rdp_bpp); /* Preferred BPP */ - out_uint16_le(s, 1); /* Receive 1 BPP */ - out_uint16_le(s, 1); /* Receive 4 BPP */ - out_uint16_le(s, 1); /* Receive 8 BPP */ - out_uint16_le(s, 800); /* Desktop width */ - out_uint16_le(s, 600); /* Desktop height */ - out_uint16_le(s, 0); /* Pad */ - out_uint16_le(s, 1); /* Allow resize */ - out_uint16_le(s, self->bitmap_compression); /* Support compression */ - out_uint16_le(s, 0); /* Unknown */ - out_uint16_le(s, 1); /* Unknown */ - out_uint16_le(s, 0); /* Pad */ - return 0; + out_uint16_le(s, RDP_CAPSET_BITMAP); + out_uint16_le(s, RDP_CAPLEN_BITMAP); + out_uint16_le(s, self->mod->rdp_bpp); /* Preferred BPP */ + out_uint16_le(s, 1); /* Receive 1 BPP */ + out_uint16_le(s, 1); /* Receive 4 BPP */ + out_uint16_le(s, 1); /* Receive 8 BPP */ + out_uint16_le(s, 800); /* Desktop width */ + out_uint16_le(s, 600); /* Desktop height */ + out_uint16_le(s, 0); /* Pad */ + out_uint16_le(s, 1); /* Allow resize */ + out_uint16_le(s, self->bitmap_compression); /* Support compression */ + out_uint16_le(s, 0); /* Unknown */ + out_uint16_le(s, 1); /* Unknown */ + out_uint16_le(s, 0); /* Pad */ + return 0; } /******************************************************************************/ /* Output order capability set */ static int APP_CC -rdp_rdp_out_order_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_out_order_caps(struct rdp_rdp *self, struct stream *s) { - char order_caps[32]; + char order_caps[32]; - g_memset(order_caps, 0, 32); - order_caps[0] = 1; /* dest blt */ - order_caps[1] = 1; /* pat blt */ - order_caps[2] = 1; /* screen blt */ - order_caps[3] = self->bitmap_cache; /* memblt */ - order_caps[4] = 0; /* triblt */ - order_caps[8] = 1; /* line */ - order_caps[9] = 1; /* line */ - order_caps[10] = 1; /* rect */ - order_caps[11] = self->desktop_save; /* desksave */ - order_caps[13] = 1; /* memblt another above */ - order_caps[14] = 1; /* triblt another above */ - order_caps[20] = self->polygon_ellipse_orders; /* polygon */ - order_caps[21] = self->polygon_ellipse_orders; /* polygon2 */ - order_caps[22] = 0; /* todo polyline */ - order_caps[25] = self->polygon_ellipse_orders; /* ellipse */ - order_caps[26] = self->polygon_ellipse_orders; /* ellipse2 */ - order_caps[27] = 1; /* text2 */ - out_uint16_le(s, RDP_CAPSET_ORDER); - out_uint16_le(s, RDP_CAPLEN_ORDER); - out_uint8s(s, 20); /* Terminal desc, pad */ - out_uint16_le(s, 1); /* Cache X granularity */ - out_uint16_le(s, 20); /* Cache Y granularity */ - out_uint16_le(s, 0); /* Pad */ - out_uint16_le(s, 1); /* Max order level */ - out_uint16_le(s, 0x147); /* Number of fonts */ - out_uint16_le(s, 0x2a); /* Capability flags */ - out_uint8p(s, order_caps, 32); /* Orders supported */ - out_uint16_le(s, 0x6a1); /* Text capability flags */ - out_uint8s(s, 6); /* Pad */ - out_uint32_le(s, self->desktop_save * 0x38400); /* Desktop cache size */ - out_uint32_le(s, 0); /* Unknown */ - out_uint32_le(s, 0x4e4); /* Unknown */ - return 0; + g_memset(order_caps, 0, 32); + order_caps[0] = 1; /* dest blt */ + order_caps[1] = 1; /* pat blt */ + order_caps[2] = 1; /* screen blt */ + order_caps[3] = self->bitmap_cache; /* memblt */ + order_caps[4] = 0; /* triblt */ + order_caps[8] = 1; /* line */ + order_caps[9] = 1; /* line */ + order_caps[10] = 1; /* rect */ + order_caps[11] = self->desktop_save; /* desksave */ + order_caps[13] = 1; /* memblt another above */ + order_caps[14] = 1; /* triblt another above */ + order_caps[20] = self->polygon_ellipse_orders; /* polygon */ + order_caps[21] = self->polygon_ellipse_orders; /* polygon2 */ + order_caps[22] = 0; /* todo polyline */ + order_caps[25] = self->polygon_ellipse_orders; /* ellipse */ + order_caps[26] = self->polygon_ellipse_orders; /* ellipse2 */ + order_caps[27] = 1; /* text2 */ + out_uint16_le(s, RDP_CAPSET_ORDER); + out_uint16_le(s, RDP_CAPLEN_ORDER); + out_uint8s(s, 20); /* Terminal desc, pad */ + out_uint16_le(s, 1); /* Cache X granularity */ + out_uint16_le(s, 20); /* Cache Y granularity */ + out_uint16_le(s, 0); /* Pad */ + out_uint16_le(s, 1); /* Max order level */ + out_uint16_le(s, 0x147); /* Number of fonts */ + out_uint16_le(s, 0x2a); /* Capability flags */ + out_uint8p(s, order_caps, 32); /* Orders supported */ + out_uint16_le(s, 0x6a1); /* Text capability flags */ + out_uint8s(s, 6); /* Pad */ + out_uint32_le(s, self->desktop_save * 0x38400); /* Desktop cache size */ + out_uint32_le(s, 0); /* Unknown */ + out_uint32_le(s, 0x4e4); /* Unknown */ + return 0; } /******************************************************************************/ /* Output bitmap cache capability set */ static int APP_CC -rdp_rdp_out_bmpcache_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_out_bmpcache_caps(struct rdp_rdp *self, struct stream *s) { - int Bpp = 0; + int Bpp = 0; - out_uint16_le(s, RDP_CAPSET_BMPCACHE); - out_uint16_le(s, RDP_CAPLEN_BMPCACHE); - Bpp = (self->mod->rdp_bpp + 7) / 8; - out_uint8s(s, 24); /* unused */ - out_uint16_le(s, 0x258); /* entries */ - out_uint16_le(s, 0x100 * Bpp); /* max cell size */ - out_uint16_le(s, 0x12c); /* entries */ - out_uint16_le(s, 0x400 * Bpp); /* max cell size */ - out_uint16_le(s, 0x106); /* entries */ - out_uint16_le(s, 0x1000 * Bpp); /* max cell size */ - return 0; + out_uint16_le(s, RDP_CAPSET_BMPCACHE); + out_uint16_le(s, RDP_CAPLEN_BMPCACHE); + Bpp = (self->mod->rdp_bpp + 7) / 8; + out_uint8s(s, 24); /* unused */ + out_uint16_le(s, 0x258); /* entries */ + out_uint16_le(s, 0x100 * Bpp); /* max cell size */ + out_uint16_le(s, 0x12c); /* entries */ + out_uint16_le(s, 0x400 * Bpp); /* max cell size */ + out_uint16_le(s, 0x106); /* entries */ + out_uint16_le(s, 0x1000 * Bpp); /* max cell size */ + return 0; } /******************************************************************************/ /* Output control capability set */ static int APP_CC -rdp_rdp_out_control_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_out_control_caps(struct rdp_rdp *self, struct stream *s) { - out_uint16_le(s, RDP_CAPSET_CONTROL); - out_uint16_le(s, RDP_CAPLEN_CONTROL); - out_uint16_le(s, 0); /* Control capabilities */ - out_uint16_le(s, 0); /* Remote detach */ - out_uint16_le(s, 2); /* Control interest */ - out_uint16_le(s, 2); /* Detach interest */ - return 0; + out_uint16_le(s, RDP_CAPSET_CONTROL); + out_uint16_le(s, RDP_CAPLEN_CONTROL); + out_uint16_le(s, 0); /* Control capabilities */ + out_uint16_le(s, 0); /* Remote detach */ + out_uint16_le(s, 2); /* Control interest */ + out_uint16_le(s, 2); /* Detach interest */ + return 0; } /******************************************************************************/ /* Output activation capability set */ static int APP_CC -rdp_rdp_out_activate_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_out_activate_caps(struct rdp_rdp *self, struct stream *s) { - out_uint16_le(s, RDP_CAPSET_ACTIVATE); - out_uint16_le(s, RDP_CAPLEN_ACTIVATE); - out_uint16_le(s, 0); /* Help key */ - out_uint16_le(s, 0); /* Help index key */ - out_uint16_le(s, 0); /* Extended help key */ - out_uint16_le(s, 0); /* Window activate */ - return 0; + out_uint16_le(s, RDP_CAPSET_ACTIVATE); + out_uint16_le(s, RDP_CAPLEN_ACTIVATE); + out_uint16_le(s, 0); /* Help key */ + out_uint16_le(s, 0); /* Help index key */ + out_uint16_le(s, 0); /* Extended help key */ + out_uint16_le(s, 0); /* Window activate */ + return 0; } /******************************************************************************/ /* Output pointer capability set */ static int APP_CC -rdp_rdp_out_pointer_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_out_pointer_caps(struct rdp_rdp *self, struct stream *s) { - out_uint16_le(s, RDP_CAPSET_POINTER); - out_uint16_le(s, RDP_CAPLEN_POINTER_MONO); - out_uint16_le(s, 0); /* Color pointer */ - out_uint16_le(s, 20); /* Cache size */ - return 0; + out_uint16_le(s, RDP_CAPSET_POINTER); + out_uint16_le(s, RDP_CAPLEN_POINTER_MONO); + out_uint16_le(s, 0); /* Color pointer */ + out_uint16_le(s, 20); /* Cache size */ + return 0; } /******************************************************************************/ /* Output share capability set */ static int APP_CC -rdp_rdp_out_share_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_out_share_caps(struct rdp_rdp *self, struct stream *s) { - out_uint16_le(s, RDP_CAPSET_SHARE); - out_uint16_le(s, RDP_CAPLEN_SHARE); - out_uint16_le(s, 0); /* userid */ - out_uint16_le(s, 0); /* pad */ - return 0; + out_uint16_le(s, RDP_CAPSET_SHARE); + out_uint16_le(s, RDP_CAPLEN_SHARE); + out_uint16_le(s, 0); /* userid */ + out_uint16_le(s, 0); /* pad */ + return 0; } /******************************************************************************/ /* Output color cache capability set */ static int APP_CC -rdp_rdp_out_colcache_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_out_colcache_caps(struct rdp_rdp *self, struct stream *s) { - out_uint16_le(s, RDP_CAPSET_COLCACHE); - out_uint16_le(s, RDP_CAPLEN_COLCACHE); - out_uint16_le(s, 6); /* cache size */ - out_uint16_le(s, 0); /* pad */ - return 0; + out_uint16_le(s, RDP_CAPSET_COLCACHE); + out_uint16_le(s, RDP_CAPLEN_COLCACHE); + out_uint16_le(s, 6); /* cache size */ + out_uint16_le(s, 0); /* pad */ + return 0; } -static char caps_0x0d[] = { -0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00 +static char caps_0x0d[] = +{ + 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; static char caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 }; static char caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 }; -static char caps_0x10[] = { -0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, -0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00, -0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, -0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00, -0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, -0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00 +static char caps_0x10[] = +{ + 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, + 0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00, + 0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, + 0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00, + 0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, + 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00 }; /******************************************************************************/ /* Output unknown capability sets */ static int APP_CC -rdp_rdp_out_unknown_caps(struct rdp_rdp* self, struct stream* s, int id, - int length, char* caps) +rdp_rdp_out_unknown_caps(struct rdp_rdp *self, struct stream *s, int id, + int length, char *caps) { - out_uint16_le(s, id); - out_uint16_le(s, length); - out_uint8p(s, caps, length - 4); - return 0; + out_uint16_le(s, id); + out_uint16_le(s, length); + out_uint8p(s, caps, length - 4); + return 0; } #define RDP5_FLAG 0x0030 @@ -349,774 +358,843 @@ rdp_rdp_out_unknown_caps(struct rdp_rdp* self, struct stream* s, int id, /******************************************************************************/ /* Send a confirm active PDU */ static int APP_CC -rdp_rdp_send_confirm_active(struct rdp_rdp* self, struct stream* s) +rdp_rdp_send_confirm_active(struct rdp_rdp *self, struct stream *s) { - int sec_flags; - int caplen; + int sec_flags; + int caplen; - sec_flags = SEC_ENCRYPT; - //sec_flags = RDP5_FLAG | SEC_ENCRYPT; - caplen = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER + - RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + - RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL + - RDP_CAPLEN_POINTER_MONO + RDP_CAPLEN_SHARE + - 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ + - 4 /* w2k fix, why? */ ; - if (rdp_sec_init(self->sec_layer, s, sec_flags) != 0) - { - return 1; - } - out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE)); - out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */ - out_uint16_le(s, (self->sec_layer->mcs_layer->userid + 1001)); - out_uint32_le(s, self->share_id); - out_uint16_le(s, 0x3ea); /* userid */ - out_uint16_le(s, sizeof(RDP_SOURCE)); - out_uint16_le(s, caplen); - out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE)); - out_uint16_le(s, 0xd); /* num_caps */ - out_uint8s(s, 2); /* pad */ - rdp_rdp_out_general_caps(self, s); - rdp_rdp_out_bitmap_caps(self, s); - rdp_rdp_out_order_caps(self, s); - rdp_rdp_out_bmpcache_caps(self, s); - rdp_rdp_out_colcache_caps(self, s); - rdp_rdp_out_activate_caps(self, s); - rdp_rdp_out_control_caps(self, s); - rdp_rdp_out_pointer_caps(self, s); - rdp_rdp_out_share_caps(self, s); - rdp_rdp_out_unknown_caps(self, s, 0x0d, 0x58, caps_0x0d); /* international? */ - rdp_rdp_out_unknown_caps(self, s, 0x0c, 0x08, caps_0x0c); - rdp_rdp_out_unknown_caps(self, s, 0x0e, 0x08, caps_0x0e); - rdp_rdp_out_unknown_caps(self, s, 0x10, 0x34, caps_0x10); /* glyph cache? */ - s_mark_end(s); - if (rdp_sec_send(self->sec_layer, s, sec_flags) != 0) - { - return 1; - } - return 0; + sec_flags = SEC_ENCRYPT; + //sec_flags = RDP5_FLAG | SEC_ENCRYPT; + caplen = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER + + RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + + RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL + + RDP_CAPLEN_POINTER_MONO + RDP_CAPLEN_SHARE + + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ + + 4 /* w2k fix, why? */ ; + + if (rdp_sec_init(self->sec_layer, s, sec_flags) != 0) + { + return 1; + } + + out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE)); + out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */ + out_uint16_le(s, (self->sec_layer->mcs_layer->userid + 1001)); + out_uint32_le(s, self->share_id); + out_uint16_le(s, 0x3ea); /* userid */ + out_uint16_le(s, sizeof(RDP_SOURCE)); + out_uint16_le(s, caplen); + out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE)); + out_uint16_le(s, 0xd); /* num_caps */ + out_uint8s(s, 2); /* pad */ + rdp_rdp_out_general_caps(self, s); + rdp_rdp_out_bitmap_caps(self, s); + rdp_rdp_out_order_caps(self, s); + rdp_rdp_out_bmpcache_caps(self, s); + rdp_rdp_out_colcache_caps(self, s); + rdp_rdp_out_activate_caps(self, s); + rdp_rdp_out_control_caps(self, s); + rdp_rdp_out_pointer_caps(self, s); + rdp_rdp_out_share_caps(self, s); + rdp_rdp_out_unknown_caps(self, s, 0x0d, 0x58, caps_0x0d); /* international? */ + rdp_rdp_out_unknown_caps(self, s, 0x0c, 0x08, caps_0x0c); + rdp_rdp_out_unknown_caps(self, s, 0x0e, 0x08, caps_0x0e); + rdp_rdp_out_unknown_caps(self, s, 0x10, 0x34, caps_0x10); /* glyph cache? */ + s_mark_end(s); + + if (rdp_sec_send(self->sec_layer, s, sec_flags) != 0) + { + return 1; + } + + return 0; } /******************************************************************************/ /* Process a color pointer PDU */ static int APP_CC -rdp_rdp_process_color_pointer_pdu(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_color_pointer_pdu(struct rdp_rdp *self, struct stream *s) { - int cache_idx; - int dlen; - int mlen; - struct rdp_cursor* cursor; + int cache_idx; + int dlen; + int mlen; + struct rdp_cursor *cursor; - in_uint16_le(s, cache_idx); - if (cache_idx >= sizeof(self->cursors) / sizeof(cursor)) - { - return 1; - } - cursor = self->cursors + cache_idx; - in_uint16_le(s, cursor->x); - in_uint16_le(s, cursor->y); - in_uint16_le(s, cursor->width); - in_uint16_le(s, cursor->height); - in_uint16_le(s, mlen); /* mask length */ - in_uint16_le(s, dlen); /* data length */ - if ((mlen > sizeof(cursor->mask)) || (dlen > sizeof(cursor->data))) - { - return 1; - } - in_uint8a(s, cursor->data, dlen); - in_uint8a(s, cursor->mask, mlen); - self->mod->server_set_cursor(self->mod, cursor->x, cursor->y, - cursor->data, cursor->mask); - return 0; + in_uint16_le(s, cache_idx); + + if (cache_idx >= sizeof(self->cursors) / sizeof(cursor)) + { + return 1; + } + + cursor = self->cursors + cache_idx; + in_uint16_le(s, cursor->x); + in_uint16_le(s, cursor->y); + in_uint16_le(s, cursor->width); + in_uint16_le(s, cursor->height); + in_uint16_le(s, mlen); /* mask length */ + in_uint16_le(s, dlen); /* data length */ + + if ((mlen > sizeof(cursor->mask)) || (dlen > sizeof(cursor->data))) + { + return 1; + } + + in_uint8a(s, cursor->data, dlen); + in_uint8a(s, cursor->mask, mlen); + self->mod->server_set_cursor(self->mod, cursor->x, cursor->y, + cursor->data, cursor->mask); + return 0; } /******************************************************************************/ /* Process a cached pointer PDU */ static int APP_CC -rdp_rdp_process_cached_pointer_pdu(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_cached_pointer_pdu(struct rdp_rdp *self, struct stream *s) { - int cache_idx; - struct rdp_cursor* cursor; + int cache_idx; + struct rdp_cursor *cursor; - in_uint16_le(s, cache_idx); - if (cache_idx >= sizeof(self->cursors) / sizeof(cursor)) - { - return 1; - } - cursor = self->cursors + cache_idx; - self->mod->server_set_cursor(self->mod, cursor->x, cursor->y, - cursor->data, cursor->mask); - return 0; + in_uint16_le(s, cache_idx); + + if (cache_idx >= sizeof(self->cursors) / sizeof(cursor)) + { + return 1; + } + + cursor = self->cursors + cache_idx; + self->mod->server_set_cursor(self->mod, cursor->x, cursor->y, + cursor->data, cursor->mask); + return 0; } /******************************************************************************/ /* Process a system pointer PDU */ static int APP_CC -rdp_rdp_process_system_pointer_pdu(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_system_pointer_pdu(struct rdp_rdp *self, struct stream *s) { - int system_pointer_type; - struct rdp_cursor* cursor; + int system_pointer_type; + struct rdp_cursor *cursor; - in_uint16_le(s, system_pointer_type); - switch (system_pointer_type) - { - case RDP_NULL_POINTER: - cursor = (struct rdp_cursor*)g_malloc(sizeof(struct rdp_cursor), 1); - g_memset(cursor->mask, 0xff, sizeof(cursor->mask)); - self->mod->server_set_cursor(self->mod, cursor->x, cursor->y, - cursor->data, cursor->mask); - g_free(cursor); - break; - default: - break; - } - return 0; + in_uint16_le(s, system_pointer_type); + + switch (system_pointer_type) + { + case RDP_NULL_POINTER: + cursor = (struct rdp_cursor *)g_malloc(sizeof(struct rdp_cursor), 1); + g_memset(cursor->mask, 0xff, sizeof(cursor->mask)); + self->mod->server_set_cursor(self->mod, cursor->x, cursor->y, + cursor->data, cursor->mask); + g_free(cursor); + break; + default: + break; + } + + return 0; } /******************************************************************************/ /* Process a pointer PDU */ static int APP_CC -rdp_rdp_process_pointer_pdu(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_pointer_pdu(struct rdp_rdp *self, struct stream *s) { - int message_type; - int x; - int y; - int rv; + int message_type; + int x; + int y; + int rv; - rv = 0; - in_uint16_le(s, message_type); - in_uint8s(s, 2); /* pad */ - switch (message_type) - { - case RDP_POINTER_MOVE: - in_uint16_le(s, x); - in_uint16_le(s, y); - break; - case RDP_POINTER_COLOR: - rv = rdp_rdp_process_color_pointer_pdu(self, s); - break; - case RDP_POINTER_CACHED: - rv = rdp_rdp_process_cached_pointer_pdu(self, s); - break; - case RDP_POINTER_SYSTEM: - rv = rdp_rdp_process_system_pointer_pdu(self, s); - break; - default: - break; - } - return rv; + rv = 0; + in_uint16_le(s, message_type); + in_uint8s(s, 2); /* pad */ + + switch (message_type) + { + case RDP_POINTER_MOVE: + in_uint16_le(s, x); + in_uint16_le(s, y); + break; + case RDP_POINTER_COLOR: + rv = rdp_rdp_process_color_pointer_pdu(self, s); + break; + case RDP_POINTER_CACHED: + rv = rdp_rdp_process_cached_pointer_pdu(self, s); + break; + case RDP_POINTER_SYSTEM: + rv = rdp_rdp_process_system_pointer_pdu(self, s); + break; + default: + break; + } + + return rv; } /******************************************************************************/ /* Process bitmap updates */ static void APP_CC -rdp_rdp_process_bitmap_updates(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_bitmap_updates(struct rdp_rdp *self, struct stream *s) { - int num_updates = 0; - int left = 0; - int top = 0; - int right = 0; - int bottom = 0; - int width = 0; - int height = 0; - int cx = 0; - int cy = 0; - int bpp = 0; - int Bpp = 0; - int compress = 0; - int bufsize = 0; - int size = 0; - int i = 0; - int x = 0; - int y = 0; - char* data = NULL; - char* bmpdata0 = NULL; - char* bmpdata1 = NULL; + int num_updates = 0; + int left = 0; + int top = 0; + int right = 0; + int bottom = 0; + int width = 0; + int height = 0; + int cx = 0; + int cy = 0; + int bpp = 0; + int Bpp = 0; + int compress = 0; + int bufsize = 0; + int size = 0; + int i = 0; + int x = 0; + int y = 0; + char *data = NULL; + char *bmpdata0 = NULL; + char *bmpdata1 = NULL; - in_uint16_le(s, num_updates); - for (i = 0; i < num_updates; i++) - { - in_uint16_le(s, left); - in_uint16_le(s, top); - in_uint16_le(s, right); - in_uint16_le(s, bottom); - in_uint16_le(s, width); - in_uint16_le(s, height); - in_uint16_le(s, bpp); - Bpp = (bpp + 7) / 8; - in_uint16_le(s, compress); - in_uint16_le(s, bufsize); - cx = (right - left) + 1; - cy = (bottom - top) + 1; - bmpdata0 = (char*)g_malloc(width * height * Bpp, 0); - if (compress) + in_uint16_le(s, num_updates); + + for (i = 0; i < num_updates; i++) { - if (compress & 0x400) - { - size = bufsize; - } - else - { - in_uint8s(s, 2); /* pad */ - in_uint16_le(s, size); - in_uint8s(s, 4); /* line_size, final_size */ - } - in_uint8p(s, data, size); - rdp_bitmap_decompress(bmpdata0, width, height, data, size, Bpp); - bmpdata1 = rdp_orders_convert_bitmap(bpp, self->mod->xrdp_bpp, - bmpdata0, width, height, - self->colormap.colors); - self->mod->server_paint_rect(self->mod, left, top, cx, cy, bmpdata1, - width, height, 0, 0); - } - else /* not compressed */ - { - for (y = 0; y < height; y++) - { - data = bmpdata0 + ((height - y) - 1) * (width * Bpp); - if (Bpp == 1) + in_uint16_le(s, left); + in_uint16_le(s, top); + in_uint16_le(s, right); + in_uint16_le(s, bottom); + in_uint16_le(s, width); + in_uint16_le(s, height); + in_uint16_le(s, bpp); + Bpp = (bpp + 7) / 8; + in_uint16_le(s, compress); + in_uint16_le(s, bufsize); + cx = (right - left) + 1; + cy = (bottom - top) + 1; + bmpdata0 = (char *)g_malloc(width * height * Bpp, 0); + + if (compress) { - for (x = 0; x < width; x++) - { - in_uint8(s, data[x]); - } + if (compress & 0x400) + { + size = bufsize; + } + else + { + in_uint8s(s, 2); /* pad */ + in_uint16_le(s, size); + in_uint8s(s, 4); /* line_size, final_size */ + } + + in_uint8p(s, data, size); + rdp_bitmap_decompress(bmpdata0, width, height, data, size, Bpp); + bmpdata1 = rdp_orders_convert_bitmap(bpp, self->mod->xrdp_bpp, + bmpdata0, width, height, + self->colormap.colors); + self->mod->server_paint_rect(self->mod, left, top, cx, cy, bmpdata1, + width, height, 0, 0); } - else if (Bpp == 2) + else /* not compressed */ { - for (x = 0; x < width; x++) - { - in_uint16_le(s, ((tui16*)data)[x]); - } + for (y = 0; y < height; y++) + { + data = bmpdata0 + ((height - y) - 1) * (width * Bpp); + + if (Bpp == 1) + { + for (x = 0; x < width; x++) + { + in_uint8(s, data[x]); + } + } + else if (Bpp == 2) + { + for (x = 0; x < width; x++) + { + in_uint16_le(s, ((tui16 *)data)[x]); + } + } + else if (Bpp == 3) + { + for (x = 0; x < width; x++) + { + in_uint8(s, data[x * 3 + 0]); + in_uint8(s, data[x * 3 + 1]); + in_uint8(s, data[x * 3 + 2]); + } + } + } + + bmpdata1 = rdp_orders_convert_bitmap(bpp, self->mod->xrdp_bpp, + bmpdata0, width, height, + self->colormap.colors); + self->mod->server_paint_rect(self->mod, left, top, cx, cy, bmpdata1, + width, height, 0, 0); } - else if (Bpp == 3) + + if (bmpdata0 != bmpdata1) { - for (x = 0; x < width; x++) - { - in_uint8(s, data[x * 3 + 0]); - in_uint8(s, data[x * 3 + 1]); - in_uint8(s, data[x * 3 + 2]); - } + g_free(bmpdata1); } - } - bmpdata1 = rdp_orders_convert_bitmap(bpp, self->mod->xrdp_bpp, - bmpdata0, width, height, - self->colormap.colors); - self->mod->server_paint_rect(self->mod, left, top, cx, cy, bmpdata1, - width, height, 0, 0); + + g_free(bmpdata0); } - if (bmpdata0 != bmpdata1) - { - g_free(bmpdata1); - } - g_free(bmpdata0); - } } /******************************************************************************/ /* Process a palette update */ static void APP_CC -rdp_rdp_process_palette(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_palette(struct rdp_rdp *self, struct stream *s) { - int i; - int r; - int g; - int b; + int i; + int r; + int g; + int b; - in_uint8s(s, 2); /* pad */ - in_uint16_le(s, self->colormap.ncolors); - in_uint8s(s, 2); /* pad */ - for (i = 0; i < self->colormap.ncolors; i++) - { - in_uint8(s, r); - in_uint8(s, g); - in_uint8(s, b); - self->colormap.colors[i] = (r << 16) | (g << 8) | b; - } - //ui_set_colormap(hmap); + in_uint8s(s, 2); /* pad */ + in_uint16_le(s, self->colormap.ncolors); + in_uint8s(s, 2); /* pad */ + + for (i = 0; i < self->colormap.ncolors; i++) + { + in_uint8(s, r); + in_uint8(s, g); + in_uint8(s, b); + self->colormap.colors[i] = (r << 16) | (g << 8) | b; + } + + //ui_set_colormap(hmap); } /******************************************************************************/ /* Process an update PDU */ static int APP_CC -rdp_rdp_process_update_pdu(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_update_pdu(struct rdp_rdp *self, struct stream *s) { - int update_type; - int count; + int update_type; + int count; - in_uint16_le(s, update_type); - self->mod->server_begin_update(self->mod); - switch (update_type) - { - case RDP_UPDATE_ORDERS: - in_uint8s(s, 2); /* pad */ - in_uint16_le(s, count); - in_uint8s(s, 2); /* pad */ - rdp_orders_process_orders(self->orders, s, count); - break; - case RDP_UPDATE_BITMAP: - rdp_rdp_process_bitmap_updates(self, s); - break; - case RDP_UPDATE_PALETTE: - rdp_rdp_process_palette(self, s); - break; - case RDP_UPDATE_SYNCHRONIZE: - break; - default: - break; - } - self->mod->server_end_update(self->mod); - return 0; + in_uint16_le(s, update_type); + self->mod->server_begin_update(self->mod); + + switch (update_type) + { + case RDP_UPDATE_ORDERS: + in_uint8s(s, 2); /* pad */ + in_uint16_le(s, count); + in_uint8s(s, 2); /* pad */ + rdp_orders_process_orders(self->orders, s, count); + break; + case RDP_UPDATE_BITMAP: + rdp_rdp_process_bitmap_updates(self, s); + break; + case RDP_UPDATE_PALETTE: + rdp_rdp_process_palette(self, s); + break; + case RDP_UPDATE_SYNCHRONIZE: + break; + default: + break; + } + + self->mod->server_end_update(self->mod); + return 0; } /******************************************************************************/ void APP_CC -rdp_rdp_out_unistr(struct stream* s, char* text) +rdp_rdp_out_unistr(struct stream *s, char *text) { - int i; + int i; + + i = 0; + + while (text[i] != 0) + { + out_uint8(s, text[i]); + out_uint8(s, 0); + i++; + } - i = 0; - while (text[i] != 0) - { - out_uint8(s, text[i]); out_uint8(s, 0); - i++; - } - out_uint8(s, 0); - out_uint8(s, 0); + out_uint8(s, 0); } /******************************************************************************/ int APP_CC -rdp_rdp_send_login_info(struct rdp_rdp* self, int flags) +rdp_rdp_send_login_info(struct rdp_rdp *self, int flags) { - int len_domain; - int len_username; - int len_password; - int len_program; - int len_directory; - int sec_flags; - struct stream* s; + int len_domain; + int len_username; + int len_password; + int len_program; + int len_directory; + int sec_flags; + struct stream *s; + + DEBUG(("in rdp_rdp_send_login_info")); + make_stream(s); + init_stream(s, 8192); + len_domain = 2 * g_strlen(self->mod->domain); + len_username = 2 * g_strlen(self->mod->username); + len_password = 2 * g_strlen(self->mod->password); + len_program = 2 * g_strlen(self->mod->program); + len_directory = 2 * g_strlen(self->mod->directory); + sec_flags = SEC_LOGON_INFO | SEC_ENCRYPT; + + if (rdp_sec_init(self->sec_layer, s, sec_flags) != 0) + { + free_stream(s); + DEBUG(("out rdp_rdp_send_login_info error 1")); + return 1; + } + + out_uint32_le(s, 0); + out_uint32_le(s, flags); + out_uint16_le(s, len_domain); + out_uint16_le(s, len_username); + out_uint16_le(s, len_password); + out_uint16_le(s, len_program); + out_uint16_le(s, len_directory); + rdp_rdp_out_unistr(s, self->mod->domain); + rdp_rdp_out_unistr(s, self->mod->username); + rdp_rdp_out_unistr(s, self->mod->password); + rdp_rdp_out_unistr(s, self->mod->program); + rdp_rdp_out_unistr(s, self->mod->directory); + s_mark_end(s); + + if (rdp_sec_send(self->sec_layer, s, sec_flags) != 0) + { + free_stream(s); + DEBUG(("out rdp_rdp_send_login_info error 2")); + return 1; + } - DEBUG(("in rdp_rdp_send_login_info")); - make_stream(s); - init_stream(s, 8192); - len_domain = 2 * g_strlen(self->mod->domain); - len_username = 2 * g_strlen(self->mod->username); - len_password = 2 * g_strlen(self->mod->password); - len_program = 2 * g_strlen(self->mod->program); - len_directory = 2 * g_strlen(self->mod->directory); - sec_flags = SEC_LOGON_INFO | SEC_ENCRYPT; - if (rdp_sec_init(self->sec_layer, s, sec_flags) != 0) - { free_stream(s); - DEBUG(("out rdp_rdp_send_login_info error 1")); - return 1; - } - out_uint32_le(s, 0); - out_uint32_le(s, flags); - out_uint16_le(s, len_domain); - out_uint16_le(s, len_username); - out_uint16_le(s, len_password); - out_uint16_le(s, len_program); - out_uint16_le(s, len_directory); - rdp_rdp_out_unistr(s, self->mod->domain); - rdp_rdp_out_unistr(s, self->mod->username); - rdp_rdp_out_unistr(s, self->mod->password); - rdp_rdp_out_unistr(s, self->mod->program); - rdp_rdp_out_unistr(s, self->mod->directory); - s_mark_end(s); - if (rdp_sec_send(self->sec_layer, s, sec_flags) != 0) - { - free_stream(s); - DEBUG(("out rdp_rdp_send_login_info error 2")); - return 1; - } - free_stream(s); - DEBUG(("out rdp_rdp_send_login_info")); - return 0; + DEBUG(("out rdp_rdp_send_login_info")); + return 0; } /******************************************************************************/ int APP_CC -rdp_rdp_connect(struct rdp_rdp* self, char* ip, char* port) +rdp_rdp_connect(struct rdp_rdp *self, char *ip, char *port) { - int flags; + int flags; - DEBUG(("in rdp_rdp_connect")); - flags = RDP_LOGON_NORMAL; - if (g_strlen(self->mod->password) > 0) - { - flags |= RDP_LOGON_AUTO; - } - if (rdp_sec_connect(self->sec_layer, ip, port) != 0) - { - DEBUG(("out rdp_rdp_connect error rdp_sec_connect failed")); - return 1; - } - if (rdp_rdp_send_login_info(self, flags) != 0) - { - DEBUG(("out rdp_rdp_connect error rdp_rdp_send_login_info failed")); - return 1; - } - DEBUG(("out rdp_rdp_connect")); - return 0; + DEBUG(("in rdp_rdp_connect")); + flags = RDP_LOGON_NORMAL; + + if (g_strlen(self->mod->password) > 0) + { + flags |= RDP_LOGON_AUTO; + } + + if (rdp_sec_connect(self->sec_layer, ip, port) != 0) + { + DEBUG(("out rdp_rdp_connect error rdp_sec_connect failed")); + return 1; + } + + if (rdp_rdp_send_login_info(self, flags) != 0) + { + DEBUG(("out rdp_rdp_connect error rdp_rdp_send_login_info failed")); + return 1; + } + + DEBUG(("out rdp_rdp_connect")); + return 0; } /******************************************************************************/ int APP_CC -rdp_rdp_send_input(struct rdp_rdp* self, struct stream* s, +rdp_rdp_send_input(struct rdp_rdp *self, struct stream *s, int time, int message_type, int device_flags, int param1, int param2) { - if (rdp_rdp_init_data(self, s) != 0) - { - return 1; - } - out_uint16_le(s, 1); /* number of events */ - out_uint16_le(s, 0); - out_uint32_le(s, time); - out_uint16_le(s, message_type); - out_uint16_le(s, device_flags); - out_uint16_le(s, param1); - out_uint16_le(s, param2); - s_mark_end(s); - if (rdp_rdp_send_data(self, s, RDP_DATA_PDU_INPUT) != 0) - { - return 1; - } - return 0; + if (rdp_rdp_init_data(self, s) != 0) + { + return 1; + } + + out_uint16_le(s, 1); /* number of events */ + out_uint16_le(s, 0); + out_uint32_le(s, time); + out_uint16_le(s, message_type); + out_uint16_le(s, device_flags); + out_uint16_le(s, param1); + out_uint16_le(s, param2); + s_mark_end(s); + + if (rdp_rdp_send_data(self, s, RDP_DATA_PDU_INPUT) != 0) + { + return 1; + } + + return 0; } /******************************************************************************/ int APP_CC -rdp_rdp_send_invalidate(struct rdp_rdp* self, struct stream* s, +rdp_rdp_send_invalidate(struct rdp_rdp *self, struct stream *s, int left, int top, int width, int height) { - if (rdp_rdp_init_data(self, s) != 0) - { - return 1; - } - out_uint32_le(s, 1); - out_uint16_le(s, left); - out_uint16_le(s, top); - out_uint16_le(s, (left + width) - 1); - out_uint16_le(s, (top + height) - 1); - s_mark_end(s); - if (rdp_rdp_send_data(self, s, 33) != 0) - { - return 1; - } - return 0; + if (rdp_rdp_init_data(self, s) != 0) + { + return 1; + } + + out_uint32_le(s, 1); + out_uint16_le(s, left); + out_uint16_le(s, top); + out_uint16_le(s, (left + width) - 1); + out_uint16_le(s, (top + height) - 1); + s_mark_end(s); + + if (rdp_rdp_send_data(self, s, 33) != 0) + { + return 1; + } + + return 0; } /******************************************************************************/ int APP_CC -rdp_rdp_recv(struct rdp_rdp* self, struct stream* s, int* type) +rdp_rdp_recv(struct rdp_rdp *self, struct stream *s, int *type) { - int len; - int pdu_type; - int chan; + int len; + int pdu_type; + int chan; - chan = 0; - DEBUG(("in rdp_rdp_recv")); - if (s->next_packet >= s->end || s->next_packet == 0) - { - if (rdp_sec_recv(self->sec_layer, s, &chan) != 0) + chan = 0; + DEBUG(("in rdp_rdp_recv")); + + if (s->next_packet >= s->end || s->next_packet == 0) { - DEBUG(("error in rdp_rdp_recv, rdp_sec_recv failed")); - return 1; + if (rdp_sec_recv(self->sec_layer, s, &chan) != 0) + { + DEBUG(("error in rdp_rdp_recv, rdp_sec_recv failed")); + return 1; + } + + s->next_packet = s->p; } - s->next_packet = s->p; - } - else - { - chan = MCS_GLOBAL_CHANNEL; - s->p = s->next_packet; - } - if (chan == MCS_GLOBAL_CHANNEL) - { - in_uint16_le(s, len); - DEBUG(("rdp_rdp_recv got %d len", len)); - if (len == 0x8000) + else { - s->next_packet += 8; - DEBUG(("out rdp_rdp_recv")); - return 0; + chan = MCS_GLOBAL_CHANNEL; + s->p = s->next_packet; } - in_uint16_le(s, pdu_type); - in_uint8s(s, 2); - *type = pdu_type & 0xf; - s->next_packet += len; - } - else - { - /* todo, process channel data */ - DEBUG(("got channel data channel %d", chan)); - s->next_packet = s->end; - } - DEBUG(("out rdp_rdp_recv")); - return 0; + + if (chan == MCS_GLOBAL_CHANNEL) + { + in_uint16_le(s, len); + DEBUG(("rdp_rdp_recv got %d len", len)); + + if (len == 0x8000) + { + s->next_packet += 8; + DEBUG(("out rdp_rdp_recv")); + return 0; + } + + in_uint16_le(s, pdu_type); + in_uint8s(s, 2); + *type = pdu_type & 0xf; + s->next_packet += len; + } + else + { + /* todo, process channel data */ + DEBUG(("got channel data channel %d", chan)); + s->next_packet = s->end; + } + + DEBUG(("out rdp_rdp_recv")); + return 0; } /******************************************************************************/ static int APP_CC -rdp_rdp_process_disconnect_pdu(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_disconnect_pdu(struct rdp_rdp *self, struct stream *s) { - return 0; + return 0; } /******************************************************************************/ int APP_CC -rdp_rdp_process_data_pdu(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_data_pdu(struct rdp_rdp *self, struct stream *s) { - int data_pdu_type; - int ctype; - int len; - int rv; + int data_pdu_type; + int ctype; + int len; + int rv; - rv = 0; - in_uint8s(s, 6); /* shareid, pad, streamid */ - in_uint16_le(s, len); - in_uint8(s, data_pdu_type); - in_uint8(s, ctype); - in_uint8s(s, 2); /* clen */ - switch (data_pdu_type) - { - case RDP_DATA_PDU_UPDATE: - rv = rdp_rdp_process_update_pdu(self, s); - break; - case RDP_DATA_PDU_CONTROL: - break; - case RDP_DATA_PDU_SYNCHRONISE: - break; - case RDP_DATA_PDU_POINTER: - rv = rdp_rdp_process_pointer_pdu(self, s); - break; - case RDP_DATA_PDU_PLAY_SOUND: - break; - case RDP_DATA_PDU_LOGON: - break; - case RDP_DATA_PDU_DISCONNECT: - rv = rdp_rdp_process_disconnect_pdu(self, s); - break; - default: - break; - } - return rv; + rv = 0; + in_uint8s(s, 6); /* shareid, pad, streamid */ + in_uint16_le(s, len); + in_uint8(s, data_pdu_type); + in_uint8(s, ctype); + in_uint8s(s, 2); /* clen */ + + switch (data_pdu_type) + { + case RDP_DATA_PDU_UPDATE: + rv = rdp_rdp_process_update_pdu(self, s); + break; + case RDP_DATA_PDU_CONTROL: + break; + case RDP_DATA_PDU_SYNCHRONISE: + break; + case RDP_DATA_PDU_POINTER: + rv = rdp_rdp_process_pointer_pdu(self, s); + break; + case RDP_DATA_PDU_PLAY_SOUND: + break; + case RDP_DATA_PDU_LOGON: + break; + case RDP_DATA_PDU_DISCONNECT: + rv = rdp_rdp_process_disconnect_pdu(self, s); + break; + default: + break; + } + + return rv; } /******************************************************************************/ /* Process a bitmap capability set */ static void APP_CC -rdp_rdp_process_general_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_general_caps(struct rdp_rdp *self, struct stream *s) { } /******************************************************************************/ /* Process a bitmap capability set */ static void APP_CC -rdp_rdp_process_bitmap_caps(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_bitmap_caps(struct rdp_rdp *self, struct stream *s) { - int width = 0; - int height = 0; - int bpp = 0; + int width = 0; + int height = 0; + int bpp = 0; - in_uint16_le(s, bpp); - in_uint8s(s, 6); - in_uint16_le(s, width); - in_uint16_le(s, height); - self->mod->rdp_bpp = bpp; - /* todo, call reset if needed and use width and height */ + in_uint16_le(s, bpp); + in_uint8s(s, 6); + in_uint16_le(s, width); + in_uint16_le(s, height); + self->mod->rdp_bpp = bpp; + /* todo, call reset if needed and use width and height */ } /******************************************************************************/ /* Process server capabilities */ /* returns error */ static int APP_CC -rdp_rdp_process_server_caps(struct rdp_rdp* self, struct stream* s, int len) +rdp_rdp_process_server_caps(struct rdp_rdp *self, struct stream *s, int len) { - int n = 0; - int ncapsets = 0; - int capset_type = 0; - int capset_length = 0; - char* next = NULL; - char* start = NULL; + int n = 0; + int ncapsets = 0; + int capset_type = 0; + int capset_length = 0; + char *next = NULL; + char *start = NULL; - start = s->p; - in_uint16_le(s, ncapsets); - in_uint8s(s, 2); /* pad */ - for (n = 0; n < ncapsets; n++) - { - if (s->p > start + len) + start = s->p; + in_uint16_le(s, ncapsets); + in_uint8s(s, 2); /* pad */ + + for (n = 0; n < ncapsets; n++) { - return 0; + if (s->p > start + len) + { + return 0; + } + + in_uint16_le(s, capset_type); + in_uint16_le(s, capset_length); + next = (s->p + capset_length) - 4; + + switch (capset_type) + { + case RDP_CAPSET_GENERAL: + rdp_rdp_process_general_caps(self, s); + break; + case RDP_CAPSET_BITMAP: + rdp_rdp_process_bitmap_caps(self, s); + break; + default: + break; + } + + s->p = next; } - in_uint16_le(s, capset_type); - in_uint16_le(s, capset_length); - next = (s->p + capset_length) - 4; - switch (capset_type) - { - case RDP_CAPSET_GENERAL: - rdp_rdp_process_general_caps(self, s); - break; - case RDP_CAPSET_BITMAP: - rdp_rdp_process_bitmap_caps(self, s); - break; - default: - break; - } - s->p = next; - } - return 0; + + return 0; } /******************************************************************************/ /* Send a control PDU */ /* returns error */ static int APP_CC -rdp_rdp_send_control(struct rdp_rdp* self, struct stream* s, int action) +rdp_rdp_send_control(struct rdp_rdp *self, struct stream *s, int action) { - if (rdp_rdp_init_data(self, s) != 0) - { - return 1; - } - out_uint16_le(s, action); - out_uint16_le(s, 0); /* userid */ - out_uint32_le(s, 0); /* control id */ - s_mark_end(s); - if (rdp_rdp_send_data(self, s, RDP_DATA_PDU_CONTROL) != 0) - { - return 1; - } - return 0; + if (rdp_rdp_init_data(self, s) != 0) + { + return 1; + } + + out_uint16_le(s, action); + out_uint16_le(s, 0); /* userid */ + out_uint32_le(s, 0); /* control id */ + s_mark_end(s); + + if (rdp_rdp_send_data(self, s, RDP_DATA_PDU_CONTROL) != 0) + { + return 1; + } + + return 0; } /******************************************************************************/ /* Send a synchronisation PDU */ /* returns error */ static int APP_CC -rdp_rdp_send_synchronise(struct rdp_rdp* self, struct stream* s) +rdp_rdp_send_synchronise(struct rdp_rdp *self, struct stream *s) { - if (rdp_rdp_init_data(self, s) != 0) - { - return 1; - } - out_uint16_le(s, 1); /* type */ - out_uint16_le(s, 1002); - s_mark_end(s); - if (rdp_rdp_send_data(self, s, RDP_DATA_PDU_SYNCHRONISE) != 0) - { - return 1; - } - return 0; + if (rdp_rdp_init_data(self, s) != 0) + { + return 1; + } + + out_uint16_le(s, 1); /* type */ + out_uint16_le(s, 1002); + s_mark_end(s); + + if (rdp_rdp_send_data(self, s, RDP_DATA_PDU_SYNCHRONISE) != 0) + { + return 1; + } + + return 0; } /******************************************************************************/ /* Send an (empty) font information PDU */ static int APP_CC -rdp_rdp_send_fonts(struct rdp_rdp* self, struct stream* s, int seq) +rdp_rdp_send_fonts(struct rdp_rdp *self, struct stream *s, int seq) { - if (rdp_rdp_init_data(self, s) != 0) - { - return 1; - } - out_uint16_le(s, 0); /* number of fonts */ - out_uint16_le(s, 0); /* pad? */ - out_uint16_le(s, seq); /* unknown */ - out_uint16_le(s, 0x32); /* entry size */ - s_mark_end(s); - if (rdp_rdp_send_data(self, s, RDP_DATA_PDU_FONT2) != 0) - { - return 1; - } - return 0; + if (rdp_rdp_init_data(self, s) != 0) + { + return 1; + } + + out_uint16_le(s, 0); /* number of fonts */ + out_uint16_le(s, 0); /* pad? */ + out_uint16_le(s, seq); /* unknown */ + out_uint16_le(s, 0x32); /* entry size */ + s_mark_end(s); + + if (rdp_rdp_send_data(self, s, RDP_DATA_PDU_FONT2) != 0) + { + return 1; + } + + return 0; } /******************************************************************************/ /* Respond to a demand active PDU */ int APP_CC -rdp_rdp_process_demand_active(struct rdp_rdp* self, struct stream* s) +rdp_rdp_process_demand_active(struct rdp_rdp *self, struct stream *s) { - int type = 0; - int len_src_descriptor = 0; - int len_combined_caps = 0; + int type = 0; + int len_src_descriptor = 0; + int len_combined_caps = 0; - in_uint32_le(s, self->share_id); - in_uint16_le(s, len_src_descriptor); - in_uint16_le(s, len_combined_caps); - in_uint8s(s, len_src_descriptor); - rdp_rdp_process_server_caps(self, s, len_combined_caps); - rdp_rdp_send_confirm_active(self, s); - rdp_rdp_send_synchronise(self, s); - rdp_rdp_send_control(self, s, RDP_CTL_COOPERATE); - rdp_rdp_send_control(self, s, RDP_CTL_REQUEST_CONTROL); - rdp_rdp_recv(self, s, &type); /* RDP_PDU_SYNCHRONIZE */ - rdp_rdp_recv(self, s, &type); /* RDP_CTL_COOPERATE */ - rdp_rdp_recv(self, s, &type); /* RDP_CTL_GRANT_CONTROL */ - rdp_rdp_send_input(self, s, 0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0); - rdp_rdp_send_fonts(self, s, 1); - rdp_rdp_send_fonts(self, s, 2); - rdp_rdp_recv(self, s, &type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */ - rdp_orders_reset_state(self->orders); - return 0; + in_uint32_le(s, self->share_id); + in_uint16_le(s, len_src_descriptor); + in_uint16_le(s, len_combined_caps); + in_uint8s(s, len_src_descriptor); + rdp_rdp_process_server_caps(self, s, len_combined_caps); + rdp_rdp_send_confirm_active(self, s); + rdp_rdp_send_synchronise(self, s); + rdp_rdp_send_control(self, s, RDP_CTL_COOPERATE); + rdp_rdp_send_control(self, s, RDP_CTL_REQUEST_CONTROL); + rdp_rdp_recv(self, s, &type); /* RDP_PDU_SYNCHRONIZE */ + rdp_rdp_recv(self, s, &type); /* RDP_CTL_COOPERATE */ + rdp_rdp_recv(self, s, &type); /* RDP_CTL_GRANT_CONTROL */ + rdp_rdp_send_input(self, s, 0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0); + rdp_rdp_send_fonts(self, s, 1); + rdp_rdp_send_fonts(self, s, 2); + rdp_rdp_recv(self, s, &type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */ + rdp_orders_reset_state(self->orders); + return 0; } /******************************************************************************/ int APP_CC -rdp_rec_check_file(struct rdp_rdp* self) +rdp_rec_check_file(struct rdp_rdp *self) { - char file_name[256]; - int index = 0; - int len = 0; - struct stream* s = (struct stream *)NULL; + char file_name[256]; + int index = 0; + int len = 0; + struct stream *s = (struct stream *)NULL; - g_memset(file_name,0,sizeof(char) * 256); + g_memset(file_name, 0, sizeof(char) * 256); - if (self->rec_fd == 0) - { - index = 1; - g_sprintf(file_name, "rec%8.8d.rec", index); - while (g_file_exist(file_name)) + if (self->rec_fd == 0) { - index++; - if (index >= 9999) - { - return 1; - } - g_sprintf(file_name, "rec%8.8d.rec", index); + index = 1; + g_sprintf(file_name, "rec%8.8d.rec", index); + + while (g_file_exist(file_name)) + { + index++; + + if (index >= 9999) + { + return 1; + } + + g_sprintf(file_name, "rec%8.8d.rec", index); + } + + self->rec_fd = g_file_open(file_name); + make_stream(s); + init_stream(s, 8192); + out_uint8a(s, "XRDPREC1", 8); + out_uint8s(s, 8); + s_mark_end(s); + len = s->end - s->data; + g_file_write(self->rec_fd, s->data, len); + free_stream(s); } - self->rec_fd = g_file_open(file_name); - make_stream(s); - init_stream(s, 8192); - out_uint8a(s, "XRDPREC1", 8); - out_uint8s(s, 8); + + return 0; +} + +/******************************************************************************/ +int APP_CC +rdp_rec_write_item(struct rdp_rdp *self, struct stream *s) +{ + int len = 0; + int time = 0; + + if (self->rec_fd == 0) + { + return 1; + } + + time = g_time1(); + out_uint32_le(s, time); s_mark_end(s); len = s->end - s->data; + s_pop_layer(s, iso_hdr); + out_uint32_le(s, len); g_file_write(self->rec_fd, s->data, len); - free_stream(s); - } - return 0; -} - -/******************************************************************************/ -int APP_CC -rdp_rec_write_item(struct rdp_rdp* self, struct stream* s) -{ - int len = 0; - int time = 0; - - if (self->rec_fd == 0) - { - return 1; - } - time = g_time1(); - out_uint32_le(s, time); - s_mark_end(s); - len = s->end - s->data; - s_pop_layer(s, iso_hdr); - out_uint32_le(s, len); - g_file_write(self->rec_fd, s->data, len); - return 0; + return 0; } diff --git a/rdp/rdp_sec.c b/rdp/rdp_sec.c index 5efab76e..bd0fe349 100644 --- a/rdp/rdp_sec.c +++ b/rdp/rdp_sec.c @@ -1,655 +1,713 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - librdp secure layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * librdp secure layer + */ #include "rdp.h" static char g_pad_54[40] = -{ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54 }; +{ + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54 +}; static char g_pad_92[48] = -{ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92 }; +{ + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92 +}; /*****************************************************************************/ -struct rdp_sec* APP_CC -rdp_sec_create(struct rdp_rdp* owner) +struct rdp_sec *APP_CC +rdp_sec_create(struct rdp_rdp *owner) { - struct rdp_sec* self; + struct rdp_sec *self; - self = (struct rdp_sec*)g_malloc(sizeof(struct rdp_sec), 1); - self->rdp_layer = owner; - make_stream(self->client_mcs_data); - init_stream(self->client_mcs_data, 8192); - make_stream(self->server_mcs_data); - init_stream(self->server_mcs_data, 8192); - self->mcs_layer = rdp_mcs_create(self, self->client_mcs_data, - self->server_mcs_data); - if(self->decrypt_rc4_info!=NULL) - { - g_writeln("rdp_sec_create - decrypt_rc4_info already created !!!"); - } - self->decrypt_rc4_info = ssl_rc4_info_create(); - if(self->encrypt_rc4_info!=NULL) - { - g_writeln("rdp_sec_create - encrypt_rc4_info already created !!!"); - } - self->encrypt_rc4_info = ssl_rc4_info_create(); - self->lic_layer = rdp_lic_create(self); - return self; + self = (struct rdp_sec *)g_malloc(sizeof(struct rdp_sec), 1); + self->rdp_layer = owner; + make_stream(self->client_mcs_data); + init_stream(self->client_mcs_data, 8192); + make_stream(self->server_mcs_data); + init_stream(self->server_mcs_data, 8192); + self->mcs_layer = rdp_mcs_create(self, self->client_mcs_data, + self->server_mcs_data); + + if (self->decrypt_rc4_info != NULL) + { + g_writeln("rdp_sec_create - decrypt_rc4_info already created !!!"); + } + + self->decrypt_rc4_info = ssl_rc4_info_create(); + + if (self->encrypt_rc4_info != NULL) + { + g_writeln("rdp_sec_create - encrypt_rc4_info already created !!!"); + } + + self->encrypt_rc4_info = ssl_rc4_info_create(); + self->lic_layer = rdp_lic_create(self); + return self; } /*****************************************************************************/ void APP_CC -rdp_sec_delete(struct rdp_sec* self) +rdp_sec_delete(struct rdp_sec *self) { - if (self == 0) - { - return; - } - rdp_lic_delete(self->lic_layer); - rdp_mcs_delete(self->mcs_layer); - free_stream(self->client_mcs_data); - free_stream(self->server_mcs_data); - ssl_rc4_info_delete(self->decrypt_rc4_info); - ssl_rc4_info_delete(self->encrypt_rc4_info); - g_free(self); + if (self == 0) + { + return; + } + + rdp_lic_delete(self->lic_layer); + rdp_mcs_delete(self->mcs_layer); + free_stream(self->client_mcs_data); + free_stream(self->server_mcs_data); + ssl_rc4_info_delete(self->decrypt_rc4_info); + ssl_rc4_info_delete(self->encrypt_rc4_info); + g_free(self); } /*****************************************************************************/ /* Reduce key entropy from 64 to 40 bits */ static void APP_CC -rdp_sec_make_40bit(char* key) +rdp_sec_make_40bit(char *key) { - key[0] = 0xd1; - key[1] = 0x26; - key[2] = 0x9e; + key[0] = 0xd1; + key[1] = 0x26; + key[2] = 0x9e; } /*****************************************************************************/ /* returns error */ /* update an encryption key */ static int APP_CC -rdp_sec_update(char* key, char* update_key, int key_len) +rdp_sec_update(char *key, char *update_key, int key_len) { - char shasig[20]; - void* sha1_info; - void* md5_info; - void* rc4_info; + char shasig[20]; + void *sha1_info; + void *md5_info; + void *rc4_info; - sha1_info = ssl_sha1_info_create(); - md5_info = ssl_md5_info_create(); - rc4_info = ssl_rc4_info_create(); - ssl_sha1_clear(sha1_info); - ssl_sha1_transform(sha1_info, update_key, key_len); - ssl_sha1_transform(sha1_info, g_pad_54, 40); - ssl_sha1_transform(sha1_info, key, key_len); - ssl_sha1_complete(sha1_info, shasig); - ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, update_key, key_len); - ssl_md5_transform(md5_info, g_pad_92, 48); - ssl_md5_transform(md5_info, shasig, 20); - ssl_md5_complete(md5_info, key); - ssl_rc4_set_key(rc4_info, key, key_len); - ssl_rc4_crypt(rc4_info, key, key_len); - if (key_len == 8) - { - rdp_sec_make_40bit(key); - } - ssl_sha1_info_delete(sha1_info); - ssl_md5_info_delete(md5_info); - ssl_rc4_info_delete(rc4_info); - return 0; + sha1_info = ssl_sha1_info_create(); + md5_info = ssl_md5_info_create(); + rc4_info = ssl_rc4_info_create(); + ssl_sha1_clear(sha1_info); + ssl_sha1_transform(sha1_info, update_key, key_len); + ssl_sha1_transform(sha1_info, g_pad_54, 40); + ssl_sha1_transform(sha1_info, key, key_len); + ssl_sha1_complete(sha1_info, shasig); + ssl_md5_clear(md5_info); + ssl_md5_transform(md5_info, update_key, key_len); + ssl_md5_transform(md5_info, g_pad_92, 48); + ssl_md5_transform(md5_info, shasig, 20); + ssl_md5_complete(md5_info, key); + ssl_rc4_set_key(rc4_info, key, key_len); + ssl_rc4_crypt(rc4_info, key, key_len); + + if (key_len == 8) + { + rdp_sec_make_40bit(key); + } + + ssl_sha1_info_delete(sha1_info); + ssl_md5_info_delete(md5_info); + ssl_rc4_info_delete(rc4_info); + return 0; } /*****************************************************************************/ static void APP_CC -rdp_sec_decrypt(struct rdp_sec* self, char* data, int len) +rdp_sec_decrypt(struct rdp_sec *self, char *data, int len) { - if (self->decrypt_use_count == 4096) - { - rdp_sec_update(self->decrypt_key, self->decrypt_update_key, - self->rc4_key_len); - ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, - self->rc4_key_len); - self->decrypt_use_count = 0; - } - ssl_rc4_crypt(self->decrypt_rc4_info, data, len); - self->decrypt_use_count++; + if (self->decrypt_use_count == 4096) + { + rdp_sec_update(self->decrypt_key, self->decrypt_update_key, + self->rc4_key_len); + ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, + self->rc4_key_len); + self->decrypt_use_count = 0; + } + + ssl_rc4_crypt(self->decrypt_rc4_info, data, len); + self->decrypt_use_count++; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_sec_recv(struct rdp_sec* self, struct stream* s, int* chan) +rdp_sec_recv(struct rdp_sec *self, struct stream *s, int *chan) { - int flags; + int flags; - DEBUG((" in rdp_sec_recv")); - if (rdp_mcs_recv(self->mcs_layer, s, chan) != 0) - { - DEBUG((" error in rdp_sec_recv, rdp_mcs_recv failed")); - return 1; - } - in_uint32_le(s, flags); - DEBUG((" rdp_sec_recv flags %8.8x", flags)); - if (flags & SEC_ENCRYPT) /* 0x08 */ - { - in_uint8s(s, 8); /* signature */ - rdp_sec_decrypt(self, s->p, s->end - s->p); - } - if (flags & SEC_LICENCE_NEG) /* 0x80 */ - { - DEBUG((" in rdp_sec_recv, got SEC_LICENCE_NEG")); - rdp_lic_process(self->lic_layer, s); - *chan = 0; - } - DEBUG((" out rdp_sec_recv")); - return 0; + DEBUG((" in rdp_sec_recv")); + + if (rdp_mcs_recv(self->mcs_layer, s, chan) != 0) + { + DEBUG((" error in rdp_sec_recv, rdp_mcs_recv failed")); + return 1; + } + + in_uint32_le(s, flags); + DEBUG((" rdp_sec_recv flags %8.8x", flags)); + + if (flags & SEC_ENCRYPT) /* 0x08 */ + { + in_uint8s(s, 8); /* signature */ + rdp_sec_decrypt(self, s->p, s->end - s->p); + } + + if (flags & SEC_LICENCE_NEG) /* 0x80 */ + { + DEBUG((" in rdp_sec_recv, got SEC_LICENCE_NEG")); + rdp_lic_process(self->lic_layer, s); + *chan = 0; + } + + DEBUG((" out rdp_sec_recv")); + return 0; } /*****************************************************************************/ /* prepare client mcs data to send in mcs layer */ static void APP_CC -rdp_sec_out_mcs_data(struct rdp_sec* self) +rdp_sec_out_mcs_data(struct rdp_sec *self) { - struct stream* s; - int hostlen; - int length; + struct stream *s; + int hostlen; + int length; - s = self->client_mcs_data; - init_stream(s, 512); - self->rdp_layer->mod->hostname[15] = 0; /* limit length to 15 */ - hostlen = 2 * g_strlen(self->rdp_layer->mod->hostname); - length = 158 + 76 + 12 + 4; - /* Generic Conference Control (T.124) ConferenceCreateRequest */ - out_uint16_be(s, 5); - out_uint16_be(s, 0x14); - out_uint8(s, 0x7c); - out_uint16_be(s, 1); - out_uint16_be(s, (length | 0x8000)); /* remaining length */ - out_uint16_be(s, 8); /* length? */ - out_uint16_be(s, 16); - out_uint8(s, 0); - out_uint16_le(s, 0xc001); - out_uint8(s, 0); - out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */ - out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */ - /* Client information */ - out_uint16_le(s, SEC_TAG_CLI_INFO); - out_uint16_le(s, 212); /* length */ - out_uint16_le(s, 1); /* RDP version. 1 == RDP4, 4 == RDP5. */ - out_uint16_le(s, 8); - out_uint16_le(s, self->rdp_layer->mod->width); - out_uint16_le(s, self->rdp_layer->mod->height); - out_uint16_le(s, 0xca01); - out_uint16_le(s, 0xaa03); - out_uint32_le(s, self->rdp_layer->mod->keylayout); - out_uint32_le(s, 2600); /* Client build */ - /* Unicode name of client, padded to 32 bytes */ - rdp_rdp_out_unistr(s, self->rdp_layer->mod->hostname); - out_uint8s(s, 30 - hostlen); - out_uint32_le(s, 4); - out_uint32_le(s, 0); - out_uint32_le(s, 12); - out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */ - out_uint16_le(s, 0xca01); /* color depth? */ - out_uint16_le(s, 1); - out_uint32_le(s, 0); - out_uint8(s, self->rdp_layer->mod->rdp_bpp); - out_uint16_le(s, 0x0700); - out_uint8(s, 0); - out_uint32_le(s, 1); - out_uint8s(s, 64); /* End of client info */ - out_uint16_le(s, SEC_TAG_CLI_4); - out_uint16_le(s, 12); - out_uint32_le(s, 9); - out_uint32_le(s, 0); - /* Client encryption settings */ - out_uint16_le(s, SEC_TAG_CLI_CRYPT); - out_uint16_le(s, 12); /* length */ - /* encryption supported, 128-bit supported */ - out_uint32_le(s, 0x3); - out_uint32_le(s, 0); /* Unknown */ - s_mark_end(s); + s = self->client_mcs_data; + init_stream(s, 512); + self->rdp_layer->mod->hostname[15] = 0; /* limit length to 15 */ + hostlen = 2 * g_strlen(self->rdp_layer->mod->hostname); + length = 158 + 76 + 12 + 4; + /* Generic Conference Control (T.124) ConferenceCreateRequest */ + out_uint16_be(s, 5); + out_uint16_be(s, 0x14); + out_uint8(s, 0x7c); + out_uint16_be(s, 1); + out_uint16_be(s, (length | 0x8000)); /* remaining length */ + out_uint16_be(s, 8); /* length? */ + out_uint16_be(s, 16); + out_uint8(s, 0); + out_uint16_le(s, 0xc001); + out_uint8(s, 0); + out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */ + out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */ + /* Client information */ + out_uint16_le(s, SEC_TAG_CLI_INFO); + out_uint16_le(s, 212); /* length */ + out_uint16_le(s, 1); /* RDP version. 1 == RDP4, 4 == RDP5. */ + out_uint16_le(s, 8); + out_uint16_le(s, self->rdp_layer->mod->width); + out_uint16_le(s, self->rdp_layer->mod->height); + out_uint16_le(s, 0xca01); + out_uint16_le(s, 0xaa03); + out_uint32_le(s, self->rdp_layer->mod->keylayout); + out_uint32_le(s, 2600); /* Client build */ + /* Unicode name of client, padded to 32 bytes */ + rdp_rdp_out_unistr(s, self->rdp_layer->mod->hostname); + out_uint8s(s, 30 - hostlen); + out_uint32_le(s, 4); + out_uint32_le(s, 0); + out_uint32_le(s, 12); + out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */ + out_uint16_le(s, 0xca01); /* color depth? */ + out_uint16_le(s, 1); + out_uint32_le(s, 0); + out_uint8(s, self->rdp_layer->mod->rdp_bpp); + out_uint16_le(s, 0x0700); + out_uint8(s, 0); + out_uint32_le(s, 1); + out_uint8s(s, 64); /* End of client info */ + out_uint16_le(s, SEC_TAG_CLI_4); + out_uint16_le(s, 12); + out_uint32_le(s, 9); + out_uint32_le(s, 0); + /* Client encryption settings */ + out_uint16_le(s, SEC_TAG_CLI_CRYPT); + out_uint16_le(s, 12); /* length */ + /* encryption supported, 128-bit supported */ + out_uint32_le(s, 0x3); + out_uint32_le(s, 0); /* Unknown */ + s_mark_end(s); } /*****************************************************************************/ /* Parse a public key structure */ /* returns boolean */ static int APP_CC -rdp_sec_parse_public_key(struct rdp_sec* self, struct stream* s, - char* modulus, char* exponent) +rdp_sec_parse_public_key(struct rdp_sec *self, struct stream *s, + char *modulus, char *exponent) { - int magic; - int modulus_len; + int magic; + int modulus_len; - in_uint32_le(s, magic); - if (magic != SEC_RSA_MAGIC) - { - return 0; - } - in_uint32_le(s, modulus_len); - if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE) - { - return 0; - } - in_uint8s(s, 8); - in_uint8a(s, exponent, SEC_EXPONENT_SIZE); - in_uint8a(s, modulus, SEC_MODULUS_SIZE); - in_uint8s(s, SEC_PADDING_SIZE); - return s_check(s); + in_uint32_le(s, magic); + + if (magic != SEC_RSA_MAGIC) + { + return 0; + } + + in_uint32_le(s, modulus_len); + + if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE) + { + return 0; + } + + in_uint8s(s, 8); + in_uint8a(s, exponent, SEC_EXPONENT_SIZE); + in_uint8a(s, modulus, SEC_MODULUS_SIZE); + in_uint8s(s, SEC_PADDING_SIZE); + return s_check(s); } /*****************************************************************************/ /* Parse a crypto information structure */ /* returns boolean */ static int APP_CC -rdp_sec_parse_crypt_info(struct rdp_sec* self, struct stream* s, - char* modulus, char* exponent) +rdp_sec_parse_crypt_info(struct rdp_sec *self, struct stream *s, + char *modulus, char *exponent) { - int random_len; - int rsa_info_len; - int flags; - int tag; - int length; - char* next_tag; - char* end; + int random_len; + int rsa_info_len; + int flags; + int tag; + int length; + char *next_tag; + char *end; - in_uint32_le(s, self->rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */ - in_uint32_le(s, self->crypt_level); /* 1 = low, 2 = medium, 3 = high */ - if (self->crypt_level == 0) /* no encryption */ - { - return 0; - } - in_uint32_le(s, random_len); - in_uint32_le(s, rsa_info_len); - if (random_len != SEC_RANDOM_SIZE) - { - return 0; - } - in_uint8a(s, self->server_random, random_len); - /* RSA info */ - end = s->p + rsa_info_len; - if (end > s->end) - { - return 0; - } - in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */ - if (flags & 1) - { - in_uint8s(s, 8); /* unknown */ - while (s->p < end) + in_uint32_le(s, self->rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */ + in_uint32_le(s, self->crypt_level); /* 1 = low, 2 = medium, 3 = high */ + + if (self->crypt_level == 0) /* no encryption */ { - in_uint16_le(s, tag); - in_uint16_le(s, length); - next_tag = s->p + length; - DEBUG((" rdp_sec_parse_crypt_info tag %d length %d", tag, length)); - switch (tag) - { - case SEC_TAG_PUBKEY: - if (!rdp_sec_parse_public_key(self, s, modulus, exponent)) - { - return 0; - } - break; - case SEC_TAG_KEYSIG: - break; - default: - break; - } - s->p = next_tag; + return 0; } - } - else - { - /* todo */ - return 0; - } - return s_check_end(s); + + in_uint32_le(s, random_len); + in_uint32_le(s, rsa_info_len); + + if (random_len != SEC_RANDOM_SIZE) + { + return 0; + } + + in_uint8a(s, self->server_random, random_len); + /* RSA info */ + end = s->p + rsa_info_len; + + if (end > s->end) + { + return 0; + } + + in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */ + + if (flags & 1) + { + in_uint8s(s, 8); /* unknown */ + + while (s->p < end) + { + in_uint16_le(s, tag); + in_uint16_le(s, length); + next_tag = s->p + length; + DEBUG((" rdp_sec_parse_crypt_info tag %d length %d", tag, length)); + + switch (tag) + { + case SEC_TAG_PUBKEY: + + if (!rdp_sec_parse_public_key(self, s, modulus, exponent)) + { + return 0; + } + + break; + case SEC_TAG_KEYSIG: + break; + default: + break; + } + + s->p = next_tag; + } + } + else + { + /* todo */ + return 0; + } + + return s_check_end(s); } /*****************************************************************************/ static void APP_CC -rdp_sec_rsa_op(char* out, char* in, char* mod, char* exp) +rdp_sec_rsa_op(char *out, char *in, char *mod, char *exp) { - ssl_mod_exp(out, SEC_MODULUS_SIZE, /* 64 */ - in, SEC_RANDOM_SIZE, /* 32 */ - mod, SEC_MODULUS_SIZE, /* 64 */ - exp, SEC_EXPONENT_SIZE); /* 4 */ + ssl_mod_exp(out, SEC_MODULUS_SIZE, /* 64 */ + in, SEC_RANDOM_SIZE, /* 32 */ + mod, SEC_MODULUS_SIZE, /* 64 */ + exp, SEC_EXPONENT_SIZE); /* 4 */ } /*****************************************************************************/ void APP_CC -rdp_sec_hash_48(char* out, char* in, char* salt1, char* salt2, int salt) +rdp_sec_hash_48(char *out, char *in, char *salt1, char *salt2, int salt) { - int i; - void* sha1_info; - void* md5_info; - char pad[4]; - char sha1_sig[20]; - char md5_sig[16]; + int i; + void *sha1_info; + void *md5_info; + char pad[4]; + char sha1_sig[20]; + char md5_sig[16]; - sha1_info = ssl_sha1_info_create(); - md5_info = ssl_md5_info_create(); - for (i = 0; i < 3; i++) - { - g_memset(pad, salt + i, 4); - ssl_sha1_clear(sha1_info); - ssl_sha1_transform(sha1_info, pad, i + 1); - ssl_sha1_transform(sha1_info, in, 48); - ssl_sha1_transform(sha1_info, salt1, 32); - ssl_sha1_transform(sha1_info, salt2, 32); - ssl_sha1_complete(sha1_info, sha1_sig); + sha1_info = ssl_sha1_info_create(); + md5_info = ssl_md5_info_create(); + + for (i = 0; i < 3; i++) + { + g_memset(pad, salt + i, 4); + ssl_sha1_clear(sha1_info); + ssl_sha1_transform(sha1_info, pad, i + 1); + ssl_sha1_transform(sha1_info, in, 48); + ssl_sha1_transform(sha1_info, salt1, 32); + ssl_sha1_transform(sha1_info, salt2, 32); + ssl_sha1_complete(sha1_info, sha1_sig); + ssl_md5_clear(md5_info); + ssl_md5_transform(md5_info, in, 48); + ssl_md5_transform(md5_info, sha1_sig, 20); + ssl_md5_complete(md5_info, md5_sig); + g_memcpy(out + i * 16, md5_sig, 16); + } + + ssl_sha1_info_delete(sha1_info); + ssl_md5_info_delete(md5_info); +} + +/*****************************************************************************/ +void APP_CC +rdp_sec_hash_16(char *out, char *in, char *salt1, char *salt2) +{ + void *md5_info; + + md5_info = ssl_md5_info_create(); ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, in, 48); - ssl_md5_transform(md5_info, sha1_sig, 20); - ssl_md5_complete(md5_info, md5_sig); - g_memcpy(out + i * 16, md5_sig, 16); - } - ssl_sha1_info_delete(sha1_info); - ssl_md5_info_delete(md5_info); -} - -/*****************************************************************************/ -void APP_CC -rdp_sec_hash_16(char* out, char* in, char* salt1, char* salt2) -{ - void* md5_info; - - md5_info = ssl_md5_info_create(); - ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, in, 16); - ssl_md5_transform(md5_info, salt1, 32); - ssl_md5_transform(md5_info, salt2, 32); - ssl_md5_complete(md5_info, out); - ssl_md5_info_delete(md5_info); + ssl_md5_transform(md5_info, in, 16); + ssl_md5_transform(md5_info, salt1, 32); + ssl_md5_transform(md5_info, salt2, 32); + ssl_md5_complete(md5_info, out); + ssl_md5_info_delete(md5_info); } /*****************************************************************************/ static int APP_CC -rdp_sec_generate_keys(struct rdp_sec* self) +rdp_sec_generate_keys(struct rdp_sec *self) { - char session_key[48]; - char temp_hash[48]; - char input[48]; + char session_key[48]; + char temp_hash[48]; + char input[48]; - g_memcpy(input, self->client_random, 24); - g_memcpy(input + 24, self->server_random, 24); - rdp_sec_hash_48(temp_hash, input, self->client_random, - self->server_random, 65); - rdp_sec_hash_48(session_key, temp_hash, self->client_random, - self->server_random, 88); - g_memcpy(self->sign_key, session_key, 16); - rdp_sec_hash_16(self->decrypt_key, session_key + 16, self->client_random, - self->server_random); - rdp_sec_hash_16(self->encrypt_key, session_key + 32, self->client_random, - self->server_random); - DEBUG((" rdp_sec_generate_keys, rc4_key_size is %d", self->rc4_key_size)); - DEBUG((" rdp_sec_generate_keys, crypt_level is %d", self->crypt_level)); - if (self->rc4_key_size == 1) - { - rdp_sec_make_40bit(self->sign_key); - rdp_sec_make_40bit(self->encrypt_key); - rdp_sec_make_40bit(self->decrypt_key); - self->rc4_key_len = 8; - } - else - { - self->rc4_key_len = 16; - } - g_memcpy(self->decrypt_update_key, self->decrypt_key, 16); - g_memcpy(self->encrypt_update_key, self->encrypt_key, 16); - ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, self->rc4_key_len); - ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, self->rc4_key_len); - return 0; + g_memcpy(input, self->client_random, 24); + g_memcpy(input + 24, self->server_random, 24); + rdp_sec_hash_48(temp_hash, input, self->client_random, + self->server_random, 65); + rdp_sec_hash_48(session_key, temp_hash, self->client_random, + self->server_random, 88); + g_memcpy(self->sign_key, session_key, 16); + rdp_sec_hash_16(self->decrypt_key, session_key + 16, self->client_random, + self->server_random); + rdp_sec_hash_16(self->encrypt_key, session_key + 32, self->client_random, + self->server_random); + DEBUG((" rdp_sec_generate_keys, rc4_key_size is %d", self->rc4_key_size)); + DEBUG((" rdp_sec_generate_keys, crypt_level is %d", self->crypt_level)); + + if (self->rc4_key_size == 1) + { + rdp_sec_make_40bit(self->sign_key); + rdp_sec_make_40bit(self->encrypt_key); + rdp_sec_make_40bit(self->decrypt_key); + self->rc4_key_len = 8; + } + else + { + self->rc4_key_len = 16; + } + + g_memcpy(self->decrypt_update_key, self->decrypt_key, 16); + g_memcpy(self->encrypt_update_key, self->encrypt_key, 16); + ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, self->rc4_key_len); + ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, self->rc4_key_len); + return 0; } /*****************************************************************************/ /* Process crypto information blob */ static void APP_CC -rdp_sec_process_crypt_info(struct rdp_sec* self, struct stream* s) +rdp_sec_process_crypt_info(struct rdp_sec *self, struct stream *s) { - char modulus[64]; - char exponent[64]; + char modulus[64]; + char exponent[64]; - g_memset(modulus, 0, sizeof(modulus)); - g_memset(exponent, 0, sizeof(exponent)); - if (!rdp_sec_parse_crypt_info(self, s, modulus, exponent)) - { - DEBUG((" error in rdp_sec_process_crypt_info")); - return; - } - /* Generate a client random, and determine encryption keys */ - g_random(self->client_random, 32); - rdp_sec_rsa_op(self->client_crypt_random, self->client_random, - modulus, exponent); - rdp_sec_generate_keys(self); + g_memset(modulus, 0, sizeof(modulus)); + g_memset(exponent, 0, sizeof(exponent)); + + if (!rdp_sec_parse_crypt_info(self, s, modulus, exponent)) + { + DEBUG((" error in rdp_sec_process_crypt_info")); + return; + } + + /* Generate a client random, and determine encryption keys */ + g_random(self->client_random, 32); + rdp_sec_rsa_op(self->client_crypt_random, self->client_random, + modulus, exponent); + rdp_sec_generate_keys(self); } /*****************************************************************************/ /* Process connect response data blob */ static void APP_CC -rdp_sec_process_mcs_data(struct rdp_sec* self) +rdp_sec_process_mcs_data(struct rdp_sec *self) { - int tag; - int length; - int len; - char* next_tag; - struct stream* s; + int tag; + int length; + int len; + char *next_tag; + struct stream *s; - s = self->server_mcs_data; - s->p = s->data; - in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */ - in_uint8(s, len); - if (len & 0x80) - { + s = self->server_mcs_data; + s->p = s->data; + in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */ in_uint8(s, len); - } - while (s->p < s->end) - { - in_uint16_le(s, tag); - in_uint16_le(s, length); - DEBUG((" rdp_sec_process_mcs_data tag %d length %d", tag, length)); - if (length <= 4) + + if (len & 0x80) { - return; + in_uint8(s, len); } - next_tag = (s->p + length) - 4; - switch (tag) + + while (s->p < s->end) { - case SEC_TAG_SRV_INFO: - //rdp_sec_process_srv_info(self, s); - break; - case SEC_TAG_SRV_CRYPT: - rdp_sec_process_crypt_info(self, s); - break; - case SEC_TAG_SRV_CHANNELS: - break; - default: - break; + in_uint16_le(s, tag); + in_uint16_le(s, length); + DEBUG((" rdp_sec_process_mcs_data tag %d length %d", tag, length)); + + if (length <= 4) + { + return; + } + + next_tag = (s->p + length) - 4; + + switch (tag) + { + case SEC_TAG_SRV_INFO: + //rdp_sec_process_srv_info(self, s); + break; + case SEC_TAG_SRV_CRYPT: + rdp_sec_process_crypt_info(self, s); + break; + case SEC_TAG_SRV_CHANNELS: + break; + default: + break; + } + + s->p = next_tag; } - s->p = next_tag; - } } /*****************************************************************************/ /* Transfer the client random to the server */ /* returns error */ static int APP_CC -rdp_sec_establish_key(struct rdp_sec* self) +rdp_sec_establish_key(struct rdp_sec *self) { - int length; - int flags; - struct stream* s; + int length; + int flags; + struct stream *s; + + DEBUG((" sending client random")); + make_stream(s); + init_stream(s, 8192); + length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE; + flags = SEC_CLIENT_RANDOM; + + if (rdp_sec_init(self, s, flags) != 0) + { + free_stream(s); + return 1; + } + + out_uint32_le(s, length); + out_uint8p(s, self->client_crypt_random, SEC_MODULUS_SIZE); + out_uint8s(s, SEC_PADDING_SIZE); + s_mark_end(s); + + if (rdp_sec_send(self, s, flags) != 0) + { + free_stream(s); + return 1; + } - DEBUG((" sending client random")); - make_stream(s); - init_stream(s, 8192); - length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE; - flags = SEC_CLIENT_RANDOM; - if (rdp_sec_init(self, s, flags) != 0) - { free_stream(s); - return 1; - } - out_uint32_le(s, length); - out_uint8p(s, self->client_crypt_random, SEC_MODULUS_SIZE); - out_uint8s(s, SEC_PADDING_SIZE); - s_mark_end(s); - if (rdp_sec_send(self, s, flags) != 0) - { - free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ /* Establish a secure connection */ int APP_CC -rdp_sec_connect(struct rdp_sec* self, char* ip, char* port) +rdp_sec_connect(struct rdp_sec *self, char *ip, char *port) { - DEBUG((" in rdp_sec_connect")); - rdp_sec_out_mcs_data(self); - if (rdp_mcs_connect(self->mcs_layer, ip, port) != 0) - { - DEBUG((" out rdp_sec_connect error rdp_mcs_connect failed")); - return 1; - } - rdp_sec_process_mcs_data(self); - if (rdp_sec_establish_key(self) != 0) - { - DEBUG((" out rdp_sec_connect error rdp_sec_establish_key failed")); - return 1; - } - DEBUG((" out rdp_sec_connect")); - return 0; + DEBUG((" in rdp_sec_connect")); + rdp_sec_out_mcs_data(self); + + if (rdp_mcs_connect(self->mcs_layer, ip, port) != 0) + { + DEBUG((" out rdp_sec_connect error rdp_mcs_connect failed")); + return 1; + } + + rdp_sec_process_mcs_data(self); + + if (rdp_sec_establish_key(self) != 0) + { + DEBUG((" out rdp_sec_connect error rdp_sec_establish_key failed")); + return 1; + } + + DEBUG((" out rdp_sec_connect")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_sec_init(struct rdp_sec* self, struct stream* s, int flags) +rdp_sec_init(struct rdp_sec *self, struct stream *s, int flags) { - if (rdp_mcs_init(self->mcs_layer, s) != 0) - { - return 1; - } - if (flags & SEC_ENCRYPT) - { - s_push_layer(s, sec_hdr, 12); - } - else - { - s_push_layer(s, sec_hdr, 4); - } - return 0; + if (rdp_mcs_init(self->mcs_layer, s) != 0) + { + return 1; + } + + if (flags & SEC_ENCRYPT) + { + s_push_layer(s, sec_hdr, 12); + } + else + { + s_push_layer(s, sec_hdr, 4); + } + + return 0; } /*****************************************************************************/ /* Output a uint32 into a buffer (little-endian) */ void APP_CC -rdp_sec_buf_out_uint32(char* buffer, int value) +rdp_sec_buf_out_uint32(char *buffer, int value) { - buffer[0] = value & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[3] = (value >> 24) & 0xff; + buffer[0] = value & 0xff; + buffer[1] = (value >> 8) & 0xff; + buffer[2] = (value >> 16) & 0xff; + buffer[3] = (value >> 24) & 0xff; } /*****************************************************************************/ /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */ void APP_CC -rdp_sec_sign(char* signature, int siglen, char* session_key, int keylen, - char* data, int datalen) +rdp_sec_sign(char *signature, int siglen, char *session_key, int keylen, + char *data, int datalen) { - char shasig[20]; - char md5sig[16]; - char lenhdr[4]; - void* sha1_context; - void* md5_context; + char shasig[20]; + char md5sig[16]; + char lenhdr[4]; + void *sha1_context; + void *md5_context; - rdp_sec_buf_out_uint32(lenhdr, datalen); - sha1_context = ssl_sha1_info_create(); - ssl_sha1_clear(sha1_context); - ssl_sha1_transform(sha1_context, session_key, keylen); - ssl_sha1_transform(sha1_context, g_pad_54, 40); - ssl_sha1_transform(sha1_context, lenhdr, 4); - ssl_sha1_transform(sha1_context, data, datalen); - ssl_sha1_complete(sha1_context, shasig); - ssl_sha1_info_delete(sha1_context); - md5_context = ssl_md5_info_create(); - ssl_md5_clear(md5_context); - ssl_md5_transform(md5_context, session_key, keylen); - ssl_md5_transform(md5_context, g_pad_92, 48); - ssl_md5_transform(md5_context, shasig, 20); - ssl_md5_complete(md5_context, md5sig); - ssl_md5_info_delete(md5_context); - g_memcpy(signature, md5sig, siglen); + rdp_sec_buf_out_uint32(lenhdr, datalen); + sha1_context = ssl_sha1_info_create(); + ssl_sha1_clear(sha1_context); + ssl_sha1_transform(sha1_context, session_key, keylen); + ssl_sha1_transform(sha1_context, g_pad_54, 40); + ssl_sha1_transform(sha1_context, lenhdr, 4); + ssl_sha1_transform(sha1_context, data, datalen); + ssl_sha1_complete(sha1_context, shasig); + ssl_sha1_info_delete(sha1_context); + md5_context = ssl_md5_info_create(); + ssl_md5_clear(md5_context); + ssl_md5_transform(md5_context, session_key, keylen); + ssl_md5_transform(md5_context, g_pad_92, 48); + ssl_md5_transform(md5_context, shasig, 20); + ssl_md5_complete(md5_context, md5sig); + ssl_md5_info_delete(md5_context); + g_memcpy(signature, md5sig, siglen); } /*****************************************************************************/ /* Encrypt data using RC4 */ static void APP_CC -rdp_sec_encrypt(struct rdp_sec* self, char* data, int length) +rdp_sec_encrypt(struct rdp_sec *self, char *data, int length) { - if (self->encrypt_use_count == 4096) - { - rdp_sec_update(self->encrypt_key, self->encrypt_update_key, - self->rc4_key_len); - ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, - self->rc4_key_len); - self->encrypt_use_count = 0; - } - ssl_rc4_crypt(self->encrypt_rc4_info, data, length); - self->encrypt_use_count++; + if (self->encrypt_use_count == 4096) + { + rdp_sec_update(self->encrypt_key, self->encrypt_update_key, + self->rc4_key_len); + ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, + self->rc4_key_len); + self->encrypt_use_count = 0; + } + + ssl_rc4_crypt(self->encrypt_rc4_info, data, length); + self->encrypt_use_count++; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_sec_send(struct rdp_sec* self, struct stream* s, int flags) +rdp_sec_send(struct rdp_sec *self, struct stream *s, int flags) { - int datalen; + int datalen; - DEBUG((" in rdp_sec_send flags %8.8x", flags)); - s_pop_layer(s, sec_hdr); - out_uint32_le(s, flags); - if (flags & SEC_ENCRYPT) - { - datalen = (s->end - s->p) - 8; - rdp_sec_sign(s->p, 8, self->sign_key, self->rc4_key_len, s->p + 8, - datalen); - rdp_sec_encrypt(self, s->p + 8, datalen); - } - if (rdp_mcs_send(self->mcs_layer, s) != 0) - { - DEBUG((" out rdp_sec_send, rdp_mcs_send failed")); - return 1; - } - DEBUG((" out rdp_sec_send")); - return 0; + DEBUG((" in rdp_sec_send flags %8.8x", flags)); + s_pop_layer(s, sec_hdr); + out_uint32_le(s, flags); + + if (flags & SEC_ENCRYPT) + { + datalen = (s->end - s->p) - 8; + rdp_sec_sign(s->p, 8, self->sign_key, self->rc4_key_len, s->p + 8, + datalen); + rdp_sec_encrypt(self, s->p + 8, datalen); + } + + if (rdp_mcs_send(self->mcs_layer, s) != 0) + { + DEBUG((" out rdp_sec_send, rdp_mcs_send failed")); + return 1; + } + + DEBUG((" out rdp_sec_send")); + return 0; } diff --git a/rdp/rdp_tcp.c b/rdp/rdp_tcp.c index 0f053ff6..f3c990ad 100644 --- a/rdp/rdp_tcp.c +++ b/rdp/rdp_tcp.c @@ -1,178 +1,188 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - librdp tcp layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * librdp tcp layer + */ #include "rdp.h" /*****************************************************************************/ -struct rdp_tcp* APP_CC -rdp_tcp_create(struct rdp_iso* owner) +struct rdp_tcp *APP_CC +rdp_tcp_create(struct rdp_iso *owner) { - struct rdp_tcp* self; + struct rdp_tcp *self; - self = (struct rdp_tcp*)g_malloc(sizeof(struct rdp_tcp), 1); - self->iso_layer = owner; - return self; + self = (struct rdp_tcp *)g_malloc(sizeof(struct rdp_tcp), 1); + self->iso_layer = owner; + return self; } /*****************************************************************************/ void APP_CC -rdp_tcp_delete(struct rdp_tcp* self) +rdp_tcp_delete(struct rdp_tcp *self) { - g_free(self); + g_free(self); } /*****************************************************************************/ /* get out stream ready for data */ /* returns error */ int APP_CC -rdp_tcp_init(struct rdp_tcp* self, struct stream* s) +rdp_tcp_init(struct rdp_tcp *self, struct stream *s) { - init_stream(s, 8192); - return 0; + init_stream(s, 8192); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_tcp_recv(struct rdp_tcp* self, struct stream* s, int len) +rdp_tcp_recv(struct rdp_tcp *self, struct stream *s, int len) { - int rcvd; + int rcvd; - DEBUG((" in rdp_tcp_recv gota get %d bytes on sck %d", - len, self->sck)); - if (self->sck_closed) - { - DEBUG((" out rdp_tcp_recv error sck closed")); - return 1; - } - init_stream(s, len); - while (len > 0) - { - rcvd = g_tcp_recv(self->sck, s->end, len, 0); - if (rcvd == -1) + DEBUG((" in rdp_tcp_recv gota get %d bytes on sck %d", + len, self->sck)); + + if (self->sck_closed) { - if (g_tcp_last_error_would_block(self->sck)) - { - g_tcp_can_recv(self->sck, 10); - } - else - { - self->sck_closed = 1; - DEBUG((" out rdp_tcp_recv error unknown")); + DEBUG((" out rdp_tcp_recv error sck closed")); return 1; - } } - else if (rcvd == 0) + + init_stream(s, len); + + while (len > 0) { - self->sck_closed = 1; - DEBUG((" out rdp_tcp_recv error connection dropped")); - return 1; + rcvd = g_tcp_recv(self->sck, s->end, len, 0); + + if (rcvd == -1) + { + if (g_tcp_last_error_would_block(self->sck)) + { + g_tcp_can_recv(self->sck, 10); + } + else + { + self->sck_closed = 1; + DEBUG((" out rdp_tcp_recv error unknown")); + return 1; + } + } + else if (rcvd == 0) + { + self->sck_closed = 1; + DEBUG((" out rdp_tcp_recv error connection dropped")); + return 1; + } + else + { + s->end += rcvd; + len -= rcvd; + } + } + + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +rdp_tcp_send(struct rdp_tcp *self, struct stream *s) +{ + int len; + int total; + int sent; + + if (self->sck_closed) + { + DEBUG((" out rdp_tcp_send error sck closed")); + return 1; + } + + len = s->end - s->data; + DEBUG((" in rdp_tcp_send gota send %d bytes on sck %d", len, + self->sck)); + total = 0; + + while (total < len) + { + sent = g_tcp_send(self->sck, s->data + total, len - total, 0); + + if (sent == -1) + { + if (g_tcp_last_error_would_block(self->sck)) + { + g_tcp_can_send(self->sck, 10); + } + else + { + self->sck_closed = 1; + DEBUG((" out rdp_tcp_send error unknown")); + return 1; + } + } + else if (sent == 0) + { + self->sck_closed = 1; + DEBUG((" out rdp_tcp_send error connection dropped")); + return 1; + } + else + { + total = total + sent; + } + } + + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +rdp_tcp_connect(struct rdp_tcp *self, char *ip, char *port) +{ + DEBUG((" in rdp_tcp_connect ip %s port %s", ip, port)); + self->sck = g_tcp_socket(); + + if (g_tcp_connect(self->sck, ip, port) == 0) + { + g_tcp_set_non_blocking(self->sck); } else { - s->end += rcvd; - len -= rcvd; - } - } - return 0; -} - -/*****************************************************************************/ -/* returns error */ -int APP_CC -rdp_tcp_send(struct rdp_tcp* self, struct stream* s) -{ - int len; - int total; - int sent; - - if (self->sck_closed) - { - DEBUG((" out rdp_tcp_send error sck closed")); - return 1; - } - len = s->end - s->data; - DEBUG((" in rdp_tcp_send gota send %d bytes on sck %d", len, - self->sck)); - total = 0; - while (total < len) - { - sent = g_tcp_send(self->sck, s->data + total, len - total, 0); - if (sent == -1) - { - if (g_tcp_last_error_would_block(self->sck)) - { - g_tcp_can_send(self->sck, 10); - } - else - { - self->sck_closed = 1; - DEBUG((" out rdp_tcp_send error unknown")); + DEBUG((" out rdp_tcp_connect error g_tcp_connect failed")); return 1; - } } - else if (sent == 0) - { - self->sck_closed = 1; - DEBUG((" out rdp_tcp_send error connection dropped")); - return 1; - } - else - { - total = total + sent; - } - } - return 0; + + DEBUG((" out rdp_tcp_connect")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -rdp_tcp_connect(struct rdp_tcp* self, char* ip, char* port) +rdp_tcp_disconnect(struct rdp_tcp *self) { - DEBUG((" in rdp_tcp_connect ip %s port %s", ip, port)); - self->sck = g_tcp_socket(); - if (g_tcp_connect(self->sck, ip, port) == 0) - { - g_tcp_set_non_blocking(self->sck); - } - else - { - DEBUG((" out rdp_tcp_connect error g_tcp_connect failed")); - return 1; - } - DEBUG((" out rdp_tcp_connect")); - return 0; -} + if (self->sck != 0) + { + g_tcp_close(self->sck); + } -/*****************************************************************************/ -/* returns error */ -int APP_CC -rdp_tcp_disconnect(struct rdp_tcp* self) -{ - if (self->sck != 0) - { - g_tcp_close(self->sck); - } - self->sck = 0; - return 0; + self->sck = 0; + return 0; } diff --git a/readme.txt b/readme.txt index fe6c0726..e4d71703 100644 --- a/readme.txt +++ b/readme.txt @@ -35,4 +35,4 @@ make install see file-loc.txt to see what files are installed where -Jay +Jay Sorg diff --git a/sesman/access.c b/sesman/access.c index 0037de3f..00c9c381 100644 --- a/sesman/access.c +++ b/sesman/access.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -27,102 +26,102 @@ #include "sesman.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ int DEFAULT_CC -access_login_allowed(char* user) +access_login_allowed(char *user) { - int gid; - int ok; + int gid; + int ok; + + if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) + { + log_message(LOG_LEVEL_WARNING, + "ROOT login attempted, but root login is disabled"); + return 0; + } + + if (0 == g_cfg->sec.ts_users_enable) + { + LOG_DBG("Terminal Server Users group is disabled, allowing authentication", + 1); + return 1; + } + + if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) + { + log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied"); + return 0; + } + + if (g_cfg->sec.ts_users == gid) + { + LOG_DBG("ts_users is user's primary group"); + return 1; + } + + if (0 != g_check_user_in_group(user, g_cfg->sec.ts_users, &ok)) + { + log_message(LOG_LEVEL_ERROR, "Cannot read group info! - login denied"); + return 0; + } + + if (ok) + { + return 1; + } + + log_message(LOG_LEVEL_INFO, "login denied for user %s", user); - if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) - { - log_message(LOG_LEVEL_WARNING, - "ROOT login attempted, but root login is disabled"); return 0; - } - - if (0 == g_cfg->sec.ts_users_enable) - { - LOG_DBG("Terminal Server Users group is disabled, allowing authentication", - 1); - return 1; - } - - if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) - { - log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied"); - return 0; - } - - if (g_cfg->sec.ts_users == gid) - { - LOG_DBG("ts_users is user's primary group"); - return 1; - } - - if (0 != g_check_user_in_group(user, g_cfg->sec.ts_users, &ok)) - { - log_message(LOG_LEVEL_ERROR, "Cannot read group info! - login denied"); - return 0; - } - - if (ok) - { - return 1; - } - - log_message(LOG_LEVEL_INFO, "login denied for user %s", user); - - return 0; } /******************************************************************************/ int DEFAULT_CC -access_login_mng_allowed(char* user) +access_login_mng_allowed(char *user) { - int gid; - int ok; + int gid; + int ok; + + if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) + { + log_message(LOG_LEVEL_WARNING, + "[MNG] ROOT login attempted, but root login is disabled"); + return 0; + } + + if (0 == g_cfg->sec.ts_admins_enable) + { + LOG_DBG("[MNG] Terminal Server Admin group is disabled," + "allowing authentication", 1); + return 1; + } + + if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) + { + log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied"); + return 0; + } + + if (g_cfg->sec.ts_admins == gid) + { + LOG_DBG("[MNG] ts_users is user's primary group"); + return 1; + } + + if (0 != g_check_user_in_group(user, g_cfg->sec.ts_admins, &ok)) + { + log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied"); + return 0; + } + + if (ok) + { + return 1; + } + + log_message(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user); - if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) - { - log_message(LOG_LEVEL_WARNING, - "[MNG] ROOT login attempted, but root login is disabled"); return 0; - } - - if (0 == g_cfg->sec.ts_admins_enable) - { - LOG_DBG("[MNG] Terminal Server Admin group is disabled," - "allowing authentication",1); - return 1; - } - - if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) - { - log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied"); - return 0; - } - - if (g_cfg->sec.ts_admins == gid) - { - LOG_DBG("[MNG] ts_users is user's primary group"); - return 1; - } - - if (0 != g_check_user_in_group(user, g_cfg->sec.ts_admins, &ok)) - { - log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied"); - return 0; - } - - if (ok) - { - return 1; - } - - log_message(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user); - - return 0; } diff --git a/sesman/access.h b/sesman/access.h index bad20540..d53c65ad 100644 --- a/sesman/access.h +++ b/sesman/access.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/auth.h b/sesman/auth.h index a6c5e7fa..09bec2e9 100644 --- a/sesman/auth.h +++ b/sesman/auth.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 10a42ef9..0f69f1f6 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -32,10 +32,10 @@ #include "rail.h" #include "xcommon.h" -static struct trans* g_lis_trans = 0; -static struct trans* g_con_trans = 0; -static struct trans* g_api_lis_trans = 0; -static struct trans* g_api_con_trans = 0; +static struct trans *g_lis_trans = 0; +static struct trans *g_con_trans = 0; +static struct trans *g_api_lis_trans = 0; +static struct trans *g_api_con_trans = 0; static struct chan_item g_chan_items[32]; static int g_num_chan_items = 0; static int g_cliprdr_index = -1; @@ -54,7 +54,7 @@ int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpdr_chan_id = -1; /* rdpdr */ int g_rail_chan_id = -1; /* rail */ -char* g_exec_name; +char *g_exec_name; tbus g_exec_event; tbus g_exec_mutex; tbus g_exec_sem; @@ -63,97 +63,109 @@ int g_exec_pid = 0; /* data in struct trans::callback_data */ struct xrdp_api_data { - int chan_id; - char header[64]; - int flags; + int chan_id; + char header[64]; + int flags; }; /*****************************************************************************/ /* add data to chan_item, on its way to the client */ /* returns error */ static int APP_CC -add_data_to_chan_item(struct chan_item* chan_item, char* data, int size) +add_data_to_chan_item(struct chan_item *chan_item, char *data, int size) { - struct stream* s; - struct chan_out_data* cod; + struct stream *s; + struct chan_out_data *cod; - make_stream(s); - init_stream(s, size); - g_memcpy(s->data, data, size); - s->end = s->data + size; - cod = (struct chan_out_data*)g_malloc(sizeof(struct chan_out_data), 1); - cod->s = s; - if (chan_item->tail == 0) - { - chan_item->tail = cod; - chan_item->head = cod; - } - else - { - chan_item->tail->next = cod; - chan_item->tail = cod; - } - return 0; + make_stream(s); + init_stream(s, size); + g_memcpy(s->data, data, size); + s->end = s->data + size; + cod = (struct chan_out_data *)g_malloc(sizeof(struct chan_out_data), 1); + cod->s = s; + + if (chan_item->tail == 0) + { + chan_item->tail = cod; + chan_item->head = cod; + } + else + { + chan_item->tail->next = cod; + chan_item->tail = cod; + } + + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -send_data_from_chan_item(struct chan_item* chan_item) +send_data_from_chan_item(struct chan_item *chan_item) { - struct stream* s; - struct chan_out_data* cod; - int bytes_left; - int size; - int chan_flags; - int error; + struct stream *s; + struct chan_out_data *cod; + int bytes_left; + int size; + int chan_flags; + int error; - if (chan_item->head == 0) - { - return 0; - } - cod = chan_item->head; - bytes_left = (int)(cod->s->end - cod->s->p); - size = MIN(1600, bytes_left); - chan_flags = 0; - if (cod->s->p == cod->s->data) - { - chan_flags |= 1; /* first */ - } - if (cod->s->p + size >= cod->s->end) - { - chan_flags |= 2; /* last */ - } - s = trans_get_out_s(g_con_trans, 8192); - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */ - out_uint32_le(s, 8); /* msg id */ - out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */ - out_uint16_le(s, chan_item->id); - out_uint16_le(s, chan_flags); - out_uint16_le(s, size); - out_uint32_le(s, cod->s->size); - out_uint8a(s, cod->s->p, size); - s_mark_end(s); - LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- " - "size %d chan_flags 0x%8.8x", size, chan_flags)); - error = trans_force_write(g_con_trans); - if (error != 0) - { - return 1; - } - cod->s->p += size; - if (cod->s->p >= cod->s->end) - { - free_stream(cod->s); - chan_item->head = chan_item->head->next; if (chan_item->head == 0) { - chan_item->tail = 0; + return 0; } - g_free(cod); - } - return 0; + + cod = chan_item->head; + bytes_left = (int)(cod->s->end - cod->s->p); + size = MIN(1600, bytes_left); + chan_flags = 0; + + if (cod->s->p == cod->s->data) + { + chan_flags |= 1; /* first */ + } + + if (cod->s->p + size >= cod->s->end) + { + chan_flags |= 2; /* last */ + } + + s = trans_get_out_s(g_con_trans, 8192); + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */ + out_uint32_le(s, 8); /* msg id */ + out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */ + out_uint16_le(s, chan_item->id); + out_uint16_le(s, chan_flags); + out_uint16_le(s, size); + out_uint32_le(s, cod->s->size); + out_uint8a(s, cod->s->p, size); + s_mark_end(s); + LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- " + "size %d chan_flags 0x%8.8x", size, chan_flags)); + error = trans_force_write(g_con_trans); + + if (error != 0) + { + return 1; + } + + cod->s->p += size; + + if (cod->s->p >= cod->s->end) + { + free_stream(cod->s); + chan_item->head = chan_item->head->next; + + if (chan_item->head == 0) + { + chan_item->tail = 0; + } + + g_free(cod); + } + + return 0; } /*****************************************************************************/ @@ -161,40 +173,44 @@ send_data_from_chan_item(struct chan_item* chan_item) static int APP_CC check_chan_items(void) { - int index; + int index; - for (index = 0; index < g_num_chan_items; index++) - { - if (g_chan_items[index].head != 0) + for (index = 0; index < g_num_chan_items; index++) { - send_data_from_chan_item(g_chan_items + index); + if (g_chan_items[index].head != 0) + { + send_data_from_chan_item(g_chan_items + index); + } } - } - return 0; + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -send_channel_data(int chan_id, char* data, int size) +send_channel_data(int chan_id, char *data, int size) { - int index; + int index; - LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size)); - if (chan_id == -1) - { - return 1; - } - for (index = 0; index < g_num_chan_items; index++) - { - if (g_chan_items[index].id == chan_id) + LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size)); + + if (chan_id == -1) { - add_data_to_chan_item(g_chan_items + index, data, size); - check_chan_items(); - return 0; + return 1; } - } - return 1; + + for (index = 0; index < g_num_chan_items; index++) + { + if (g_chan_items[index].id == chan_id) + { + add_data_to_chan_item(g_chan_items + index, data, size); + check_chan_items(); + return 0; + } + } + + return 1; } /*****************************************************************************/ @@ -202,20 +218,22 @@ send_channel_data(int chan_id, char* data, int size) static int APP_CC send_init_response_message(void) { - struct stream * s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - LOGM((LOG_LEVEL_INFO, "send_init_response_message:")); - s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 2); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(g_con_trans); + LOGM((LOG_LEVEL_INFO, "send_init_response_message:")); + s = trans_get_out_s(g_con_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 2); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(g_con_trans); } /*****************************************************************************/ @@ -223,20 +241,22 @@ send_init_response_message(void) static int APP_CC send_channel_setup_response_message(void) { - struct stream * s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - LOGM((LOG_LEVEL_DEBUG, "send_channel_setup_response_message:")); - s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 4); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(g_con_trans); + LOGM((LOG_LEVEL_DEBUG, "send_channel_setup_response_message:")); + s = trans_get_out_s(g_con_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 4); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(g_con_trans); } /*****************************************************************************/ @@ -244,176 +264,192 @@ send_channel_setup_response_message(void) static int APP_CC send_channel_data_response_message(void) { - struct stream * s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - LOGM((LOG_LEVEL_DEBUG, "send_channel_data_response_message:")); - s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 6); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(g_con_trans); + LOGM((LOG_LEVEL_DEBUG, "send_channel_data_response_message:")); + s = trans_get_out_s(g_con_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 6); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(g_con_trans); } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_init(struct stream* s) +process_message_init(struct stream *s) { - LOGM((LOG_LEVEL_DEBUG, "process_message_init:")); - return send_init_response_message(); + LOGM((LOG_LEVEL_DEBUG, "process_message_init:")); + return send_init_response_message(); } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_channel_setup(struct stream* s) +process_message_channel_setup(struct stream *s) { - int num_chans; - int index; - int rv; - struct chan_item* ci; + int num_chans; + int index; + int rv; + struct chan_item *ci; - g_num_chan_items = 0; - g_cliprdr_index = -1; - g_rdpsnd_index = -1; - g_rdpdr_index = -1; - g_rail_index = -1; - g_cliprdr_chan_id = -1; - g_rdpsnd_chan_id = -1; - g_rdpdr_chan_id = -1; - g_rail_chan_id = -1; - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:")); - in_uint16_le(s, num_chans); - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d", - num_chans)); - for (index = 0; index < num_chans; index++) - { - ci = &(g_chan_items[g_num_chan_items]); - g_memset(ci->name, 0, sizeof(ci->name)); - in_uint8a(s, ci->name, 8); - in_uint16_le(s, ci->id); - in_uint16_le(s, ci->flags); - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' " - "id %d flags %8.8x", ci->name, ci->id, ci->flags)); - if (g_strcasecmp(ci->name, "cliprdr") == 0) + g_num_chan_items = 0; + g_cliprdr_index = -1; + g_rdpsnd_index = -1; + g_rdpdr_index = -1; + g_rail_index = -1; + g_cliprdr_chan_id = -1; + g_rdpsnd_chan_id = -1; + g_rdpdr_chan_id = -1; + g_rail_chan_id = -1; + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:")); + in_uint16_le(s, num_chans); + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d", + num_chans)); + + for (index = 0; index < num_chans; index++) { - g_cliprdr_index = g_num_chan_items; - g_cliprdr_chan_id = ci->id; + ci = &(g_chan_items[g_num_chan_items]); + g_memset(ci->name, 0, sizeof(ci->name)); + in_uint8a(s, ci->name, 8); + in_uint16_le(s, ci->id); + in_uint16_le(s, ci->flags); + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' " + "id %d flags %8.8x", ci->name, ci->id, ci->flags)); + + if (g_strcasecmp(ci->name, "cliprdr") == 0) + { + g_cliprdr_index = g_num_chan_items; + g_cliprdr_chan_id = ci->id; + } + else if (g_strcasecmp(ci->name, "rdpsnd") == 0) + { + g_rdpsnd_index = g_num_chan_items; + g_rdpsnd_chan_id = ci->id; + } + else if (g_strcasecmp(ci->name, "rdpdr") == 0) + { + g_rdpdr_index = g_num_chan_items; + g_rdpdr_chan_id = ci->id; + } + else if (g_strcasecmp(ci->name, "rail") == 0) + { + g_rail_index = g_num_chan_items; + g_rail_chan_id = ci->id; + } + else + { + LOG(10, ("other %s", ci->name)); + } + + g_num_chan_items++; } - else if (g_strcasecmp(ci->name, "rdpsnd") == 0) + + rv = send_channel_setup_response_message(); + + if (g_cliprdr_index >= 0) { - g_rdpsnd_index = g_num_chan_items; - g_rdpsnd_chan_id = ci->id; + clipboard_init(); } - else if (g_strcasecmp(ci->name, "rdpdr") == 0) + + if (g_rdpsnd_index >= 0) { - g_rdpdr_index = g_num_chan_items; - g_rdpdr_chan_id = ci->id; + sound_init(); } - else if (g_strcasecmp(ci->name, "rail") == 0) + + if (g_rdpdr_index >= 0) { - g_rail_index = g_num_chan_items; - g_rail_chan_id = ci->id; + dev_redir_init(); } - else + + if (g_rail_index >= 0) { - LOG(10, ("other %s", ci->name)); + rail_init(); } - g_num_chan_items++; - } - rv = send_channel_setup_response_message(); - if (g_cliprdr_index >= 0) - { - clipboard_init(); - } - if (g_rdpsnd_index >= 0) - { - sound_init(); - } - if (g_rdpdr_index >= 0) - { - dev_redir_init(); - } - if (g_rail_index >= 0) - { - rail_init(); - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_channel_data(struct stream* s) +process_message_channel_data(struct stream *s) { - int chan_id = 0; - int chan_flags = 0; - int rv = 0; - int length = 0; - int total_length = 0; - struct stream* ls; + int chan_id = 0; + int chan_flags = 0; + int rv = 0; + int length = 0; + int total_length = 0; + struct stream *ls; - in_uint16_le(s, chan_id); - in_uint16_le(s, chan_flags); - in_uint16_le(s, length); - in_uint32_le(s, total_length); - LOGM((LOG_LEVEL_DEBUG,"process_message_channel_data: chan_id %d " - "chan_flags %d", chan_id, chan_flags)); - LOG(10, ("process_message_channel_data")); - rv = send_channel_data_response_message(); - if (rv == 0) - { - if (chan_id == g_cliprdr_chan_id) + in_uint16_le(s, chan_id); + in_uint16_le(s, chan_flags); + in_uint16_le(s, length); + in_uint32_le(s, total_length); + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_data: chan_id %d " + "chan_flags %d", chan_id, chan_flags)); + LOG(10, ("process_message_channel_data")); + rv = send_channel_data_response_message(); + + if (rv == 0) { - rv = clipboard_data_in(s, chan_id, chan_flags, length, total_length); + if (chan_id == g_cliprdr_chan_id) + { + rv = clipboard_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == g_rdpsnd_chan_id) + { + rv = sound_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == g_rdpdr_chan_id) + { + rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == g_rail_chan_id) + { + rv = rail_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == ((struct xrdp_api_data *) + (g_api_con_trans->callback_data))->chan_id) + { + LOG(10, ("process_message_channel_data length %d total_length %d " + "chan_flags 0x%8.8x", length, total_length, chan_flags)); + ls = g_api_con_trans->out_s; + + if (chan_flags & 1) /* first */ + { + init_stream(ls, total_length); + } + + out_uint8a(ls, s->p, length); + + if (chan_flags & 2) /* last */ + { + s_mark_end(ls); + trans_force_write(g_api_con_trans); + } + } } - else if (chan_id == g_rdpsnd_chan_id) - { - rv = sound_data_in(s, chan_id, chan_flags, length, total_length); - } - else if (chan_id == g_rdpdr_chan_id) - { - rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length); - } - else if (chan_id == g_rail_chan_id) - { - rv = rail_data_in(s, chan_id, chan_flags, length, total_length); - } - else if (chan_id == ((struct xrdp_api_data*) - (g_api_con_trans->callback_data))->chan_id) - { - LOG(10, ("process_message_channel_data length %d total_length %d " - "chan_flags 0x%8.8x", length, total_length, chan_flags)); - ls = g_api_con_trans->out_s; - if (chan_flags & 1) /* first */ - { - init_stream(ls, total_length); - } - out_uint8a(ls, s->p, length); - if (chan_flags & 2) /* last */ - { - s_mark_end(ls); - trans_force_write(g_api_con_trans); - } - } - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_channel_data_response(struct stream* s) +process_message_channel_data_response(struct stream *s) { - LOG(10, ("process_message_channel_data_response:")); - check_chan_items(); - return 0; + LOG(10, ("process_message_channel_data_response:")); + check_chan_items(); + return 0; } /*****************************************************************************/ @@ -421,680 +457,752 @@ process_message_channel_data_response(struct stream* s) static int APP_CC process_message(void) { - struct stream * s = (struct stream *)NULL; - int size = 0; - int id = 0; - int rv = 0; - char* next_msg = (char *)NULL; + struct stream *s = (struct stream *)NULL; + int size = 0; + int id = 0; + int rv = 0; + char *next_msg = (char *)NULL; - if (g_con_trans == 0) - { - return 1; - } - s = trans_get_in_s(g_con_trans); - if (s == 0) - { - return 1; - } - rv = 0; - while (s_check_rem(s, 8)) - { - next_msg = s->p; + if (g_con_trans == 0) + { + return 1; + } + + s = trans_get_in_s(g_con_trans); + + if (s == 0) + { + return 1; + } + + rv = 0; + + while (s_check_rem(s, 8)) + { + next_msg = s->p; + in_uint32_le(s, id); + in_uint32_le(s, size); + next_msg += size; + + switch (id) + { + case 1: /* init */ + rv = process_message_init(s); + break; + case 3: /* channel setup */ + rv = process_message_channel_setup(s); + break; + case 5: /* channel data */ + rv = process_message_channel_data(s); + break; + case 7: /* channel data response */ + rv = process_message_channel_data_response(s); + break; + default: + LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ", + "unknown msg %d", id)); + break; + } + + if (rv != 0) + { + break; + } + + s->p = next_msg; + } + + return rv; +} + +/*****************************************************************************/ +/* returns error */ +int DEFAULT_CC +my_trans_data_in(struct trans *trans) +{ + struct stream *s = (struct stream *)NULL; + int id = 0; + int size = 0; + int error = 0; + + if (trans == 0) + { + return 0; + } + + if (trans != g_con_trans) + { + return 1; + } + + LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:")); + s = trans_get_in_s(trans); in_uint32_le(s, id); in_uint32_le(s, size); - next_msg += size; - switch (id) + error = trans_force_read(trans, size - 8); + + if (error == 0) { - case 1: /* init */ - rv = process_message_init(s); - break; - case 3: /* channel setup */ - rv = process_message_channel_setup(s); - break; - case 5: /* channel data */ - rv = process_message_channel_data(s); - break; - case 7: /* channel data response */ - rv = process_message_channel_data_response(s); - break; - default: - LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ", - "unknown msg %d", id)); - break; + /* here, the entire message block is read in, process it */ + error = process_message(); } - if (rv != 0) - { - break; - } - s->p = next_msg; - } - return rv; + + return error; } /*****************************************************************************/ /* returns error */ int DEFAULT_CC -my_trans_data_in(struct trans* trans) +my_api_trans_data_in(struct trans *trans) { - struct stream * s = (struct stream *)NULL; - int id = 0; - int size = 0; - int error = 0; + struct stream *s; + int error; + struct xrdp_api_data *ad; - if (trans == 0) - { - return 0; - } - if (trans != g_con_trans) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:")); - s = trans_get_in_s(trans); - in_uint32_le(s, id); - in_uint32_le(s, size); - error = trans_force_read(trans, size - 8); - if (error == 0) - { - /* here, the entire message block is read in, process it */ - error = process_message(); - } - return error; -} + LOG(10, ("my_api_trans_data_in:")); -/*****************************************************************************/ -/* returns error */ -int DEFAULT_CC -my_api_trans_data_in(struct trans* trans) -{ - struct stream* s; - int error; - struct xrdp_api_data* ad; - - LOG(10, ("my_api_trans_data_in:")); - if (trans == 0) - { - return 0; - } - if (trans != g_api_con_trans) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:")); - s = trans_get_in_s(trans); - error = g_tcp_recv(trans->sck, s->data, 8192, 0); - if (error > 0) - { - LOG(10, ("my_api_trans_data_in: got data %d", error)); - ad = (struct xrdp_api_data*)(trans->callback_data); - if (send_channel_data(ad->chan_id, s->data, error) != 0) + if (trans == 0) { - LOG(0, ("my_api_trans_data_in: send_channel_data failed")); + return 0; } - } - else - { - LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected")); - return 1; - } - return 0; + + if (trans != g_api_con_trans) + { + return 1; + } + + LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:")); + s = trans_get_in_s(trans); + error = g_tcp_recv(trans->sck, s->data, 8192, 0); + + if (error > 0) + { + LOG(10, ("my_api_trans_data_in: got data %d", error)); + ad = (struct xrdp_api_data *)(trans->callback_data); + + if (send_channel_data(ad->chan_id, s->data, error) != 0) + { + LOG(0, ("my_api_trans_data_in: send_channel_data failed")); + } + } + else + { + LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected")); + return 1; + } + + return 0; } /*****************************************************************************/ int DEFAULT_CC -my_trans_conn_in(struct trans* trans, struct trans* new_trans) +my_trans_conn_in(struct trans *trans, struct trans *new_trans) { - if (trans == 0) - { - return 1; - } - if (trans != g_lis_trans) - { - return 1; - } - if (g_con_trans != 0) /* if already set, error */ - { - return 1; - } - if (new_trans == 0) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_trans_conn_in:")); - g_con_trans = new_trans; - g_con_trans->trans_data_in = my_trans_data_in; - g_con_trans->header_size = 8; - /* stop listening */ - trans_delete(g_lis_trans); - g_lis_trans = 0; - return 0; + if (trans == 0) + { + return 1; + } + + if (trans != g_lis_trans) + { + return 1; + } + + if (g_con_trans != 0) /* if already set, error */ + { + return 1; + } + + if (new_trans == 0) + { + return 1; + } + + LOGM((LOG_LEVEL_DEBUG, "my_trans_conn_in:")); + g_con_trans = new_trans; + g_con_trans->trans_data_in = my_trans_data_in; + g_con_trans->header_size = 8; + /* stop listening */ + trans_delete(g_lis_trans); + g_lis_trans = 0; + return 0; } /*****************************************************************************/ int DEFAULT_CC -my_api_trans_conn_in(struct trans* trans, struct trans* new_trans) +my_api_trans_conn_in(struct trans *trans, struct trans *new_trans) { - struct xrdp_api_data* ad; - int error; - int index; - int found; - struct stream* s; + struct xrdp_api_data *ad; + int error; + int index; + int found; + struct stream *s; - if (trans == 0) - { - return 1; - } - if (trans != g_api_lis_trans) - { - return 1; - } - if (new_trans == 0) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:")); + if (trans == 0) + { + return 1; + } - LOG(10, ("my_api_trans_conn_in: got incoming")); + if (trans != g_api_lis_trans) + { + return 1; + } - s = trans_get_in_s(new_trans); - s->end = s->data; - error = trans_force_read(new_trans, 64); - if (error != 0) - { - LOG(0, ("my_api_trans_conn_in: trans_force_read failed")); - trans_delete(new_trans); - } - s->end = s->data; + if (new_trans == 0) + { + return 1; + } - ad = (struct xrdp_api_data*)g_malloc(sizeof(struct xrdp_api_data), 1); + LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:")); - g_memcpy(ad->header, s->data, 64); + LOG(10, ("my_api_trans_conn_in: got incoming")); - ad->flags = GGET_UINT32(ad->header, 16); + s = trans_get_in_s(new_trans); + s->end = s->data; + error = trans_force_read(new_trans, 64); + + if (error != 0) + { + LOG(0, ("my_api_trans_conn_in: trans_force_read failed")); + trans_delete(new_trans); + } + + s->end = s->data; + + ad = (struct xrdp_api_data *)g_malloc(sizeof(struct xrdp_api_data), 1); + + g_memcpy(ad->header, s->data, 64); + + ad->flags = GGET_UINT32(ad->header, 16); - found = 0; - if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */ - { - /* TODO */ found = 0; - } - else - { - for (index = 0; index < g_num_chan_items; index++) + + if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */ { - LOG(10, (" %s %s", ad->header, g_chan_items[index].name)); - if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0) - { - LOG(10, ("my_api_trans_conn_in: found it at %d", index)); - ad->chan_id = g_chan_items[index].id; - found = 1; - break; - } + /* TODO */ + found = 0; } - } - LOG(10, ("my_api_trans_conn_in: found %d", found)); - if (!found) - { - ad->chan_id = -1; - } + else + { + for (index = 0; index < g_num_chan_items; index++) + { + LOG(10, (" %s %s", ad->header, g_chan_items[index].name)); - new_trans->callback_data = ad; + if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0) + { + LOG(10, ("my_api_trans_conn_in: found it at %d", index)); + ad->chan_id = g_chan_items[index].id; + found = 1; + break; + } + } + } - trans_delete(g_api_con_trans); - g_api_con_trans = new_trans; - g_api_con_trans->trans_data_in = my_api_trans_data_in; - g_api_con_trans->header_size = 0; + LOG(10, ("my_api_trans_conn_in: found %d", found)); - return 0; + if (!found) + { + ad->chan_id = -1; + } + + new_trans->callback_data = ad; + + trans_delete(g_api_con_trans); + g_api_con_trans = new_trans; + g_api_con_trans->trans_data_in = my_api_trans_data_in; + g_api_con_trans->header_size = 0; + + return 0; } /*****************************************************************************/ static int APP_CC setup_listen(void) { - char port[256]; - int error = 0; + char port[256]; + int error = 0; - if (g_lis_trans != 0) - { - trans_delete(g_lis_trans); - } - if (g_use_unix_socket) - { - g_lis_trans = trans_create(2, 8192, 8192); - g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", - 7200 + g_display_num); - } - else - { - g_lis_trans = trans_create(1, 8192, 8192); - g_snprintf(port, 255, "%d", 7200 + g_display_num); - } - g_lis_trans->trans_conn_in = my_trans_conn_in; - error = trans_listen(g_lis_trans, port); - if (error != 0) - { - LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s", - port)); - return 1; - } - return 0; + if (g_lis_trans != 0) + { + trans_delete(g_lis_trans); + } + + if (g_use_unix_socket) + { + g_lis_trans = trans_create(2, 8192, 8192); + g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", + 7200 + g_display_num); + } + else + { + g_lis_trans = trans_create(1, 8192, 8192); + g_snprintf(port, 255, "%d", 7200 + g_display_num); + } + + g_lis_trans->trans_conn_in = my_trans_conn_in; + error = trans_listen(g_lis_trans, port); + + if (error != 0) + { + LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s", + port)); + return 1; + } + + return 0; } /*****************************************************************************/ static int APP_CC setup_api_listen(void) { - char port[256]; - int error = 0; + char port[256]; + int error = 0; - g_api_lis_trans = trans_create(2, 8192, 8192); - g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num); - g_api_lis_trans->trans_conn_in = my_api_trans_conn_in; - error = trans_listen(g_api_lis_trans, port); - if (error != 0) - { - LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s", - port)); - return 1; - } - return 0; + g_api_lis_trans = trans_create(2, 8192, 8192); + g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num); + g_api_lis_trans->trans_conn_in = my_api_trans_conn_in; + error = trans_listen(g_api_lis_trans, port); + + if (error != 0) + { + LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s", + port)); + return 1; + } + + return 0; } /*****************************************************************************/ THREAD_RV THREAD_CC -channel_thread_loop(void* in_val) +channel_thread_loop(void *in_val) { - tbus objs[32]; - int num_objs; - int timeout; - int error; - THREAD_RV rv; + tbus objs[32]; + int num_objs; + int timeout; + int error; + THREAD_RV rv; - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); - rv = 0; - setup_api_listen(); - error = setup_listen(); - if (error == 0) - { - timeout = -1; - num_objs = 0; - objs[num_objs] = g_term_event; - num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); - while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); + rv = 0; + setup_api_listen(); + error = setup_listen(); + + if (error == 0) { - if (g_is_wait_obj_set(g_term_event)) - { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set")); - clipboard_deinit(); - sound_deinit(); - dev_redir_deinit(); - rail_deinit(); - break; - } - if (g_lis_trans != 0) - { - if (trans_check_wait_objs(g_lis_trans) != 0) - { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " - "trans_check_wait_objs error")); - } - } - if (g_con_trans != 0) - { - if (trans_check_wait_objs(g_con_trans) != 0) - { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " - "trans_check_wait_objs error resetting")); - clipboard_deinit(); - sound_deinit(); - dev_redir_deinit(); - rail_deinit(); - /* delete g_con_trans */ - trans_delete(g_con_trans); - g_con_trans = 0; - /* create new listener */ - error = setup_listen(); - if (error != 0) - { - break; - } - } - } - if (g_api_lis_trans != 0) - { - if (trans_check_wait_objs(g_api_lis_trans) != 0) - { - LOG(0, ("channel_thread_loop: trans_check_wait_objs failed")); - } - } + timeout = -1; + num_objs = 0; + objs[num_objs] = g_term_event; + num_objs++; + trans_get_wait_objs(g_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); - LOG(10, ("0 %p", g_api_con_trans)); - if (g_api_con_trans != 0) - { - LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0))); - if (trans_check_wait_objs(g_api_con_trans) != 0) + while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) { - LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, " - "or disconnected")); - g_free(g_api_con_trans->callback_data); - trans_delete(g_api_con_trans); - g_api_con_trans = 0; - } - } + if (g_is_wait_obj_set(g_term_event)) + { + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set")); + clipboard_deinit(); + sound_deinit(); + dev_redir_deinit(); + rail_deinit(); + break; + } - xcommon_check_wait_objs(); - sound_check_wait_objs(); - dev_redir_check_wait_objs(); - timeout = -1; - num_objs = 0; - objs[num_objs] = g_term_event; - num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_con_trans, objs, &num_objs); - trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_api_con_trans, objs, &num_objs); - xcommon_get_wait_objs(objs, &num_objs, &timeout); - sound_get_wait_objs(objs, &num_objs, &timeout); - dev_redir_get_wait_objs(objs, &num_objs, &timeout); + if (g_lis_trans != 0) + { + if (trans_check_wait_objs(g_lis_trans) != 0) + { + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " + "trans_check_wait_objs error")); + } + } + + if (g_con_trans != 0) + { + if (trans_check_wait_objs(g_con_trans) != 0) + { + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " + "trans_check_wait_objs error resetting")); + clipboard_deinit(); + sound_deinit(); + dev_redir_deinit(); + rail_deinit(); + /* delete g_con_trans */ + trans_delete(g_con_trans); + g_con_trans = 0; + /* create new listener */ + error = setup_listen(); + + if (error != 0) + { + break; + } + } + } + + if (g_api_lis_trans != 0) + { + if (trans_check_wait_objs(g_api_lis_trans) != 0) + { + LOG(0, ("channel_thread_loop: trans_check_wait_objs failed")); + } + } + + LOG(10, ("0 %p", g_api_con_trans)); + + if (g_api_con_trans != 0) + { + LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0))); + + if (trans_check_wait_objs(g_api_con_trans) != 0) + { + LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, " + "or disconnected")); + g_free(g_api_con_trans->callback_data); + trans_delete(g_api_con_trans); + g_api_con_trans = 0; + } + } + + xcommon_check_wait_objs(); + sound_check_wait_objs(); + dev_redir_check_wait_objs(); + timeout = -1; + num_objs = 0; + objs[num_objs] = g_term_event; + num_objs++; + trans_get_wait_objs(g_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_con_trans, objs, &num_objs); + trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_api_con_trans, objs, &num_objs); + xcommon_get_wait_objs(objs, &num_objs, &timeout); + sound_get_wait_objs(objs, &num_objs, &timeout); + dev_redir_get_wait_objs(objs, &num_objs, &timeout); + } } - } - trans_delete(g_lis_trans); - g_lis_trans = 0; - trans_delete(g_con_trans); - g_con_trans = 0; - trans_delete(g_api_lis_trans); - g_api_lis_trans = 0; - trans_delete(g_api_con_trans); - g_api_con_trans = 0; - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop")); - g_set_wait_obj(g_thread_done_event); - return rv; + + trans_delete(g_lis_trans); + g_lis_trans = 0; + trans_delete(g_con_trans); + g_con_trans = 0; + trans_delete(g_api_lis_trans); + g_api_lis_trans = 0; + trans_delete(g_api_con_trans); + g_api_con_trans = 0; + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop")); + g_set_wait_obj(g_thread_done_event); + return rv; } /*****************************************************************************/ void DEFAULT_CC term_signal_handler(int sig) { - LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig)); - g_set_wait_obj(g_term_event); + LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig)); + g_set_wait_obj(g_term_event); } /*****************************************************************************/ void DEFAULT_CC nil_signal_handler(int sig) { - LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig)); + LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig)); } /*****************************************************************************/ void DEFAULT_CC child_signal_handler(int sig) { - int i1; + int i1; - LOG(10, ("child_signal_handler:")); - do - { - i1 = g_waitchild(); - if (i1 == g_exec_pid) + LOG(10, ("child_signal_handler:")); + + do { - LOG(0, ("child_signal_handler: found pid %d", i1)); - //shutdownx(); + i1 = g_waitchild(); + + if (i1 == g_exec_pid) + { + LOG(0, ("child_signal_handler: found pid %d", i1)); + //shutdownx(); + } + + LOG(10, (" %d", i1)); } - LOG(10, (" %d", i1)); - } while (i1 >= 0); + while (i1 >= 0); } /*****************************************************************************/ static int APP_CC -get_display_num_from_display(char* display_text) +get_display_num_from_display(char *display_text) { - int index; - int mode; - int host_index; - int disp_index; - int scre_index; - char host[256]; - char disp[256]; - char scre[256]; + int index; + int mode; + int host_index; + int disp_index; + int scre_index; + char host[256]; + char disp[256]; + char scre[256]; - g_memset(host, 0, 256); - g_memset(disp, 0, 256); - g_memset(scre, 0, 256); + g_memset(host, 0, 256); + g_memset(disp, 0, 256); + g_memset(scre, 0, 256); - index = 0; - host_index = 0; - disp_index = 0; - scre_index = 0; - mode = 0; - while (display_text[index] != 0) - { - if (display_text[index] == ':') + index = 0; + host_index = 0; + disp_index = 0; + scre_index = 0; + mode = 0; + + while (display_text[index] != 0) { - mode = 1; + if (display_text[index] == ':') + { + mode = 1; + } + else if (display_text[index] == '.') + { + mode = 2; + } + else if (mode == 0) + { + host[host_index] = display_text[index]; + host_index++; + } + else if (mode == 1) + { + disp[disp_index] = display_text[index]; + disp_index++; + } + else if (mode == 2) + { + scre[scre_index] = display_text[index]; + scre_index++; + } + + index++; } - else if (display_text[index] == '.') - { - mode = 2; - } - else if (mode == 0) - { - host[host_index] = display_text[index]; - host_index++; - } - else if (mode == 1) - { - disp[disp_index] = display_text[index]; - disp_index++; - } - else if (mode == 2) - { - scre[scre_index] = display_text[index]; - scre_index++; - } - index++; - } - host[host_index] = 0; - disp[disp_index] = 0; - scre[scre_index] = 0; - g_display_num = g_atoi(disp); - return 0; + + host[host_index] = 0; + disp[disp_index] = 0; + scre[scre_index] = 0; + g_display_num = g_atoi(disp); + return 0; } /*****************************************************************************/ int APP_CC main_cleanup(void) { - g_delete_wait_obj(g_term_event); - g_delete_wait_obj(g_thread_done_event); - g_delete_wait_obj(g_exec_event); - tc_mutex_delete(g_exec_mutex); - g_deinit(); /* os_calls */ - return 0; + g_delete_wait_obj(g_term_event); + g_delete_wait_obj(g_thread_done_event); + g_delete_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); + g_deinit(); /* os_calls */ + return 0; } /*****************************************************************************/ static int APP_CC read_ini(void) { - char filename[256]; - struct list* names; - struct list* values; - char* name; - char* value; - int index; + char filename[256]; + struct list *names; + struct list *values; + char *name; + char *value; + int index; - g_memset(filename,0,(sizeof(char) * 256)); - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - g_use_unix_socket = 0; - g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH); - if (file_by_name_read_section(filename, "Globals", names, values) == 0) - { - for (index = 0; index < names->count; index++) + g_memset(filename, 0, (sizeof(char) * 256)); + names = list_create(); + names->auto_free = 1; + values = list_create(); + values->auto_free = 1; + g_use_unix_socket = 0; + g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH); + + if (file_by_name_read_section(filename, "Globals", names, values) == 0) { - name = (char*)list_get_item(names, index); - value = (char*)list_get_item(values, index); - if (g_strcasecmp(name, "ListenAddress") == 0) - { - if (g_strcasecmp(value, "127.0.0.1") == 0) + for (index = 0; index < names->count; index++) { - g_use_unix_socket = 1; + name = (char *)list_get_item(names, index); + value = (char *)list_get_item(values, index); + + if (g_strcasecmp(name, "ListenAddress") == 0) + { + if (g_strcasecmp(value, "127.0.0.1") == 0) + { + g_use_unix_socket = 1; + } + } } - } } - } - list_delete(names); - list_delete(values); - return 0; + + list_delete(names); + list_delete(values); + return 0; } /*****************************************************************************/ static int APP_CC run_exec(void) { - int pid; + int pid; - LOG(10, ("run_exec:")); - pid = g_fork(); - if (pid == 0) - { - trans_delete(g_con_trans); - g_close_wait_obj(g_term_event); - g_close_wait_obj(g_thread_done_event); - g_close_wait_obj(g_exec_event); - tc_mutex_delete(g_exec_mutex); - tc_sem_delete(g_exec_sem); - g_execlp3(g_exec_name, g_exec_name, 0); - g_exit(0); - } - g_exec_pid = pid; - tc_sem_inc(g_exec_sem); + LOG(10, ("run_exec:")); + pid = g_fork(); - return 0; + if (pid == 0) + { + trans_delete(g_con_trans); + g_close_wait_obj(g_term_event); + g_close_wait_obj(g_thread_done_event); + g_close_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); + tc_sem_delete(g_exec_sem); + g_execlp3(g_exec_name, g_exec_name, 0); + g_exit(0); + } + + g_exec_pid = pid; + tc_sem_inc(g_exec_sem); + + return 0; } /*****************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - tbus waiters[4]; - int pid = 0; - char text[256]; - char* home_text; - char* display_text; - char log_file[256]; - enum logReturns error; - struct log_config logconfig; + tbus waiters[4]; + int pid = 0; + char text[256]; + char *home_text; + char *display_text; + char log_file[256]; + enum logReturns error; + struct log_config logconfig; - g_init("xrdp-chansrv"); /* os_calls */ + g_init("xrdp-chansrv"); /* os_calls */ - home_text = g_getenv("HOME"); - if (home_text == 0) - { - g_writeln("error reading HOME environment variable"); + home_text = g_getenv("HOME"); + + if (home_text == 0) + { + g_writeln("error reading HOME environment variable"); + g_deinit(); + return 1; + } + + read_ini(); + pid = g_getpid(); + + /* starting logging subsystem */ + g_memset(&logconfig, 0, sizeof(struct log_config)); + logconfig.program_name = "XRDP-Chansrv"; + g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); + g_writeln("chansrv::main: using log file [%s]", log_file); + + if (g_file_exist(log_file)) + { + g_file_delete(log_file); + } + + logconfig.log_file = log_file; + logconfig.fd = -1; + logconfig.log_level = LOG_LEVEL_ERROR; + logconfig.enable_syslog = 0; + logconfig.syslog_level = 0; + error = log_start_from_param(&logconfig); + + if (error != LOG_STARTUP_OK) + { + switch (error) + { + case LOG_ERROR_MALLOC: + g_writeln("error on malloc. cannot start logging. quitting."); + break; + case LOG_ERROR_FILE_OPEN: + g_writeln("error opening log file [%s]. quitting.", + getLogFile(text, 255)); + break; + default: + g_writeln("log_start error"); + break; + } + + g_deinit(); + return 1; + } + + LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); + /* set up signal handler */ + g_signal_kill(term_signal_handler); /* SIGKILL */ + g_signal_terminate(term_signal_handler); /* SIGTERM */ + g_signal_user_interrupt(term_signal_handler); /* SIGINT */ + g_signal_pipe(nil_signal_handler); /* SIGPIPE */ + g_signal_child_stop(child_signal_handler); /* SIGCHLD */ + display_text = g_getenv("DISPLAY"); + LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); + get_display_num_from_display(display_text); + + if (g_display_num == 0) + { + LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); + g_deinit(); + return 1; + } + + LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); + g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); + g_thread_done_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); + g_exec_event = g_create_wait_obj(text); + g_exec_mutex = tc_mutex_create(); + g_exec_sem = tc_sem_create(0); + tc_thread_create(channel_thread_loop, 0); + + while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) + { + waiters[0] = g_term_event; + waiters[1] = g_exec_event; + + if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) + { + LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); + break; + } + + if (g_is_wait_obj_set(g_term_event)) + { + break; + } + + if (g_is_wait_obj_set(g_exec_event)) + { + g_reset_wait_obj(g_exec_event); + run_exec(); + } + } + + while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) + { + /* wait for thread to exit */ + if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0) + { + LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); + break; + } + } + + /* cleanup */ + main_cleanup(); + LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); g_deinit(); - return 1; - } - - read_ini(); - pid = g_getpid(); - - /* starting logging subsystem */ - g_memset(&logconfig, 0, sizeof(struct log_config)); - logconfig.program_name = "XRDP-Chansrv"; - g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); - g_writeln("chansrv::main: using log file [%s]", log_file); - if (g_file_exist(log_file)) - { - g_file_delete(log_file); - } - logconfig.log_file = log_file; - logconfig.fd = -1; - logconfig.log_level = LOG_LEVEL_ERROR; - logconfig.enable_syslog = 0; - logconfig.syslog_level = 0; - error = log_start_from_param(&logconfig); - if (error != LOG_STARTUP_OK) - { - switch (error) - { - case LOG_ERROR_MALLOC: - g_writeln("error on malloc. cannot start logging. quitting."); - break; - case LOG_ERROR_FILE_OPEN: - g_writeln("error opening log file [%s]. quitting.", - getLogFile(text, 255)); - break; - default: - g_writeln("log_start error"); - break; - } - g_deinit(); - return 1; - } - LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); - /* set up signal handler */ - g_signal_kill(term_signal_handler); /* SIGKILL */ - g_signal_terminate(term_signal_handler); /* SIGTERM */ - g_signal_user_interrupt(term_signal_handler); /* SIGINT */ - g_signal_pipe(nil_signal_handler); /* SIGPIPE */ - g_signal_child_stop(child_signal_handler); /* SIGCHLD */ - display_text = g_getenv("DISPLAY"); - LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); - get_display_num_from_display(display_text); - if (g_display_num == 0) - { - LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); - g_deinit(); - return 1; - } - LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); - g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); - g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); - g_thread_done_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); - g_exec_event = g_create_wait_obj(text); - g_exec_mutex = tc_mutex_create(); - g_exec_sem = tc_sem_create(0); - tc_thread_create(channel_thread_loop, 0); - while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) - { - waiters[0] = g_term_event; - waiters[1] = g_exec_event; - if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) - { - LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); - break; - } - if (g_is_wait_obj_set(g_term_event)) - { - break; - } - if (g_is_wait_obj_set(g_exec_event)) - { - g_reset_wait_obj(g_exec_event); - run_exec(); - } - } - while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) - { - /* wait for thread to exit */ - if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0) - { - LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); - break; - } - } - /* cleanup */ - main_cleanup(); - LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); - g_deinit(); - return 0; + return 0; } diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 3bea9704..1541170d 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -48,10 +48,10 @@ static char g_bmp_image_header[] = extern int g_cliprdr_chan_id; /* in chansrv.c */ -extern Display* g_display; /* in xcommon.c */ +extern Display *g_display; /* in xcommon.c */ extern int g_x_socket; /* in xcommon.c */ 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 */ int g_clip_up = 0; @@ -73,18 +73,18 @@ static Window g_wnd = 0; static int g_xfixes_event_base = 0; static int g_last_clip_size = 0; -static char* g_last_clip_data = 0; +static char *g_last_clip_data = 0; static Atom g_last_clip_type = 0; static int g_got_selection = 0; /* boolean */ static Time g_selection_time = 0; -static struct stream* g_ins = 0; +static struct stream *g_ins = 0; static XSelectionRequestEvent g_selection_request_event[16]; static int g_selection_request_event_count = 0; -static char* g_data_in = 0; +static char *g_data_in = 0; static int g_data_in_size = 0; static int g_data_in_time = 0; static int g_data_in_up_to_date = 0; @@ -98,7 +98,7 @@ static XSelectionRequestEvent g_saved_selection_req_event; static Atom g_incr_atom; static Atom g_incr_atom_type; static Atom g_incr_atom_target; -static char* g_incr_data = 0; +static char *g_incr_data = 0; static int g_incr_data_size = 0; static int g_incr_in_progress = 0; @@ -109,19 +109,22 @@ static int clipboard_format_id = CB_FORMAT_UNICODETEXT; static Time APP_CC clipboard_get_server_time(void) { - XEvent xevent; - unsigned char no_text[4]; + XEvent xevent; + unsigned char no_text[4]; - /* append nothing */ - no_text[0] = 0; - XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8, - PropModeAppend, no_text, 0); - /* wait for PropertyNotify */ - do - { - XMaskEvent(g_display, PropertyChangeMask, &xevent); - } while (xevent.type != PropertyNotify); - return xevent.xproperty.time; + /* append nothing */ + no_text[0] = 0; + XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8, + PropModeAppend, no_text, 0); + + /* wait for PropertyNotify */ + do + { + XMaskEvent(g_display, PropertyChangeMask, &xevent); + } + while (xevent.type != PropertyNotify); + + return xevent.xproperty.time; } /*****************************************************************************/ @@ -132,7 +135,7 @@ clipboard_get_server_time(void) static int APP_CC clipboard_get_local_time(void) { - return g_time3(); + return g_time3(); } /*****************************************************************************/ @@ -140,386 +143,416 @@ clipboard_get_local_time(void) int APP_CC clipboard_init(void) { - struct stream* s; - int size; - int rv; - int input_mask; - int dummy; - int ver_maj; - int ver_min; - Status st; + struct stream *s; + int size; + int rv; + int input_mask; + int dummy; + int ver_maj; + int ver_min; + Status st; - LOGM((LOG_LEVEL_DEBUG, "xrdp-chansrv: in clipboard_init")); - if (g_clip_up) - { - return 0; - } - xcommon_init(); - clipboard_deinit(); - rv = 0; - if (rv == 0) - { - g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False); - if (g_clipboard_atom == None) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed")); - rv = 3; - } - } - if (rv == 0) - { - if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy)) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: no xfixes")); - rv = 5; - } - } - if (rv == 0) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d", - g_xfixes_event_base)); - st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); - LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st, - ver_maj, ver_min)); - g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", - False); - g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", - False); - g_timestamp_atom = XInternAtom(g_display, "TIMESTAMP", False); - g_targets_atom = XInternAtom(g_display, "TARGETS", False); - g_multiple_atom = XInternAtom(g_display, "MULTIPLE", False); - g_primary_atom = XInternAtom(g_display, "PRIMARY", False); - g_secondary_atom = XInternAtom(g_display, "SECONDARY", False); - g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False); + LOGM((LOG_LEVEL_DEBUG, "xrdp-chansrv: in clipboard_init")); - g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False); - g_incr_atom = XInternAtom(g_display, "INCR", False); - if (g_image_bmp_atom == None) + if (g_clip_up) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was " - "not allocated")); + return 0; } - g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), - 0, 0, 4, 4, 0, 0, 0); - input_mask = StructureNotifyMask | PropertyChangeMask; - XSelectInput(g_display, g_wnd, input_mask); - //XMapWindow(g_display, g_wnd); - XFixesSelectSelectionInput(g_display, g_wnd, - g_clipboard_atom, - XFixesSetSelectionOwnerNotifyMask | - XFixesSelectionWindowDestroyNotifyMask | - XFixesSelectionClientCloseNotifyMask); - } - if (rv == 0) - { - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 1); /* CLIPRDR_CONNECT */ - out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 0); /* length */ - out_uint32_le(s, 0); /* extra 4 bytes ? */ - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG, "clipboard_init: data out, sending " - "CLIPRDR_CONNECT (clip_msg_id = 1)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - if (rv != 0) + xcommon_init(); + clipboard_deinit(); + rv = 0; + + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed " - "rv = %d", rv)); - rv = 4; + g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False); + + if (g_clipboard_atom == None) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed")); + rv = 3; + } } - free_stream(s); - } - if (rv == 0) - { - g_clip_up = 1; - make_stream(g_ins); - init_stream(g_ins, 8192); - } - else - { - LOGM((LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit")); - } - return rv; + + if (rv == 0) + { + if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy)) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: no xfixes")); + rv = 5; + } + } + + if (rv == 0) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d", + g_xfixes_event_base)); + st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); + LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st, + ver_maj, ver_min)); + g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", + False); + g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", + False); + g_timestamp_atom = XInternAtom(g_display, "TIMESTAMP", False); + g_targets_atom = XInternAtom(g_display, "TARGETS", False); + g_multiple_atom = XInternAtom(g_display, "MULTIPLE", False); + g_primary_atom = XInternAtom(g_display, "PRIMARY", False); + g_secondary_atom = XInternAtom(g_display, "SECONDARY", False); + g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False); + + g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False); + g_incr_atom = XInternAtom(g_display, "INCR", False); + + if (g_image_bmp_atom == None) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was " + "not allocated")); + } + + g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), + 0, 0, 4, 4, 0, 0, 0); + input_mask = StructureNotifyMask | PropertyChangeMask; + XSelectInput(g_display, g_wnd, input_mask); + //XMapWindow(g_display, g_wnd); + XFixesSelectSelectionInput(g_display, g_wnd, + g_clipboard_atom, + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); + } + + if (rv == 0) + { + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 1); /* CLIPRDR_CONNECT */ + out_uint16_le(s, 0); /* status */ + out_uint32_le(s, 0); /* length */ + out_uint32_le(s, 0); /* extra 4 bytes ? */ + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_init: data out, sending " + "CLIPRDR_CONNECT (clip_msg_id = 1)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + + if (rv != 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed " + "rv = %d", rv)); + rv = 4; + } + + free_stream(s); + } + + if (rv == 0) + { + g_clip_up = 1; + make_stream(g_ins); + init_stream(g_ins, 8192); + } + else + { + LOGM((LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit")); + } + + return rv; } /*****************************************************************************/ int APP_CC clipboard_deinit(void) { - if (g_wnd != 0) - { - XDestroyWindow(g_display, g_wnd); - g_wnd = 0; - } - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = 0; - free_stream(g_ins); - g_ins = 0; - g_clip_up = 0; - return 0; + if (g_wnd != 0) + { + XDestroyWindow(g_display, g_wnd); + g_wnd = 0; + } + + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = 0; + free_stream(g_ins); + g_ins = 0; + g_clip_up = 0; + return 0; } /*****************************************************************************/ static int APP_CC clipboard_send_data_request(void) { - struct stream* s; - int size; - int rv; + struct stream *s; + int size; + int rv; - LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request:")); - if (!g_got_format_announce) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_request: error, " - "no format announce")); - return 0; - } - g_got_format_announce = 0; - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */ - out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 4); /* length */ - out_uint32_le(s, clipboard_format_id); - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_request: data out, sending " - "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request:")); + + if (!g_got_format_announce) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_request: error, " + "no format announce")); + return 0; + } + + g_got_format_announce = 0; + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */ + out_uint16_le(s, 0); /* status */ + out_uint32_le(s, 4); /* length */ + out_uint32_le(s, clipboard_format_id); + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request: data out, sending " + "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC clipboard_send_format_ack(void) { - struct stream* s; - int size; - int rv; + struct stream *s; + int size; + int rv; - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 3); /* CLIPRDR_FORMAT_ACK */ - out_uint16_le(s, 1); /* status */ - out_uint32_le(s, 0); /* length */ - out_uint32_le(s, 0); /* extra 4 bytes ? */ - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_ack: data out, sending " - "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 3); /* CLIPRDR_FORMAT_ACK */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, 0); /* length */ + out_uint32_le(s, 0); /* extra 4 bytes ? */ + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_format_ack: data out, sending " + "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } static char windows_native_format[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /*****************************************************************************/ static int APP_CC -clipboard_send_format_announce(tui32 format_id, char* format_name) +clipboard_send_format_announce(tui32 format_id, char *format_name) { - struct stream* s; - int size; - int rv; + struct stream *s; + int size; + int rv; - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */ - out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */ - out_uint32_le(s, format_id); - out_uint8p(s, windows_native_format, sizeof(windows_native_format)); - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_announce: data out, sending " - "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */ + out_uint16_le(s, 0); /* status */ + out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */ + out_uint32_le(s, format_id); + out_uint8p(s, windows_native_format, sizeof(windows_native_format)); + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_format_announce: data out, sending " + "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ /* returns number of bytes written */ static int APP_CC -clipboard_out_unicode(struct stream* s, char* text, int num_chars) +clipboard_out_unicode(struct stream *s, char *text, int num_chars) { - int index; - int lnum_chars; - twchar* ltext; + int index; + int lnum_chars; + twchar *ltext; - if ((num_chars < 1) || (text == 0)) - { - return 0; - } - lnum_chars = g_mbstowcs(0, text, num_chars); - if (lnum_chars < 0) - { - return 0; - } - ltext = g_malloc((num_chars + 1) * sizeof(twchar), 1); - g_mbstowcs(ltext, text, num_chars); - index = 0; - while (index < num_chars) - { - out_uint16_le(s, ltext[index]); - index++; - } - g_free(ltext); - return index * 2; + if ((num_chars < 1) || (text == 0)) + { + return 0; + } + + lnum_chars = g_mbstowcs(0, text, num_chars); + + if (lnum_chars < 0) + { + return 0; + } + + ltext = g_malloc((num_chars + 1) * sizeof(twchar), 1); + g_mbstowcs(ltext, text, num_chars); + index = 0; + + while (index < num_chars) + { + out_uint16_le(s, ltext[index]); + index++; + } + + g_free(ltext); + return index * 2; } /*****************************************************************************/ static int APP_CC clipboard_send_data_response_for_image(void) { - struct stream* s; - int size; - int rv; + struct stream *s; + int size; + int rv; - LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n", - g_last_clip_size)); - make_stream(s); - init_stream(s, 64 + g_last_clip_size); - out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ - out_uint16_le(s, 1); /* status */ - out_uint32_le(s, g_last_clip_size); /* length */ - /* insert image data */ - if (g_last_clip_type == g_image_bmp_atom) - { - /* do not insert first header */ - out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14); - } - out_uint16_le(s, 0); /* nil for string */ - out_uint32_le(s, 0); - out_uint32_le(s, 0); - out_uint32_le(s, 0); - s_mark_end(s); - size = (int)(s->end - s->data); - /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */ - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n", + g_last_clip_size)); + make_stream(s); + init_stream(s, 64 + g_last_clip_size); + out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, g_last_clip_size); /* length */ + + /* insert image data */ + if (g_last_clip_type == g_image_bmp_atom) + { + /* do not insert first header */ + out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14); + } + + out_uint16_le(s, 0); /* nil for string */ + out_uint32_le(s, 0); + out_uint32_le(s, 0); + out_uint32_le(s, 0); + s_mark_end(s); + size = (int)(s->end - s->data); + /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */ + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC clipboard_send_data_response(void) { - struct stream* s; - int size; - int rv; - int num_chars; + struct stream *s; + int size; + int rv; + int num_chars; - LOG(10, ("clipboard_send_data_response:")); - num_chars = 0; - if (g_last_clip_data != 0) - { - if (g_last_clip_type == g_image_bmp_atom) + LOG(10, ("clipboard_send_data_response:")); + num_chars = 0; + + if (g_last_clip_data != 0) { - return clipboard_send_data_response_for_image(); + if (g_last_clip_type == g_image_bmp_atom) + { + return clipboard_send_data_response_for_image(); + } + + if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom)) + { + num_chars = g_mbstowcs(0, g_last_clip_data, 0); + + if (num_chars < 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: bad string")); + num_chars = 0; + } + } } - if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom)) + + LOG(10, ("clipboard_send_data_response: g_last_clip_size %d " + "num_chars %d", g_last_clip_size, num_chars)); + make_stream(s); + init_stream(s, 64 + num_chars * 2); + out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, num_chars * 2 + 2); /* length */ + + if (clipboard_out_unicode(s, g_last_clip_data, num_chars) != num_chars * 2) { - num_chars = g_mbstowcs(0, g_last_clip_data, 0); - if (num_chars < 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: bad string")); - num_chars = 0; - } + LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: error " + "clipboard_out_unicode didn't write right number of bytes")); } - } - LOG(10, ("clipboard_send_data_response: g_last_clip_size %d " - "num_chars %d", g_last_clip_size, num_chars)); - make_stream(s); - init_stream(s, 64 + num_chars * 2); - out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ - out_uint16_le(s, 1); /* status */ - out_uint32_le(s, num_chars * 2 + 2); /* length */ - if (clipboard_out_unicode(s, g_last_clip_data, num_chars) != num_chars * 2) - { - LOGM((LOG_LEVEL_ERROR,"clipboard_send_data_response: error " - "clipboard_out_unicode didn't write right number of bytes")); - } - out_uint16_le(s, 0); /* nil for string */ - out_uint32_le(s, 0); - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_response: data out, sending " - "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d", - size, num_chars)); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + + out_uint16_le(s, 0); /* nil for string */ + out_uint32_le(s, 0); + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_response: data out, sending " + "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d", + size, num_chars)); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC clipboard_set_selection_owner(void) { - Window owner; + Window owner; - g_selection_time = clipboard_get_server_time(); - XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time); - owner = XGetSelectionOwner(g_display, g_clipboard_atom); - if (owner != g_wnd) - { - g_got_selection = 0; - return 1; - } - g_got_selection = 1; - return 0; + g_selection_time = clipboard_get_server_time(); + XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time); + owner = XGetSelectionOwner(g_display, g_clipboard_atom); + + if (owner != g_wnd) + { + g_got_selection = 0; + return 1; + } + + g_got_selection = 1; + return 0; } /*****************************************************************************/ static int APP_CC -clipboard_provide_selection(XSelectionRequestEvent* req, Atom type, int format, - char* data, int length) +clipboard_provide_selection(XSelectionRequestEvent *req, Atom type, int format, + char *data, int length) { - XEvent xev; + XEvent xev; - XChangeProperty(g_display, req->requestor, req->property, - type, format, PropModeReplace, (tui8*)data, length); - g_memset(&xev, 0, sizeof(xev)); - xev.xselection.type = SelectionNotify; - xev.xselection.send_event = True; - xev.xselection.display = req->display; - xev.xselection.requestor = req->requestor; - xev.xselection.selection = req->selection; - xev.xselection.target = req->target; - xev.xselection.property = req->property; - xev.xselection.time = req->time; - XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); - return 0; + XChangeProperty(g_display, req->requestor, req->property, + type, format, PropModeReplace, (tui8 *)data, length); + g_memset(&xev, 0, sizeof(xev)); + xev.xselection.type = SelectionNotify; + xev.xselection.send_event = True; + xev.xselection.display = req->display; + xev.xselection.requestor = req->requestor; + xev.xselection.selection = req->selection; + xev.xselection.target = req->target; + xev.xselection.property = req->property; + xev.xselection.time = req->time; + XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); + return 0; } /*****************************************************************************/ static int APP_CC -clipboard_refuse_selection(XSelectionRequestEvent* req) +clipboard_refuse_selection(XSelectionRequestEvent *req) { - XEvent xev; + XEvent xev; - g_memset(&xev, 0, sizeof(xev)); - xev.xselection.type = SelectionNotify; - xev.xselection.send_event = True; - xev.xselection.display = req->display; - xev.xselection.requestor = req->requestor; - xev.xselection.selection = req->selection; - xev.xselection.target = req->target; - xev.xselection.property = None; - xev.xselection.time = req->time; - XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); - return 0; + g_memset(&xev, 0, sizeof(xev)); + xev.xselection.type = SelectionNotify; + xev.xselection.send_event = True; + xev.xselection.display = req->display; + xev.xselection.requestor = req->requestor; + xev.xselection.selection = req->selection; + xev.xselection.target = req->target; + xev.xselection.property = None; + xev.xselection.time = req->time; + XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); + return 0; } /*****************************************************************************/ @@ -527,47 +560,49 @@ clipboard_refuse_selection(XSelectionRequestEvent* req) updated with new clipboard data; contains Clipboard Format ID and name pairs of new Clipboard Formats on the clipboard. */ static int APP_CC -clipboard_process_format_announce(struct stream* s, int clip_msg_status, +clipboard_process_format_announce(struct stream *s, int clip_msg_status, int clip_msg_len) { - LOGM((LOG_LEVEL_DEBUG, "clipboard_process_format_announce: " - "CLIPRDR_FORMAT_ANNOUNCE")); - //g_hexdump(s->p, s->end - s->p); - clipboard_send_format_ack(); - g_got_format_announce = 1; - g_data_in_up_to_date = 0; - if (clipboard_set_selection_owner() != 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_process_format_announce: " - "XSetSelectionOwner failed")); - } - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_format_announce: " + "CLIPRDR_FORMAT_ANNOUNCE")); + //g_hexdump(s->p, s->end - s->p); + clipboard_send_format_ack(); + g_got_format_announce = 1; + g_data_in_up_to_date = 0; + + if (clipboard_set_selection_owner() != 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_process_format_announce: " + "XSetSelectionOwner failed")); + } + + return 0; } /*****************************************************************************/ /* response to CB_FORMAT_LIST; used to indicate whether processing of the Format List PDU was successful */ static int APP_CC -clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status, +clipboard_prcoess_format_ack(struct stream *s, int clip_msg_status, int clip_msg_len) { - LOGM((LOG_LEVEL_DEBUG,"clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK")); - //g_hexdump(s->p, s->end - s->p); - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK")); + //g_hexdump(s->p, s->end - s->p); + return 0; } /*****************************************************************************/ /* sent by recipient of CB_FORMAT_LIST; used to request data for one of the formats that was listed in CB_FORMAT_LIST */ static int APP_CC -clipboard_process_data_request(struct stream* s, int clip_msg_status, +clipboard_process_data_request(struct stream *s, int clip_msg_status, int clip_msg_len) { - LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_request: " - "CLIPRDR_DATA_REQUEST")); - //g_hexdump(s->p, s->end - s->p); - clipboard_send_data_response(); - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_request: " + "CLIPRDR_DATA_REQUEST")); + //g_hexdump(s->p, s->end - s->p); + clipboard_send_data_response(); + return 0; } /*****************************************************************************/ @@ -576,54 +611,61 @@ clipboard_process_data_request(struct stream* s, int clip_msg_status, was successful, CB_FORMAT_DATA_RESPONSE includes contents of requested clipboard data. */ static int APP_CC -clipboard_process_data_response_for_image(struct stream * s, - int clip_msg_status, - int clip_msg_len) +clipboard_process_data_response_for_image(struct stream *s, + int clip_msg_status, + int clip_msg_len) { - XSelectionRequestEvent* lxev = &g_saved_selection_req_event; - char* cptr; - char cdata; - int len; - int index; + XSelectionRequestEvent *lxev = &g_saved_selection_req_event; + char *cptr; + char cdata; + int len; + int index; - LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: " - "CLIPRDR_DATA_RESPONSE_FOR_IMAGE")); - g_waiting_for_data_response = 0; - len = (int)(s->end - s->p); - if (len < 1) - { - return 0; - } - if (g_last_clip_type == g_image_bmp_atom) - { - /* space for inserting bmp image header */ - len += 14; - cptr = (char*)g_malloc(len, 0); - if (cptr == 0) + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: " + "CLIPRDR_DATA_RESPONSE_FOR_IMAGE")); + g_waiting_for_data_response = 0; + len = (int)(s->end - s->p); + + if (len < 1) { - return 0; + return 0; } - g_memcpy(cptr, g_bmp_image_header, 14); - index = 14; - } - else - { + + if (g_last_clip_type == g_image_bmp_atom) + { + /* space for inserting bmp image header */ + len += 14; + cptr = (char *)g_malloc(len, 0); + + if (cptr == 0) + { + return 0; + } + + g_memcpy(cptr, g_bmp_image_header, 14); + index = 14; + } + else + { + return 0; + } + + while (s_check(s)) + { + in_uint8(s, cdata); + cptr[index++] = cdata; + } + + if (len >= 0) + { + g_data_in = cptr; + g_data_in_size = len; + g_data_in_time = clipboard_get_local_time(); + g_data_in_up_to_date = 1; + } + + clipboard_provide_selection(lxev, lxev->target, 8, cptr, len); return 0; - } - while (s_check(s)) - { - in_uint8(s, cdata); - cptr[index++] = cdata; - } - if (len >= 0) - { - g_data_in = cptr; - g_data_in_size = len; - g_data_in_time = clipboard_get_local_time(); - g_data_in_up_to_date = 1; - } - clipboard_provide_selection(lxev, lxev->target, 8, cptr, len); - return 0; } /*****************************************************************************/ @@ -633,159 +675,181 @@ clipboard_process_data_response_for_image(struct stream * s, clipboard data. */ /*****************************************************************************/ static int APP_CC -clipboard_process_data_response(struct stream* s, int clip_msg_status, +clipboard_process_data_response(struct stream *s, int clip_msg_status, int clip_msg_len) { - XSelectionRequestEvent* lxev; - twchar* wtext; - twchar wchr; - int len; - int index; - int data_in_len; + XSelectionRequestEvent *lxev; + twchar *wtext; + twchar wchr; + int len; + int index; + int data_in_len; - if (g_want_image_data) - { - g_want_image_data = 0; - clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len); - return 0; - } - LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: " - "CLIPRDR_DATA_RESPONSE")); - g_waiting_for_data_response = 0; - len = (int)(s->end - s->p); - if (len < 1) - { - return 0; - } - //g_hexdump(s->p, len); - wtext = (twchar*)g_malloc(((len / 2) + 1) * sizeof(twchar), 0); - if (wtext == 0) - { - return 0; - } - index = 0; - while (s_check(s)) - { - in_uint16_le(s, wchr); - wtext[index] = wchr; - if (wchr == 0) + if (g_want_image_data) { - break; + g_want_image_data = 0; + clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len); + return 0; } - index++; - } - wtext[index] = 0; - g_free(g_data_in); - g_data_in = 0; - g_data_in_size = 0; - g_data_in_time = 0; - len = g_wcstombs(0, wtext, 0); - if (len >= 0) - { - g_data_in = (char*)g_malloc(len + 16, 0); - if (g_data_in == 0) + + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response: " + "CLIPRDR_DATA_RESPONSE")); + g_waiting_for_data_response = 0; + len = (int)(s->end - s->p); + + if (len < 1) { - g_free(wtext); - return 0; + return 0; } - g_data_in_size = len; - g_wcstombs(g_data_in, wtext, len + 1); - g_data_in_time = xcommon_get_local_time(); - g_data_in_up_to_date = 1; - } - if (g_data_in != 0) - { - data_in_len = g_strlen(g_data_in); - for (index = 0; index < g_selection_request_event_count; index++) + + //g_hexdump(s->p, len); + wtext = (twchar *)g_malloc(((len / 2) + 1) * sizeof(twchar), 0); + + if (wtext == 0) { - lxev = &(g_selection_request_event[index]); - clipboard_provide_selection(lxev, lxev->target, 8, g_data_in, - data_in_len); - LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: requestor %d " - "data_in_len %d", lxev->requestor, data_in_len)); + return 0; } - } - g_selection_request_event_count = 0; - g_free(wtext); - return 0; + + index = 0; + + while (s_check(s)) + { + in_uint16_le(s, wchr); + wtext[index] = wchr; + + if (wchr == 0) + { + break; + } + + index++; + } + + wtext[index] = 0; + g_free(g_data_in); + g_data_in = 0; + g_data_in_size = 0; + g_data_in_time = 0; + len = g_wcstombs(0, wtext, 0); + + if (len >= 0) + { + g_data_in = (char *)g_malloc(len + 16, 0); + + if (g_data_in == 0) + { + g_free(wtext); + return 0; + } + + g_data_in_size = len; + g_wcstombs(g_data_in, wtext, len + 1); + g_data_in_time = xcommon_get_local_time(); + g_data_in_up_to_date = 1; + } + + if (g_data_in != 0) + { + data_in_len = g_strlen(g_data_in); + + for (index = 0; index < g_selection_request_event_count; index++) + { + lxev = &(g_selection_request_event[index]); + clipboard_provide_selection(lxev, lxev->target, 8, g_data_in, + data_in_len); + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response: requestor %d " + "data_in_len %d", lxev->requestor, data_in_len)); + } + } + + g_selection_request_event_count = 0; + g_free(wtext); + return 0; } /*****************************************************************************/ int APP_CC -clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, +clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - int clip_msg_id; - int clip_msg_len; - int clip_msg_status; - int rv; - struct stream* ls; + int clip_msg_id; + int clip_msg_len; + int clip_msg_status; + int rv; + struct stream *ls; - LOG(10, ("clipboard_data_in: chan_is %d " - "chan_flags %d length %d total_length %d", - chan_id, chan_flags, length, total_length)); - if ((chan_flags & 3) == 3) - { - ls = s; - } - else - { - if (chan_flags & 1) + LOG(10, ("clipboard_data_in: chan_is %d " + "chan_flags %d length %d total_length %d", + chan_id, chan_flags, length, total_length)); + + if ((chan_flags & 3) == 3) { - init_stream(g_ins, total_length); + ls = s; } - in_uint8a(s, g_ins->end, length); - g_ins->end += length; - if ((chan_flags & 2) == 0) + else { - return 0; + if (chan_flags & 1) + { + init_stream(g_ins, total_length); + } + + in_uint8a(s, g_ins->end, length); + g_ins->end += length; + + if ((chan_flags & 2) == 0) + { + return 0; + } + + ls = g_ins; } - ls = g_ins; - } - in_uint16_le(ls, clip_msg_id); - in_uint16_le(ls, clip_msg_status); - in_uint32_le(ls, clip_msg_len); - LOG(10, ("clipboard_data_in: clip_msg_id %d " - "clip_msg_status %d clip_msg_len %d", - clip_msg_id, clip_msg_status, clip_msg_len)); - rv = 0; - switch (clip_msg_id) - { - /* sent by client or server when its local system clipboard is */ - /* updated with new clipboard data; contains Clipboard Format ID */ - /* and name pairs of new Clipboard Formats on the clipboard. */ - case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */ - rv = clipboard_process_format_announce(ls, clip_msg_status, - clip_msg_len); - break; - /* response to CB_FORMAT_LIST; used to indicate whether */ - /* processing of the Format List PDU was successful */ - case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */ - rv = clipboard_prcoess_format_ack(ls, clip_msg_status, - clip_msg_len); - break; - /* sent by recipient of CB_FORMAT_LIST; used to request data for one */ - /* of the formats that was listed in CB_FORMAT_LIST */ - case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */ - rv = clipboard_process_data_request(ls, clip_msg_status, - clip_msg_len); - break; - /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */ - /* whether processing of the CB_FORMAT_DATA_REQUEST was */ - /* successful; if processing was successful, */ - /* CB_FORMAT_DATA_RESPONSE includes contents of requested */ - /* clipboard data. */ - case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */ - rv = clipboard_process_data_response(ls, clip_msg_status, - clip_msg_len); - break; - default: - LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d", - clip_msg_id)); - break; - } - XFlush(g_display); - return rv; + + in_uint16_le(ls, clip_msg_id); + in_uint16_le(ls, clip_msg_status); + in_uint32_le(ls, clip_msg_len); + LOG(10, ("clipboard_data_in: clip_msg_id %d " + "clip_msg_status %d clip_msg_len %d", + clip_msg_id, clip_msg_status, clip_msg_len)); + rv = 0; + + switch (clip_msg_id) + { + /* sent by client or server when its local system clipboard is */ + /* updated with new clipboard data; contains Clipboard Format ID */ + /* and name pairs of new Clipboard Formats on the clipboard. */ + case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */ + rv = clipboard_process_format_announce(ls, clip_msg_status, + clip_msg_len); + break; + /* response to CB_FORMAT_LIST; used to indicate whether */ + /* processing of the Format List PDU was successful */ + case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */ + rv = clipboard_prcoess_format_ack(ls, clip_msg_status, + clip_msg_len); + break; + /* sent by recipient of CB_FORMAT_LIST; used to request data for one */ + /* of the formats that was listed in CB_FORMAT_LIST */ + case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */ + rv = clipboard_process_data_request(ls, clip_msg_status, + clip_msg_len); + break; + /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */ + /* whether processing of the CB_FORMAT_DATA_REQUEST was */ + /* successful; if processing was successful, */ + /* CB_FORMAT_DATA_RESPONSE includes contents of requested */ + /* clipboard data. */ + case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */ + rv = clipboard_process_data_response(ls, clip_msg_status, + clip_msg_len); + break; + default: + LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d", + clip_msg_id)); + break; + } + + XFlush(g_display); + return rv; } /*****************************************************************************/ @@ -805,132 +869,151 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, Time selection_timestamp; } XFixesSelectionNotifyEvent; */ static int APP_CC -clipboard_event_selection_owner_notify(XEvent* xevent) +clipboard_event_selection_owner_notify(XEvent *xevent) { - XFixesSelectionNotifyEvent* lxevent; + XFixesSelectionNotifyEvent *lxevent; - lxevent = (XFixesSelectionNotifyEvent*)xevent; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: " - "window %d subtype %d owner %d g_wnd %d", - lxevent->window, lxevent->subtype, lxevent->owner, g_wnd)); - if (lxevent->owner == g_wnd) - { - LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_owner_notify: skipping, " - "onwer == g_wnd")); - g_got_selection = 1; + lxevent = (XFixesSelectionNotifyEvent *)xevent; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: " + "window %d subtype %d owner %d g_wnd %d", + lxevent->window, lxevent->subtype, lxevent->owner, g_wnd)); + + if (lxevent->owner == g_wnd) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: skipping, " + "onwer == g_wnd")); + g_got_selection = 1; + return 0; + } + + g_got_selection = 0; + XConvertSelection(g_display, g_clipboard_atom, g_targets_atom, + g_clip_property_atom, g_wnd, lxevent->timestamp); return 0; - } - g_got_selection = 0; - XConvertSelection(g_display, g_clipboard_atom, g_targets_atom, - g_clip_property_atom, g_wnd, lxevent->timestamp); - return 0; } /*****************************************************************************/ /* returns error get a window property from wnd */ static int APP_CC -clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, - int* n_items, char** xdata, int* xdata_size) +clipboard_get_window_property(Window wnd, Atom prop, Atom *type, int *fmt, + int *n_items, char **xdata, int *xdata_size) { - int lfmt; - int lxdata_size; - unsigned long ln_items; - unsigned long llen_after; - tui8* lxdata; - Atom ltype; + int lfmt; + int lxdata_size; + unsigned long ln_items; + unsigned long llen_after; + tui8 *lxdata; + Atom ltype; - lxdata = 0; - ltype = 0; - XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0, - AnyPropertyType, <ype, &lfmt, &ln_items, - &llen_after, &lxdata); - if (lxdata != 0) - { - XFree(lxdata); - } - if (ltype == 0) - { - /* XGetWindowProperty failed */ - return 1; - } + lxdata = 0; + ltype = 0; + XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0, + AnyPropertyType, <ype, &lfmt, &ln_items, + &llen_after, &lxdata); + + if (lxdata != 0) + { + XFree(lxdata); + } + + if (ltype == 0) + { + /* XGetWindowProperty failed */ + return 1; + } + + if (ltype == g_incr_atom) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start")); + g_incr_in_progress = 1; + g_incr_atom_type = prop; + g_incr_data_size = 0; + g_free(g_incr_data); + g_incr_data = 0; + XDeleteProperty(g_display, g_wnd, prop); + return 0; + } + + if (llen_after < 1) + { + /* no data, ok */ + return 0; + } + + lxdata = 0; + ltype = 0; + XGetWindowProperty(g_display, g_wnd, prop, 0, (llen_after + 3) / 4, 0, + AnyPropertyType, <ype, &lfmt, &ln_items, + &llen_after, &lxdata); + + if (ltype == 0) + { + /* XGetWindowProperty failed */ + if (lxdata != 0) + { + XFree(lxdata); + } + + return 1; + } + + lxdata_size = (lfmt / 8) * ln_items; + + if (lxdata_size < 1) + { + /* should not happen */ + if (lxdata != 0) + { + XFree(lxdata); + } + + return 2; + } + + if (llen_after > 0) + { + /* should not happen */ + if (lxdata != 0) + { + XFree(lxdata); + } + + return 3; + } + + if (xdata != 0) + { + *xdata = (char *)g_malloc(lxdata_size, 0); + g_memcpy(*xdata, lxdata, lxdata_size); + } + + if (lxdata != 0) + { + XFree(lxdata); + } + + if (xdata_size != 0) + { + *xdata_size = lxdata_size; + } + + if (fmt != 0) + { + *fmt = (int)lfmt; + } + + if (n_items != 0) + { + *n_items = (int)ln_items; + } + + if (type != 0) + { + *type = ltype; + } - if (ltype == g_incr_atom) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start")); - g_incr_in_progress = 1; - g_incr_atom_type = prop; - g_incr_data_size = 0; - g_free(g_incr_data); - g_incr_data = 0; - XDeleteProperty(g_display, g_wnd, prop); return 0; - } - - if (llen_after < 1) - { - /* no data, ok */ - return 0; - } - lxdata = 0; - ltype = 0; - XGetWindowProperty(g_display, g_wnd, prop, 0, (llen_after + 3) / 4, 0, - AnyPropertyType, <ype, &lfmt, &ln_items, - &llen_after, &lxdata); - if (ltype == 0) - { - /* XGetWindowProperty failed */ - if (lxdata != 0) - { - XFree(lxdata); - } - return 1; - } - lxdata_size = (lfmt / 8) * ln_items; - if (lxdata_size < 1) - { - /* should not happen */ - if (lxdata != 0) - { - XFree(lxdata); - } - return 2; - } - if (llen_after > 0) - { - /* should not happen */ - if (lxdata != 0) - { - XFree(lxdata); - } - return 3; - } - if (xdata != 0) - { - *xdata = (char*)g_malloc(lxdata_size, 0); - g_memcpy(*xdata, lxdata, lxdata_size); - } - if (lxdata != 0) - { - XFree(lxdata); - } - if (xdata_size != 0) - { - *xdata_size = lxdata_size; - } - if (fmt != 0) - { - *fmt = (int)lfmt; - } - if (n_items != 0) - { - *n_items = (int)ln_items; - } - if (type != 0) - { - *type = ltype; - } - return 0; } /*****************************************************************************/ @@ -948,178 +1031,188 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, Time time; } XSelectionEvent; */ static int APP_CC -clipboard_event_selection_notify(XEvent* xevent) +clipboard_event_selection_notify(XEvent *xevent) { - XSelectionEvent* lxevent; - char* data; - int data_size; - int n_items; - int fmt; - int rv; - int index; - int convert_to_string; - int convert_to_utf8; - int convert_to_bmp_image; - int send_format_announce; - int atom; - Atom* atoms; - Atom type; - tui32 format_id; - char format_name[32]; + XSelectionEvent *lxevent; + char *data; + int data_size; + int n_items; + int fmt; + int rv; + int index; + int convert_to_string; + int convert_to_utf8; + int convert_to_bmp_image; + int send_format_announce; + int atom; + Atom *atoms; + Atom type; + tui32 format_id; + char format_name[32]; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:")); - data_size = 0; - n_items = 0; - fmt = 0; - convert_to_string = 0; - convert_to_utf8 = 0; - convert_to_bmp_image = 0; - send_format_announce = 0; - format_id = 0; - rv = 0; - data = 0; - type = 0; - lxevent = (XSelectionEvent*)xevent; - g_memset(format_name, 0, 32); - if (lxevent->property == None) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could " - "not be converted")); - rv = 1; - } - if (rv == 0) - { - /* we need this if the call below turns out to be a - clipboard INCR operation */ - if (!g_incr_in_progress) + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:")); + data_size = 0; + n_items = 0; + fmt = 0; + convert_to_string = 0; + convert_to_utf8 = 0; + convert_to_bmp_image = 0; + send_format_announce = 0; + format_id = 0; + rv = 0; + data = 0; + type = 0; + lxevent = (XSelectionEvent *)xevent; + g_memset(format_name, 0, 32); + + if (lxevent->property == None) { - g_incr_atom_target = lxevent->target; + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could " + "not be converted")); + rv = 1; } - rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, - &type, &fmt, - &n_items, &data, &data_size); - if (rv != 0) + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " - "clipboard_get_window_property failed error %d", rv)); - } - XDeleteProperty(g_display, lxevent->requestor, lxevent->property); - } - if (rv == 0) - { - if (lxevent->selection == g_clipboard_atom) - { - if (lxevent->target == g_targets_atom) - { - /* on a 64 bit machine, actual_format_return of 32 implies long */ - if ((type == XA_ATOM) && (fmt == 32)) + /* we need this if the call below turns out to be a + clipboard INCR operation */ + if (!g_incr_in_progress) { - atoms = (Atom*)data; - for (index = 0; index < n_items; index++) - { - atom = atoms[index]; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d", - atom, XGetAtomName(g_display, atom), XA_STRING)); - if (atom == g_utf8_atom) + g_incr_atom_target = lxevent->target; + } + + rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, + &type, &fmt, + &n_items, &data, &data_size); + + if (rv != 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " + "clipboard_get_window_property failed error %d", rv)); + } + + XDeleteProperty(g_display, lxevent->requestor, lxevent->property); + } + + if (rv == 0) + { + if (lxevent->selection == g_clipboard_atom) + { + if (lxevent->target == g_targets_atom) { - convert_to_utf8 = 1; + /* on a 64 bit machine, actual_format_return of 32 implies long */ + if ((type == XA_ATOM) && (fmt == 32)) + { + atoms = (Atom *)data; + + for (index = 0; index < n_items; index++) + { + atom = atoms[index]; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d", + atom, XGetAtomName(g_display, atom), XA_STRING)); + + if (atom == g_utf8_atom) + { + convert_to_utf8 = 1; + } + else if (atom == XA_STRING) + { + convert_to_string = 1; + } + else if (atom == g_image_bmp_atom) + { + convert_to_bmp_image = 1; + } + } + } + else + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: error, " + "target is 'TARGETS' and type[%d] or fmt[%d] not right, " + "should be type[%d], fmt[%d]", type, fmt, XA_ATOM, 32)); + } } - else if (atom == XA_STRING) + else if (lxevent->target == g_utf8_atom) { - convert_to_string = 1; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: UTF8_STRING " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); + g_last_clip_type = g_utf8_atom; + g_memcpy(g_last_clip_data, data, g_last_clip_size); + g_last_clip_data[g_last_clip_size] = 0; + send_format_announce = 1; + format_id = CB_FORMAT_UNICODETEXT; } - else if (atom == g_image_bmp_atom) + else if (lxevent->target == XA_STRING) { - convert_to_bmp_image = 1; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: XA_STRING " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); + g_last_clip_type = XA_STRING; + g_memcpy(g_last_clip_data, data, g_last_clip_size); + g_last_clip_data[g_last_clip_size] = 0; + send_format_announce = 1; + format_id = CB_FORMAT_UNICODETEXT; + } + else if (lxevent->target == g_image_bmp_atom) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(data_size, 0); + g_last_clip_type = g_image_bmp_atom; + g_memcpy(g_last_clip_data, data, data_size); + send_format_announce = 1; + format_id = CB_FORMAT_DIB; + g_strcpy(format_name, "image/bmp"); + } + else + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " + "unknown target")); } - } } else { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: error, " - "target is 'TARGETS' and type[%d] or fmt[%d] not right, " - "should be type[%d], fmt[%d]", type, fmt, XA_ATOM, 32)); + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " + "unknown selection")); } - } - else if (lxevent->target == g_utf8_atom) - { - LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: UTF8_STRING " - "data_size %d", data_size)); - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = data_size; - g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); - g_last_clip_type = g_utf8_atom; - g_memcpy(g_last_clip_data, data, g_last_clip_size); - g_last_clip_data[g_last_clip_size] = 0; - send_format_announce = 1; - format_id = CB_FORMAT_UNICODETEXT; - } - else if (lxevent->target == XA_STRING) - { - LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: XA_STRING " - "data_size %d", data_size)); - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = data_size; - g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); - g_last_clip_type = XA_STRING; - g_memcpy(g_last_clip_data, data, g_last_clip_size); - g_last_clip_data[g_last_clip_size] = 0; - send_format_announce = 1; - format_id = CB_FORMAT_UNICODETEXT; - } - else if (lxevent->target == g_image_bmp_atom) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp " - "data_size %d", data_size)); - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = data_size; - g_last_clip_data = g_malloc(data_size, 0); - g_last_clip_type = g_image_bmp_atom; - g_memcpy(g_last_clip_data, data, data_size); - send_format_announce = 1; - format_id = CB_FORMAT_DIB; - g_strcpy(format_name, "image/bmp"); - } - else - { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " - "unknown target")); - } } - else + + if (convert_to_utf8) { - LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_notify: " - "unknown selection")); + XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom, + g_clip_property_atom, g_wnd, lxevent->time); } - } - if (convert_to_utf8) - { - XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom, - g_clip_property_atom, g_wnd, lxevent->time); - } - else if (convert_to_string) - { - XConvertSelection(g_display, g_clipboard_atom, XA_STRING, - g_clip_property_atom, g_wnd, lxevent->time); - } - else if (convert_to_bmp_image) - { - XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom, - g_clip_property_atom, g_wnd, lxevent->time); - } - if (send_format_announce) - { - if (clipboard_send_format_announce(format_id, format_name) != 0) + else if (convert_to_string) { - rv = 4; + XConvertSelection(g_display, g_clipboard_atom, XA_STRING, + g_clip_property_atom, g_wnd, lxevent->time); } - } - g_free(data); - return rv; + else if (convert_to_bmp_image) + { + XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom, + g_clip_property_atom, g_wnd, lxevent->time); + } + + if (send_format_announce) + { + if (clipboard_send_format_announce(format_id, format_name) != 0) + { + rv = 4; + } + } + + g_free(data); + return rv; } /*****************************************************************************/ @@ -1143,113 +1236,120 @@ clipboard_event_selection_notify(XEvent* xevent) * a 32bit machine and 8 bytes on a 64 machine */ static int APP_CC -clipboard_event_selection_request(XEvent* xevent) +clipboard_event_selection_request(XEvent *xevent) { - XSelectionRequestEvent* lxev; - XEvent xev; - Atom atom_buf[10]; - Atom type; - int fmt; - int n_items; - int xdata_size; - char* xdata; + XSelectionRequestEvent *lxev; + XEvent xev; + Atom atom_buf[10]; + Atom type; + int fmt; + int n_items; + int xdata_size; + char *xdata; - lxev = (XSelectionRequestEvent*)xevent; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, " - ".requestor %d .owner %d .selection %d '%s' .target %d .property %d", - g_wnd, lxev->requestor, lxev->owner, lxev->selection, - XGetAtomName(g_display, lxev->selection), - lxev->target, lxev->property)); - if (lxev->property == None) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "lxev->property is None")); - } - else if (lxev->target == g_targets_atom) - { - /* requestor is asking what the selection can be converted to */ - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "g_targets_atom")); - atom_buf[0] = g_targets_atom; - atom_buf[1] = g_timestamp_atom; - atom_buf[2] = g_multiple_atom; - atom_buf[3] = XA_STRING; - atom_buf[4] = g_utf8_atom; - atom_buf[5] = g_image_bmp_atom; - return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)atom_buf, 6); - } - else if (lxev->target == g_timestamp_atom) - { - /* requestor is asking the time I got the selection */ - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "g_timestamp_atom")); - atom_buf[0] = g_selection_time; - return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)atom_buf, 1); - } - else if (lxev->target == g_multiple_atom) - { - /* target, property pairs */ - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "g_multiple_atom")); - if (clipboard_get_window_property(xev.xselection.requestor, - xev.xselection.property, - &type, &fmt, &n_items, &xdata, - &xdata_size) == 0) + lxev = (XSelectionRequestEvent *)xevent; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, " + ".requestor %d .owner %d .selection %d '%s' .target %d .property %d", + g_wnd, lxev->requestor, lxev->owner, lxev->selection, + XGetAtomName(g_display, lxev->selection), + lxev->target, lxev->property)); + + if (lxev->property == None) { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom " - "n_items %d", n_items)); - /* todo */ - g_free(xdata); + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "lxev->property is None")); } - } - else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom)) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s", - XGetAtomName(g_display, lxev->target))); - clipboard_format_id = CB_FORMAT_UNICODETEXT; - if (g_data_in_up_to_date) + else if (lxev->target == g_targets_atom) { - return clipboard_provide_selection(lxev, lxev->target, 8, - g_data_in, g_strlen(g_data_in)); + /* requestor is asking what the selection can be converted to */ + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "g_targets_atom")); + atom_buf[0] = g_targets_atom; + atom_buf[1] = g_timestamp_atom; + atom_buf[2] = g_multiple_atom; + atom_buf[3] = XA_STRING; + atom_buf[4] = g_utf8_atom; + atom_buf[5] = g_image_bmp_atom; + return clipboard_provide_selection(lxev, XA_ATOM, 32, (char *)atom_buf, 6); } - if (g_selection_request_event_count > 10) + else if (lxev->target == g_timestamp_atom) { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: error, " - "too many requests")); + /* requestor is asking the time I got the selection */ + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "g_timestamp_atom")); + atom_buf[0] = g_selection_time; + return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char *)atom_buf, 1); + } + else if (lxev->target == g_multiple_atom) + { + /* target, property pairs */ + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "g_multiple_atom")); + + if (clipboard_get_window_property(xev.xselection.requestor, + xev.xselection.property, + &type, &fmt, &n_items, &xdata, + &xdata_size) == 0) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom " + "n_items %d", n_items)); + /* todo */ + g_free(xdata); + } + } + else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom)) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s", + XGetAtomName(g_display, lxev->target))); + clipboard_format_id = CB_FORMAT_UNICODETEXT; + + if (g_data_in_up_to_date) + { + return clipboard_provide_selection(lxev, lxev->target, 8, + g_data_in, g_strlen(g_data_in)); + } + + if (g_selection_request_event_count > 10) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: error, " + "too many requests")); + } + else + { + g_memcpy(&(g_selection_request_event[g_selection_request_event_count]), + lxev, sizeof(g_selection_request_event[0])); + + if (g_selection_request_event_count == 0) + { + clipboard_send_data_request(); + g_waiting_for_data_response = 1; + g_waiting_for_data_response_time = xcommon_get_local_time(); + } + + g_selection_request_event_count++; + return 0; + } + } + else if (lxev->target == g_image_bmp_atom) + { + g_memcpy(&g_saved_selection_req_event, lxev, + sizeof(g_saved_selection_req_event)); + g_last_clip_type = g_image_bmp_atom; + g_want_image_data = 1; + clipboard_format_id = CB_FORMAT_DIB; + clipboard_send_data_request(); + g_waiting_for_data_response = 1; + g_waiting_for_data_response_time = clipboard_get_local_time(); + return 0; } else { - g_memcpy(&(g_selection_request_event[g_selection_request_event_count]), - lxev, sizeof(g_selection_request_event[0])); - if (g_selection_request_event_count == 0) - { - clipboard_send_data_request(); - g_waiting_for_data_response = 1; - g_waiting_for_data_response_time = xcommon_get_local_time(); - } - g_selection_request_event_count++; - return 0; + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown " + "target %s", XGetAtomName(g_display, lxev->target))); } - } - else if (lxev->target == g_image_bmp_atom) - { - g_memcpy(&g_saved_selection_req_event, lxev, - sizeof(g_saved_selection_req_event)); - g_last_clip_type = g_image_bmp_atom; - g_want_image_data = 1; - clipboard_format_id = CB_FORMAT_DIB; - clipboard_send_data_request(); - g_waiting_for_data_response = 1; - g_waiting_for_data_response_time = clipboard_get_local_time(); + + clipboard_refuse_selection(lxev); return 0; - } - else - { - LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_request: unknown " - "target %s", XGetAtomName(g_display, lxev->target))); - } - clipboard_refuse_selection(lxev); - return 0; } /*****************************************************************************/ @@ -1265,10 +1365,10 @@ clipboard_event_selection_request(XEvent* xevent) Time time; } XSelectionClearEvent; */ static int APP_CC -clipboard_event_selection_clear(XEvent* xevent) +clipboard_event_selection_clear(XEvent *xevent) { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:")); - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:")); + return 0; } /*****************************************************************************/ @@ -1284,134 +1384,153 @@ clipboard_event_selection_clear(XEvent* xevent) int state; // PropertyNewValue or PropertyDelete } XPropertyEvent; */ static int APP_CC -clipboard_event_property_notify(XEvent* xevent) +clipboard_event_property_notify(XEvent *xevent) { - Atom actual_type_return; - int actual_format_return; - unsigned long nitems_returned; - unsigned long bytes_left; - unsigned char* data; - int rv; - int format_in_bytes; - int new_data_len; - char* cptr; - char format_name[32]; + Atom actual_type_return; + int actual_format_return; + unsigned long nitems_returned; + unsigned long bytes_left; + unsigned char *data; + int rv; + int format_in_bytes; + int new_data_len; + char *cptr; + char format_name[32]; - LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d " - ".state %d .atom %d", xevent->xproperty.window, - xevent->xproperty.state, xevent->xproperty.atom)); - if (g_incr_in_progress && - (xevent->xproperty.atom == g_incr_atom_type) && - (xevent->xproperty.state == PropertyNewValue)) - { - rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0, - AnyPropertyType, &actual_type_return, &actual_format_return, - &nitems_returned, &bytes_left, (unsigned char **) &data); - if (data != 0) - { - XFree(data); - data = 0; - } - if (bytes_left <= 0) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done")); - g_memset(format_name, 0, 32); - /* clipboard INCR cycle has completed */ - g_incr_in_progress = 0; - g_last_clip_size = g_incr_data_size; - g_last_clip_data = g_incr_data; - g_incr_data = 0; - g_last_clip_type = g_incr_atom_target; - if (g_incr_atom_target == g_image_bmp_atom) - { - g_snprintf(format_name, 31, "image/bmp"); - clipboard_send_format_announce(CB_FORMAT_DIB, format_name); - } - XDeleteProperty(g_display, g_wnd, g_incr_atom_type); - } - else - { - rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0, - AnyPropertyType, &actual_type_return, &actual_format_return, - &nitems_returned, &bytes_left, (unsigned char **) &data); + LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d " + ".state %d .atom %d", xevent->xproperty.window, + xevent->xproperty.state, xevent->xproperty.atom)); + + if (g_incr_in_progress && + (xevent->xproperty.atom == g_incr_atom_type) && + (xevent->xproperty.state == PropertyNewValue)) + { + rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0, + AnyPropertyType, &actual_type_return, &actual_format_return, + &nitems_returned, &bytes_left, (unsigned char **) &data); - format_in_bytes = actual_format_return / 8; - if ((actual_format_return == 32) && (sizeof(long) == 8)) - { - /* on a 64 bit machine, actual_format_return of 32 implies long */ - format_in_bytes = 8; - } - new_data_len = nitems_returned * format_in_bytes; - cptr = (char*)g_malloc(g_incr_data_size + new_data_len, 0); - g_memcpy(cptr, g_incr_data, g_incr_data_size); - g_free(g_incr_data); - if (cptr == NULL) - { - g_incr_data = 0; - /* cannot add any more data */ if (data != 0) { - XFree(data); + XFree(data); + data = 0; + } + + if (bytes_left <= 0) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done")); + g_memset(format_name, 0, 32); + /* clipboard INCR cycle has completed */ + g_incr_in_progress = 0; + g_last_clip_size = g_incr_data_size; + g_last_clip_data = g_incr_data; + g_incr_data = 0; + g_last_clip_type = g_incr_atom_target; + + if (g_incr_atom_target == g_image_bmp_atom) + { + g_snprintf(format_name, 31, "image/bmp"); + clipboard_send_format_announce(CB_FORMAT_DIB, format_name); + } + + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); + } + else + { + rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0, + AnyPropertyType, &actual_type_return, &actual_format_return, + &nitems_returned, &bytes_left, (unsigned char **) &data); + + format_in_bytes = actual_format_return / 8; + + if ((actual_format_return == 32) && (sizeof(long) == 8)) + { + /* on a 64 bit machine, actual_format_return of 32 implies long */ + format_in_bytes = 8; + } + + new_data_len = nitems_returned * format_in_bytes; + cptr = (char *)g_malloc(g_incr_data_size + new_data_len, 0); + g_memcpy(cptr, g_incr_data, g_incr_data_size); + g_free(g_incr_data); + + if (cptr == NULL) + { + g_incr_data = 0; + + /* cannot add any more data */ + if (data != 0) + { + XFree(data); + } + + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); + return 0; + } + + g_incr_data = cptr; + g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len); + g_incr_data_size += new_data_len; + + if (data) + { + XFree(data); + } + + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); } - XDeleteProperty(g_display, g_wnd, g_incr_atom_type); - return 0; - } - g_incr_data = cptr; - g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len); - g_incr_data_size += new_data_len; - if (data) - { - XFree(data); - } - XDeleteProperty(g_display, g_wnd, g_incr_atom_type); } - } - return 0; + + return 0; } /*****************************************************************************/ /* returns 0, event handled, 1 unhandled */ int APP_CC -clipboard_xevent(void* xevent) +clipboard_xevent(void *xevent) { - XEvent* lxevent; + XEvent *lxevent; - if (!g_clip_up) - { - return 1; - } - lxevent = (XEvent*)xevent; - switch (lxevent->type) - { - case SelectionNotify: - clipboard_event_selection_notify(lxevent); - break; - case SelectionRequest: - clipboard_event_selection_request(lxevent); - break; - case SelectionClear: - clipboard_event_selection_clear(lxevent); - break; - case MappingNotify: - break; - case PropertyNotify: - clipboard_event_property_notify(lxevent); - break; - case UnmapNotify: - LOG(0, ("chansrv::clipboard_xevent: got UnmapNotify")); - break; - case ClientMessage: - LOG(0, ("chansrv::clipboard_xevent: got ClientMessage")); - break; - default: - if (lxevent->type == g_xfixes_event_base + - XFixesSetSelectionOwnerNotify) - { - clipboard_event_selection_owner_notify(lxevent); - break; - } - /* we didn't handle this message */ - return 1; - } - return 0; + if (!g_clip_up) + { + return 1; + } + + lxevent = (XEvent *)xevent; + + switch (lxevent->type) + { + case SelectionNotify: + clipboard_event_selection_notify(lxevent); + break; + case SelectionRequest: + clipboard_event_selection_request(lxevent); + break; + case SelectionClear: + clipboard_event_selection_clear(lxevent); + break; + case MappingNotify: + break; + case PropertyNotify: + clipboard_event_property_notify(lxevent); + break; + case UnmapNotify: + LOG(0, ("chansrv::clipboard_xevent: got UnmapNotify")); + break; + case ClientMessage: + LOG(0, ("chansrv::clipboard_xevent: got ClientMessage")); + break; + default: + + if (lxevent->type == g_xfixes_event_base + + XFixesSetSelectionOwnerNotify) + { + clipboard_event_selection_owner_notify(lxevent); + break; + } + + /* we didn't handle this message */ + return 1; + } + + return 0; } diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index dd244572..e6407211 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -26,34 +26,34 @@ extern int g_rdpdr_chan_id; /* in chansrv.c */ int APP_CC dev_redir_init(void) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC dev_redir_deinit(void) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -dev_redir_data_in(struct stream* s, int chan_id, int chan_flags, int length, +dev_redir_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -dev_redir_get_wait_objs(tbus* objs, int* count, int* timeout) +dev_redir_get_wait_objs(tbus *objs, int *count, int *timeout) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC dev_redir_check_wait_objs(void) { - return 0; + return 0; } diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index 6b47f867..1ea8d73a 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -31,13 +31,13 @@ extern int g_rail_chan_id; /* in chansrv.c */ extern int g_display_num; /* in chansrv.c */ -extern char* g_exec_name; /* in chansrv.c */ +extern char *g_exec_name; /* in chansrv.c */ extern tbus g_exec_event; /* in chansrv.c */ extern tbus g_exec_mutex; /* in chansrv.c */ extern tbus g_exec_sem; /* in chansrv.c */ -extern Display* g_display; /* in xcommon.c */ -extern Screen* g_screen; /* in xcommon.c */ +extern Display *g_display; /* in xcommon.c */ +extern Screen *g_screen; /* in xcommon.c */ extern Window g_root_window; /* in xcommon.c */ extern Atom g_wm_delete_window_atom; /* in xcommon.c */ extern Atom g_wm_protocols_atom; /* in xcommon.c */ @@ -105,573 +105,597 @@ static int g_rail_running = 1; static int APP_CC is_window_valid_child_of_root(unsigned int window_id) { - int found; - unsigned int i; - unsigned int nchild; - Window r; - Window p; - Window* children; + int found; + unsigned int i; + unsigned int nchild; + Window r; + Window p; + Window *children; - found = 0; - XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild); - for (i = 0; i < nchild; i++) - { - if (window_id == children[i]) + found = 0; + XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild); + + for (i = 0; i < nchild; i++) { - found = 1; - break; + if (window_id == children[i]) + { + found = 1; + break; + } } - } - XFree(children); - return found; + + XFree(children); + return found; } /*****************************************************************************/ static int APP_CC rail_send_init(void) { - struct stream* s; - int bytes; - char* size_ptr; + struct stream *s; + int bytes; + char *size_ptr; - LOG(10, ("chansrv::rail_send_init:")); - make_stream(s); - init_stream(s, 8182); - out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - out_uint32_le(s, 1); /* build number */ - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rail_chan_id, s->data, bytes); - free_stream(s); - return 0; + LOG(10, ("chansrv::rail_send_init:")); + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + out_uint32_le(s, 1); /* build number */ + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rail_chan_id, s->data, bytes); + free_stream(s); + return 0; } /******************************************************************************/ static int DEFAULT_CC -anotherWMRunning(Display* display, XErrorEvent* xe) +anotherWMRunning(Display *display, XErrorEvent *xe) { - g_rail_running = 0; - return -1; + g_rail_running = 0; + return -1; } /******************************************************************************/ static int APP_CC rail_is_another_wm_running(void) { - XErrorHandler old; + XErrorHandler old; - g_rail_running = 1; - old = XSetErrorHandler((XErrorHandler)anotherWMRunning); - XSelectInput(g_display, g_root_window, - PropertyChangeMask | StructureNotifyMask | - SubstructureRedirectMask | ButtonPressMask | - SubstructureNotifyMask | FocusChangeMask | - EnterWindowMask | LeaveWindowMask); - XSync(g_display, 0); - XSetErrorHandler((XErrorHandler)old); - g_rail_up = g_rail_running; - if (!g_rail_up) - { - return 1; - } - return 0; + g_rail_running = 1; + old = XSetErrorHandler((XErrorHandler)anotherWMRunning); + XSelectInput(g_display, g_root_window, + PropertyChangeMask | StructureNotifyMask | + SubstructureRedirectMask | ButtonPressMask | + SubstructureNotifyMask | FocusChangeMask | + EnterWindowMask | LeaveWindowMask); + XSync(g_display, 0); + XSetErrorHandler((XErrorHandler)old); + g_rail_up = g_rail_running; + + if (!g_rail_up) + { + return 1; + } + + return 0; } /*****************************************************************************/ int APP_CC rail_init(void) { - LOG(10, ("chansrv::rail_init:")); - xcommon_init(); - if (rail_is_another_wm_running()) - { - log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " - "is running"); - } - rail_send_init(); - g_rail_up = 1; - return 0; + LOG(10, ("chansrv::rail_init:")); + xcommon_init(); + + if (rail_is_another_wm_running()) + { + log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " + "is running"); + } + + rail_send_init(); + g_rail_up = 1; + return 0; } /*****************************************************************************/ int APP_CC rail_deinit(void) { - if (g_rail_up) - { - /* no longer window manager */ - XSelectInput(g_display, g_root_window, 0); - g_rail_up = 0; - } - return 0; -} - -/*****************************************************************************/ -static char* APP_CC -read_uni(struct stream* s, int num_chars) -{ - twchar* rchrs; - char* rv; - int index; - int lchars; - - rchrs = 0; - rv = 0; - if (num_chars > 0) - { - rchrs = (twchar*)g_malloc((num_chars + 1) * sizeof(twchar), 0); - for (index = 0; index < num_chars; index++) + if (g_rail_up) { - in_uint16_le(s, rchrs[index]); + /* no longer window manager */ + XSelectInput(g_display, g_root_window, 0); + g_rail_up = 0; } - rchrs[num_chars] = 0; - lchars = g_wcstombs(0, rchrs, 0); - if (lchars > 0) + + return 0; +} + +/*****************************************************************************/ +static char *APP_CC +read_uni(struct stream *s, int num_chars) +{ + twchar *rchrs; + char *rv; + int index; + int lchars; + + rchrs = 0; + rv = 0; + + if (num_chars > 0) { - rv = (char*)g_malloc((lchars + 1) * 4, 0); - g_wcstombs(rv, rchrs, lchars); - rv[lchars] = 0; + rchrs = (twchar *)g_malloc((num_chars + 1) * sizeof(twchar), 0); + + for (index = 0; index < num_chars; index++) + { + in_uint16_le(s, rchrs[index]); + } + + rchrs[num_chars] = 0; + lchars = g_wcstombs(0, rchrs, 0); + + if (lchars > 0) + { + rv = (char *)g_malloc((lchars + 1) * 4, 0); + g_wcstombs(rv, rchrs, lchars); + rv[lchars] = 0; + } } - } - g_free(rchrs); - return rv; + + g_free(rchrs); + return rv; } /*****************************************************************************/ static int APP_CC -rail_process_exec(struct stream* s, int size) +rail_process_exec(struct stream *s, int size) { - int pid; - int flags; - int ExeOrFileLength; - int WorkingDirLength; - int ArgumentsLen; - char* ExeOrFile; - char* WorkingDir; - char* Arguments; + int pid; + int flags; + int ExeOrFileLength; + int WorkingDirLength; + int ArgumentsLen; + char *ExeOrFile; + char *WorkingDir; + char *Arguments; - LOG(0, ("chansrv::rail_process_exec:")); - in_uint16_le(s, flags); - in_uint16_le(s, ExeOrFileLength); - in_uint16_le(s, WorkingDirLength); - in_uint16_le(s, ArgumentsLen); - ExeOrFile = read_uni(s, ExeOrFileLength); - WorkingDir = read_uni(s, WorkingDirLength); - Arguments = read_uni(s, ArgumentsLen); - LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " - "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " - "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, - ArgumentsLen, ExeOrFile, WorkingDir, Arguments)); - if (g_strlen(ExeOrFile) > 0) - { - LOG(10, ("rail_process_exec: pre")); - /* ask main thread to fork */ - tc_mutex_lock(g_exec_mutex); - g_exec_name = ExeOrFile; - g_set_wait_obj(g_exec_event); - tc_sem_dec(g_exec_sem); - tc_mutex_unlock(g_exec_mutex); - LOG(10, ("rail_process_exec: post")); - } - g_free(ExeOrFile); - g_free(WorkingDir); - g_free(Arguments); - return 0; + LOG(0, ("chansrv::rail_process_exec:")); + in_uint16_le(s, flags); + in_uint16_le(s, ExeOrFileLength); + in_uint16_le(s, WorkingDirLength); + in_uint16_le(s, ArgumentsLen); + ExeOrFile = read_uni(s, ExeOrFileLength); + WorkingDir = read_uni(s, WorkingDirLength); + Arguments = read_uni(s, ArgumentsLen); + LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " + "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " + "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, + ArgumentsLen, ExeOrFile, WorkingDir, Arguments)); + + if (g_strlen(ExeOrFile) > 0) + { + LOG(10, ("rail_process_exec: pre")); + /* ask main thread to fork */ + tc_mutex_lock(g_exec_mutex); + g_exec_name = ExeOrFile; + g_set_wait_obj(g_exec_event); + tc_sem_dec(g_exec_sem); + tc_mutex_unlock(g_exec_mutex); + LOG(10, ("rail_process_exec: post")); + } + + g_free(ExeOrFile); + g_free(WorkingDir); + g_free(Arguments); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_activate(struct stream* s, int size) +rail_process_activate(struct stream *s, int size) { - int window_id; - int enabled; + int window_id; + int enabled; - LOG(10, ("chansrv::rail_process_activate:")); - in_uint32_le(s, window_id); - in_uint8(s, enabled); - LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); - if (enabled) - { - LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); - XRaiseWindow(g_display, window_id); - LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); - XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); - } - return 0; + LOG(10, ("chansrv::rail_process_activate:")); + in_uint32_le(s, window_id); + in_uint8(s, enabled); + LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); + + if (enabled) + { + LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); + XRaiseWindow(g_display, window_id); + LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); + XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); + } + + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_system_param(struct stream* s, int size) +rail_process_system_param(struct stream *s, int size) { - int system_param; + int system_param; - LOG(10, ("chansrv::rail_process_system_param:")); - in_uint32_le(s, system_param); - LOG(10, (" system_param 0x%8.8x", system_param)); - return 0; + LOG(10, ("chansrv::rail_process_system_param:")); + in_uint32_le(s, system_param); + LOG(10, (" system_param 0x%8.8x", system_param)); + return 0; } /******************************************************************************/ static int APP_CC rail_close_window(int window_id) { - XEvent ce; + XEvent ce; - LOG(0, ("chansrv::rail_close_window:")); - g_memset(&ce, 0, sizeof(ce)); - ce.xclient.type = ClientMessage; - ce.xclient.message_type = g_wm_protocols_atom; - ce.xclient.display = g_display; - ce.xclient.window = window_id; - ce.xclient.format = 32; - ce.xclient.data.l[0] = g_wm_delete_window_atom; - ce.xclient.data.l[1] = CurrentTime; - XSendEvent(g_display, window_id, False, NoEventMask, &ce); - return 0; + LOG(0, ("chansrv::rail_close_window:")); + g_memset(&ce, 0, sizeof(ce)); + ce.xclient.type = ClientMessage; + ce.xclient.message_type = g_wm_protocols_atom; + ce.xclient.display = g_display; + ce.xclient.window = window_id; + ce.xclient.format = 32; + ce.xclient.data.l[0] = g_wm_delete_window_atom; + ce.xclient.data.l[1] = CurrentTime; + XSendEvent(g_display, window_id, False, NoEventMask, &ce); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_system_command(struct stream* s, int size) +rail_process_system_command(struct stream *s, int size) { - int window_id; - int command; + int window_id; + int command; - LOG(10, ("chansrv::rail_process_system_command:")); - in_uint32_le(s, window_id); - in_uint16_le(s, command); - switch (command) - { - case SC_SIZE: - LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id)); - break; - case SC_MOVE: - LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id)); - break; - case SC_MINIMIZE: - LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id)); - break; - case SC_MAXIMIZE: - LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id)); - break; - case SC_CLOSE: - LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id)); - rail_close_window(window_id); - break; - case SC_KEYMENU: - LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id)); - break; - case SC_RESTORE: - LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id)); - break; - case SC_DEFAULT: - LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id)); - break; - default: - LOG(10, (" window_id 0x%8.8x unknown command command %d", - window_id, command)); - break; - } - return 0; + LOG(10, ("chansrv::rail_process_system_command:")); + in_uint32_le(s, window_id); + in_uint16_le(s, command); + + switch (command) + { + case SC_SIZE: + LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id)); + break; + case SC_MOVE: + LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id)); + break; + case SC_MINIMIZE: + LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id)); + break; + case SC_MAXIMIZE: + LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id)); + break; + case SC_CLOSE: + LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id)); + rail_close_window(window_id); + break; + case SC_KEYMENU: + LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id)); + break; + case SC_RESTORE: + LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id)); + break; + case SC_DEFAULT: + LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id)); + break; + default: + LOG(10, (" window_id 0x%8.8x unknown command command %d", + window_id, command)); + break; + } + + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_handshake(struct stream* s, int size) +rail_process_handshake(struct stream *s, int size) { - int build_number; + int build_number; - LOG(10, ("chansrv::rail_process_handshake:")); - in_uint32_le(s, build_number); - LOG(10, (" build_number 0x%8.8x", build_number)); - return 0; + LOG(10, ("chansrv::rail_process_handshake:")); + in_uint32_le(s, build_number); + LOG(10, (" build_number 0x%8.8x", build_number)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_notify_event(struct stream* s, int size) +rail_process_notify_event(struct stream *s, int size) { - int window_id; - int notify_id; - int message; + int window_id; + int notify_id; + int message; - LOG(10, ("chansrv::rail_process_notify_event:")); - in_uint32_le(s, window_id); - in_uint32_le(s, notify_id); - in_uint32_le(s, message); - LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x", - window_id, notify_id, message)); - return 0; + LOG(10, ("chansrv::rail_process_notify_event:")); + in_uint32_le(s, window_id); + in_uint32_le(s, notify_id); + in_uint32_le(s, message); + LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x", + window_id, notify_id, message)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_window_move(struct stream* s, int size) +rail_process_window_move(struct stream *s, int size) { - int window_id; - int left; - int top; - int right; - int bottom; + int window_id; + int left; + int top; + int right; + int bottom; - LOG(10, ("chansrv::rail_process_window_move:")); - in_uint32_le(s, window_id); - in_uint16_le(s, left); - in_uint16_le(s, top); - in_uint16_le(s, right); - in_uint16_le(s, bottom); - LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", - window_id, left, top, right, bottom, right - left, bottom - top)); - XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); - return 0; + LOG(10, ("chansrv::rail_process_window_move:")); + in_uint32_le(s, window_id); + in_uint16_le(s, left); + in_uint16_le(s, top); + in_uint16_le(s, right); + in_uint16_le(s, bottom); + LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", + window_id, left, top, right, bottom, right - left, bottom - top)); + XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_local_move_size(struct stream* s, int size) +rail_process_local_move_size(struct stream *s, int size) { - int window_id; - int is_move_size_start; - int move_size_type; - int pos_x; - int pos_y; + int window_id; + int is_move_size_start; + int move_size_type; + int pos_x; + int pos_y; - LOG(10, ("chansrv::rail_process_local_move_size:")); - in_uint32_le(s, window_id); - in_uint16_le(s, is_move_size_start); - in_uint16_le(s, move_size_type); - in_uint16_le(s, pos_x); - in_uint16_le(s, pos_y); - LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d " - "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type, - pos_x, pos_y)); - return 0; + LOG(10, ("chansrv::rail_process_local_move_size:")); + in_uint32_le(s, window_id); + in_uint16_le(s, is_move_size_start); + in_uint16_le(s, move_size_type); + in_uint16_le(s, pos_x); + in_uint16_le(s, pos_y); + LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d " + "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type, + pos_x, pos_y)); + return 0; } /*****************************************************************************/ /* server to client only */ static int APP_CC -rail_process_min_max_info(struct stream* s, int size) +rail_process_min_max_info(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_min_max_info:")); - return 0; + LOG(10, ("chansrv::rail_process_min_max_info:")); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_client_status(struct stream* s, int size) +rail_process_client_status(struct stream *s, int size) { - int flags; + int flags; - LOG(10, ("chansrv::rail_process_client_status:")); - in_uint32_le(s, flags); - LOG(10, (" flags 0x%8.8x", flags)); - return 0; + LOG(10, ("chansrv::rail_process_client_status:")); + in_uint32_le(s, flags); + LOG(10, (" flags 0x%8.8x", flags)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_sys_menu(struct stream* s, int size) +rail_process_sys_menu(struct stream *s, int size) { - int window_id; - int left; - int top; + int window_id; + int left; + int top; - LOG(10, ("chansrv::rail_process_sys_menu:")); - in_uint32_le(s, window_id); - in_uint16_le(s, left); - in_uint16_le(s, top); - LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top)); - return 0; + LOG(10, ("chansrv::rail_process_sys_menu:")); + in_uint32_le(s, window_id); + in_uint16_le(s, left); + in_uint16_le(s, top); + LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_lang_bar_info(struct stream* s, int size) +rail_process_lang_bar_info(struct stream *s, int size) { - int language_bar_status; + int language_bar_status; - LOG(10, ("chansrv::rail_process_lang_bar_info:")); - in_uint32_le(s, language_bar_status); - LOG(10, (" language_bar_status 0x%8.8x", language_bar_status)); - return 0; + LOG(10, ("chansrv::rail_process_lang_bar_info:")); + in_uint32_le(s, language_bar_status); + LOG(10, (" language_bar_status 0x%8.8x", language_bar_status)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_appid_req(struct stream* s, int size) +rail_process_appid_req(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_appid_req:")); - return 0; + LOG(10, ("chansrv::rail_process_appid_req:")); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_appid_resp(struct stream* s, int size) +rail_process_appid_resp(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_appid_resp:")); - return 0; + LOG(10, ("chansrv::rail_process_appid_resp:")); + return 0; } /*****************************************************************************/ /* server to client only */ static int APP_CC -rail_process_exec_result(struct stream* s, int size) +rail_process_exec_result(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_exec_result:")); - return 0; + LOG(10, ("chansrv::rail_process_exec_result:")); + return 0; } /*****************************************************************************/ /* data in from client ( client -> xrdp -> chansrv ) */ int APP_CC -rail_data_in(struct stream* s, int chan_id, int chan_flags, int length, +rail_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - int code; - int size; + int code; + int size; - LOG(10, ("chansrv::rail_data_in:")); - in_uint8(s, code); - in_uint8s(s, 1); - in_uint16_le(s, size); - switch (code) - { - case TS_RAIL_ORDER_EXEC: /* 1 */ - rail_process_exec(s, size); - break; - case TS_RAIL_ORDER_ACTIVATE: /* 2 */ - rail_process_activate(s, size); - break; - case TS_RAIL_ORDER_SYSPARAM: /* 3 */ - rail_process_system_param(s, size); - break; - case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */ - rail_process_system_command(s, size); - break; - case TS_RAIL_ORDER_HANDSHAKE: /* 5 */ - rail_process_handshake(s, size); - break; - case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */ - rail_process_notify_event(s, size); - break; - case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */ - rail_process_window_move(s, size); - break; - case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */ - rail_process_local_move_size(s, size); - break; - case TS_RAIL_ORDER_MINMAXINFO: /* 10 */ - rail_process_min_max_info(s, size); - break; - case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */ - rail_process_client_status(s, size); - break; - case TS_RAIL_ORDER_SYSMENU: /* 12 */ - rail_process_sys_menu(s, size); - break; - case TS_RAIL_ORDER_LANGBARINFO: /* 13 */ - rail_process_lang_bar_info(s, size); - break; - case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */ - rail_process_appid_req(s, size); - break; - case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */ - rail_process_appid_resp(s, size); - break; - case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */ - rail_process_exec_result(s, size); - break; - default: - LOG(10, ("rail_data_in: unknown code %d size %d", code, size)); - break; - } - XFlush(g_display); - return 0; + LOG(10, ("chansrv::rail_data_in:")); + in_uint8(s, code); + in_uint8s(s, 1); + in_uint16_le(s, size); + + switch (code) + { + case TS_RAIL_ORDER_EXEC: /* 1 */ + rail_process_exec(s, size); + break; + case TS_RAIL_ORDER_ACTIVATE: /* 2 */ + rail_process_activate(s, size); + break; + case TS_RAIL_ORDER_SYSPARAM: /* 3 */ + rail_process_system_param(s, size); + break; + case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */ + rail_process_system_command(s, size); + break; + case TS_RAIL_ORDER_HANDSHAKE: /* 5 */ + rail_process_handshake(s, size); + break; + case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */ + rail_process_notify_event(s, size); + break; + case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */ + rail_process_window_move(s, size); + break; + case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */ + rail_process_local_move_size(s, size); + break; + case TS_RAIL_ORDER_MINMAXINFO: /* 10 */ + rail_process_min_max_info(s, size); + break; + case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */ + rail_process_client_status(s, size); + break; + case TS_RAIL_ORDER_SYSMENU: /* 12 */ + rail_process_sys_menu(s, size); + break; + case TS_RAIL_ORDER_LANGBARINFO: /* 13 */ + rail_process_lang_bar_info(s, size); + break; + case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */ + rail_process_appid_req(s, size); + break; + case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */ + rail_process_appid_resp(s, size); + break; + case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */ + rail_process_exec_result(s, size); + break; + default: + LOG(10, ("rail_data_in: unknown code %d size %d", code, size)); + break; + } + + XFlush(g_display); + return 0; } /*****************************************************************************/ /* returns 0, event handled, 1 unhandled */ int APP_CC -rail_xevent(void* xevent) +rail_xevent(void *xevent) { - XEvent* lxevent; - XWindowChanges xwc; - int rv; - int nchildren_return = 0; - Window root_return; - Window parent_return; - Window *children_return; - Window wreturn; - int revert_to; - XWindowAttributes wnd_attributes; + XEvent *lxevent; + XWindowChanges xwc; + int rv; + int nchildren_return = 0; + Window root_return; + Window parent_return; + Window *children_return; + Window wreturn; + int revert_to; + XWindowAttributes wnd_attributes; - LOG(10, ("chansrv::rail_xevent:")); - if (!g_rail_up) - { - return 1; - } - rv = 1; - lxevent = (XEvent*)xevent; - switch (lxevent->type) - { - case ConfigureRequest: - LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window)); - g_memset(&xwc, 0, sizeof(xwc)); - xwc.x = lxevent->xconfigurerequest.x; - xwc.y = lxevent->xconfigurerequest.y; - xwc.width = lxevent->xconfigurerequest.width; - xwc.height = lxevent->xconfigurerequest.height; - xwc.border_width = lxevent->xconfigurerequest.border_width; - xwc.sibling = lxevent->xconfigurerequest.above; - xwc.stack_mode = lxevent->xconfigurerequest.detail; - XConfigureWindow(g_display, - lxevent->xconfigurerequest.window, - lxevent->xconfigurerequest.value_mask, - &xwc); - rv = 0; - break; + LOG(10, ("chansrv::rail_xevent:")); - case MapRequest: - LOG(10, (" got MapRequest")); - XMapWindow(g_display, lxevent->xmaprequest.window); - rv = 0; - break; + if (!g_rail_up) + { + return 1; + } - case MapNotify: - LOG(10, (" got MapNotify")); - break; + rv = 1; + lxevent = (XEvent *)xevent; - case UnmapNotify: - LOG(10, (" got UnmapNotify")); - break; + switch (lxevent->type) + { + case ConfigureRequest: + LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window)); + g_memset(&xwc, 0, sizeof(xwc)); + xwc.x = lxevent->xconfigurerequest.x; + xwc.y = lxevent->xconfigurerequest.y; + xwc.width = lxevent->xconfigurerequest.width; + xwc.height = lxevent->xconfigurerequest.height; + xwc.border_width = lxevent->xconfigurerequest.border_width; + xwc.sibling = lxevent->xconfigurerequest.above; + xwc.stack_mode = lxevent->xconfigurerequest.detail; + XConfigureWindow(g_display, + lxevent->xconfigurerequest.window, + lxevent->xconfigurerequest.value_mask, + &xwc); + rv = 0; + break; - case ConfigureNotify: - LOG(10, (" got ConfigureNotify")); - break; + case MapRequest: + LOG(10, (" got MapRequest")); + XMapWindow(g_display, lxevent->xmaprequest.window); + rv = 0; + break; - case FocusIn: - LOG(10, (" got FocusIn")); - break; + case MapNotify: + LOG(10, (" got MapNotify")); + break; - case ButtonPress: - LOG(10, (" got ButtonPress")); - break; + case UnmapNotify: + LOG(10, (" got UnmapNotify")); + break; - case EnterNotify: - LOG(10, (" got EnterNotify")); - break; + case ConfigureNotify: + LOG(10, (" got ConfigureNotify")); + break; - case LeaveNotify: - LOG(10, (" got LeaveNotify")); - break; + case FocusIn: + LOG(10, (" got FocusIn")); + break; - } - return rv; + case ButtonPress: + LOG(10, (" got ButtonPress")); + break; + + case EnterNotify: + LOG(10, (" got EnterNotify")); + break; + + case LeaveNotify: + LOG(10, (" got LeaveNotify")); + break; + + } + + return rv; } diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c index e4d54bb0..e8b801c6 100644 --- a/sesman/chansrv/sound.c +++ b/sesman/chansrv/sound.c @@ -28,100 +28,100 @@ static int g_training_sent_time = 0; static int g_cBlockNo = 0; #if defined(XRDP_SIMPLESOUND) -static void* DEFAULT_CC -read_raw_audio_data(void* arg); +static void *DEFAULT_CC +read_raw_audio_data(void *arg); #endif /*****************************************************************************/ static int APP_CC sound_send_server_formats(void) { - struct stream* s; - int bytes; - char* size_ptr; + struct stream *s; + int bytes; + char *size_ptr; - print_got_here(); + print_got_here(); - make_stream(s); - init_stream(s, 8182); - out_uint16_le(s, SNDC_FORMATS); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - out_uint32_le(s, 0); /* dwFlags */ - out_uint32_le(s, 0); /* dwVolume */ - out_uint32_le(s, 0); /* dwPitch */ - out_uint16_le(s, 0); /* wDGramPort */ - out_uint16_le(s, 1); /* wNumberOfFormats */ - out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */ - out_uint16_le(s, 2); /* wVersion */ - out_uint8(s, 0); /* bPad */ + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, SNDC_FORMATS); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + out_uint32_le(s, 0); /* dwFlags */ + out_uint32_le(s, 0); /* dwVolume */ + out_uint32_le(s, 0); /* dwPitch */ + out_uint16_le(s, 0); /* wDGramPort */ + out_uint16_le(s, 1); /* wNumberOfFormats */ + out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */ + out_uint16_le(s, 2); /* wVersion */ + out_uint8(s, 0); /* bPad */ - /* sndFormats */ - /* - wFormatTag 2 byte offset 0 - nChannels 2 byte offset 2 - nSamplesPerSec 4 byte offset 4 - nAvgBytesPerSec 4 byte offset 8 - nBlockAlign 2 byte offset 12 - wBitsPerSample 2 byte offset 14 - cbSize 2 byte offset 16 - data variable offset 18 - */ + /* sndFormats */ + /* + wFormatTag 2 byte offset 0 + nChannels 2 byte offset 2 + nSamplesPerSec 4 byte offset 4 + nAvgBytesPerSec 4 byte offset 8 + nBlockAlign 2 byte offset 12 + wBitsPerSample 2 byte offset 14 + cbSize 2 byte offset 16 + data variable offset 18 + */ - /* examples - 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D........... - 00 00 - 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X...... - 00 00 - */ + /* examples + 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D........... + 00 00 + 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X...... + 00 00 + */ - out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM - out_uint16_le(s, 2); // num of channels - out_uint32_le(s, 44100); // samples per sec - out_uint32_le(s, 176400); // avg bytes per sec - out_uint16_le(s, 4); // block align - out_uint16_le(s, 16); // bits per sample - out_uint16_le(s, 0); // size + out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM + out_uint16_le(s, 2); // num of channels + out_uint32_le(s, 44100); // samples per sec + out_uint32_le(s, 176400); // avg bytes per sec + out_uint16_le(s, 4); // block align + out_uint16_le(s, 16); // bits per sample + out_uint16_le(s, 0); // size - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - free_stream(s); - return 0; + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + free_stream(s); + return 0; } /*****************************************************************************/ static int sound_send_training(void) { - struct stream* s; - int bytes; - int time; - char* size_ptr; + struct stream *s; + int bytes; + int time; + char *size_ptr; - print_got_here(); + print_got_here(); - make_stream(s); - init_stream(s, 8182); - out_uint16_le(s, SNDC_TRAINING); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - time = g_time2(); - g_training_sent_time = time; - out_uint16_le(s, time); - out_uint16_le(s, 1024); - out_uint8s(s, (1024 - 4)); - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - free_stream(s); - return 0; + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, SNDC_TRAINING); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + time = g_time2(); + g_training_sent_time = time; + out_uint16_le(s, time); + out_uint16_le(s, 1024); + out_uint8s(s, (1024 - 4)); + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + free_stream(s); + return 0; } /*****************************************************************************/ @@ -132,318 +132,339 @@ sound_send_training(void) */ static int APP_CC -sound_process_formats(struct stream* s, int size) +sound_process_formats(struct stream *s, int size) { - int num_formats; + int num_formats; - print_got_here(); + print_got_here(); - LOG(0, ("sound_process_formats:")); - if (size < 16) - { - return 1; - } - in_uint8s(s, 14); - in_uint16_le(s, num_formats); - if (num_formats > 0) - { - sound_send_training(); - } - return 0; + LOG(0, ("sound_process_formats:")); + + if (size < 16) + { + return 1; + } + + in_uint8s(s, 14); + in_uint16_le(s, num_formats); + + if (num_formats > 0) + { + sound_send_training(); + } + + return 0; } /*****************************************************************************/ static int -sound_send_wave_data(char* data, int data_bytes) +sound_send_wave_data(char *data, int data_bytes) { - struct stream* s; - int bytes; - int time; - char* size_ptr; + struct stream *s; + int bytes; + int time; + char *size_ptr; - print_got_here(); + print_got_here(); - if ((data_bytes < 4) || (data_bytes > 32 * 1024)) - { - LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes)); - } + if ((data_bytes < 4) || (data_bytes > 32 * 1024)) + { + LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes)); + } - /* part one of 2 PDU wave info */ + /* part one of 2 PDU wave info */ - LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes)); + LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes)); - make_stream(s); - init_stream(s, data_bytes); - out_uint16_le(s, SNDC_WAVE); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - time = g_time2(); - out_uint16_le(s, time); - out_uint16_le(s, 0); /* wFormatNo */ - g_cBlockNo++; - out_uint8(s, g_cBlockNo); + make_stream(s); + init_stream(s, data_bytes); + out_uint16_le(s, SNDC_WAVE); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + time = g_time2(); + out_uint16_le(s, time); + out_uint16_le(s, 0); /* wFormatNo */ + g_cBlockNo++; + out_uint8(s, g_cBlockNo); - LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d", - time & 0xffff, g_cBlockNo & 0xff)); + LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d", + time & 0xffff, g_cBlockNo & 0xff)); - out_uint8s(s, 3); - out_uint8a(s, data, 4); - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - bytes += data_bytes; - bytes -= 4; - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + out_uint8s(s, 3); + out_uint8a(s, data, 4); + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + bytes += data_bytes; + bytes -= 4; + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - /* part two of 2 PDU wave info */ - init_stream(s, data_bytes); - out_uint32_le(s, 0); - out_uint8a(s, data + 4, data_bytes - 4); - s_mark_end(s); - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - free_stream(s); - return 0; + /* part two of 2 PDU wave info */ + init_stream(s, data_bytes); + out_uint32_le(s, 0); + out_uint8a(s, data + 4, data_bytes - 4); + s_mark_end(s); + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + free_stream(s); + return 0; } /*****************************************************************************/ static int APP_CC -sound_process_training(struct stream* s, int size) +sound_process_training(struct stream *s, int size) { - int time_diff; + int time_diff; - print_got_here(); + print_got_here(); - time_diff = g_time2() - g_training_sent_time; - LOG(0, ("sound_process_training: round trip time %u", time_diff)); - return 0; + time_diff = g_time2() - g_training_sent_time; + LOG(0, ("sound_process_training: round trip time %u", time_diff)); + return 0; } /*****************************************************************************/ static int APP_CC -sound_process_wave_confirm(struct stream* s, int size) +sound_process_wave_confirm(struct stream *s, int size) { - int wTimeStamp; - int cConfirmedBlockNo; + int wTimeStamp; + int cConfirmedBlockNo; - print_got_here(); + print_got_here(); - in_uint16_le(s, wTimeStamp); - in_uint8(s, cConfirmedBlockNo); + in_uint16_le(s, wTimeStamp); + in_uint8(s, cConfirmedBlockNo); - LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d", - wTimeStamp, cConfirmedBlockNo)); + LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d", + wTimeStamp, cConfirmedBlockNo)); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -process_pcm_message(int id, int size, struct stream* s) +process_pcm_message(int id, int size, struct stream *s) { - print_got_here(); + print_got_here(); - sound_send_wave_data(s->p, size); - return 0; + sound_send_wave_data(s->p, size); + return 0; } /*****************************************************************************/ /* data coming in from audio source, eg pulse, alsa */ static int DEFAULT_CC -sound_trans_audio_data_in(struct trans* trans) +sound_trans_audio_data_in(struct trans *trans) { - struct stream *s; - int id; - int size; - int error; + struct stream *s; + int id; + int size; + int error; - if (trans == 0) - { - return 0; - } - if (trans != g_audio_c_trans) - { - return 1; - } - s = trans_get_in_s(trans); - in_uint32_le(s, id); - in_uint32_le(s, size); - if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1)) - { - LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size)); - return 1; - } - error = trans_force_read(trans, size - 8); - if (error == 0) - { - /* here, the entire message block is read in, process it */ - error = process_pcm_message(id, size - 8, s); - } - return error; + if (trans == 0) + { + return 0; + } + + if (trans != g_audio_c_trans) + { + return 1; + } + + s = trans_get_in_s(trans); + in_uint32_le(s, id); + in_uint32_le(s, size); + + if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1)) + { + LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size)); + return 1; + } + + error = trans_force_read(trans, size - 8); + + if (error == 0) + { + /* here, the entire message block is read in, process it */ + error = process_pcm_message(id, size - 8, s); + } + + return error; } /*****************************************************************************/ static int DEFAULT_CC sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans) { - print_got_here(); + print_got_here(); - if (trans == 0) - { - return 1; - } - if (trans != g_audio_l_trans) - { - return 1; - } - if (g_audio_c_trans != 0) /* if already set, error */ - { - return 1; - } - if (new_trans == 0) - { - return 1; - } - g_audio_c_trans = new_trans; - g_audio_c_trans->trans_data_in = sound_trans_audio_data_in; - g_audio_c_trans->header_size = 8; - trans_delete(g_audio_l_trans); - g_audio_l_trans = 0; - return 0; + if (trans == 0) + { + return 1; + } + + if (trans != g_audio_l_trans) + { + return 1; + } + + if (g_audio_c_trans != 0) /* if already set, error */ + { + return 1; + } + + if (new_trans == 0) + { + return 1; + } + + g_audio_c_trans = new_trans; + g_audio_c_trans->trans_data_in = sound_trans_audio_data_in; + g_audio_c_trans->header_size = 8; + trans_delete(g_audio_l_trans); + g_audio_l_trans = 0; + return 0; } /*****************************************************************************/ int APP_CC sound_init(void) { - char port[256]; - int error; + char port[256]; + int error; - print_got_here(); - LOG(0, ("sound_init:")); + print_got_here(); + LOG(0, ("sound_init:")); - sound_send_server_formats(); - g_audio_l_trans = trans_create(2, 33 * 1024, 8192); - g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); - g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in; - error = trans_listen(g_audio_l_trans, port); - if (error != 0) - { - LOG(0, ("sound_init: trans_listen failed")); - } + sound_send_server_formats(); + g_audio_l_trans = trans_create(2, 33 * 1024, 8192); + g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); + g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in; + error = trans_listen(g_audio_l_trans, port); + + if (error != 0) + { + LOG(0, ("sound_init: trans_listen failed")); + } #if defined(XRDP_SIMPLESOUND) - /* start thread to read raw audio data from pulseaudio device */ - tc_thread_create(read_raw_audio_data, 0); + /* start thread to read raw audio data from pulseaudio device */ + tc_thread_create(read_raw_audio_data, 0); #endif - return 0; + return 0; } /*****************************************************************************/ int APP_CC sound_deinit(void) { - print_got_here(); + print_got_here(); - if (g_audio_l_trans != 0) - { - trans_delete(g_audio_l_trans); - g_audio_l_trans = 0; - } - if (g_audio_c_trans != 0) - { - trans_delete(g_audio_c_trans); - g_audio_l_trans = 0; - } + if (g_audio_l_trans != 0) + { + trans_delete(g_audio_l_trans); + g_audio_l_trans = 0; + } - return 0; + if (g_audio_c_trans != 0) + { + trans_delete(g_audio_c_trans); + g_audio_l_trans = 0; + } + + return 0; } /*****************************************************************************/ /* data in from client ( clinet -> xrdp -> chansrv ) */ int APP_CC -sound_data_in(struct stream* s, int chan_id, int chan_flags, int length, +sound_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - int code; - int size; + int code; + int size; - print_got_here(); + print_got_here(); - in_uint8(s, code); - in_uint8s(s, 1); - in_uint16_le(s, size); - switch (code) - { - case SNDC_WAVECONFIRM: - sound_process_wave_confirm(s, size); - break; + in_uint8(s, code); + in_uint8s(s, 1); + in_uint16_le(s, size); - case SNDC_TRAINING: - sound_process_training(s, size); - break; + switch (code) + { + case SNDC_WAVECONFIRM: + sound_process_wave_confirm(s, size); + break; - case SNDC_FORMATS: - sound_process_formats(s, size); - break; + case SNDC_TRAINING: + sound_process_training(s, size); + break; - default: - LOG(0, ("sound_data_in: unknown code %d size %d", code, size)); - break; - } - return 0; + case SNDC_FORMATS: + sound_process_formats(s, size); + break; + + default: + LOG(0, ("sound_data_in: unknown code %d size %d", code, size)); + break; + } + + return 0; } /*****************************************************************************/ int APP_CC -sound_get_wait_objs(tbus* objs, int* count, int* timeout) +sound_get_wait_objs(tbus *objs, int *count, int *timeout) { - int lcount; + int lcount; - lcount = *count; - if (g_audio_l_trans != 0) - { - objs[lcount] = g_audio_l_trans->sck; - lcount++; - } - if (g_audio_c_trans != 0) - { - objs[lcount] = g_audio_c_trans->sck; - lcount++; - } - *count = lcount; - return 0; + lcount = *count; + + if (g_audio_l_trans != 0) + { + objs[lcount] = g_audio_l_trans->sck; + lcount++; + } + + if (g_audio_c_trans != 0) + { + objs[lcount] = g_audio_c_trans->sck; + lcount++; + } + + *count = lcount; + return 0; } /*****************************************************************************/ int APP_CC sound_check_wait_objs(void) { - if (g_audio_l_trans != 0) - { - trans_check_wait_objs(g_audio_l_trans); - } + if (g_audio_l_trans != 0) + { + trans_check_wait_objs(g_audio_l_trans); + } - if (g_audio_c_trans != 0) - { - trans_check_wait_objs(g_audio_c_trans); - } + if (g_audio_c_trans != 0) + { + trans_check_wait_objs(g_audio_c_trans); + } - return 0; + return 0; } #if defined(XRDP_SIMPLESOUND) static int DEFAULT_CC -sttrans_data_in(struct trans* self) +sttrans_data_in(struct trans *self) { - LOG(0, ("sttrans_data_in:\n")); - return 0; + LOG(0, ("sttrans_data_in:\n")); + return 0; } /** @@ -451,103 +472,112 @@ sttrans_data_in(struct trans* self) * to a unix domain socket on which trans server is listening */ -static void* DEFAULT_CC -read_raw_audio_data(void* arg) +static void *DEFAULT_CC +read_raw_audio_data(void *arg) { - pa_sample_spec samp_spec; - pa_simple* simple = NULL; - uint32_t bytes_read; - char* cptr; - int i; - int error; - struct trans* strans; - char path[256]; - struct stream* outs; + pa_sample_spec samp_spec; + pa_simple *simple = NULL; + uint32_t bytes_read; + char *cptr; + int i; + int error; + struct trans *strans; + char path[256]; + struct stream *outs; - strans = trans_create(TRANS_MODE_UNIX, 8192, 8192); - if (strans == 0) - { - LOG(0, ("read_raw_audio_data: trans_create failed\n")); - return 0; - } - strans->trans_data_in = sttrans_data_in; - g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); - if (trans_connect(strans, "", path, 100) != 0) - { - LOG(0, ("read_raw_audio_data: trans_connect failed\n")); - trans_delete(strans); - return 0; - } + strans = trans_create(TRANS_MODE_UNIX, 8192, 8192); - /* setup audio format */ - samp_spec.format = PA_SAMPLE_S16LE; - samp_spec.rate = 44100; - samp_spec.channels = 2; - - /* if we are root, then for first 8 seconds connection to pulseaudo server - fails; if we are non-root, then connection succeeds on first attempt; - for now we have changed code to be non-root, but this may change in the - future - so pretend we are root and try connecting to pulseaudio server - for upto one minute */ - for (i = 0; i < 60; i++) - { - simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL, - "record", &samp_spec, NULL, NULL, &error); - if (simple) + if (strans == 0) { - /* connected to pulseaudio server */ - LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n")); - break; + LOG(0, ("read_raw_audio_data: trans_create failed\n")); + return 0; } - LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n")); - LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); - g_sleep(1000); - } - if (i == 60) - { - /* failed to connect to audio server */ + strans->trans_data_in = sttrans_data_in; + g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); + + if (trans_connect(strans, "", path, 100) != 0) + { + LOG(0, ("read_raw_audio_data: trans_connect failed\n")); + trans_delete(strans); + return 0; + } + + /* setup audio format */ + samp_spec.format = PA_SAMPLE_S16LE; + samp_spec.rate = 44100; + samp_spec.channels = 2; + + /* if we are root, then for first 8 seconds connection to pulseaudo server + fails; if we are non-root, then connection succeeds on first attempt; + for now we have changed code to be non-root, but this may change in the + future - so pretend we are root and try connecting to pulseaudio server + for upto one minute */ + for (i = 0; i < 60; i++) + { + simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL, + "record", &samp_spec, NULL, NULL, &error); + + if (simple) + { + /* connected to pulseaudio server */ + LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n")); + break; + } + + LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n")); + LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); + g_sleep(1000); + } + + if (i == 60) + { + /* failed to connect to audio server */ + trans_delete(strans); + return NULL; + } + + /* insert header just once */ + outs = trans_get_out_s(strans, 8192); + out_uint32_le(outs, 0); + out_uint32_le(outs, AUDIO_BUF_SIZE + 8); + cptr = outs->p; + out_uint8s(outs, AUDIO_BUF_SIZE); + s_mark_end(outs); + + while (1) + { + /* read a block of raw audio data... */ + g_memset(cptr, 0, 4); + bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error); + + if (bytes_read < 0) + { + LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n")); + LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); + break; + } + + /* bug workaround: + even when there is no audio data, pulseaudio is returning without + errors but the data itself is zero; we use this zero data to + determine that there is no audio data present */ + if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0) + { + g_sleep(10); + continue; + } + + if (trans_force_write_s(strans, outs) != 0) + { + LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n")); + break; + } + } + + pa_simple_free(simple); trans_delete(strans); return NULL; - } - - /* insert header just once */ - outs = trans_get_out_s(strans, 8192); - out_uint32_le(outs, 0); - out_uint32_le(outs, AUDIO_BUF_SIZE + 8); - cptr = outs->p; - out_uint8s(outs, AUDIO_BUF_SIZE); - s_mark_end(outs); - - while (1) - { - /* read a block of raw audio data... */ - g_memset(cptr, 0, 4); - bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error); - if (bytes_read < 0) - { - LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n")); - LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); - break; - } - /* bug workaround: - even when there is no audio data, pulseaudio is returning without - errors but the data itself is zero; we use this zero data to - determine that there is no audio data present */ - if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0) - { - g_sleep(10); - continue; - } - if (trans_force_write_s(strans, outs) != 0) - { - LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n")); - break; - } - } - pa_simple_free(simple); - trans_delete(strans); - return NULL; } #endif diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index 70b52694..f7f95768 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -31,10 +31,10 @@ extern int g_waiting_for_data_response_time; /* in clipboard.c */ extern int g_rail_up; /* in rail.c */ -Display* g_display = 0; +Display *g_display = 0; int g_x_socket = 0; tbus g_x_wait_obj = 0; -Screen* g_screen = 0; +Screen *g_screen = 0; int g_screen_num = 0; Window g_root_window = 0; Atom g_wm_delete_window_atom = 0; @@ -42,15 +42,15 @@ Atom g_wm_protocols_atom = 0; /*****************************************************************************/ static int DEFAULT_CC -xcommon_error_handler(Display* dis, XErrorEvent* xer) +xcommon_error_handler(Display *dis, XErrorEvent *xer) { - char text[256]; + char text[256]; - XGetErrorText(dis, xer->error_code, text, 255); - LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d " - "resource 0x%lx", text, xer->error_code, - xer->request_code, xer->minor_code, xer->resourceid)); - return 0; + XGetErrorText(dis, xer->error_code, text, 255); + LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d " + "resource 0x%lx", text, xer->error_code, + xer->request_code, xer->minor_code, xer->resourceid)); + return 0; } /*****************************************************************************/ @@ -58,9 +58,9 @@ xcommon_error_handler(Display* dis, XErrorEvent* xer) Do any cleanup that needs to be done on exit, like removing temporary files. Don't worry about memory leaks */ static int DEFAULT_CC -xcommon_fatal_handler(Display* dis) +xcommon_fatal_handler(Display *dis) { - return 0; + return 0; } /*****************************************************************************/ @@ -71,7 +71,7 @@ xcommon_fatal_handler(Display* dis) int APP_CC xcommon_get_local_time(void) { - return g_time3(); + return g_time3(); } /******************************************************************************/ @@ -79,42 +79,45 @@ xcommon_get_local_time(void) int APP_CC xcommon_init(void) { - if (g_display != 0) - { - LOG(10, ("xcommon_init: xcommon_init already called")); + if (g_display != 0) + { + LOG(10, ("xcommon_init: xcommon_init already called")); + return 0; + } + + g_display = XOpenDisplay(0); + + if (g_display == 0) + { + LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed")); + return 1; + } + + LOG(0, ("xcommon_init: connected to display ok")); + + /* setting the error handlers can cause problem when shutting down + chansrv on some xlibs */ + XSetErrorHandler(xcommon_error_handler); + //XSetIOErrorHandler(xcommon_fatal_handler); + + g_x_socket = XConnectionNumber(g_display); + + if (g_x_socket == 0) + { + LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed")); + return 1; + } + + g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0); + g_screen_num = DefaultScreen(g_display); + g_screen = ScreenOfDisplay(g_display, g_screen_num); + + g_root_window = RootWindowOfScreen(g_screen); + + g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0); + g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0); + return 0; - } - g_display = XOpenDisplay(0); - if (g_display == 0) - { - LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed")); - return 1; - } - - LOG(0, ("xcommon_init: connected to display ok")); - - /* setting the error handlers can cause problem when shutting down - chansrv on some xlibs */ - XSetErrorHandler(xcommon_error_handler); - //XSetIOErrorHandler(xcommon_fatal_handler); - - g_x_socket = XConnectionNumber(g_display); - if (g_x_socket == 0) - { - LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed")); - return 1; - } - - g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0); - g_screen_num = DefaultScreen(g_display); - g_screen = ScreenOfDisplay(g_display, g_screen_num); - - g_root_window = RootWindowOfScreen(g_screen); - - g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0); - g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0); - - return 0; } /*****************************************************************************/ @@ -122,66 +125,73 @@ xcommon_init(void) this is called to get any wait objects for the main loop timeout can be nil */ int APP_CC -xcommon_get_wait_objs(tbus* objs, int* count, int* timeout) +xcommon_get_wait_objs(tbus *objs, int *count, int *timeout) { - int lcount; + int lcount; - if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0)) - { - LOG(10, ("xcommon_get_wait_objs: nothing to do")); + if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0)) + { + LOG(10, ("xcommon_get_wait_objs: nothing to do")); + return 0; + } + + lcount = *count; + objs[lcount] = g_x_wait_obj; + lcount++; + *count = lcount; return 0; - } - lcount = *count; - objs[lcount] = g_x_wait_obj; - lcount++; - *count = lcount; - return 0; } /*****************************************************************************/ int APP_CC xcommon_check_wait_objs(void) { - XEvent xevent; - int time_diff; - int clip_rv; - int rail_rv; + XEvent xevent; + int time_diff; + int clip_rv; + int rail_rv; + + if ((!g_clip_up) && (!g_rail_up)) + { + LOG(10, ("xcommon_check_wait_objs: nothing to do")); + return 0; + } + + if (g_is_wait_obj_set(g_x_wait_obj)) + { + if (XPending(g_display) < 1) + { + /* something is wrong, should not get here */ + LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed")); + return 0; + } + + if (g_waiting_for_data_response) + { + time_diff = xcommon_get_local_time() - + g_waiting_for_data_response_time; + + if (time_diff > 10000) + { + LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " + "waiting for data response too long")); + } + } + + while (XPending(g_display) > 0) + { + g_memset(&xevent, 0, sizeof(xevent)); + XNextEvent(g_display, &xevent); + + clip_rv = clipboard_xevent(&xevent); + rail_rv = rail_xevent(&xevent); + + if ((clip_rv == 1) && (rail_rv == 1)) + { + LOG(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); + } + } + } - if ((!g_clip_up) && (!g_rail_up)) - { - LOG(10, ("xcommon_check_wait_objs: nothing to do")); return 0; - } - if (g_is_wait_obj_set(g_x_wait_obj)) - { - if (XPending(g_display) < 1) - { - /* something is wrong, should not get here */ - LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed")); - return 0; - } - if (g_waiting_for_data_response) - { - time_diff = xcommon_get_local_time() - - g_waiting_for_data_response_time; - if (time_diff > 10000) - { - LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " - "waiting for data response too long")); - } - } - while (XPending(g_display) > 0) - { - g_memset(&xevent, 0, sizeof(xevent)); - XNextEvent(g_display, &xevent); - - clip_rv = clipboard_xevent(&xevent); - rail_rv = rail_xevent(&xevent); - if ((clip_rv == 1) && (rail_rv == 1)) - { - LOG(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); - } - } - } - return 0; } diff --git a/sesman/config.c b/sesman/config.c index a4342676..9938249f 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,146 +30,153 @@ #include "sesman.h" #include "log.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ int DEFAULT_CC -config_read(struct config_sesman* cfg) +config_read(struct config_sesman *cfg) { - int fd; - struct list* sec; - struct list* param_n; - struct list* param_v; - char cfg_file[256]; + int fd; + struct list *sec; + struct list *param_n; + struct list *param_v; + char cfg_file[256]; - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); - if (-1 == fd) - { - //if (g_cfg->log.fd >= 0) - //{ - /* logging is already active */ - log_message(LOG_LEVEL_ALWAYS, "error opening %s in \ + g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); + fd = g_file_open(cfg_file); + + if (-1 == fd) + { + //if (g_cfg->log.fd >= 0) + //{ + /* logging is already active */ + log_message(LOG_LEVEL_ALWAYS, "error opening %s in \ config_read", cfg_file); - //} - //else - //{ - g_printf("error opening %s in config_read", cfg_file); - //} - return 1; - } - g_memset(cfg, 0, sizeof(struct config_sesman)); - sec = list_create(); - sec->auto_free = 1; - file_read_sections(fd, sec); - param_n = list_create(); - param_n->auto_free = 1; - param_v = list_create(); - param_v->auto_free = 1; + //} + //else + //{ + g_printf("error opening %s in config_read", cfg_file); + //} + return 1; + } - /* read global config */ - config_read_globals(fd, cfg, param_n, param_v); + g_memset(cfg, 0, sizeof(struct config_sesman)); + sec = list_create(); + sec->auto_free = 1; + file_read_sections(fd, sec); + param_n = list_create(); + param_n->auto_free = 1; + param_v = list_create(); + param_v->auto_free = 1; - /* read Xvnc/X11rdp parameter list */ - config_read_vnc_params(fd, cfg, param_n, param_v); - config_read_rdp_params(fd, cfg, param_n, param_v); + /* read global config */ + config_read_globals(fd, cfg, param_n, param_v); - /* read logging config */ - // config_read_logging(fd, &(cfg->log), param_n, param_v); + /* read Xvnc/X11rdp parameter list */ + config_read_vnc_params(fd, cfg, param_n, param_v); + config_read_rdp_params(fd, cfg, param_n, param_v); - /* read security config */ - config_read_security(fd, &(cfg->sec), param_n, param_v); + /* read logging config */ + // config_read_logging(fd, &(cfg->log), param_n, param_v); - /* read session config */ - config_read_sessions(fd, &(cfg->sess), param_n, param_v); + /* read security config */ + config_read_security(fd, &(cfg->sec), param_n, param_v); - /* cleanup */ - list_delete(sec); - list_delete(param_v); - list_delete(param_n); - g_file_close(fd); - return 0; + /* read session config */ + config_read_sessions(fd, &(cfg->sess), param_n, param_v); + + /* cleanup */ + list_delete(sec); + list_delete(param_v); + list_delete(param_n); + g_file_close(fd); + return 0; } /******************************************************************************/ int DEFAULT_CC -config_read_globals(int file, struct config_sesman* cf, struct list* param_n, - struct list* param_v) +config_read_globals(int file, struct config_sesman *cf, struct list *param_n, + struct list *param_v) { - int i; - char* buf; + int i; + char *buf; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - /* resetting the struct */ - cf->listen_address[0] = '\0'; - cf->listen_port[0] = '\0'; - cf->enable_user_wm = 0; - cf->user_wm[0] = '\0'; - cf->default_wm[0] = '\0'; - cf->auth_file_path = 0; - - file_read_section(file, SESMAN_CFG_GLOBALS, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - buf = (char*)list_get_item(param_n, i); - if (0 == g_strcasecmp(buf, SESMAN_CFG_DEFWM)) - { - g_strncpy(cf->default_wm, (char*)list_get_item(param_v, i), 31); - } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_USERWM)) - { - g_strncpy(cf->user_wm, (char*)list_get_item(param_v, i), 31); - } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_ENABLE_USERWM)) - { - cf->enable_user_wm = text2bool((char*)list_get_item(param_v, i)); - } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_PORT)) - { - g_strncpy(cf->listen_port, (char*)list_get_item(param_v, i), 15); - } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_ADDRESS)) - { - g_strncpy(cf->listen_address, (char*)list_get_item(param_v, i), 31); - } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_AUTH_FILE_PATH)) - { - cf->auth_file_path = g_strdup((char*)list_get_item(param_v, i)); - } - } - - /* checking for missing required parameters */ - if ('\0' == cf->listen_address[0]) - { - g_strncpy(cf->listen_address, "0.0.0.0", 8); - } - if ('\0' == cf->listen_port[0]) - { - g_strncpy(cf->listen_port, "3350", 5); - } - if ('\0' == cf->user_wm[0]) - { + /* resetting the struct */ + cf->listen_address[0] = '\0'; + cf->listen_port[0] = '\0'; cf->enable_user_wm = 0; - } - if ('\0' == cf->default_wm[0]) - { - g_strncpy(cf->default_wm, "startwm.sh", 11); - } + cf->user_wm[0] = '\0'; + cf->default_wm[0] = '\0'; + cf->auth_file_path = 0; - /* showing read config */ - g_printf("sesman config:\r\n"); - g_printf("\tListenAddress: %s\r\n", cf->listen_address); - g_printf("\tListenPort: %s\r\n", cf->listen_port); - g_printf("\tEnableUserWindowManager: %i\r\n", cf->enable_user_wm); - g_printf("\tUserWindowManager: %s\r\n", cf->user_wm); - g_printf("\tDefaultWindowManager: %s\r\n", cf->default_wm); - g_printf("\tAuthFilePath: %s\r\n", ((cf->auth_file_path) ? (cf->auth_file_path) : ("disabled"))); + file_read_section(file, SESMAN_CFG_GLOBALS, param_n, param_v); - return 0; + for (i = 0; i < param_n->count; i++) + { + buf = (char *)list_get_item(param_n, i); + + if (0 == g_strcasecmp(buf, SESMAN_CFG_DEFWM)) + { + g_strncpy(cf->default_wm, (char *)list_get_item(param_v, i), 31); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_USERWM)) + { + g_strncpy(cf->user_wm, (char *)list_get_item(param_v, i), 31); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_ENABLE_USERWM)) + { + cf->enable_user_wm = text2bool((char *)list_get_item(param_v, i)); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_PORT)) + { + g_strncpy(cf->listen_port, (char *)list_get_item(param_v, i), 15); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_ADDRESS)) + { + g_strncpy(cf->listen_address, (char *)list_get_item(param_v, i), 31); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_AUTH_FILE_PATH)) + { + cf->auth_file_path = g_strdup((char *)list_get_item(param_v, i)); + } + } + + /* checking for missing required parameters */ + if ('\0' == cf->listen_address[0]) + { + g_strncpy(cf->listen_address, "0.0.0.0", 8); + } + + if ('\0' == cf->listen_port[0]) + { + g_strncpy(cf->listen_port, "3350", 5); + } + + if ('\0' == cf->user_wm[0]) + { + cf->enable_user_wm = 0; + } + + if ('\0' == cf->default_wm[0]) + { + g_strncpy(cf->default_wm, "startwm.sh", 11); + } + + /* showing read config */ + g_printf("sesman config:\r\n"); + g_printf("\tListenAddress: %s\r\n", cf->listen_address); + g_printf("\tListenPort: %s\r\n", cf->listen_port); + g_printf("\tEnableUserWindowManager: %i\r\n", cf->enable_user_wm); + g_printf("\tUserWindowManager: %s\r\n", cf->user_wm); + g_printf("\tDefaultWindowManager: %s\r\n", cf->default_wm); + g_printf("\tAuthFilePath: %s\r\n", ((cf->auth_file_path) ? (cf->auth_file_path) : ("disabled"))); + + return 0; } /****************************************************************************** @@ -184,7 +190,7 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n, list_clear(param_v); list_clear(param_n); - // setting defaults + // setting defaults lc->program_name = g_strdup("sesman"); lc->log_file = 0; lc->fd = 0; @@ -230,185 +236,201 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n, */ /******************************************************************************/ int DEFAULT_CC -config_read_security(int file, struct config_security* sc, - struct list* param_n, - struct list* param_v) +config_read_security(int file, struct config_security *sc, + struct list *param_n, + struct list *param_v) { - int i; - int gid; - char* buf; + int i; + int gid; + char *buf; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - /* setting defaults */ - sc->allow_root = 0; - sc->login_retry = 3; - sc->ts_users_enable = 0; - sc->ts_admins_enable = 0; + /* setting defaults */ + sc->allow_root = 0; + sc->login_retry = 3; + sc->ts_users_enable = 0; + sc->ts_admins_enable = 0; - file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - buf = (char*)list_get_item(param_n, i); - if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALLOW_ROOT)) + file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v); + + for (i = 0; i < param_n->count; i++) { - sc->allow_root = text2bool((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_LOGIN_RETRY)) - { - sc->login_retry = g_atoi((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_USR_GROUP)) - { - if (g_getgroup_info((char*)list_get_item(param_v, i), &gid) == 0) - { - sc->ts_users_enable = 1; - sc->ts_users = gid; - } - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP)) - { - if (g_getgroup_info((char*)list_get_item(param_v, i), &gid) == 0) - { - sc->ts_admins_enable = 1; - sc->ts_admins = gid; - } - } - } + buf = (char *)list_get_item(param_n, i); - /* printing security config */ - g_printf("security configuration:\r\n"); - g_printf("\tAllowRootLogin: %i\r\n",sc->allow_root); - g_printf("\tMaxLoginRetry: %i\r\n",sc->login_retry); - if (sc->ts_users_enable) - { - g_printf("\tTSUsersGroup: %i\r\n", sc->ts_users); - } - else - { - g_printf("\tNo TSUsersGroup defined\r\n"); - } - if (sc->ts_admins_enable) - { - g_printf("\tTSAdminsGroup: %i\r\n", sc->ts_admins); - } - else - { - g_printf("\tNo TSAdminsGroup defined\r\n"); - } + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALLOW_ROOT)) + { + sc->allow_root = text2bool((char *)list_get_item(param_v, i)); + } - return 0; + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_LOGIN_RETRY)) + { + sc->login_retry = g_atoi((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_USR_GROUP)) + { + if (g_getgroup_info((char *)list_get_item(param_v, i), &gid) == 0) + { + sc->ts_users_enable = 1; + sc->ts_users = gid; + } + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP)) + { + if (g_getgroup_info((char *)list_get_item(param_v, i), &gid) == 0) + { + sc->ts_admins_enable = 1; + sc->ts_admins = gid; + } + } + } + + /* printing security config */ + g_printf("security configuration:\r\n"); + g_printf("\tAllowRootLogin: %i\r\n", sc->allow_root); + g_printf("\tMaxLoginRetry: %i\r\n", sc->login_retry); + + if (sc->ts_users_enable) + { + g_printf("\tTSUsersGroup: %i\r\n", sc->ts_users); + } + else + { + g_printf("\tNo TSUsersGroup defined\r\n"); + } + + if (sc->ts_admins_enable) + { + g_printf("\tTSAdminsGroup: %i\r\n", sc->ts_admins); + } + else + { + g_printf("\tNo TSAdminsGroup defined\r\n"); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC -config_read_sessions(int file, struct config_sessions* se, struct list* param_n, - struct list* param_v) +config_read_sessions(int file, struct config_sessions *se, struct list *param_n, + struct list *param_v) { - int i; - char* buf; + int i; + char *buf; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - /* setting defaults */ - se->x11_display_offset=10; - se->max_sessions=0; - se->max_idle_time=0; - se->max_disc_time=0; - se->kill_disconnected=0; + /* setting defaults */ + se->x11_display_offset = 10; + se->max_sessions = 0; + se->max_idle_time = 0; + se->max_disc_time = 0; + se->kill_disconnected = 0; - file_read_section(file, SESMAN_CFG_SESSIONS, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - buf = (char*)list_get_item(param_n, i); - if (0 == g_strcasecmp(buf, SESMAN_CFG_X11DISPLAYOFFSET)) - { - se->x11_display_offset = g_atoi((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_MAX)) - { - se->max_sessions = g_atoi((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_KILL_DISC)) - { - se->kill_disconnected = text2bool((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_IDLE_LIMIT)) - { - se->max_idle_time=g_atoi((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_DISC_LIMIT)) - { - se->max_disc_time=g_atoi((char*)list_get_item(param_v, i)); - } - } + file_read_section(file, SESMAN_CFG_SESSIONS, param_n, param_v); - /* printing security config */ - g_printf("session configuration:\r\n"); - g_printf("\tMaxSessions: %i\r\n", se->max_sessions); - g_printf("\tX11DisplayOffset: %i\r\n", se->x11_display_offset); - g_printf("\tKillDisconnected: %i\r\n", se->kill_disconnected); - g_printf("\tIdleTimeLimit: %i\r\n", se->max_idle_time); - g_printf("\tDisconnectedTimeLimit: %i\r\n", se->max_idle_time); + for (i = 0; i < param_n->count; i++) + { + buf = (char *)list_get_item(param_n, i); - return 0; + if (0 == g_strcasecmp(buf, SESMAN_CFG_X11DISPLAYOFFSET)) + { + se->x11_display_offset = g_atoi((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_MAX)) + { + se->max_sessions = g_atoi((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_KILL_DISC)) + { + se->kill_disconnected = text2bool((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_IDLE_LIMIT)) + { + se->max_idle_time = g_atoi((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_DISC_LIMIT)) + { + se->max_disc_time = g_atoi((char *)list_get_item(param_v, i)); + } + } + + /* printing security config */ + g_printf("session configuration:\r\n"); + g_printf("\tMaxSessions: %i\r\n", se->max_sessions); + g_printf("\tX11DisplayOffset: %i\r\n", se->x11_display_offset); + g_printf("\tKillDisconnected: %i\r\n", se->kill_disconnected); + g_printf("\tIdleTimeLimit: %i\r\n", se->max_idle_time); + g_printf("\tDisconnectedTimeLimit: %i\r\n", se->max_idle_time); + + return 0; } /******************************************************************************/ int DEFAULT_CC -config_read_rdp_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v) +config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n, + struct list *param_v) { - int i; + int i; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - cs->rdp_params=list_create(); + cs->rdp_params = list_create(); - file_read_section(file, SESMAN_CFG_RDP_PARAMS, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - list_add_item(cs->rdp_params, (long)g_strdup((char*)list_get_item(param_v, i))); - } + file_read_section(file, SESMAN_CFG_RDP_PARAMS, param_n, param_v); - /* printing security config */ - g_printf("X11rdp parameters:\r\n"); - for (i = 0; i < cs->rdp_params->count; i++) - { - g_printf("\tParameter %02d %s\r\n", i, (char*)list_get_item(cs->rdp_params, i)); - } + for (i = 0; i < param_n->count; i++) + { + list_add_item(cs->rdp_params, (long)g_strdup((char *)list_get_item(param_v, i))); + } - return 0; + /* printing security config */ + g_printf("X11rdp parameters:\r\n"); + + for (i = 0; i < cs->rdp_params->count; i++) + { + g_printf("\tParameter %02d %s\r\n", i, (char *)list_get_item(cs->rdp_params, i)); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC -config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v) +config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n, + struct list *param_v) { - int i; + int i; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - cs->vnc_params=list_create(); + cs->vnc_params = list_create(); - file_read_section(file, SESMAN_CFG_VNC_PARAMS, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - list_add_item(cs->vnc_params, (long)g_strdup((char*)list_get_item(param_v, i))); - } + file_read_section(file, SESMAN_CFG_VNC_PARAMS, param_n, param_v); - /* printing security config */ - g_printf("Xvnc parameters:\r\n"); - for (i = 0; i < cs->vnc_params->count; i++) - { - g_printf("\tParameter %02d %s\r\n", i, (char*)list_get_item(cs->vnc_params, i)); - } + for (i = 0; i < param_n->count; i++) + { + list_add_item(cs->vnc_params, (long)g_strdup((char *)list_get_item(param_v, i))); + } - return 0; + /* printing security config */ + g_printf("Xvnc parameters:\r\n"); + + for (i = 0; i < cs->vnc_params->count; i++) + { + g_printf("\tParameter %02d %s\r\n", i, (char *)list_get_item(cs->vnc_params, i)); + } + + return 0; } - diff --git a/sesman/config.h b/sesman/config.h index 73fab38f..72c6cac4 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -296,4 +295,3 @@ config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n, struct list* param_v); #endif - diff --git a/sesman/env.c b/sesman/env.c index f7abe120..9f35f368 100644 --- a/sesman/env.c +++ b/sesman/env.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file env.c * @brief User environment handling code * @author Jay Sorg - * + * */ #include "sesman.h" @@ -31,95 +30,105 @@ #include "grp.h" extern unsigned char g_fixedkey[8]; /* in sesman.c */ -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ int DEFAULT_CC -env_check_password_file(char* filename, char* password) +env_check_password_file(char *filename, char *password) { - char encryptedPasswd[16]; - int fd; + char encryptedPasswd[16]; + int fd; - g_memset(encryptedPasswd, 0, 16); - g_strncpy(encryptedPasswd, password, 8); - rfbDesKey(g_fixedkey, 0); - rfbDes((unsigned char*)encryptedPasswd, (unsigned char*)encryptedPasswd); - fd = g_file_open(filename); - if (fd == -1) - { - log_message(LOG_LEVEL_WARNING, - "can't read vnc password file - %s", - filename); - return 1; - } - g_file_write(fd, encryptedPasswd, 8); - g_file_close(fd); - return 0; + g_memset(encryptedPasswd, 0, 16); + g_strncpy(encryptedPasswd, password, 8); + rfbDesKey(g_fixedkey, 0); + rfbDes((unsigned char *)encryptedPasswd, (unsigned char *)encryptedPasswd); + fd = g_file_open(filename); + + if (fd == -1) + { + log_message(LOG_LEVEL_WARNING, + "can't read vnc password file - %s", + filename); + return 1; + } + + g_file_write(fd, encryptedPasswd, 8); + g_file_close(fd); + return 0; } /******************************************************************************/ int DEFAULT_CC -env_set_user(char* username, char* passwd_file, int display) +env_set_user(char *username, char *passwd_file, int display) { - int error; - int pw_uid; - int pw_gid; - int uid; - char pw_shell[256]; - char pw_dir[256]; - char pw_gecos[256]; - char text[256]; + int error; + int pw_uid; + int pw_gid; + int uid; + char pw_shell[256]; + char pw_dir[256]; + char pw_gecos[256]; + char text[256]; + + error = g_getuser_info(username, &pw_gid, &pw_uid, pw_shell, pw_dir, + pw_gecos); - error = g_getuser_info(username, &pw_gid, &pw_uid, pw_shell, pw_dir, - pw_gecos); - if (error == 0) - { - g_rm_temp_dir(); - error = g_setgid(pw_gid); if (error == 0) { - error = g_initgroups(username, pw_gid); - } - if (error == 0) - { - uid = pw_uid; - error = g_setuid(uid); - } - g_mk_temp_dir(0); - if (error == 0) - { - g_clearenv(); - g_setenv("SHELL", pw_shell, 1); - g_setenv("PATH", "/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin", 1); - g_setenv("USER", username, 1); - g_sprintf(text, "%d", uid); - g_setenv("UID", text, 1); - g_setenv("HOME", pw_dir, 1); - g_set_current_dir(pw_dir); - g_sprintf(text, ":%d.0", display); - g_setenv("DISPLAY", text, 1); - if (passwd_file != 0) - { - if (0 == g_cfg->auth_file_path) + g_rm_temp_dir(); + error = g_setgid(pw_gid); + + if (error == 0) { - /* if no auth_file_path is set, then we go for - $HOME/.vnc/sesman_username_passwd */ - g_mkdir(".vnc"); - g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username); + error = g_initgroups(username, pw_gid); } - else + + if (error == 0) { - /* we use auth_file_path as requested */ - g_sprintf(passwd_file, g_cfg->auth_file_path, username); + uid = pw_uid; + error = g_setuid(uid); + } + + g_mk_temp_dir(0); + + if (error == 0) + { + g_clearenv(); + g_setenv("SHELL", pw_shell, 1); + g_setenv("PATH", "/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin", 1); + g_setenv("USER", username, 1); + g_sprintf(text, "%d", uid); + g_setenv("UID", text, 1); + g_setenv("HOME", pw_dir, 1); + g_set_current_dir(pw_dir); + g_sprintf(text, ":%d.0", display); + g_setenv("DISPLAY", text, 1); + + if (passwd_file != 0) + { + if (0 == g_cfg->auth_file_path) + { + /* if no auth_file_path is set, then we go for + $HOME/.vnc/sesman_username_passwd */ + g_mkdir(".vnc"); + g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username); + } + else + { + /* we use auth_file_path as requested */ + g_sprintf(passwd_file, g_cfg->auth_file_path, username); + } + + LOG_DBG("pass file: %s", passwd_file); + } } - LOG_DBG("pass file: %s", passwd_file); - } } - } - else - { - log_message(LOG_LEVEL_ERROR, - "error getting user info for user %s", username); - } - return error; + else + { + log_message(LOG_LEVEL_ERROR, + "error getting user info for user %s", username); + } + + return error; } diff --git a/sesman/env.h b/sesman/env.h index b14344af..c185ae30 100644 --- a/sesman/env.h +++ b/sesman/env.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file env.h * @brief User environment handling code declarations * @author Jay Sorg - * + * */ #ifndef ENV_H @@ -42,7 +41,7 @@ env_check_password_file(char* filename, char* password); /** * * @brief Sets user environment ($PATH, $HOME, $UID, and others) - * @param username Username + * @param username Username * @param passwd_file VNC password file * @param display The session display * @return 0 on success, g_getuser_info() error codes on error @@ -52,4 +51,3 @@ int DEFAULT_CC env_set_user(char* username, char* passwd_file, int display); #endif - diff --git a/sesman/libscp/libscp.h b/sesman/libscp/libscp.h index e06803cf..ed73380f 100644 --- a/sesman/libscp/libscp.h +++ b/sesman/libscp/libscp.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_commands.h b/sesman/libscp/libscp_commands.h index 8745c6bf..8c8d5f08 100644 --- a/sesman/libscp/libscp_commands.h +++ b/sesman/libscp/libscp_commands.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_commands_mng.h b/sesman/libscp/libscp_commands_mng.h index 78dffcf4..e1d6ba7c 100644 --- a/sesman/libscp/libscp_commands_mng.h +++ b/sesman/libscp/libscp_commands_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_connection.c b/sesman/libscp/libscp_connection.c index bf49fb84..6366d51a 100644 --- a/sesman/libscp/libscp_connection.c +++ b/sesman/libscp/libscp_connection.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -29,32 +28,32 @@ //extern struct log_config* s_log; -struct SCP_CONNECTION* +struct SCP_CONNECTION * scp_connection_create(int sck) { - struct SCP_CONNECTION* conn; + struct SCP_CONNECTION *conn; - conn = g_malloc(sizeof(struct SCP_CONNECTION), 0); + conn = g_malloc(sizeof(struct SCP_CONNECTION), 0); - if (0 == conn) - { - log_message(LOG_LEVEL_WARNING, "[connection:%d] connection create: malloc error", __LINE__); - return 0; - } + if (0 == conn) + { + log_message(LOG_LEVEL_WARNING, "[connection:%d] connection create: malloc error", __LINE__); + return 0; + } - conn->in_sck=sck; - make_stream(conn->in_s); - init_stream(conn->in_s, 8196); - make_stream(conn->out_s); - init_stream(conn->out_s, 8196); + conn->in_sck = sck; + make_stream(conn->in_s); + init_stream(conn->in_s, 8196); + make_stream(conn->out_s); + init_stream(conn->out_s, 8196); - return conn; + return conn; } void -scp_connection_destroy(struct SCP_CONNECTION* c) +scp_connection_destroy(struct SCP_CONNECTION *c) { - free_stream(c->in_s); - free_stream(c->out_s); - g_free(c); + free_stream(c->in_s); + free_stream(c->out_s); + g_free(c); } diff --git a/sesman/libscp/libscp_connection.h b/sesman/libscp/libscp_connection.h index ba94f429..e5bdbe27 100644 --- a/sesman/libscp/libscp_connection.h +++ b/sesman/libscp/libscp_connection.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file libscp_connection.h * @brief SCP_CONNECTION handling code * @author Simone Fedele - * + * */ #ifndef LIBSCP_CONNECTION_H @@ -37,7 +36,7 @@ * * @return a struct SCP_CONNECTION* object on success, NULL otherwise * - */ + */ struct SCP_CONNECTION* scp_connection_create(int sck); @@ -45,10 +44,9 @@ scp_connection_create(int sck); * * @brief destroys a struct SCP_CONNECTION* object * @param c the object to be destroyed - * + * */ void scp_connection_destroy(struct SCP_CONNECTION* c); #endif - diff --git a/sesman/libscp/libscp_init.c b/sesman/libscp/libscp_init.c index 4c48fb1f..eae57c6e 100644 --- a/sesman/libscp/libscp_init.c +++ b/sesman/libscp/libscp_init.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,19 +32,18 @@ int DEFAULT_CC scp_init() { -/* - if (0 == log) - { - return 1; - } -*/ + /* + if (0 == log) + { + return 1; + } + */ - //s_log = log; + //s_log = log; - scp_lock_init(); + scp_lock_init(); - log_message(LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__); + log_message(LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__); - return 0; + return 0; } - diff --git a/sesman/libscp/libscp_init.h b/sesman/libscp/libscp_init.h index 92dbc659..20a75857 100644 --- a/sesman/libscp/libscp_init.h +++ b/sesman/libscp/libscp_init.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file libscp_init.h * @brief libscp initialization code header * @author Simone Fedele - * + * */ #ifndef LIBSCP_INIT_H @@ -41,8 +40,7 @@ * It this memory needs to be g_free()d * */ -int DEFAULT_CC +int DEFAULT_CC scp_init(); #endif - diff --git a/sesman/libscp/libscp_lock.c b/sesman/libscp/libscp_lock.c index 9556b872..4db05422 100644 --- a/sesman/libscp/libscp_lock.c +++ b/sesman/libscp/libscp_lock.c @@ -1,25 +1,23 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - session manager - linux only - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * session manager + * linux only + */ #include "libscp_lock.h" @@ -37,110 +35,114 @@ int lock_fork_waiting_count; /* threads suspended until the fork finish void DEFAULT_CC scp_lock_init(void) { - /* initializing fork lock */ - pthread_mutexattr_init(&lock_fork_attr); - pthread_mutex_init(&lock_fork, &lock_fork_attr); - sem_init(&lock_fork_req, 0, 0); - sem_init(&lock_fork_wait, 0, 0); + /* initializing fork lock */ + pthread_mutexattr_init(&lock_fork_attr); + pthread_mutex_init(&lock_fork, &lock_fork_attr); + sem_init(&lock_fork_req, 0, 0); + sem_init(&lock_fork_wait, 0, 0); - /* here we don't use locking because lock_init() should be called BEFORE */ - /* any thread is created */ - lock_fork_blockers_count=0; - lock_fork_waiting_count=0; - lock_fork_forkers_count=0; + /* here we don't use locking because lock_init() should be called BEFORE */ + /* any thread is created */ + lock_fork_blockers_count = 0; + lock_fork_waiting_count = 0; + lock_fork_forkers_count = 0; } /******************************************************************************/ void DEFAULT_CC scp_lock_fork_request(void) { - /* lock mutex */ - pthread_mutex_lock(&lock_fork); - if (lock_fork_blockers_count == 0) - { - /* if noone is blocking fork(), then we're allowed to fork */ - sem_post(&lock_fork_req); - } - lock_fork_forkers_count++; - pthread_mutex_unlock(&lock_fork); + /* lock mutex */ + pthread_mutex_lock(&lock_fork); - /* we wait to be allowed to fork() */ - sem_wait(&lock_fork_req); + if (lock_fork_blockers_count == 0) + { + /* if noone is blocking fork(), then we're allowed to fork */ + sem_post(&lock_fork_req); + } + + lock_fork_forkers_count++; + pthread_mutex_unlock(&lock_fork); + + /* we wait to be allowed to fork() */ + sem_wait(&lock_fork_req); } /******************************************************************************/ void DEFAULT_CC scp_lock_fork_release(void) { - pthread_mutex_lock(&lock_fork); - lock_fork_forkers_count--; + pthread_mutex_lock(&lock_fork); + lock_fork_forkers_count--; - /* if there's someone else that want to fork, we let him fork() */ - if (lock_fork_forkers_count > 0) - { - sem_post(&lock_fork_req); - } + /* if there's someone else that want to fork, we let him fork() */ + if (lock_fork_forkers_count > 0) + { + sem_post(&lock_fork_req); + } - for (;lock_fork_waiting_count > 0; lock_fork_waiting_count--) - { - /* waking up the other processes */ - sem_post(&lock_fork_wait); - } - pthread_mutex_unlock(&lock_fork); + for (; lock_fork_waiting_count > 0; lock_fork_waiting_count--) + { + /* waking up the other processes */ + sem_post(&lock_fork_wait); + } + + pthread_mutex_unlock(&lock_fork); } /******************************************************************************/ void DEFAULT_CC scp_lock_fork_critical_section_end(int blocking) { - //LOG_DBG("lock_fork_critical_secection_end()",0); - /* lock mutex */ - pthread_mutex_lock(&lock_fork); + //LOG_DBG("lock_fork_critical_secection_end()",0); + /* lock mutex */ + pthread_mutex_lock(&lock_fork); - if (blocking == LIBSCP_LOCK_FORK_BLOCKER) - { - lock_fork_blockers_count--; - } + if (blocking == LIBSCP_LOCK_FORK_BLOCKER) + { + lock_fork_blockers_count--; + } - /* if there's someone who wants to fork and we're the last blocking */ - /* then we let him go */ - if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count>0)) - { - sem_post(&lock_fork_req); - } - pthread_mutex_unlock(&lock_fork); + /* if there's someone who wants to fork and we're the last blocking */ + /* then we let him go */ + if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count > 0)) + { + sem_post(&lock_fork_req); + } + + pthread_mutex_unlock(&lock_fork); } /******************************************************************************/ int DEFAULT_CC scp_lock_fork_critical_section_start(void) { - //LOG_DBG("lock_fork_critical_secection_start()",0); - do - { - pthread_mutex_lock(&lock_fork); - - /* someone requested to fork */ - if (lock_fork_forkers_count > 0) + //LOG_DBG("lock_fork_critical_secection_start()",0); + do { - lock_fork_waiting_count++; - pthread_mutex_unlock(&lock_fork); + pthread_mutex_lock(&lock_fork); - /* we wait until the fork finishes */ - sem_wait(&lock_fork_wait); + /* someone requested to fork */ + if (lock_fork_forkers_count > 0) + { + lock_fork_waiting_count++; + pthread_mutex_unlock(&lock_fork); + /* we wait until the fork finishes */ + sem_wait(&lock_fork_wait); + + } + else + { + /* no fork, so we can go on... */ + lock_fork_blockers_count++; + pthread_mutex_unlock(&lock_fork); + + return LIBSCP_LOCK_FORK_BLOCKER; + } } - else - { - /* no fork, so we can go on... */ - lock_fork_blockers_count++; - pthread_mutex_unlock(&lock_fork); + while (1); - return LIBSCP_LOCK_FORK_BLOCKER; - } - } while (1); - - /* we'll never get here */ - return LIBSCP_LOCK_FORK_WAITING; + /* we'll never get here */ + return LIBSCP_LOCK_FORK_WAITING; } - diff --git a/sesman/libscp/libscp_lock.h b/sesman/libscp/libscp_lock.h index 5c96cc5b..b4e93c52 100644 --- a/sesman/libscp/libscp_lock.h +++ b/sesman/libscp/libscp_lock.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef LIBSCP_LOCK_H #define LIBSCP_LOCK_H @@ -72,4 +71,3 @@ void DEFAULT_CC scp_lock_fork_critical_section_end(int blocking); #endif - diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c index 3ed5070a..4c389655 100644 --- a/sesman/libscp/libscp_session.c +++ b/sesman/libscp/libscp_session.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -34,379 +33,425 @@ //extern struct log_config* s_log; /*******************************************************************/ -struct SCP_SESSION* +struct SCP_SESSION * scp_session_create() { - struct SCP_SESSION* s; + struct SCP_SESSION *s; + + s = (struct SCP_SESSION *)g_malloc(sizeof(struct SCP_SESSION), 1); + + if (0 == s) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] session create: malloc error", __LINE__); + return 0; + } + + return s; +} + +/*******************************************************************/ +int +scp_session_set_type(struct SCP_SESSION *s, tui8 type) +{ + switch (type) + { + case SCP_SESSION_TYPE_XVNC: + s->type = SCP_SESSION_TYPE_XVNC; + break; + case SCP_SESSION_TYPE_XRDP: + s->type = SCP_SESSION_TYPE_XRDP; + break; + case SCP_GW_AUTHENTICATION: + s->type = SCP_GW_AUTHENTICATION; + break; + case SCP_SESSION_TYPE_MANAGE: + s->type = SCP_SESSION_TYPE_MANAGE; + s->mng = (struct SCP_MNG_DATA *)g_malloc(sizeof(struct SCP_MNG_DATA), 1); + + if (NULL == s->mng) + { + log_message(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__); + return 1; + } + + break; + default: + log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__); + return 1; + } - s = (struct SCP_SESSION*)g_malloc(sizeof(struct SCP_SESSION), 1); - if (0 == s) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] session create: malloc error", __LINE__); return 0; - } - return s; } /*******************************************************************/ int -scp_session_set_type(struct SCP_SESSION* s, tui8 type) +scp_session_set_version(struct SCP_SESSION *s, tui32 version) { - switch (type) - { - case SCP_SESSION_TYPE_XVNC: - s->type = SCP_SESSION_TYPE_XVNC; - break; - case SCP_SESSION_TYPE_XRDP: - s->type = SCP_SESSION_TYPE_XRDP; - break; - case SCP_GW_AUTHENTICATION: - s->type = SCP_GW_AUTHENTICATION; - break; - case SCP_SESSION_TYPE_MANAGE: - s->type = SCP_SESSION_TYPE_MANAGE; - s->mng = (struct SCP_MNG_DATA*)g_malloc(sizeof(struct SCP_MNG_DATA), 1); - if (NULL == s->mng) - { - log_message(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__); + switch (version) + { + case 0: + s->version = 0; + break; + case 1: + s->version = 1; + break; + default: + log_message(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__); + return 1; + } + + return 0; +} + +/*******************************************************************/ +int +scp_session_set_height(struct SCP_SESSION *s, tui16 h) +{ + s->height = h; + return 0; +} + +/*******************************************************************/ +int +scp_session_set_width(struct SCP_SESSION *s, tui16 w) +{ + s->width = w; + return 0; +} + +/*******************************************************************/ +int +scp_session_set_bpp(struct SCP_SESSION *s, tui8 bpp) +{ + switch (bpp) + { + case 8: + case 15: + case 16: + case 24: + s->bpp = bpp; + default: + return 1; + } + + return 0; +} + +/*******************************************************************/ +int +scp_session_set_rsr(struct SCP_SESSION *s, tui8 rsr) +{ + if (s->rsr) + { + s->rsr = 1; + } + else + { + s->rsr = 0; + } + + return 0; +} + +/*******************************************************************/ +int +scp_session_set_locale(struct SCP_SESSION *s, char *str) +{ + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__); + s->locale[0] = '\0'; return 1; - } - break; - default: - log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__); - return 1; - } - return 0; + } + + g_strncpy(s->locale, str, 17); + s->locale[17] = '\0'; + return 0; } /*******************************************************************/ int -scp_session_set_version(struct SCP_SESSION* s, tui32 version) +scp_session_set_username(struct SCP_SESSION *s, char *str) { - switch (version) - { - case 0: - s->version = 0; - break; - case 1: - s->version = 1; - break; - default: - log_message(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__); + return 1; + } + + if (0 != s->username) + { + g_free(s->username); + } + + s->username = g_strdup(str); + + if (0 == s->username) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_height(struct SCP_SESSION* s, tui16 h) +scp_session_set_password(struct SCP_SESSION *s, char *str) { - s->height = h; - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__); + return 1; + } + + if (0 != s->password) + { + g_free(s->password); + } + + s->password = g_strdup(str); + + if (0 == s->password) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_width(struct SCP_SESSION* s, tui16 w) +scp_session_set_domain(struct SCP_SESSION *s, char *str) { - s->width = w; - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__); + return 1; + } + + if (0 != s->domain) + { + g_free(s->domain); + } + + s->domain = g_strdup(str); + + if (0 == s->domain) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_bpp(struct SCP_SESSION* s, tui8 bpp) +scp_session_set_program(struct SCP_SESSION *s, char *str) { - switch (bpp) - { - case 8: - case 15: - case 16: - case 24: - s->bpp = bpp; - default: - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__); + return 1; + } + + if (0 != s->program) + { + g_free(s->program); + } + + s->program = g_strdup(str); + + if (0 == s->program) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_rsr(struct SCP_SESSION* s, tui8 rsr) +scp_session_set_directory(struct SCP_SESSION *s, char *str) { - if (s->rsr) - { - s->rsr = 1; - } - else - { - s->rsr = 0; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__); + return 1; + } + + if (0 != s->directory) + { + g_free(s->directory); + } + + s->directory = g_strdup(str); + + if (0 == s->directory) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_locale(struct SCP_SESSION* s, char* str) +scp_session_set_client_ip(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__); - s->locale[0]='\0'; - return 1; - } - g_strncpy(s->locale, str, 17); - s->locale[17]='\0'; - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__); + return 1; + } + + if (0 != s->client_ip) + { + g_free(s->client_ip); + } + + s->client_ip = g_strdup(str); + + if (0 == s->client_ip) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_username(struct SCP_SESSION* s, char* str) +scp_session_set_hostname(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__); - return 1; - } - if (0 != s->username) - { - g_free(s->username); - } - s->username = g_strdup(str); - if (0 == s->username) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__); + return 1; + } + + if (0 != s->hostname) + { + g_free(s->hostname); + } + + s->hostname = g_strdup(str); + + if (0 == s->hostname) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_password(struct SCP_SESSION* s, char* str) +scp_session_set_errstr(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__); - return 1; - } - if (0 != s->password) - { - g_free(s->password); - } - s->password = g_strdup(str); - if (0 == s->password) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__); + return 1; + } + + if (0 != s->errstr) + { + g_free(s->errstr); + } + + s->errstr = g_strdup(str); + + if (0 == s->errstr) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_domain(struct SCP_SESSION* s, char* str) +scp_session_set_display(struct SCP_SESSION *s, SCP_DISPLAY display) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__); - return 1; - } - if (0 != s->domain) - { - g_free(s->domain); - } - s->domain = g_strdup(str); - if (0 == s->domain) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__); - return 1; - } - return 0; + s->display = display; + return 0; } /*******************************************************************/ int -scp_session_set_program(struct SCP_SESSION* s, char* str) +scp_session_set_addr(struct SCP_SESSION *s, int type, void *addr) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__); - return 1; - } - if (0 != s->program) - { - g_free(s->program); - } - s->program = g_strdup(str); - if (0 == s->program) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__); - return 1; - } - return 0; -} - -/*******************************************************************/ -int -scp_session_set_directory(struct SCP_SESSION* s, char* str) -{ - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__); - return 1; - } - if (0 != s->directory) - { - g_free(s->directory); - } - s->directory = g_strdup(str); - if (0 == s->directory) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__); - return 1; - } - return 0; -} - -/*******************************************************************/ -int -scp_session_set_client_ip(struct SCP_SESSION* s, char* str) -{ - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__); - return 1; - } - if (0 != s->client_ip) - { - g_free(s->client_ip); - } - s->client_ip = g_strdup(str); - if (0 == s->client_ip) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__); - return 1; - } - return 0; -} - -/*******************************************************************/ -int -scp_session_set_hostname(struct SCP_SESSION* s, char* str) -{ - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__); - return 1; - } - if (0 != s->hostname) - { - g_free(s->hostname); - } - s->hostname = g_strdup(str); - if (0 == s->hostname) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__); - return 1; - } - return 0; -} - -/*******************************************************************/ -int -scp_session_set_errstr(struct SCP_SESSION* s, char* str) -{ - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__); - return 1; - } - if (0 != s->errstr) - { - g_free(s->errstr); - } - s->errstr = g_strdup(str); - if (0 == s->errstr) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__); - return 1; - } - return 0; -} - -/*******************************************************************/ -int -scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display) -{ - s->display = display; - return 0; -} - -/*******************************************************************/ -int -scp_session_set_addr(struct SCP_SESSION* s, int type, void* addr) -{ - struct in_addr ip4; + struct in_addr ip4; #ifdef IN6ADDR_ANY_INIT - struct in6_addr ip6; + struct in6_addr ip6; #endif - int ret; + int ret; - switch (type) - { - case SCP_ADDRESS_TYPE_IPV4: - /* convert from char to 32bit*/ - ret = inet_pton(AF_INET, addr, &ip4); - if (ret == 0) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__); - inet_pton(AF_INET, "127.0.0.1", &ip4); - g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4); - return 1; - } - g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4); - break; - case SCP_ADDRESS_TYPE_IPV4_BIN: - g_memcpy(&(s->ipv4addr), addr, 4); - break; + switch (type) + { + case SCP_ADDRESS_TYPE_IPV4: + /* convert from char to 32bit*/ + ret = inet_pton(AF_INET, addr, &ip4); + + if (ret == 0) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__); + inet_pton(AF_INET, "127.0.0.1", &ip4); + g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4); + return 1; + } + + g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4); + break; + case SCP_ADDRESS_TYPE_IPV4_BIN: + g_memcpy(&(s->ipv4addr), addr, 4); + break; #ifdef IN6ADDR_ANY_INIT - case SCP_ADDRESS_TYPE_IPV6: - /* convert from char to 128bit*/ - ret = inet_pton(AF_INET6, addr, &ip6); - if (ret == 0) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__); - inet_pton(AF_INET, "::1", &ip6); - g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16); - return 1; - } - g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16); - break; - case SCP_ADDRESS_TYPE_IPV6_BIN: - g_memcpy(s->ipv6addr, addr, 16); - break; + case SCP_ADDRESS_TYPE_IPV6: + /* convert from char to 128bit*/ + ret = inet_pton(AF_INET6, addr, &ip6); + + if (ret == 0) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__); + inet_pton(AF_INET, "::1", &ip6); + g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16); + return 1; + } + + g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16); + break; + case SCP_ADDRESS_TYPE_IPV6_BIN: + g_memcpy(s->ipv6addr, addr, 16); + break; #endif - default: - return 1; - } - return 0; + default: + return 1; + } + + return 0; } /*******************************************************************/ void -scp_session_destroy(struct SCP_SESSION* s) +scp_session_destroy(struct SCP_SESSION *s) { - g_free(s->username); - g_free(s->password); - g_free(s->hostname); - g_free(s->domain); - g_free(s->program); - g_free(s->directory); - g_free(s->client_ip); - g_free(s->errstr); - g_free(s->mng); - g_free(s); + g_free(s->username); + g_free(s->password); + g_free(s->hostname); + g_free(s->domain); + g_free(s->program); + g_free(s->directory); + g_free(s->client_ip); + g_free(s->errstr); + g_free(s->mng); + g_free(s); } diff --git a/sesman/libscp/libscp_session.h b/sesman/libscp/libscp_session.h index f5fe413e..b545af9e 100644 --- a/sesman/libscp/libscp_session.h +++ b/sesman/libscp/libscp_session.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_tcp.c b/sesman/libscp/libscp_tcp.c index 459992fe..29870563 100644 --- a/sesman/libscp/libscp_tcp.c +++ b/sesman/libscp/libscp_tcp.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,102 +32,103 @@ #include #include -extern struct log_config* s_log; +extern struct log_config *s_log; /*****************************************************************************/ int DEFAULT_CC -scp_tcp_force_recv(int sck, char* data, int len) +scp_tcp_force_recv(int sck, char *data, int len) { - int rcvd; - int block; + int rcvd; + int block; - LOG_DBG("scp_tcp_force_recv()"); - block = scp_lock_fork_critical_section_start(); + LOG_DBG("scp_tcp_force_recv()"); + block = scp_lock_fork_critical_section_start(); - while (len > 0) - { - rcvd = g_tcp_recv(sck, data, len, 0); - if (rcvd == -1) + while (len > 0) { - if (g_tcp_last_error_would_block(sck)) - { - g_sleep(1); - } - else - { - scp_lock_fork_critical_section_end(block); - return 1; - } - } - else if (rcvd == 0) - { - scp_lock_fork_critical_section_end(block); - return 1; - } - else - { - data += rcvd; - len -= rcvd; - } - } + rcvd = g_tcp_recv(sck, data, len, 0); - scp_lock_fork_critical_section_end(block); + if (rcvd == -1) + { + if (g_tcp_last_error_would_block(sck)) + { + g_sleep(1); + } + else + { + scp_lock_fork_critical_section_end(block); + return 1; + } + } + else if (rcvd == 0) + { + scp_lock_fork_critical_section_end(block); + return 1; + } + else + { + data += rcvd; + len -= rcvd; + } + } - return 0; + scp_lock_fork_critical_section_end(block); + + return 0; } /*****************************************************************************/ int DEFAULT_CC -scp_tcp_force_send(int sck, char* data, int len) +scp_tcp_force_send(int sck, char *data, int len) { - int sent; - int block; + int sent; + int block; - LOG_DBG("scp_tcp_force_send()"); - block = scp_lock_fork_critical_section_start(); + LOG_DBG("scp_tcp_force_send()"); + block = scp_lock_fork_critical_section_start(); - while (len > 0) - { - sent = g_tcp_send(sck, data, len, 0); - if (sent == -1) + while (len > 0) { - if (g_tcp_last_error_would_block(sck)) - { - g_sleep(1); - } - else - { - scp_lock_fork_critical_section_end(block); - return 1; - } - } - else if (sent == 0) - { - scp_lock_fork_critical_section_end(block); - return 1; - } - else - { - data += sent; - len -= sent; - } - } + sent = g_tcp_send(sck, data, len, 0); - scp_lock_fork_critical_section_end(block); + if (sent == -1) + { + if (g_tcp_last_error_would_block(sck)) + { + g_sleep(1); + } + else + { + scp_lock_fork_critical_section_end(block); + return 1; + } + } + else if (sent == 0) + { + scp_lock_fork_critical_section_end(block); + return 1; + } + else + { + data += sent; + len -= sent; + } + } - return 0; + scp_lock_fork_critical_section_end(block); + + return 0; } /*****************************************************************************/ int DEFAULT_CC -scp_tcp_bind(int sck, char* addr, char* port) +scp_tcp_bind(int sck, char *addr, char *port) { - struct sockaddr_in s; + struct sockaddr_in s; - memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons(atoi(port)); - s.sin_addr.s_addr = inet_addr(addr); - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); + memset(&s, 0, sizeof(struct sockaddr_in)); + s.sin_family = AF_INET; + s.sin_port = htons(atoi(port)); + s.sin_addr.s_addr = inet_addr(addr); + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_in)); } - diff --git a/sesman/libscp/libscp_tcp.h b/sesman/libscp/libscp_tcp.h index 985984dc..1db70797 100644 --- a/sesman/libscp/libscp_tcp.h +++ b/sesman/libscp/libscp_tcp.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h index e6521741..2140eced 100644 --- a/sesman/libscp/libscp_types.h +++ b/sesman/libscp/libscp_types.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -43,7 +42,7 @@ #define SCP_SESSION_TYPE_XRDP 0x01 #define SCP_SESSION_TYPE_MANAGE 0x02 /* SCP_GW_AUTHENTICATION can be used when XRDP + sesman act as a gateway - * XRDP sends this command to let sesman verify if the user is allowed + * XRDP sends this command to let sesman verify if the user is allowed * to use the gateway */ #define SCP_GW_AUTHENTICATION 0x04 diff --git a/sesman/libscp/libscp_types_mng.h b/sesman/libscp/libscp_types_mng.h index e34dd413..e0edad55 100644 --- a/sesman/libscp/libscp_types_mng.h +++ b/sesman/libscp/libscp_types_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c index f8b5a9d6..afa09bd8 100644 --- a/sesman/libscp/libscp_v0.c +++ b/sesman/libscp/libscp_v0.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -29,361 +28,386 @@ #include "os_calls.h" -extern struct log_config* s_log; +extern struct log_config *s_log; /* client API */ /******************************************************************************/ enum SCP_CLIENT_STATES_E -scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - tui32 version; - tui32 size; - tui16 sz; + tui32 version; + tui32 size; + tui16 sz; - init_stream(c->in_s, c->in_s->size); - init_stream(c->out_s, c->in_s->size); + init_stream(c->in_s, c->in_s->size); + init_stream(c->out_s, c->in_s->size); - LOG_DBG("[v0:%d] starting connection", __LINE__); - g_tcp_set_non_blocking(c->in_sck); - g_tcp_set_no_delay(c->in_sck); - s_push_layer(c->out_s, channel_hdr, 8); + LOG_DBG("[v0:%d] starting connection", __LINE__); + g_tcp_set_non_blocking(c->in_sck); + g_tcp_set_no_delay(c->in_sck); + s_push_layer(c->out_s, channel_hdr, 8); - /* code */ - if (s->type == SCP_SESSION_TYPE_XVNC) - { - out_uint16_be(c->out_s, 0); - } - else if (s->type == SCP_SESSION_TYPE_XRDP) - { - out_uint16_be(c->out_s, 10); - } - else - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_INTERNAL_ERR; - } - sz = g_strlen(s->username); - out_uint16_be(c->out_s, sz); - out_uint8a(c->out_s, s->username, sz); + /* code */ + if (s->type == SCP_SESSION_TYPE_XVNC) + { + out_uint16_be(c->out_s, 0); + } + else if (s->type == SCP_SESSION_TYPE_XRDP) + { + out_uint16_be(c->out_s, 10); + } + else + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_INTERNAL_ERR; + } - sz = g_strlen(s->password); - out_uint16_be(c->out_s,sz); - out_uint8a(c->out_s, s->password, sz); - out_uint16_be(c->out_s, s->width); - out_uint16_be(c->out_s, s->height); - out_uint16_be(c->out_s, s->bpp); + sz = g_strlen(s->username); + out_uint16_be(c->out_s, sz); + out_uint8a(c->out_s, s->username, sz); - s_mark_end(c->out_s); - s_pop_layer(c->out_s, channel_hdr); + sz = g_strlen(s->password); + out_uint16_be(c->out_s, sz); + out_uint8a(c->out_s, s->password, sz); + out_uint16_be(c->out_s, s->width); + out_uint16_be(c->out_s, s->height); + out_uint16_be(c->out_s, s->bpp); - /* version */ - out_uint32_be(c->out_s, 0); - /* size */ - out_uint32_be(c->out_s, c->out_s->end - c->out_s->data); + s_mark_end(c->out_s); + s_pop_layer(c->out_s, channel_hdr); - if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_NETWORK_ERR; - } + /* version */ + out_uint32_be(c->out_s, 0); + /* size */ + out_uint32_be(c->out_s, c->out_s->end - c->out_s->data); - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; + } - in_uint32_be(c->in_s, version); - if (0 != version) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); - return SCP_CLIENT_STATE_VERSION_ERR; - } + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; + } - in_uint32_be(c->in_s, size); - if (size < 14) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__); - return SCP_CLIENT_STATE_SIZE_ERR; - } + in_uint32_be(c->in_s, version); - /* getting payload */ - init_stream(c->in_s, c->in_s->size); - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_NETWORK_ERR; - } + if (0 != version) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); + return SCP_CLIENT_STATE_VERSION_ERR; + } - /* check code */ - in_uint16_be(c->in_s, sz); - if (3 != sz) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } + in_uint32_be(c->in_s, size); - /* message payload */ - in_uint16_be(c->in_s, sz); - if (1 != sz) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__); - return SCP_CLIENT_STATE_CONNECTION_DENIED; - } + if (size < 14) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__); + return SCP_CLIENT_STATE_SIZE_ERR; + } - in_uint16_be(c->in_s, sz); - s->display = sz; + /* getting payload */ + init_stream(c->in_s, c->in_s->size); - LOG_DBG("[v0:%d] connection terminated", __LINE__); - return SCP_CLIENT_STATE_END; + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + /* check code */ + in_uint16_be(c->in_s, sz); + + if (3 != sz) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); + return SCP_CLIENT_STATE_SEQUENCE_ERR; + } + + /* message payload */ + in_uint16_be(c->in_s, sz); + + if (1 != sz) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__); + return SCP_CLIENT_STATE_CONNECTION_DENIED; + } + + in_uint16_be(c->in_s, sz); + s->display = sz; + + LOG_DBG("[v0:%d] connection terminated", __LINE__); + return SCP_CLIENT_STATE_END; } /* server API */ /******************************************************************************/ enum SCP_SERVER_STATES_E -scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) +scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) { - tui32 version = 0; - tui32 size; - struct SCP_SESSION* session = 0; - tui16 sz; - tui32 code = 0; - char buf[257]; + tui32 version = 0; + tui32 size; + struct SCP_SESSION *session = 0; + tui16 sz; + tui32 code = 0; + char buf[257]; - if (!skipVchk) - { - LOG_DBG("[v0:%d] starting connection", __LINE__); - if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + if (!skipVchk) { - c->in_s->end = c->in_s->data + 8; - in_uint32_be(c->in_s, version); - if (version != 0) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); - return SCP_SERVER_STATE_VERSION_ERR; - } + LOG_DBG("[v0:%d] starting connection", __LINE__); + + if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + c->in_s->end = c->in_s->data + 8; + in_uint32_be(c->in_s, version); + + if (version != 0) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_STATE_VERSION_ERR; + } + } + else + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + } + + in_uint32_be(c->in_s, size); + + init_stream(c->in_s, 8196); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + c->in_s->end = c->in_s->data + (size - 8); + + in_uint16_be(c->in_s, code); + + if (code == 0 || code == 10) + { + session = scp_session_create(); + + if (0 == session) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + scp_session_set_version(session, version); + + if (code == 0) + { + scp_session_set_type(session, SCP_SESSION_TYPE_XVNC); + } + else + { + scp_session_set_type(session, SCP_SESSION_TYPE_XRDP); + } + + /* reading username */ + in_uint16_be(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); + + if (0 != scp_session_set_username(session, buf)) + { + scp_session_destroy(session); + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading password */ + in_uint16_be(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); + + if (0 != scp_session_set_password(session, buf)) + { + scp_session_destroy(session); + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* width */ + in_uint16_be(c->in_s, sz); + scp_session_set_width(session, sz); + /* height */ + in_uint16_be(c->in_s, sz); + scp_session_set_height(session, sz); + /* bpp */ + in_uint16_be(c->in_s, sz); + scp_session_set_bpp(session, (tui8)sz); + + if (s_check_rem(c->in_s, 2)) + { + /* reading domain */ + in_uint16_be(c->in_s, sz); + + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_domain(session, buf); + } + } + + if (s_check_rem(c->in_s, 2)) + { + /* reading program */ + in_uint16_be(c->in_s, sz); + + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_program(session, buf); + } + } + + if (s_check_rem(c->in_s, 2)) + { + /* reading directory */ + in_uint16_be(c->in_s, sz); + + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_directory(session, buf); + } + } + + if (s_check_rem(c->in_s, 2)) + { + /* reading client IP address */ + in_uint16_be(c->in_s, sz); + + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_client_ip(session, buf); + } + } + } + else if (code == SCP_GW_AUTHENTICATION) + { + /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */ + session = scp_session_create(); + + if (0 == session) + { + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + scp_session_set_version(session, version); + scp_session_set_type(session, SCP_GW_AUTHENTICATION); + /* reading username */ + in_uint16_be(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); + + /* g_writeln("Received user name: %s",buf); */ + if (0 != scp_session_set_username(session, buf)) + { + scp_session_destroy(session); + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading password */ + in_uint16_be(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); + + /* g_writeln("Received password: %s",buf); */ + if (0 != scp_session_set_password(session, buf)) + { + scp_session_destroy(session); + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */ + return SCP_SERVER_STATE_INTERNAL_ERR; + } } else { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - } - - in_uint32_be(c->in_s, size); - - init_stream(c->in_s, 8196); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - c->in_s->end = c->in_s->data + (size - 8); - - in_uint16_be(c->in_s, code); - - if (code == 0 || code == 10) - { - session = scp_session_create(); - if (0 == session) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; } - scp_session_set_version(session, version); - if (code == 0) - { - scp_session_set_type(session, SCP_SESSION_TYPE_XVNC); - } - else - { - scp_session_set_type(session, SCP_SESSION_TYPE_XRDP); - } - - /* reading username */ - in_uint16_be(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_username(session, buf)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading password */ - in_uint16_be(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_password(session, buf)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* width */ - in_uint16_be(c->in_s, sz); - scp_session_set_width(session, sz); - /* height */ - in_uint16_be(c->in_s, sz); - scp_session_set_height(session, sz); - /* bpp */ - in_uint16_be(c->in_s, sz); - scp_session_set_bpp(session, (tui8)sz); - if (s_check_rem(c->in_s, 2)) - { - /* reading domain */ - in_uint16_be(c->in_s, sz); - if (sz > 0) - { - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; - scp_session_set_domain(session, buf); - } - } - if (s_check_rem(c->in_s, 2)) - { - /* reading program */ - in_uint16_be(c->in_s, sz); - if (sz > 0) - { - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; - scp_session_set_program(session, buf); - } - } - if (s_check_rem(c->in_s, 2)) - { - /* reading directory */ - in_uint16_be(c->in_s, sz); - if (sz > 0) - { - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; - scp_session_set_directory(session, buf); - } - } - if (s_check_rem(c->in_s, 2)) - { - /* reading client IP address */ - in_uint16_be(c->in_s, sz); - if (sz > 0) - { - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; - scp_session_set_client_ip(session, buf); - } - } - } - else if (code == SCP_GW_AUTHENTICATION) - { - /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */ - session = scp_session_create(); - if (0 == session) - { - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - scp_session_set_version(session, version); - scp_session_set_type(session, SCP_GW_AUTHENTICATION); - /* reading username */ - in_uint16_be(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - /* g_writeln("Received user name: %s",buf); */ - if (0 != scp_session_set_username(session, buf)) - { - scp_session_destroy(session); - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading password */ - in_uint16_be(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); - /* g_writeln("Received password: %s",buf); */ - if (0 != scp_session_set_password(session, buf)) - { - scp_session_destroy(session); - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */ - return SCP_SERVER_STATE_INTERNAL_ERR; - } - } - else - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - (*s)=session; - return SCP_SERVER_STATE_OK; + (*s) = session; + return SCP_SERVER_STATE_OK; } /******************************************************************************/ enum SCP_SERVER_STATES_E -scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d) +scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d) { - out_uint32_be(c->out_s, 0); /* version */ - out_uint32_be(c->out_s, 14); /* size */ - out_uint16_be(c->out_s, 3); /* cmd */ - out_uint16_be(c->out_s, 1); /* data */ - out_uint16_be(c->out_s, d); /* data */ - s_mark_end(c->out_s); + out_uint32_be(c->out_s, 0); /* version */ + out_uint32_be(c->out_s, 14); /* size */ + out_uint16_be(c->out_s, 3); /* cmd */ + out_uint16_be(c->out_s, 1); /* data */ + out_uint16_be(c->out_s, d); /* data */ + s_mark_end(c->out_s); - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } - LOG_DBG("[v0:%d] connection terminated (allowed)", __LINE__); - return SCP_SERVER_STATE_OK; + LOG_DBG("[v0:%d] connection terminated (allowed)", __LINE__); + return SCP_SERVER_STATE_OK; } /******************************************************************************/ enum SCP_SERVER_STATES_E -scp_v0s_deny_connection(struct SCP_CONNECTION* c) +scp_v0s_deny_connection(struct SCP_CONNECTION *c) { - out_uint32_be(c->out_s, 0); /* version */ - out_uint32_be(c->out_s, 14); /* size */ - out_uint16_be(c->out_s, 3); /* cmd */ - out_uint16_be(c->out_s, 0); /* data = 0 - means NOT ok*/ - out_uint16_be(c->out_s, 0); /* reserved for display number*/ - s_mark_end(c->out_s); + out_uint32_be(c->out_s, 0); /* version */ + out_uint32_be(c->out_s, 14); /* size */ + out_uint16_be(c->out_s, 3); /* cmd */ + out_uint16_be(c->out_s, 0); /* data = 0 - means NOT ok*/ + out_uint16_be(c->out_s, 0); /* reserved for display number*/ + s_mark_end(c->out_s); - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } - LOG_DBG("[v0:%d] connection terminated (denied)", __LINE__); - return SCP_SERVER_STATE_OK; + LOG_DBG("[v0:%d] connection terminated (denied)", __LINE__); + return SCP_SERVER_STATE_OK; } /******************************************************************************/ enum SCP_SERVER_STATES_E -scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value) +scp_v0s_replyauthentication(struct SCP_CONNECTION *c, unsigned short int value) { - out_uint32_be(c->out_s, 0); /* version */ - out_uint32_be(c->out_s, 14); /* size */ - /* cmd SCP_GW_AUTHENTICATION means authentication reply */ - out_uint16_be(c->out_s, SCP_GW_AUTHENTICATION); - out_uint16_be(c->out_s, value); /* reply code */ - out_uint16_be(c->out_s, 0); /* dummy data */ - s_mark_end(c->out_s); + out_uint32_be(c->out_s, 0); /* version */ + out_uint32_be(c->out_s, 14); /* size */ + /* cmd SCP_GW_AUTHENTICATION means authentication reply */ + out_uint16_be(c->out_s, SCP_GW_AUTHENTICATION); + out_uint16_be(c->out_s, value); /* reply code */ + out_uint16_be(c->out_s, 0); /* dummy data */ + s_mark_end(c->out_s); - /* g_writeln("Total number of bytes that will be sent %d",c->out_s->end - c->out_s->data);*/ - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) - { - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); */ - return SCP_SERVER_STATE_NETWORK_ERR; - } + /* g_writeln("Total number of bytes that will be sent %d",c->out_s->end - c->out_s->data);*/ + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) + { + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); */ + return SCP_SERVER_STATE_NETWORK_ERR; + } - /* until syslog merge LOG_DBG(s_log, "[v0:%d] connection terminated (scp_v0s_deny_authentication)", __LINE__);*/ - return SCP_SERVER_STATE_OK; + /* until syslog merge LOG_DBG(s_log, "[v0:%d] connection terminated (scp_v0s_deny_authentication)", __LINE__);*/ + return SCP_SERVER_STATE_OK; } diff --git a/sesman/libscp/libscp_v0.h b/sesman/libscp/libscp_v0.h index 92b835f0..16e49e05 100644 --- a/sesman/libscp/libscp_v0.h +++ b/sesman/libscp/libscp_v0.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -39,7 +38,7 @@ * @param d display * */ -enum SCP_CLIENT_STATES_E +enum SCP_CLIENT_STATES_E scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s); /* server API */ @@ -52,7 +51,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s); * scp_vXs_accept() ) * */ -enum SCP_SERVER_STATES_E +enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk); /** @@ -61,7 +60,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk); * @param c connection descriptor * */ -enum SCP_SERVER_STATES_E +enum SCP_SERVER_STATES_E scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d); /** @@ -70,17 +69,16 @@ scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d); * @param c connection descriptor * */ -enum SCP_SERVER_STATES_E +enum SCP_SERVER_STATES_E scp_v0s_deny_connection(struct SCP_CONNECTION* c); /** * @brief send reply to an authentication request * @param c connection descriptor * @param value the reply code 0 means ok - * @return + * @return */ enum SCP_SERVER_STATES_E scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value); #endif - diff --git a/sesman/libscp/libscp_v1c.c b/sesman/libscp/libscp_v1c.c index 6e1c3b8a..7d1b9db8 100644 --- a/sesman/libscp/libscp_v1c.c +++ b/sesman/libscp/libscp_v1c.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,443 +30,477 @@ #include static enum SCP_CLIENT_STATES_E -_scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s); +_scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s); /* client API */ /* 001 */ enum SCP_CLIENT_STATES_E -scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - tui8 sz; - tui32 size; + tui8 sz; + tui32 size; - init_stream(c->out_s, c->out_s->size); - init_stream(c->in_s, c->in_s->size); + init_stream(c->out_s, c->out_s->size); + init_stream(c->in_s, c->in_s->size); - size = 19 + 17 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + - g_strlen(s->password); - if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) - { - size = size + 4; - } - else - { - size = size + 16; - } + size = 19 + 17 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + + g_strlen(s->password); - /* sending request */ + if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) + { + size = size + 4; + } + else + { + size = size + 16; + } - /* header */ - out_uint32_be(c->out_s, 1); /* version */ - out_uint32_be(c->out_s, size); - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); - out_uint16_be(c->out_s, 1); + /* sending request */ - /* body */ - out_uint8(c->out_s, s->type); - out_uint16_be(c->out_s, s->height); - out_uint16_be(c->out_s, s->width); - out_uint8(c->out_s, s->bpp); - out_uint8(c->out_s, s->rsr); - out_uint8p(c->out_s, s->locale, 17); - out_uint8(c->out_s, s->addr_type); + /* header */ + out_uint32_be(c->out_s, 1); /* version */ + out_uint32_be(c->out_s, size); + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); + out_uint16_be(c->out_s, 1); - if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) - { - out_uint32_be(c->out_s, s->ipv4addr); - } - else if (s->addr_type == SCP_ADDRESS_TYPE_IPV6) - { - out_uint8p(c->out_s, s->ipv6addr, 16); - } + /* body */ + out_uint8(c->out_s, s->type); + out_uint16_be(c->out_s, s->height); + out_uint16_be(c->out_s, s->width); + out_uint8(c->out_s, s->bpp); + out_uint8(c->out_s, s->rsr); + out_uint8p(c->out_s, s->locale, 17); + out_uint8(c->out_s, s->addr_type); - sz = g_strlen(s->hostname); - out_uint8(c->out_s, sz); - out_uint8p(c->out_s, s->hostname, sz); - sz = g_strlen(s->username); - out_uint8(c->out_s, sz); - out_uint8p(c->out_s, s->username, sz); - sz = g_strlen(s->password); - out_uint8(c->out_s, sz); - out_uint8p(c->out_s, s->password, sz); + if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) + { + out_uint32_be(c->out_s, s->ipv4addr); + } + else if (s->addr_type == SCP_ADDRESS_TYPE_IPV6) + { + out_uint8p(c->out_s, s->ipv6addr, 16); + } - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } + sz = g_strlen(s->hostname); + out_uint8(c->out_s, sz); + out_uint8p(c->out_s, s->hostname, sz); + sz = g_strlen(s->username); + out_uint8(c->out_s, sz); + out_uint8p(c->out_s, s->username, sz); + sz = g_strlen(s->password); + out_uint8(c->out_s, sz); + out_uint8p(c->out_s, s->password, sz); - /* wait for response */ - return _scp_v1c_check_response(c, s); + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + /* wait for response */ + return _scp_v1c_check_response(c, s); } /* 004 */ enum SCP_CLIENT_STATES_E -scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1c_resend_credentials(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - tui8 sz; - tui32 size; + tui8 sz; + tui32 size; - init_stream(c->out_s, c->out_s->size); - init_stream(c->in_s, c->in_s->size); + init_stream(c->out_s, c->out_s->size); + init_stream(c->in_s, c->in_s->size); - size = 12 + 2 + g_strlen(s->username) + g_strlen(s->password); + size = 12 + 2 + g_strlen(s->username) + g_strlen(s->password); - /* sending request */ - /* header */ - out_uint32_be(c->out_s, 1); /* version */ - out_uint32_be(c->out_s, size); - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); - out_uint16_be(c->out_s, 4); + /* sending request */ + /* header */ + out_uint32_be(c->out_s, 1); /* version */ + out_uint32_be(c->out_s, size); + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); + out_uint16_be(c->out_s, 4); - /* body */ - sz = g_strlen(s->username); - out_uint8(c->out_s, sz); - out_uint8p(c->out_s, s->username, sz); - sz = g_strlen(s->password); - out_uint8(c->out_s, sz); - out_uint8p(c->out_s, s->password, sz); + /* body */ + sz = g_strlen(s->username); + out_uint8(c->out_s, sz); + out_uint8p(c->out_s, s->username, sz); + sz = g_strlen(s->password); + out_uint8(c->out_s, sz); + out_uint8p(c->out_s, s->password, sz); - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } - /* wait for response */ - return _scp_v1c_check_response(c, s); + /* wait for response */ + return _scp_v1c_check_response(c, s); } /* 021 */ enum SCP_CLIENT_STATES_E -scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass); +scp_v1c_pwd_change(struct SCP_CONNECTION *c, char *newpass); /* 022 */ enum SCP_CLIENT_STATES_E -scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c); +scp_v1c_pwd_change_cancel(struct SCP_CONNECTION *c); /* 041 */ enum SCP_CLIENT_STATES_E -scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, - struct SCP_DISCONNECTED_SESSION** s) +scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount, + struct SCP_DISCONNECTED_SESSION **s) { - tui32 version = 1; - tui32 size = 12; - tui16 cmd = 41; - tui32 sescnt = 0; /* total session number */ - tui32 sestmp = 0; /* additional total session number */ - tui8 pktcnt = 0; /* packet session count */ - tui32 totalcnt = 0; /* session counter */ - tui8 continued = 0; /* continue flag */ - int firstpkt = 1; /* "first packet" flag */ - int idx; - struct SCP_DISCONNECTED_SESSION* ds = 0; + tui32 version = 1; + tui32 size = 12; + tui16 cmd = 41; + tui32 sescnt = 0; /* total session number */ + tui32 sestmp = 0; /* additional total session number */ + tui8 pktcnt = 0; /* packet session count */ + tui32 totalcnt = 0; /* session counter */ + tui8 continued = 0; /* continue flag */ + int firstpkt = 1; /* "first packet" flag */ + int idx; + struct SCP_DISCONNECTED_SESSION *ds = 0; - init_stream(c->out_s, c->out_s->size); + init_stream(c->out_s, c->out_s->size); - /* we request session list */ - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, size); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ + /* we request session list */ + out_uint32_be(c->out_s, version); /* version */ + out_uint32_be(c->out_s, size); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ + out_uint16_be(c->out_s, cmd); /* cmd */ - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } - - do - { - /* then we wait for server response */ - init_stream(c->in_s, c->in_s->size); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - return SCP_CLIENT_STATE_NETWORK_ERR; + return SCP_CLIENT_STATE_NETWORK_ERR; } - in_uint32_be(c->in_s, version); - if (version != 1) + do { - return SCP_CLIENT_STATE_VERSION_ERR; + /* then we wait for server response */ + init_stream(c->in_s, c->in_s->size); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + in_uint32_be(c->in_s, version); + + if (version != 1) + { + return SCP_CLIENT_STATE_VERSION_ERR; + } + + in_uint32_be(c->in_s, size); + + if (size < 12) + { + return SCP_CLIENT_STATE_SIZE_ERR; + } + + init_stream(c->in_s, c->in_s->size); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != SCP_COMMAND_SET_DEFAULT) + { + return SCP_CLIENT_STATE_SEQUENCE_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != 42) + { + return SCP_CLIENT_STATE_SEQUENCE_ERR; + } + + if (firstpkt) + { + firstpkt = 0; + in_uint32_be(c->in_s, sescnt); + sestmp = sescnt; + + ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0); + + if (ds == 0) + { + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + } + else + { + in_uint32_be(c->in_s, sestmp); + } + + in_uint8(c->in_s, continued); + in_uint8(c->in_s, pktcnt); + + for (idx = 0; idx < pktcnt; idx++) + { + in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */ + in_uint8(c->in_s, (ds[totalcnt]).type); + in_uint16_be(c->in_s, (ds[totalcnt]).height); + in_uint16_be(c->in_s, (ds[totalcnt]).width); + in_uint8(c->in_s, (ds[totalcnt]).bpp); + in_uint8(c->in_s, (ds[totalcnt]).idle_days); + in_uint8(c->in_s, (ds[totalcnt]).idle_hours); + in_uint8(c->in_s, (ds[totalcnt]).idle_minutes); + + in_uint16_be(c->in_s, (ds[totalcnt]).conn_year); + in_uint8(c->in_s, (ds[totalcnt]).conn_month); + in_uint8(c->in_s, (ds[totalcnt]).conn_day); + in_uint8(c->in_s, (ds[totalcnt]).conn_hour); + in_uint8(c->in_s, (ds[totalcnt]).conn_minute); + in_uint8(c->in_s, (ds[totalcnt]).addr_type); + + if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr); + } + else if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16); + } + + totalcnt++; + } } + while (continued); - in_uint32_be(c->in_s, size); - if (size < 12) - { - return SCP_CLIENT_STATE_SIZE_ERR; - } + printf("fine\n"); + /* return data... */ + (*scount) = sescnt; + (*s) = ds; - init_stream(c->in_s, c->in_s->size); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_DEFAULT) - { - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd != 42) - { - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } - - if (firstpkt) - { - firstpkt = 0; - in_uint32_be(c->in_s, sescnt); - sestmp = sescnt; - - ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0); - if (ds == 0) - { - return SCP_CLIENT_STATE_INTERNAL_ERR; - } - } - else - { - in_uint32_be(c->in_s, sestmp); - } - in_uint8(c->in_s, continued); - in_uint8(c->in_s, pktcnt); - - for (idx = 0; idx < pktcnt; idx++) - { - in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */ - in_uint8(c->in_s, (ds[totalcnt]).type); - in_uint16_be(c->in_s, (ds[totalcnt]).height); - in_uint16_be(c->in_s, (ds[totalcnt]).width); - in_uint8(c->in_s, (ds[totalcnt]).bpp); - in_uint8(c->in_s, (ds[totalcnt]).idle_days); - in_uint8(c->in_s, (ds[totalcnt]).idle_hours); - in_uint8(c->in_s, (ds[totalcnt]).idle_minutes); - - in_uint16_be(c->in_s, (ds[totalcnt]).conn_year); - in_uint8(c->in_s, (ds[totalcnt]).conn_month); - in_uint8(c->in_s, (ds[totalcnt]).conn_day); - in_uint8(c->in_s, (ds[totalcnt]).conn_hour); - in_uint8(c->in_s, (ds[totalcnt]).conn_minute); - in_uint8(c->in_s, (ds[totalcnt]).addr_type); - if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4) - { - in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr); - } - else if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6) - { - in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16); - } - totalcnt++; - } - } - while (continued); - - printf("fine\n"); - /* return data... */ - (*scount) = sescnt; - (*s) = ds; - - return SCP_CLIENT_STATE_LIST_OK; + return SCP_CLIENT_STATE_LIST_OK; } /* 043 */ enum SCP_CLIENT_STATES_E -scp_v1c_select_session(struct SCP_CONNECTION* c, struct SCP_SESSION* s, +scp_v1c_select_session(struct SCP_CONNECTION *c, struct SCP_SESSION *s, SCP_SID sid) { - tui32 version = 1; - tui32 size = 16; - tui16 cmd = 43; + tui32 version = 1; + tui32 size = 16; + tui16 cmd = 43; - init_stream(c->out_s, c->out_s->size); + init_stream(c->out_s, c->out_s->size); - /* sending our selection */ - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, size); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ + /* sending our selection */ + out_uint32_be(c->out_s, version); /* version */ + out_uint32_be(c->out_s, size); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ + out_uint16_be(c->out_s, cmd); /* cmd */ - out_uint32_be(c->out_s, sid); + out_uint32_be(c->out_s, sid); - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } - /* waiting for response.... */ - init_stream(c->in_s, c->in_s->size); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } + /* waiting for response.... */ + init_stream(c->in_s, c->in_s->size); - in_uint32_be(c->in_s, version); - if (version != 1) - { - return SCP_CLIENT_STATE_VERSION_ERR; - } + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } - in_uint32_be(c->in_s, size); - if (size < 12) - { - return SCP_CLIENT_STATE_SIZE_ERR; - } + in_uint32_be(c->in_s, version); - init_stream(c->in_s, c->in_s->size); - /* read the rest of the packet */ - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } + if (version != 1) + { + return SCP_CLIENT_STATE_VERSION_ERR; + } - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_DEFAULT) - { - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } + in_uint32_be(c->in_s, size); - in_uint16_be(c->in_s, cmd); - if (cmd != 46) - { - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } + if (size < 12) + { + return SCP_CLIENT_STATE_SIZE_ERR; + } - /* session display */ - in_uint16_be(c->in_s, (s->display)); - /*we don't need to return any data other than the display */ - /*because we already sent that */ + init_stream(c->in_s, c->in_s->size); - return SCP_CLIENT_STATE_OK; + /* read the rest of the packet */ + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != SCP_COMMAND_SET_DEFAULT) + { + return SCP_CLIENT_STATE_SEQUENCE_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != 46) + { + return SCP_CLIENT_STATE_SEQUENCE_ERR; + } + + /* session display */ + in_uint16_be(c->in_s, (s->display)); + /*we don't need to return any data other than the display */ + /*because we already sent that */ + + return SCP_CLIENT_STATE_OK; } /* 044 */ enum SCP_CLIENT_STATES_E -scp_v1c_select_session_cancel(struct SCP_CONNECTION* c) +scp_v1c_select_session_cancel(struct SCP_CONNECTION *c) { - tui32 version = 1; - tui32 size = 12; - tui16 cmd = 44; + tui32 version = 1; + tui32 size = 12; + tui16 cmd = 44; - init_stream(c->out_s, c->out_s->size); + init_stream(c->out_s, c->out_s->size); - /* sending our selection */ - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, size); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ + /* sending our selection */ + out_uint32_be(c->out_s, version); /* version */ + out_uint32_be(c->out_s, size); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ + out_uint16_be(c->out_s, cmd); /* cmd */ - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } - return SCP_CLIENT_STATE_END; + return SCP_CLIENT_STATE_END; } static enum SCP_CLIENT_STATES_E -_scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +_scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - tui32 version; - tui32 size; - tui16 cmd; - tui16 dim; + tui32 version; + tui32 size; + tui16 cmd; + tui16 dim; - init_stream(c->in_s, c->in_s->size); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } + init_stream(c->in_s, c->in_s->size); - in_uint32_be(c->in_s, version); - if (version != 1) - { - return SCP_CLIENT_STATE_VERSION_ERR; - } + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } - in_uint32_be(c->in_s, size); + in_uint32_be(c->in_s, version); - init_stream(c->in_s, c->in_s->size); - /* read the rest of the packet */ - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } + if (version != 1) + { + return SCP_CLIENT_STATE_VERSION_ERR; + } + + in_uint32_be(c->in_s, size); + + init_stream(c->in_s, c->in_s->size); + + /* read the rest of the packet */ + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != SCP_COMMAND_SET_DEFAULT) + { + return SCP_CLIENT_STATE_SEQUENCE_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd == 2) /* connection denied */ + { + in_uint16_be(c->in_s, dim); + + if (s->errstr != 0) + { + g_free(s->errstr); + } + + s->errstr = g_malloc(dim + 1, 0); + + if (s->errstr == 0) + { + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + + in_uint8a(c->in_s, s->errstr, dim); + (s->errstr)[dim] = '\0'; + + return SCP_CLIENT_STATE_CONNECTION_DENIED; + } + else if (cmd == 3) /* resend usr/pwd */ + { + in_uint16_be(c->in_s, dim); + + if (s->errstr != 0) + { + g_free(s->errstr); + } + + s->errstr = g_malloc(dim + 1, 0); + + if (s->errstr == 0) + { + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + + in_uint8a(c->in_s, s->errstr, dim); + (s->errstr)[dim] = '\0'; + + return SCP_CLIENT_STATE_RESEND_CREDENTIALS; + } + else if (cmd == 20) /* password change */ + { + in_uint16_be(c->in_s, dim); + + if (s->errstr != 0) + { + g_free(s->errstr); + } + + s->errstr = g_malloc(dim + 1, 0); + + if (s->errstr == 0) + { + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + + in_uint8a(c->in_s, s->errstr, dim); + (s->errstr)[dim] = '\0'; + + return SCP_CLIENT_STATE_PWD_CHANGE_REQ; + } + else if (cmd == 30) /* display */ + { + in_uint16_be(c->in_s, s->display); + + return SCP_CLIENT_STATE_OK; + } + //else if (cmd == 31) /* there's a disconnected session */ + //{ + // return SCP_CLIENT_STATE_RECONNECT_SINGLE; + //} + //else if (cmd == 33) /* display of a disconnected session */ + //{ + // return SCP_CLIENT_STATE_RECONNECT; + //} + else if (cmd == 40) /* session list */ + { + return SCP_CLIENT_STATE_SESSION_LIST; + } - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_DEFAULT) - { return SCP_CLIENT_STATE_SEQUENCE_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd == 2) /* connection denied */ - { - in_uint16_be(c->in_s, dim); - if (s->errstr != 0) - { - g_free(s->errstr); - } - s->errstr = g_malloc(dim + 1, 0); - if (s->errstr == 0) - { - return SCP_CLIENT_STATE_INTERNAL_ERR; - } - in_uint8a(c->in_s, s->errstr, dim); - (s->errstr)[dim] = '\0'; - - return SCP_CLIENT_STATE_CONNECTION_DENIED; - } - else if (cmd == 3) /* resend usr/pwd */ - { - in_uint16_be(c->in_s, dim); - if (s->errstr != 0) - { - g_free(s->errstr); - } - s->errstr = g_malloc(dim + 1, 0); - if (s->errstr == 0) - { - return SCP_CLIENT_STATE_INTERNAL_ERR; - } - in_uint8a(c->in_s, s->errstr, dim); - (s->errstr)[dim] = '\0'; - - return SCP_CLIENT_STATE_RESEND_CREDENTIALS; - } - else if (cmd == 20) /* password change */ - { - in_uint16_be(c->in_s, dim); - if (s->errstr != 0) - { - g_free(s->errstr); - } - s->errstr = g_malloc(dim + 1, 0); - if (s->errstr == 0) - { - return SCP_CLIENT_STATE_INTERNAL_ERR; - } - in_uint8a(c->in_s, s->errstr, dim); - (s->errstr)[dim] = '\0'; - - return SCP_CLIENT_STATE_PWD_CHANGE_REQ; - } - else if (cmd == 30) /* display */ - { - in_uint16_be(c->in_s, s->display); - - return SCP_CLIENT_STATE_OK; - } - //else if (cmd == 31) /* there's a disconnected session */ - //{ - // return SCP_CLIENT_STATE_RECONNECT_SINGLE; - //} - //else if (cmd == 33) /* display of a disconnected session */ - //{ - // return SCP_CLIENT_STATE_RECONNECT; - //} - else if (cmd == 40) /* session list */ - { - return SCP_CLIENT_STATE_SESSION_LIST; - } - - return SCP_CLIENT_STATE_SEQUENCE_ERR; } diff --git a/sesman/libscp/libscp_v1c.h b/sesman/libscp/libscp_v1c.h index f6fd4492..ef5a06cb 100644 --- a/sesman/libscp/libscp_v1c.h +++ b/sesman/libscp/libscp_v1c.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_v1c_mng.c b/sesman/libscp/libscp_v1c_mng.c index 88f86f4f..59762e36 100644 --- a/sesman/libscp/libscp_v1c_mng.c +++ b/sesman/libscp/libscp_v1c_mng.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,215 +32,228 @@ //extern struct log_config* s_log; static enum SCP_CLIENT_STATES_E -_scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s); +_scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s); /* client API */ /* 001 */ enum SCP_CLIENT_STATES_E -scp_v1c_mng_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1c_mng_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - tui8 sz; - tui32 size; + tui8 sz; + tui32 size; - init_stream(c->out_s, c->out_s->size); - init_stream(c->in_s, c->in_s->size); + init_stream(c->out_s, c->out_s->size); + init_stream(c->in_s, c->in_s->size); - size = 12 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + - g_strlen(s->password); - if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) - { - size = size + 4; - } - else - { - size = size + 16; - } + size = 12 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + + g_strlen(s->password); - /* sending request */ + if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) + { + size = size + 4; + } + else + { + size = size + 16; + } - /* header */ - out_uint32_be(c->out_s, 1); /* version */ - out_uint32_be(c->out_s, size); - out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); - out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN); + /* sending request */ - /* data */ - sz = g_strlen(s->username); - out_uint8(c->out_s, sz); - out_uint8p(c->out_s, s->username, sz); - sz = g_strlen(s->password); - out_uint8(c->out_s, sz); - out_uint8p(c->out_s, s->password, sz); + /* header */ + out_uint32_be(c->out_s, 1); /* version */ + out_uint32_be(c->out_s, size); + out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); + out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN); - /* address */ - out_uint8(c->out_s, s->addr_type); - if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) - { - out_uint32_be(c->out_s, s->ipv4addr); - } - else - { - out_uint8p(c->out_s, s->ipv6addr, 16); - } + /* data */ + sz = g_strlen(s->username); + out_uint8(c->out_s, sz); + out_uint8p(c->out_s, s->username, sz); + sz = g_strlen(s->password); + out_uint8(c->out_s, sz); + out_uint8p(c->out_s, s->password, sz); - /* hostname */ - sz = g_strlen(s->hostname); - out_uint8(c->out_s, sz); - out_uint8p(c->out_s, s->hostname, sz); + /* address */ + out_uint8(c->out_s, s->addr_type); - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_NETWORK_ERR; - } + if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) + { + out_uint32_be(c->out_s, s->ipv4addr); + } + else + { + out_uint8p(c->out_s, s->ipv6addr, 16); + } - /* wait for response */ - return _scp_v1c_mng_check_response(c, s); + /* hostname */ + sz = g_strlen(s->hostname); + out_uint8(c->out_s, sz); + out_uint8p(c->out_s, s->hostname, sz); + + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + /* wait for response */ + return _scp_v1c_mng_check_response(c, s); } /* 004 */ enum SCP_CLIENT_STATES_E -scp_v1c_mng_get_session_list(struct SCP_CONNECTION* c, int* scount, - struct SCP_DISCONNECTED_SESSION** s) +scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount, + struct SCP_DISCONNECTED_SESSION **s) { - tui32 version = 1; - tui32 size = 12; - tui16 cmd = SCP_CMD_MNG_LIST_REQ; /* request session list */ - tui32 sescnt = 0; /* total session number */ - tui32 sestmp = 0; /* additional total session number */ - tui8 pktcnt = 0; /* packet session count */ - tui32 totalcnt = 0; /* session counter */ - tui8 continued = 0; /* continue flag */ - int firstpkt = 1; /* "first packet" flag */ - int idx; - struct SCP_DISCONNECTED_SESSION* ds = 0; -// tui8 addr[16]; + tui32 version = 1; + tui32 size = 12; + tui16 cmd = SCP_CMD_MNG_LIST_REQ; /* request session list */ + tui32 sescnt = 0; /* total session number */ + tui32 sestmp = 0; /* additional total session number */ + tui8 pktcnt = 0; /* packet session count */ + tui32 totalcnt = 0; /* session counter */ + tui8 continued = 0; /* continue flag */ + int firstpkt = 1; /* "first packet" flag */ + int idx; + struct SCP_DISCONNECTED_SESSION *ds = 0; + // tui8 addr[16]; - init_stream(c->out_s, c->out_s->size); + init_stream(c->out_s, c->out_s->size); - /* we request session list */ - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, size); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ + /* we request session list */ + out_uint32_be(c->out_s, version); /* version */ + out_uint32_be(c->out_s, size); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); /* cmdset */ + out_uint16_be(c->out_s, cmd); /* cmd */ - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_NETWORK_ERR; - } - - do - { - /* then we wait for server response */ - init_stream(c->in_s, c->in_s->size); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_NETWORK_ERR; + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; } - in_uint32_be(c->in_s, version); - if (version != 1) + do { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); - return SCP_CLIENT_STATE_VERSION_ERR; + /* then we wait for server response */ + init_stream(c->in_s, c->in_s->size); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + in_uint32_be(c->in_s, version); + + if (version != 1) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); + return SCP_CLIENT_STATE_VERSION_ERR; + } + + in_uint32_be(c->in_s, size); + + if (size < 12) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__); + return SCP_CLIENT_STATE_SIZE_ERR; + } + + init_stream(c->in_s, c->in_s->size); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != SCP_COMMAND_SET_MANAGE) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); + return SCP_CLIENT_STATE_SEQUENCE_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != SCP_CMD_MNG_LIST) /* session list */ + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); + return SCP_CLIENT_STATE_SEQUENCE_ERR; + } + + if (firstpkt) + { + firstpkt = 0; + in_uint32_be(c->in_s, sescnt); + sestmp = sescnt; + + if (0 == sescnt) + { + /* return data... */ + (*scount) = sescnt; + (*s) = NULL; + + LOG_DBG("[v1c_mng] end list - no session on TS"); + return SCP_CLIENT_STATE_LIST_OK; + } + + ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0); + + if (ds == 0) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__); + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + } + else + { + in_uint32_be(c->in_s, sestmp); + } + + in_uint8(c->in_s, continued); + in_uint8(c->in_s, pktcnt); + + for (idx = 0; idx < pktcnt; idx++) + { + in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */ + in_uint8(c->in_s, (ds[totalcnt]).type); + in_uint16_be(c->in_s, (ds[totalcnt]).height); + in_uint16_be(c->in_s, (ds[totalcnt]).width); + in_uint8(c->in_s, (ds[totalcnt]).bpp); + in_uint8(c->in_s, (ds[totalcnt]).idle_days); + in_uint8(c->in_s, (ds[totalcnt]).idle_hours); + in_uint8(c->in_s, (ds[totalcnt]).idle_minutes); + + in_uint16_be(c->in_s, (ds[totalcnt]).conn_year); + in_uint8(c->in_s, (ds[totalcnt]).conn_month); + in_uint8(c->in_s, (ds[totalcnt]).conn_day); + in_uint8(c->in_s, (ds[totalcnt]).conn_hour); + in_uint8(c->in_s, (ds[totalcnt]).conn_minute); + in_uint8(c->in_s, (ds[totalcnt]).addr_type); + + if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr); + } + + if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16); + } + + totalcnt++; + } } + while (continued); - in_uint32_be(c->in_s, size); - if (size < 12) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__); - return SCP_CLIENT_STATE_SIZE_ERR; - } + /* return data... */ + (*scount) = sescnt; + (*s) = ds; - init_stream(c->in_s, c->in_s->size); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_NETWORK_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_MANAGE) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_CMD_MNG_LIST) /* session list */ - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } - - if (firstpkt) - { - firstpkt = 0; - in_uint32_be(c->in_s, sescnt); - sestmp = sescnt; - - if (0 == sescnt) - { - /* return data... */ - (*scount) = sescnt; - (*s) = NULL; - - LOG_DBG("[v1c_mng] end list - no session on TS"); - return SCP_CLIENT_STATE_LIST_OK; - } - - ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0); - if (ds == 0) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__); - return SCP_CLIENT_STATE_INTERNAL_ERR; - } - } - else - { - in_uint32_be(c->in_s, sestmp); - } - in_uint8(c->in_s, continued); - in_uint8(c->in_s, pktcnt); - - for (idx = 0; idx < pktcnt; idx++) - { - in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */ - in_uint8(c->in_s, (ds[totalcnt]).type); - in_uint16_be(c->in_s, (ds[totalcnt]).height); - in_uint16_be(c->in_s, (ds[totalcnt]).width); - in_uint8(c->in_s, (ds[totalcnt]).bpp); - in_uint8(c->in_s, (ds[totalcnt]).idle_days); - in_uint8(c->in_s, (ds[totalcnt]).idle_hours); - in_uint8(c->in_s, (ds[totalcnt]).idle_minutes); - - in_uint16_be(c->in_s, (ds[totalcnt]).conn_year); - in_uint8(c->in_s, (ds[totalcnt]).conn_month); - in_uint8(c->in_s, (ds[totalcnt]).conn_day); - in_uint8(c->in_s, (ds[totalcnt]).conn_hour); - in_uint8(c->in_s, (ds[totalcnt]).conn_minute); - in_uint8(c->in_s, (ds[totalcnt]).addr_type); - if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4) - { - in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr); - } - if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6) - { - in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16); - } - totalcnt++; - } - } - while (continued); - - /* return data... */ - (*scount) = sescnt; - (*s) = ds; - - LOG_DBG("[v1c_mng] end list"); - return SCP_CLIENT_STATE_LIST_OK; + LOG_DBG("[v1c_mng] end list"); + return SCP_CLIENT_STATE_LIST_OK; } /* 043 * / @@ -339,62 +351,67 @@ scp_v1c_select_session_cancel(struct SCP_CONNECTION* c) }*/ static enum SCP_CLIENT_STATES_E -_scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +_scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - tui32 version; - tui32 size; - tui16 cmd; - tui8 dim; - char buf[257]; + tui32 version; + tui32 size; + tui16 cmd; + tui8 dim; + char buf[257]; - init_stream(c->in_s, c->in_s->size); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_NETWORK_ERR; - } + init_stream(c->in_s, c->in_s->size); - in_uint32_be(c->in_s, version); - if (version != 1) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); - return SCP_CLIENT_STATE_VERSION_ERR; - } + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; + } - in_uint32_be(c->in_s, size); + in_uint32_be(c->in_s, version); - init_stream(c->in_s, c->in_s->size); - /* read the rest of the packet */ - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); - return SCP_CLIENT_STATE_NETWORK_ERR; - } + if (version != 1) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); + return SCP_CLIENT_STATE_VERSION_ERR; + } - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_MANAGE) - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); + in_uint32_be(c->in_s, size); + + init_stream(c->in_s, c->in_s->size); + + /* read the rest of the packet */ + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != SCP_COMMAND_SET_MANAGE) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); + return SCP_CLIENT_STATE_SEQUENCE_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */ + { + log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__); + return SCP_CLIENT_STATE_OK; + } + else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */ + { + in_uint8(c->in_s, dim); + buf[dim] = '\0'; + in_uint8a(c->in_s, buf, dim); + scp_session_set_errstr(s, buf); + + log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr); + return SCP_CLIENT_STATE_CONNECTION_DENIED; + } + + log_message(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__); return SCP_CLIENT_STATE_SEQUENCE_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */ - { - log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__); - return SCP_CLIENT_STATE_OK; - } - else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */ - { - in_uint8(c->in_s, dim); - buf[dim]='\0'; - in_uint8a(c->in_s, buf, dim); - scp_session_set_errstr(s, buf); - - log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr); - return SCP_CLIENT_STATE_CONNECTION_DENIED; - } - - log_message(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__); - return SCP_CLIENT_STATE_SEQUENCE_ERR; } diff --git a/sesman/libscp/libscp_v1c_mng.h b/sesman/libscp/libscp_v1c_mng.h index f030d4bf..126c9113 100644 --- a/sesman/libscp/libscp_v1c_mng.h +++ b/sesman/libscp/libscp_v1c_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c index e10af26c..69997ab2 100644 --- a/sesman/libscp/libscp_v1s.c +++ b/sesman/libscp/libscp_v1s.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,634 +32,668 @@ //extern struct log_config* s_log; /* server API */ -enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) +enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) { - struct SCP_SESSION* session; - tui32 version; - tui32 size; - tui16 cmdset; - tui16 cmd; - tui8 sz; - char buf[257]; + struct SCP_SESSION *session; + tui32 version; + tui32 size; + tui16 cmdset; + tui16 cmd; + tui8 sz; + char buf[257]; - if (!skipVchk) - { - - if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + if (!skipVchk) + { + + if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + in_uint32_be(c->in_s, version); + + if (version != 1) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_STATE_VERSION_ERR; + } + } + else + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + } + + in_uint32_be(c->in_s, size); + + if (size < 12) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } + + init_stream(c->in_s, c->in_s->size); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + /* reading command set */ + in_uint16_be(c->in_s, cmdset); + + /* if we are starting a management session */ + if (cmdset == SCP_COMMAND_SET_MANAGE) + { + log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__); + /* should return SCP_SERVER_STATE_START_MANAGE */ + return scp_v1s_mng_accept(c, s); + } + + /* if we started with resource sharing... */ + if (cmdset == SCP_COMMAND_SET_RSR) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + /* reading command */ + in_uint16_be(c->in_s, cmd); + + if (cmd != 1) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + session = scp_session_create(); + + if (0 == session) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + scp_session_set_version(session, 1); + + in_uint8(c->in_s, sz); + + if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP)) + { + scp_session_destroy(session); + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__); + return SCP_SERVER_STATE_SESSION_TYPE_ERR; + } + + scp_session_set_type(session, sz); + + in_uint16_be(c->in_s, cmd); + scp_session_set_height(session, cmd); + in_uint16_be(c->in_s, cmd); + scp_session_set_height(session, cmd); + in_uint8(c->in_s, sz); + scp_session_set_bpp(session, sz); + in_uint8(c->in_s, sz); + scp_session_set_rsr(session, sz); + in_uint8a(c->in_s, buf, 17); + buf[17] = '\0'; + scp_session_set_locale(session, buf); + + in_uint8(c->in_s, sz); + + if (sz == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->in_s, size); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &size); + } + else if (sz == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->in_s, buf, 16); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); + } + + buf[256] = '\0'; + /* reading hostname */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); + + if (0 != scp_session_set_hostname(session, buf)) + { + scp_session_destroy(session); + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading username */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); + + if (0 != scp_session_set_username(session, buf)) + { + scp_session_destroy(session); + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading password */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); + + if (0 != scp_session_set_password(session, buf)) + { + scp_session_destroy(session); + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* returning the struct */ + (*s) = session; + + return SCP_SERVER_STATE_OK; +} + +enum SCP_SERVER_STATES_E +scp_v1s_deny_connection(struct SCP_CONNECTION *c, char *reason) +{ + int rlen; + + init_stream(c->out_s, c->out_s->size); + + /* forcing message not to exceed 64k */ + rlen = g_strlen(reason); + + if (rlen > 65535) + { + rlen = 65535; + } + + out_uint32_be(c->out_s, 1); + /* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason)*/ + /* version + size + cmdset + cmd + msglen + msg */ + out_uint32_be(c->out_s, rlen + 14); + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); + out_uint16_be(c->out_s, 2); + out_uint16_be(c->out_s, rlen); + out_uint8p(c->out_s, reason, rlen); + + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, rlen + 14)) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + return SCP_SERVER_STATE_END; +} + +enum SCP_SERVER_STATES_E +scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, char *reason) +{ + tui8 sz; + tui32 version; + tui32 size; + tui16 cmdset; + tui16 cmd; + int rlen; + char buf[257]; + + init_stream(c->in_s, c->in_s->size); + init_stream(c->out_s, c->out_s->size); + + /* forcing message not to exceed 64k */ + rlen = g_strlen(reason); + + if (rlen > 65535) + { + rlen = 65535; + } + + /* send password request */ + version = 1; + cmd = 3; + + out_uint32_be(c->out_s, version); /* version */ + out_uint32_be(c->out_s, 14 + rlen); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ + out_uint16_be(c->out_s, cmd); /* cmd */ + + out_uint16_be(c->out_s, rlen); + out_uint8p(c->out_s, reason, rlen); + + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 14 + rlen)) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + /* receive password & username */ + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + in_uint32_be(c->in_s, version); + + if (version != 1) { - in_uint32_be(c->in_s, version); - if (version != 1) - { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; - } } - else - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - } - in_uint32_be(c->in_s, size); - if (size < 12) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); - return SCP_SERVER_STATE_SIZE_ERR; - } - - init_stream(c->in_s, c->in_s->size); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8))) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - - /* reading command set */ - in_uint16_be(c->in_s, cmdset); - - /* if we are starting a management session */ - if (cmdset == SCP_COMMAND_SET_MANAGE) - { - log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__); - /* should return SCP_SERVER_STATE_START_MANAGE */ - return scp_v1s_mng_accept(c, s); - } - - /* if we started with resource sharing... */ - if (cmdset == SCP_COMMAND_SET_RSR) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - /* reading command */ - in_uint16_be(c->in_s, cmd); - if (cmd != 1) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - session = scp_session_create(); - if (0 == session) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - scp_session_set_version(session, 1); - - in_uint8(c->in_s, sz); - if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__); - return SCP_SERVER_STATE_SESSION_TYPE_ERR; - } - scp_session_set_type(session, sz); - - in_uint16_be(c->in_s, cmd); - scp_session_set_height(session, cmd); - in_uint16_be(c->in_s, cmd); - scp_session_set_height(session, cmd); - in_uint8(c->in_s, sz); - scp_session_set_bpp(session, sz); - in_uint8(c->in_s, sz); - scp_session_set_rsr(session, sz); - in_uint8a(c->in_s, buf, 17); - buf[17]='\0'; - scp_session_set_locale(session, buf); - - in_uint8(c->in_s, sz); - if (sz == SCP_ADDRESS_TYPE_IPV4) - { in_uint32_be(c->in_s, size); - scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &size); - } - else if (sz == SCP_ADDRESS_TYPE_IPV6) - { - in_uint8a(c->in_s, buf, 16); - scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); - } - buf[256] = '\0'; - /* reading hostname */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_hostname(session, buf)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } + if (size < 12) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } - /* reading username */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_username(session, buf)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } + init_stream(c->in_s, c->in_s->size); - /* reading password */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_password(session, buf)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } - /* returning the struct */ - (*s)=session; + in_uint16_be(c->in_s, cmdset); - return SCP_SERVER_STATE_OK; -} + if (cmdset != SCP_COMMAND_SET_DEFAULT) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } -enum SCP_SERVER_STATES_E -scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason) -{ - int rlen; + in_uint16_be(c->in_s, cmd); - init_stream(c->out_s,c->out_s->size); + if (cmd != 4) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } - /* forcing message not to exceed 64k */ - rlen = g_strlen(reason); - if (rlen > 65535) - { - rlen = 65535; - } + buf[256] = '\0'; + /* reading username */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); - out_uint32_be(c->out_s, 1); - /* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason)*/ - /* version + size + cmdset + cmd + msglen + msg */ - out_uint32_be(c->out_s, rlen+14); - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); - out_uint16_be(c->out_s, 2); - out_uint16_be(c->out_s, rlen); - out_uint8p(c->out_s, reason, rlen); + if (0 != scp_session_set_username(s, buf)) + { + scp_session_destroy(s); + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } - if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, rlen+14)) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } + /* reading password */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); - return SCP_SERVER_STATE_END; -} + if (0 != scp_session_set_password(s, buf)) + { + scp_session_destroy(s); + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } -enum SCP_SERVER_STATES_E -scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason) -{ - tui8 sz; - tui32 version; - tui32 size; - tui16 cmdset; - tui16 cmd; - int rlen; - char buf[257]; - - init_stream(c->in_s, c->in_s->size); - init_stream(c->out_s, c->out_s->size); - - /* forcing message not to exceed 64k */ - rlen = g_strlen(reason); - if (rlen > 65535) - { - rlen = 65535; - } - - /* send password request */ - version=1; - cmd=3; - - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, 14+rlen); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ - - out_uint16_be(c->out_s, rlen); - out_uint8p(c->out_s, reason, rlen); - - if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14+rlen)) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - - /* receive password & username */ - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - - in_uint32_be(c->in_s, version); - if (version!=1) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); - return SCP_SERVER_STATE_VERSION_ERR; - } - - in_uint32_be(c->in_s, size); - if (size<12) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); - return SCP_SERVER_STATE_SIZE_ERR; - } - - init_stream(c->in_s, c->in_s->size); - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8))) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - - in_uint16_be(c->in_s, cmdset); - if (cmdset != SCP_COMMAND_SET_DEFAULT) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd != 4) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - buf[256] = '\0'; - /* reading username */ - in_uint8(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_username(s, buf)) - { - scp_session_destroy(s); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading password */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_password(s, buf)) - { - scp_session_destroy(s); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - return SCP_SERVER_STATE_OK; + return SCP_SERVER_STATE_OK; } /* 020 */ enum SCP_SERVER_STATES_E -scp_v1s_request_pwd_change(struct SCP_CONNECTION* c, char* reason, char* npw) +scp_v1s_request_pwd_change(struct SCP_CONNECTION *c, char *reason, char *npw) { - return SCP_SERVER_STATE_INTERNAL_ERR; + return SCP_SERVER_STATE_INTERNAL_ERR; } /* 023 */ enum SCP_SERVER_STATES_E -scp_v1s_pwd_change_error(struct SCP_CONNECTION* c, char* error, int retry, char* npw) +scp_v1s_pwd_change_error(struct SCP_CONNECTION *c, char *error, int retry, char *npw) { - return SCP_SERVER_STATE_INTERNAL_ERR; + return SCP_SERVER_STATE_INTERNAL_ERR; } /* 030 */ enum SCP_SERVER_STATES_E -scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d) +scp_v1s_connect_new_session(struct SCP_CONNECTION *c, SCP_DISPLAY d) { - /* send password request */ - tui32 version=1; - tui32 size=14; - tui16 cmd=30; + /* send password request */ + tui32 version = 1; + tui32 size = 14; + tui16 cmd = 30; - init_stream(c->out_s, c->out_s->size); + init_stream(c->out_s, c->out_s->size); - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, size); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ + out_uint32_be(c->out_s, version); /* version */ + out_uint32_be(c->out_s, size); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ + out_uint16_be(c->out_s, cmd); /* cmd */ - out_uint16_be(c->out_s, d); /* display */ + out_uint16_be(c->out_s, d); /* display */ - if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14)) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 14)) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } - return SCP_SERVER_STATE_OK; + return SCP_SERVER_STATE_OK; } /* 032 */ enum SCP_SERVER_STATES_E -scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error) +scp_v1s_connection_error(struct SCP_CONNECTION *c, char *error) { - tui16 len; + tui16 len; - len = g_strlen(error); - init_stream(c->out_s,c->out_s->size); + len = g_strlen(error); + init_stream(c->out_s, c->out_s->size); - out_uint32_be(c->out_s, 1); - /* packet size: 4 + 4 + 2 + 2 + len */ - /* version + size + cmdset + cmd */ - out_uint32_be(c->out_s, (12 + len)); - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); - out_uint16_be(c->out_s, SCP_CMD_CONN_ERROR); + out_uint32_be(c->out_s, 1); + /* packet size: 4 + 4 + 2 + 2 + len */ + /* version + size + cmdset + cmd */ + out_uint32_be(c->out_s, (12 + len)); + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); + out_uint16_be(c->out_s, SCP_CMD_CONN_ERROR); - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, (12 + len))) - { - return SCP_SERVER_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, (12 + len))) + { + return SCP_SERVER_STATE_NETWORK_ERR; + } - return SCP_SERVER_STATE_END; + return SCP_SERVER_STATE_END; } /* 040 */ enum SCP_SERVER_STATES_E -scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNECTED_SESSION* ds, SCP_SID* sid) +scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNECTED_SESSION *ds, SCP_SID *sid) { - tui32 version=1; - tui32 size=12; - tui16 cmd=40; - int pktcnt; - int idx; - int sidx; - int pidx; - struct SCP_DISCONNECTED_SESSION* cds; + tui32 version = 1; + tui32 size = 12; + tui16 cmd = 40; + int pktcnt; + int idx; + int sidx; + int pidx; + struct SCP_DISCONNECTED_SESSION *cds; - /* first we send a notice that we have some disconnected sessions */ - init_stream(c->out_s, c->out_s->size); - - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, size); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ - - if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - - /* then we wait for client ack */ -#warning maybe this message could say if the session should be resized on -#warning server side or client side - init_stream(c->in_s, c->in_s->size); - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - - in_uint32_be(c->in_s, version); - if (version!=1) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); - return SCP_SERVER_STATE_VERSION_ERR; - } - - in_uint32_be(c->in_s, size); - if (size<12) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); - return SCP_SERVER_STATE_SIZE_ERR; - } - - init_stream(c->in_s, c->in_s->size); - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8))) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_DEFAULT) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd != 41) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - /* calculating the number of packets to send */ - pktcnt=sescnt/SCP_SERVER_MAX_LIST_SIZE; - if ((sescnt%SCP_SERVER_MAX_LIST_SIZE)!=0) - { - pktcnt++; - } - - for (idx=0; idxout_s, c->out_s->size); - /* size: ver+size+cmdset+cmd+sescnt+continue+count */ - size=4+4+2+2+4+1+1; - - /* header */ - cmd=42; - s_push_layer(c->out_s, channel_hdr, 8); - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); - out_uint16_be(c->out_s, cmd); - - /* session count */ - out_uint32_be(c->out_s, sescnt); - - /* setting the continue flag */ - if ((idx+1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt) - { - out_uint8(c->out_s, 0); - /* setting session count for this packet */ - pidx=sescnt-(idx*SCP_SERVER_MAX_LIST_SIZE); - out_uint8(c->out_s, pidx); - } - else - { - out_uint8(c->out_s, 1); - /* setting session count for this packet */ - pidx=SCP_SERVER_MAX_LIST_SIZE; - out_uint8(c->out_s, pidx); - } - - /* adding session descriptors */ - for (sidx=0; sidxout_s, cds->SID); /* session id */ - out_uint8(c->out_s, cds->type); - out_uint16_be(c->out_s, cds->height); - out_uint16_be(c->out_s, cds->width); - out_uint8(c->out_s, cds->bpp); - out_uint8(c->out_s, cds->idle_days); - out_uint8(c->out_s, cds->idle_hours); - out_uint8(c->out_s, cds->idle_minutes); - size += 13; - - out_uint16_be(c->out_s, cds->conn_year); - out_uint8(c->out_s, cds->conn_month); - out_uint8(c->out_s, cds->conn_day); - out_uint8(c->out_s, cds->conn_hour); - out_uint8(c->out_s, cds->conn_minute); - out_uint8(c->out_s, cds->addr_type); - size += 7; - - if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4) - { - in_uint32_be(c->out_s, cds->ipv4addr); - size += 4; - } - else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6) - { - in_uint8a(c->out_s, cds->ipv6addr, 16); - size += 16; - } - } - - s_pop_layer(c->out_s, channel_hdr); - out_uint32_be(c->out_s, version); - out_uint32_be(c->out_s, size); + out_uint32_be(c->out_s, version); /* version */ + out_uint32_be(c->out_s, size); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ + out_uint16_be(c->out_s, cmd); /* cmd */ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; } - } - /* we get the response */ - init_stream(c->in_s, c->in_s->size); - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (8))) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } + /* then we wait for client ack */ +#warning maybe this message could say if the session should be resized on +#warning server side or client side + init_stream(c->in_s, c->in_s->size); - in_uint32_be(c->in_s, version); - if (version != 1) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); - return SCP_SERVER_STATE_VERSION_ERR; - } - - in_uint32_be(c->in_s, size); - if (size < 12) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); - return SCP_SERVER_STATE_SIZE_ERR; - } - - /* rest of the packet */ - init_stream(c->in_s, c->in_s->size); - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8))) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_DEFAULT) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd == 43) - { - /* select session */ - in_uint32_be(c->in_s, (*sid)); - - /* checking sid value */ - for (idx=0; idxin_sck, c->in_s->data, 8)) { - /* the sid is valid */ - if (ds[idx].SID==(*sid)) - { - /* ok, session selected */ - return SCP_SERVER_STATE_OK; - } + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; } - /* if we got here, the requested sid wasn't one from the list we sent */ - /* we should kill the connection */ - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__); - return SCP_CLIENT_STATE_INTERNAL_ERR; - } - else if (cmd == 44) - { - /* cancel connection */ - return SCP_SERVER_STATE_SELECTION_CANCEL; - } -// else if (cmd == 45) -// { -// /* force new connection */ -// return SCP_SERVER_STATE_FORCE_NEW; -// } - else - { - /* wrong response */ - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } + in_uint32_be(c->in_s, version); - return SCP_SERVER_STATE_OK; + if (version != 1) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_STATE_VERSION_ERR; + } + + in_uint32_be(c->in_s, size); + + if (size < 12) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } + + init_stream(c->in_s, c->in_s->size); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != SCP_COMMAND_SET_DEFAULT) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != 41) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + /* calculating the number of packets to send */ + pktcnt = sescnt / SCP_SERVER_MAX_LIST_SIZE; + + if ((sescnt % SCP_SERVER_MAX_LIST_SIZE) != 0) + { + pktcnt++; + } + + for (idx = 0; idx < pktcnt; idx++) + { + /* ok, we send session session list */ + init_stream(c->out_s, c->out_s->size); + + /* size: ver+size+cmdset+cmd+sescnt+continue+count */ + size = 4 + 4 + 2 + 2 + 4 + 1 + 1; + + /* header */ + cmd = 42; + s_push_layer(c->out_s, channel_hdr, 8); + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); + out_uint16_be(c->out_s, cmd); + + /* session count */ + out_uint32_be(c->out_s, sescnt); + + /* setting the continue flag */ + if ((idx + 1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt) + { + out_uint8(c->out_s, 0); + /* setting session count for this packet */ + pidx = sescnt - (idx * SCP_SERVER_MAX_LIST_SIZE); + out_uint8(c->out_s, pidx); + } + else + { + out_uint8(c->out_s, 1); + /* setting session count for this packet */ + pidx = SCP_SERVER_MAX_LIST_SIZE; + out_uint8(c->out_s, pidx); + } + + /* adding session descriptors */ + for (sidx = 0; sidx < pidx; sidx++) + { + /* shortcut to the current session to send */ + cds = ds + ((idx) * SCP_SERVER_MAX_LIST_SIZE) + sidx; + + /* session data */ + out_uint32_be(c->out_s, cds->SID); /* session id */ + out_uint8(c->out_s, cds->type); + out_uint16_be(c->out_s, cds->height); + out_uint16_be(c->out_s, cds->width); + out_uint8(c->out_s, cds->bpp); + out_uint8(c->out_s, cds->idle_days); + out_uint8(c->out_s, cds->idle_hours); + out_uint8(c->out_s, cds->idle_minutes); + size += 13; + + out_uint16_be(c->out_s, cds->conn_year); + out_uint8(c->out_s, cds->conn_month); + out_uint8(c->out_s, cds->conn_day); + out_uint8(c->out_s, cds->conn_hour); + out_uint8(c->out_s, cds->conn_minute); + out_uint8(c->out_s, cds->addr_type); + size += 7; + + if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->out_s, cds->ipv4addr); + size += 4; + } + else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->out_s, cds->ipv6addr, 16); + size += 16; + } + } + + s_pop_layer(c->out_s, channel_hdr); + out_uint32_be(c->out_s, version); + out_uint32_be(c->out_s, size); + + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + } + + /* we get the response */ + init_stream(c->in_s, c->in_s->size); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (8))) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + in_uint32_be(c->in_s, version); + + if (version != 1) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_STATE_VERSION_ERR; + } + + in_uint32_be(c->in_s, size); + + if (size < 12) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } + + /* rest of the packet */ + init_stream(c->in_s, c->in_s->size); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != SCP_COMMAND_SET_DEFAULT) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd == 43) + { + /* select session */ + in_uint32_be(c->in_s, (*sid)); + + /* checking sid value */ + for (idx = 0; idx < sescnt; idx++) + { + /* the sid is valid */ + if (ds[idx].SID == (*sid)) + { + /* ok, session selected */ + return SCP_SERVER_STATE_OK; + } + } + + /* if we got here, the requested sid wasn't one from the list we sent */ + /* we should kill the connection */ + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__); + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + else if (cmd == 44) + { + /* cancel connection */ + return SCP_SERVER_STATE_SELECTION_CANCEL; + } + // else if (cmd == 45) + // { + // /* force new connection */ + // return SCP_SERVER_STATE_FORCE_NEW; + // } + else + { + /* wrong response */ + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + return SCP_SERVER_STATE_OK; } /* 046 was: 031 struct SCP_DISCONNECTED_SESSION* ds, */ enum SCP_SERVER_STATES_E -scp_v1s_reconnect_session(struct SCP_CONNECTION* c, SCP_DISPLAY d) +scp_v1s_reconnect_session(struct SCP_CONNECTION *c, SCP_DISPLAY d) { - tui32 version = 1; - tui32 size = 14; - tui16 cmd = 46; + tui32 version = 1; + tui32 size = 14; + tui16 cmd = 46; - /* ok, we send session data and display */ - init_stream(c->out_s, c->out_s->size); + /* ok, we send session data and display */ + init_stream(c->out_s, c->out_s->size); - /* header */ - out_uint32_be(c->out_s, version); - out_uint32_be(c->out_s, size); - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); - out_uint16_be(c->out_s, cmd); + /* header */ + out_uint32_be(c->out_s, version); + out_uint32_be(c->out_s, size); + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); + out_uint16_be(c->out_s, cmd); - /* session data */ - out_uint16_be(c->out_s, d); /* session display */ - /*out_uint8(c->out_s, ds->type); - out_uint16_be(c->out_s, ds->height); - out_uint16_be(c->out_s, ds->width); - out_uint8(c->out_s, ds->bpp); - out_uint8(c->out_s, ds->idle_days); - out_uint8(c->out_s, ds->idle_hours); - out_uint8(c->out_s, ds->idle_minutes);*/ - /* these last three are not really needed... */ + /* session data */ + out_uint16_be(c->out_s, d); /* session display */ + /*out_uint8(c->out_s, ds->type); + out_uint16_be(c->out_s, ds->height); + out_uint16_be(c->out_s, ds->width); + out_uint8(c->out_s, ds->bpp); + out_uint8(c->out_s, ds->idle_days); + out_uint8(c->out_s, ds->idle_hours); + out_uint8(c->out_s, ds->idle_minutes);*/ + /* these last three are not really needed... */ - if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } - return SCP_SERVER_STATE_OK; + return SCP_SERVER_STATE_OK; } #endif diff --git a/sesman/libscp/libscp_v1s.h b/sesman/libscp/libscp_v1s.h index 32de0bba..5e3ec980 100644 --- a/sesman/libscp/libscp_v1s.h +++ b/sesman/libscp/libscp_v1s.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c index 599545ab..24553429 100644 --- a/sesman/libscp/libscp_v1s_mng.c +++ b/sesman/libscp/libscp_v1s_mng.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,309 +32,323 @@ //extern struct log_config* s_log; static enum SCP_SERVER_STATES_E -_scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s); +_scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s); /* server API */ enum SCP_SERVER_STATES_E -scp_v1s_mng_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s) +scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) { - struct SCP_SESSION* session; - tui32 ipaddr; - tui16 cmd; - tui8 sz; - char buf[257]; + struct SCP_SESSION *session; + tui32 ipaddr; + tui16 cmd; + tui8 sz; + char buf[257]; - /* reading command */ - in_uint16_be(c->in_s, cmd); - if (cmd != 1) /* manager login */ - { - return SCP_SERVER_STATE_SEQUENCE_ERR; - } + /* reading command */ + in_uint16_be(c->in_s, cmd); - session = scp_session_create(); - if (0 == session) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } + if (cmd != 1) /* manager login */ + { + return SCP_SERVER_STATE_SEQUENCE_ERR; + } - scp_session_set_version(session, 1); - scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); + session = scp_session_create(); - /* reading username */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_username(session, buf)) - { - scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } + if (0 == session) + { + return SCP_SERVER_STATE_INTERNAL_ERR; + } - /* reading password */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_password(session, buf)) - { - scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } + scp_session_set_version(session, 1); + scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); - /* reading remote address */ - in_uint8(c->in_s, sz); - if (sz == SCP_ADDRESS_TYPE_IPV4) - { - in_uint32_be(c->in_s, ipaddr); - scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &ipaddr); - } - else if (sz == SCP_ADDRESS_TYPE_IPV6) - { - in_uint8a(c->in_s, buf, 16); - scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); - } + /* reading username */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); - /* reading hostname */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_hostname(session, buf)) - { - scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } + if (0 != scp_session_set_username(session, buf)) + { + scp_session_destroy(session); + return SCP_SERVER_STATE_INTERNAL_ERR; + } - /* returning the struct */ - (*s)=session; + /* reading password */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); - return SCP_SERVER_STATE_START_MANAGE; + if (0 != scp_session_set_password(session, buf)) + { + scp_session_destroy(session); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading remote address */ + in_uint8(c->in_s, sz); + + if (sz == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->in_s, ipaddr); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &ipaddr); + } + else if (sz == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->in_s, buf, 16); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); + } + + /* reading hostname */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); + + if (0 != scp_session_set_hostname(session, buf)) + { + scp_session_destroy(session); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* returning the struct */ + (*s) = session; + + return SCP_SERVER_STATE_START_MANAGE; } /* 002 */ enum SCP_SERVER_STATES_E -scp_v1s_mng_allow_connection(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - init_stream(c->out_s,c->out_s->size); + init_stream(c->out_s, c->out_s->size); - out_uint32_be(c->out_s, 1); - /* packet size: 4 + 4 + 2 + 2 */ - /* version + size + cmdset + cmd */ - out_uint32_be(c->out_s, 12); - out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); - out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN_ALLOW); + out_uint32_be(c->out_s, 1); + /* packet size: 4 + 4 + 2 + 2 */ + /* version + size + cmdset + cmd */ + out_uint32_be(c->out_s, 12); + out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); + out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN_ALLOW); - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 12)) - { - return SCP_SERVER_STATE_NETWORK_ERR; - } + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 12)) + { + return SCP_SERVER_STATE_NETWORK_ERR; + } - return _scp_v1s_mng_check_response(c, s); + return _scp_v1s_mng_check_response(c, s); } /* 003 */ enum SCP_SERVER_STATES_E -scp_v1s_mng_deny_connection(struct SCP_CONNECTION* c, char* reason) +scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, char *reason) { - int rlen; + int rlen; - init_stream(c->out_s,c->out_s->size); + init_stream(c->out_s, c->out_s->size); - /* forcing message not to exceed 64k */ - rlen = g_strlen(reason); - if (rlen > 65535) - { - rlen = 65535; - } + /* forcing message not to exceed 64k */ + rlen = g_strlen(reason); - out_uint32_be(c->out_s, 1); - /* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason)*/ - /* version + size + cmdset + cmd + msglen + msg */ - out_uint32_be(c->out_s, rlen+14); - out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); - out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN_DENY); - out_uint16_be(c->out_s, rlen); - out_uint8p(c->out_s, reason, rlen); + if (rlen > 65535) + { + rlen = 65535; + } - if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, rlen+14)) - { - return SCP_SERVER_STATE_NETWORK_ERR; - } + out_uint32_be(c->out_s, 1); + /* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason)*/ + /* version + size + cmdset + cmd + msglen + msg */ + out_uint32_be(c->out_s, rlen + 14); + out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); + out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN_DENY); + out_uint16_be(c->out_s, rlen); + out_uint8p(c->out_s, reason, rlen); - return SCP_SERVER_STATE_END; + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, rlen + 14)) + { + return SCP_SERVER_STATE_NETWORK_ERR; + } + + return SCP_SERVER_STATE_END; } /* 006 */ enum SCP_SERVER_STATES_E -scp_v1s_mng_list_sessions(struct SCP_CONNECTION* c, struct SCP_SESSION* s, - int sescnt, struct SCP_DISCONNECTED_SESSION* ds) +scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s, + int sescnt, struct SCP_DISCONNECTED_SESSION *ds) { - tui32 version = 1; - tui32 size = 12; - tui16 cmd = SCP_CMD_MNG_LIST; - int pktcnt; - int idx; - int sidx; - int pidx; - struct SCP_DISCONNECTED_SESSION* cds; + tui32 version = 1; + tui32 size = 12; + tui16 cmd = SCP_CMD_MNG_LIST; + int pktcnt; + int idx; + int sidx; + int pidx; + struct SCP_DISCONNECTED_SESSION *cds; - /* calculating the number of packets to send */ - pktcnt=sescnt/SCP_SERVER_MAX_LIST_SIZE; - if ((sescnt%SCP_SERVER_MAX_LIST_SIZE)!=0) - { - pktcnt++; - } + /* calculating the number of packets to send */ + pktcnt = sescnt / SCP_SERVER_MAX_LIST_SIZE; - for (idx=0; idxout_s, c->out_s->size); - - /* size: ver+size+cmdset+cmd+sescnt+continue+count */ - size=4+4+2+2+4+1+1; - - /* header */ - s_push_layer(c->out_s, channel_hdr, 8); - out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); - out_uint16_be(c->out_s, cmd); - - /* session count */ - out_uint32_be(c->out_s, sescnt); - - /* setting the continue flag */ - if ((idx+1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt) + if ((sescnt % SCP_SERVER_MAX_LIST_SIZE) != 0) { - out_uint8(c->out_s, 0); - /* setting session count for this packet */ - pidx=sescnt-(idx*SCP_SERVER_MAX_LIST_SIZE); - out_uint8(c->out_s, pidx); - } - else - { - out_uint8(c->out_s, 1); - /* setting session count for this packet */ - pidx=SCP_SERVER_MAX_LIST_SIZE; - out_uint8(c->out_s, pidx); + pktcnt++; } - /* adding session descriptors */ - for (sidx=0; sidxout_s, c->out_s->size); - /* session data */ - out_uint32_be(c->out_s, cds->SID); /* session id */ - out_uint8(c->out_s, cds->type); - out_uint16_be(c->out_s, cds->height); - out_uint16_be(c->out_s, cds->width); - out_uint8(c->out_s, cds->bpp); - out_uint8(c->out_s, cds->idle_days); - out_uint8(c->out_s, cds->idle_hours); - out_uint8(c->out_s, cds->idle_minutes); - size += 13; + /* size: ver+size+cmdset+cmd+sescnt+continue+count */ + size = 4 + 4 + 2 + 2 + 4 + 1 + 1; - out_uint16_be(c->out_s, cds->conn_year); - out_uint8(c->out_s, cds->conn_month); - out_uint8(c->out_s, cds->conn_day); - out_uint8(c->out_s, cds->conn_hour); - out_uint8(c->out_s, cds->conn_minute); - out_uint8(c->out_s, cds->addr_type); - size += 7; + /* header */ + s_push_layer(c->out_s, channel_hdr, 8); + out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); + out_uint16_be(c->out_s, cmd); - if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4) - { - in_uint32_be(c->out_s, cds->ipv4addr); - size += 4; - } - else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6) - { - in_uint8a(c->out_s, cds->ipv6addr, 16); - size += 16; - } + /* session count */ + out_uint32_be(c->out_s, sescnt); + + /* setting the continue flag */ + if ((idx + 1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt) + { + out_uint8(c->out_s, 0); + /* setting session count for this packet */ + pidx = sescnt - (idx * SCP_SERVER_MAX_LIST_SIZE); + out_uint8(c->out_s, pidx); + } + else + { + out_uint8(c->out_s, 1); + /* setting session count for this packet */ + pidx = SCP_SERVER_MAX_LIST_SIZE; + out_uint8(c->out_s, pidx); + } + + /* adding session descriptors */ + for (sidx = 0; sidx < pidx; sidx++) + { + /* shortcut to the current session to send */ + cds = ds + ((idx) * SCP_SERVER_MAX_LIST_SIZE) + sidx; + + /* session data */ + out_uint32_be(c->out_s, cds->SID); /* session id */ + out_uint8(c->out_s, cds->type); + out_uint16_be(c->out_s, cds->height); + out_uint16_be(c->out_s, cds->width); + out_uint8(c->out_s, cds->bpp); + out_uint8(c->out_s, cds->idle_days); + out_uint8(c->out_s, cds->idle_hours); + out_uint8(c->out_s, cds->idle_minutes); + size += 13; + + out_uint16_be(c->out_s, cds->conn_year); + out_uint8(c->out_s, cds->conn_month); + out_uint8(c->out_s, cds->conn_day); + out_uint8(c->out_s, cds->conn_hour); + out_uint8(c->out_s, cds->conn_minute); + out_uint8(c->out_s, cds->addr_type); + size += 7; + + if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->out_s, cds->ipv4addr); + size += 4; + } + else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->out_s, cds->ipv6addr, 16); + size += 16; + } + } + + s_pop_layer(c->out_s, channel_hdr); + out_uint32_be(c->out_s, version); + out_uint32_be(c->out_s, size); + + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } } - s_pop_layer(c->out_s, channel_hdr); - out_uint32_be(c->out_s, version); - out_uint32_be(c->out_s, size); - - if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - } - - return _scp_v1s_mng_check_response(c, s); + return _scp_v1s_mng_check_response(c, s); } static enum SCP_SERVER_STATES_E -_scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +_scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - tui32 version; - tui32 size; - tui16 cmd; -// tui8 dim; -// char buf[257]; + tui32 version; + tui32 size; + tui16 cmd; + // tui8 dim; + // char buf[257]; - init_stream(c->in_s, c->in_s->size); - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } + init_stream(c->in_s, c->in_s->size); - in_uint32_be(c->in_s, version); - if (version != 1) - { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__); - return SCP_SERVER_STATE_VERSION_ERR; - } + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } - in_uint32_be(c->in_s, size); + in_uint32_be(c->in_s, version); - init_stream(c->in_s, c->in_s->size); - /* read the rest of the packet */ - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } + if (version != 1) + { + log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_STATE_VERSION_ERR; + } + + in_uint32_be(c->in_s, size); + + init_stream(c->in_s, c->in_s->size); + + /* read the rest of the packet */ + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) + { + log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd != SCP_COMMAND_SET_MANAGE) + { + log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + in_uint16_be(c->in_s, cmd); + + if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */ + { + log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__); + return SCP_SERVER_STATE_MNG_LISTREQ; + } + else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */ + { + /*in_uint8(c->in_s, dim); + buf[dim]='\0'; + in_uint8a(c->in_s, buf, dim); + scp_session_set_errstr(s, buf);*/ + + log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__); + return SCP_SERVER_STATE_MNG_ACTION; + } + + /* else if (cmd == 20) / * password change * / + { + in_uint16_be(c->in_s, s->display); + + return SCP_SERVER_STATE_OK; + } + else if (cmd == 40) / * session list * / + { + return SCP_SERVER_STATE_SESSION_LIST; + }*/ - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_MANAGE) - { log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */ - { - log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__); - return SCP_SERVER_STATE_MNG_LISTREQ; - } - else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */ - { - /*in_uint8(c->in_s, dim); - buf[dim]='\0'; - in_uint8a(c->in_s, buf, dim); - scp_session_set_errstr(s, buf);*/ - - log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__); - return SCP_SERVER_STATE_MNG_ACTION; - } - /* else if (cmd == 20) / * password change * / - { - in_uint16_be(c->in_s, s->display); - - return SCP_SERVER_STATE_OK; - } - else if (cmd == 40) / * session list * / - { - return SCP_SERVER_STATE_SESSION_LIST; - }*/ - - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; } #endif diff --git a/sesman/libscp/libscp_v1s_mng.h b/sesman/libscp/libscp_v1s_mng.h index ab296632..72df9fa6 100644 --- a/sesman/libscp/libscp_v1s_mng.h +++ b/sesman/libscp/libscp_v1s_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_vX.c b/sesman/libscp/libscp_vX.c index b121da2d..e590fe73 100644 --- a/sesman/libscp/libscp_vX.c +++ b/sesman/libscp/libscp_vX.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -28,26 +27,26 @@ #include "libscp_vX.h" /* server API */ -enum SCP_SERVER_STATES_E scp_vXs_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s) +enum SCP_SERVER_STATES_E scp_vXs_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) { - tui32 version; + tui32 version; - /* reading version and packet size */ - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - return SCP_SERVER_STATE_NETWORK_ERR; - } + /* reading version and packet size */ + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + return SCP_SERVER_STATE_NETWORK_ERR; + } - in_uint32_be(c->in_s, version); + in_uint32_be(c->in_s, version); - if (version == 0) - { - return scp_v0s_accept(c, s, 1); - } - else if (version == 1) - { - return scp_v1s_accept(c, s, 1); - } + if (version == 0) + { + return scp_v0s_accept(c, s, 1); + } + else if (version == 1) + { + return scp_v1s_accept(c, s, 1); + } - return SCP_SERVER_STATE_VERSION_ERR; + return SCP_SERVER_STATE_VERSION_ERR; } diff --git a/sesman/libscp/libscp_vX.h b/sesman/libscp/libscp_vX.h index c59bc1af..a68a9ede 100644 --- a/sesman/libscp/libscp_vX.h +++ b/sesman/libscp/libscp_vX.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file libscp_vX.h * @brief libscp version neutral code header * @author Simone Fedele - * + * */ #ifndef LIBSCP_VX_H diff --git a/sesman/lock.c b/sesman/lock.c index 83023cba..dd78ebbe 100644 --- a/sesman/lock.c +++ b/sesman/lock.c @@ -1,29 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - session manager - linux only - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * session manager + * linux only + */ #include "sesman.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ static tbus g_sync_mutex = 0; static tbus g_lock_chain = 0; @@ -34,90 +32,90 @@ static tbus g_lock_socket = 0; void APP_CC lock_init(void) { - g_sync_mutex = tc_mutex_create(); - g_lock_chain = tc_mutex_create(); - g_sync_sem = tc_sem_create(0); - g_lock_socket = tc_sem_create(1); + g_sync_mutex = tc_mutex_create(); + g_lock_chain = tc_mutex_create(); + g_sync_sem = tc_sem_create(0); + g_lock_socket = tc_sem_create(1); } /******************************************************************************/ void APP_CC lock_deinit(void) { - tc_mutex_delete(g_sync_mutex); - tc_mutex_delete(g_lock_chain); - tc_sem_delete(g_sync_sem); - tc_sem_delete(g_lock_socket); + tc_mutex_delete(g_sync_mutex); + tc_mutex_delete(g_lock_chain); + tc_sem_delete(g_sync_sem); + tc_sem_delete(g_lock_socket); } /******************************************************************************/ void APP_CC lock_chain_acquire(void) { - /* lock the chain */ - LOG_DBG("lock_chain_acquire()"); - tc_mutex_lock(g_lock_chain); + /* lock the chain */ + LOG_DBG("lock_chain_acquire()"); + tc_mutex_lock(g_lock_chain); } /******************************************************************************/ void APP_CC lock_chain_release(void) { - /* unlock the chain */ - LOG_DBG("lock_chain_release()"); - tc_mutex_unlock(g_lock_chain); + /* unlock the chain */ + LOG_DBG("lock_chain_release()"); + tc_mutex_unlock(g_lock_chain); } /******************************************************************************/ void APP_CC lock_socket_acquire(void) { - /* lock socket variable */ - LOG_DBG("lock_socket_acquire()"); - tc_sem_dec(g_lock_socket); + /* lock socket variable */ + LOG_DBG("lock_socket_acquire()"); + tc_sem_dec(g_lock_socket); } /******************************************************************************/ void APP_CC lock_socket_release(void) { - /* unlock socket variable */ - LOG_DBG("lock_socket_release()"); - tc_sem_inc(g_lock_socket); + /* unlock socket variable */ + LOG_DBG("lock_socket_release()"); + tc_sem_inc(g_lock_socket); } /******************************************************************************/ void APP_CC lock_sync_acquire(void) { - /* lock sync variable */ - LOG_DBG("lock_sync_acquire()"); - tc_mutex_lock(g_sync_mutex); + /* lock sync variable */ + LOG_DBG("lock_sync_acquire()"); + tc_mutex_lock(g_sync_mutex); } /******************************************************************************/ void APP_CC lock_sync_release(void) { - /* unlock socket variable */ - LOG_DBG("lock_sync_release()"); - tc_mutex_unlock(g_sync_mutex); + /* unlock socket variable */ + LOG_DBG("lock_sync_release()"); + tc_mutex_unlock(g_sync_mutex); } /******************************************************************************/ void APP_CC lock_sync_sem_acquire(void) { - /* dec sem */ - LOG_DBG("lock_sync_sem_acquire()"); - tc_sem_dec(g_sync_sem); + /* dec sem */ + LOG_DBG("lock_sync_sem_acquire()"); + tc_sem_dec(g_sync_sem); } /******************************************************************************/ void APP_CC lock_sync_sem_release(void) { - /* inc sem */ - LOG_DBG("lock_sync_sem_release()"); - tc_sem_inc(g_sync_sem); + /* inc sem */ + LOG_DBG("lock_sync_sem_release()"); + tc_sem_inc(g_sync_sem); } diff --git a/sesman/lock.h b/sesman/lock.h index 28c147f2..0b7c905f 100644 --- a/sesman/lock.h +++ b/sesman/lock.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef LOCK_H #define LOCK_H diff --git a/sesman/scp.c b/sesman/scp.c index bbe495ea..db97fda5 100644 --- a/sesman/scp.c +++ b/sesman/scp.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,72 +30,75 @@ #include "sesman.h" extern int g_thread_sck; /* in thread.c */ -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ -void* DEFAULT_CC -scp_process_start(void* sck) +void *DEFAULT_CC +scp_process_start(void *sck) { - struct SCP_CONNECTION scon; - struct SCP_SESSION* sdata; + struct SCP_CONNECTION scon; + struct SCP_SESSION *sdata; - /* making a local copy of the socket (it's on the stack) */ - /* probably this is just paranoia */ - scon.in_sck = g_thread_sck; - LOG_DBG("started scp thread on socket %d", scon.in_sck); + /* making a local copy of the socket (it's on the stack) */ + /* probably this is just paranoia */ + scon.in_sck = g_thread_sck; + LOG_DBG("started scp thread on socket %d", scon.in_sck); - /* unlocking g_thread_sck */ - lock_socket_release(); + /* unlocking g_thread_sck */ + lock_socket_release(); - make_stream(scon.in_s); - make_stream(scon.out_s); + make_stream(scon.in_s); + make_stream(scon.out_s); - init_stream(scon.in_s, 8192); - init_stream(scon.out_s, 8192); + init_stream(scon.in_s, 8192); + init_stream(scon.out_s, 8192); - switch (scp_vXs_accept(&scon, &(sdata))) - { - case SCP_SERVER_STATE_OK: - if (sdata->version == 0) - { - /* starts processing an scp v0 connection */ - LOG_DBG("accept ok, go on with scp v0\n",0); - scp_v0_process(&scon, sdata); - } - else - { - LOG_DBG("accept ok, go on with scp v1\n",0); - /*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/ - scp_v1_process(&scon, sdata); - } - break; - case SCP_SERVER_STATE_START_MANAGE: - /* starting a management session */ - log_message(LOG_LEVEL_WARNING, - "starting a sesman management session..."); - scp_v1_mng_process(&scon, sdata); - break; - case SCP_SERVER_STATE_VERSION_ERR: - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING, - "unknown protocol version specified. connection refused."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); - break; - case SCP_SERVER_STATE_SEQUENCE_ERR: - log_message(LOG_LEVEL_WARNING, "libscp sequence error."); - break; - case SCP_SERVER_STATE_INTERNAL_ERR: - /* internal error occurred (eg. malloc() error, ecc.) */ - log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); - break; - default: - log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()"); - } - g_tcp_close(scon.in_sck); - free_stream(scon.in_s); - free_stream(scon.out_s); - return 0; + switch (scp_vXs_accept(&scon, &(sdata))) + { + case SCP_SERVER_STATE_OK: + + if (sdata->version == 0) + { + /* starts processing an scp v0 connection */ + LOG_DBG("accept ok, go on with scp v0\n", 0); + scp_v0_process(&scon, sdata); + } + else + { + LOG_DBG("accept ok, go on with scp v1\n", 0); + /*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/ + scp_v1_process(&scon, sdata); + } + + break; + case SCP_SERVER_STATE_START_MANAGE: + /* starting a management session */ + log_message(LOG_LEVEL_WARNING, + "starting a sesman management session..."); + scp_v1_mng_process(&scon, sdata); + break; + case SCP_SERVER_STATE_VERSION_ERR: + /* an unknown scp version was requested, so we shut down the */ + /* connection (and log the fact) */ + log_message(LOG_LEVEL_WARNING, + "unknown protocol version specified. connection refused."); + break; + case SCP_SERVER_STATE_NETWORK_ERR: + log_message(LOG_LEVEL_WARNING, "libscp network error."); + break; + case SCP_SERVER_STATE_SEQUENCE_ERR: + log_message(LOG_LEVEL_WARNING, "libscp sequence error."); + break; + case SCP_SERVER_STATE_INTERNAL_ERR: + /* internal error occurred (eg. malloc() error, ecc.) */ + log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + break; + default: + log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()"); + } + + g_tcp_close(scon.in_sck); + free_stream(scon.in_s); + free_stream(scon.out_s); + return 0; } diff --git a/sesman/scp.h b/sesman/scp.h index b3433f4e..c4f3de3a 100644 --- a/sesman/scp.h +++ b/sesman/scp.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index dac04ad3..da6ab919 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -27,121 +26,128 @@ #include "sesman.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ void DEFAULT_CC -scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - int display = 0; - tbus data; - struct session_item* s_item; + int display = 0; + tbus data; + struct session_item *s_item; - data = auth_userpass(s->username, s->password); - if (s->type == SCP_GW_AUTHENTICATION) - { - /* this is just authentication in a gateway situation */ - /* g_writeln("SCP_GW_AUTHENTICATION message received"); */ - if (data) + data = auth_userpass(s->username, s->password); + + if (s->type == SCP_GW_AUTHENTICATION) { - if (1 == access_login_allowed(s->username)) - { - /* the user is member of the correct groups. */ - scp_v0s_replyauthentication(c, 0); - log_message(LOG_LEVEL_INFO, "Access permitted for user: %s", - s->username); - /* g_writeln("Connection allowed"); */ - } - else - { - scp_v0s_replyauthentication(c,3); - log_message(LOG_LEVEL_INFO, "Username okey but group problem for " - "user: %s", s->username); - /* g_writeln("user password ok, but group problem"); */ - } - } - else - { - /* g_writeln("username or password error"); */ - log_message(LOG_LEVEL_INFO, "Username or password error for user: %s", - s->username); - scp_v0s_replyauthentication(c, 2); - } - auth_end(data); - } - else if (data) - { - s_item = session_get_bydata(s->username, s->width, s->height, - s->bpp, s->type); - if (s_item != 0) - { - display = s_item->display; - if (0 != s->client_ip) - { - log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, " - "display :%d.0, session_pid %d, ip %s", - s->username, display, s_item->pid, s->client_ip); - } - else - { - log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, " - "display :%d.0, session_pid %d", s->username, display, - s_item->pid); - } - session_reconnect(display, s->username); - auth_end(data); - /* don't set data to null here */ - } - else - { - LOG_DBG("pre auth"); - if (1 == access_login_allowed(s->username)) - { - if (0 != s->client_ip) + /* this is just authentication in a gateway situation */ + /* g_writeln("SCP_GW_AUTHENTICATION message received"); */ + if (data) { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s, ip %s", s->username, s->client_ip); + if (1 == access_login_allowed(s->username)) + { + /* the user is member of the correct groups. */ + scp_v0s_replyauthentication(c, 0); + log_message(LOG_LEVEL_INFO, "Access permitted for user: %s", + s->username); + /* g_writeln("Connection allowed"); */ + } + else + { + scp_v0s_replyauthentication(c, 3); + log_message(LOG_LEVEL_INFO, "Username okey but group problem for " + "user: %s", s->username); + /* g_writeln("user password ok, but group problem"); */ + } } else { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s", s->username); + /* g_writeln("username or password error"); */ + log_message(LOG_LEVEL_INFO, "Username or password error for user: %s", + s->username); + scp_v0s_replyauthentication(c, 2); } - if (SCP_SESSION_TYPE_XVNC == s->type) + auth_end(data); + } + else if (data) + { + s_item = session_get_bydata(s->username, s->width, s->height, + s->bpp, s->type); + + if (s_item != 0) { - log_message( LOG_LEVEL_INFO, "starting Xvnc session..."); - display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XVNC, - s->domain, s->program, s->directory, - s->client_ip); + display = s_item->display; + + if (0 != s->client_ip) + { + log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, " + "display :%d.0, session_pid %d, ip %s", + s->username, display, s_item->pid, s->client_ip); + } + else + { + log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, " + "display :%d.0, session_pid %d", s->username, display, + s_item->pid); + } + + session_reconnect(display, s->username); + auth_end(data); + /* don't set data to null here */ } else { - log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); - display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XRDP, - s->domain, s->program, s->directory, - s->client_ip); + LOG_DBG("pre auth"); + + if (1 == access_login_allowed(s->username)) + { + if (0 != s->client_ip) + { + log_message(LOG_LEVEL_INFO, "++ created session (access granted): " + "username %s, ip %s", s->username, s->client_ip); + } + else + { + log_message(LOG_LEVEL_INFO, "++ created session (access granted): " + "username %s", s->username); + } + + if (SCP_SESSION_TYPE_XVNC == s->type) + { + log_message( LOG_LEVEL_INFO, "starting Xvnc session..."); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XVNC, + s->domain, s->program, s->directory, + s->client_ip); + } + else + { + log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XRDP, + s->domain, s->program, s->directory, + s->client_ip); + } + } + else + { + display = 0; + } + } + + if (display == 0) + { + auth_end(data); + scp_v0s_deny_connection(c); + } + else + { + scp_v0s_allow_connection(c, display); } - } - else - { - display = 0; - } - } - if (display == 0) - { - auth_end(data); - scp_v0s_deny_connection(c); } else { - scp_v0s_allow_connection(c, display); + scp_v0s_deny_connection(c); } - } - else - { - scp_v0s_deny_connection(c); - } } diff --git a/sesman/scp_v0.h b/sesman/scp_v0.h index 64d2475a..e5c2f576 100644 --- a/sesman/scp_v0.h +++ b/sesman/scp_v0.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file scp_v0.h * @brief scp version 0 declarations * @author Simone Fedele - * + * */ #ifndef SCP_V0_H @@ -38,7 +37,7 @@ * @param out_s output stream * */ -void DEFAULT_CC +void DEFAULT_CC scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s); #endif diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index f93f89ee..295fbce4 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -30,203 +29,213 @@ //#include "libscp_types.h" #include "libscp.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ -static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f); +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f); /******************************************************************************/ void DEFAULT_CC -scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - long data; - int display; - int retries; - int current_try; - enum SCP_SERVER_STATES_E e; - struct SCP_DISCONNECTED_SESSION* slist; - struct session_item* sitem; - int scount; - SCP_SID sid; + long data; + int display; + int retries; + int current_try; + enum SCP_SERVER_STATES_E e; + struct SCP_DISCONNECTED_SESSION *slist; + struct session_item *sitem; + int scount; + SCP_SID sid; - retries = g_cfg->sec.login_retry; - current_try = retries; + retries = g_cfg->sec.login_retry; + current_try = retries; - data = auth_userpass(s->username, s->password); - /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ + data = auth_userpass(s->username, s->password); + /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ - while ((!data) && ((retries == 0) || (current_try > 0))) - { - LOG_DBG("data %d - retry %d - currenttry %d - expr %d", - data, retries, current_try, - ((!data) && ((retries == 0) || (current_try > 0)))); - - e = scp_v1s_request_password(c, s, "Wrong username and/or password"); - - switch (e) + while ((!data) && ((retries == 0) || (current_try > 0))) { - case SCP_SERVER_STATE_OK: - /* all ok, we got new username and password */ - data = auth_userpass(s->username, s->password); - /* one try less */ - if (current_try > 0) + LOG_DBG("data %d - retry %d - currenttry %d - expr %d", + data, retries, current_try, + ((!data) && ((retries == 0) || (current_try > 0)))); + + e = scp_v1s_request_password(c, s, "Wrong username and/or password"); + + switch (e) { - current_try--; + case SCP_SERVER_STATE_OK: + /* all ok, we got new username and password */ + data = auth_userpass(s->username, s->password); + + /* one try less */ + if (current_try > 0) + { + current_try--; + } + + break; + default: + /* we check the other errors */ + parseCommonStates(e, "scp_v1s_list_sessions()"); + scp_session_destroy(s); + return; + //break; } - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_list_sessions()"); + } + + if (!data) + { + scp_v1s_deny_connection(c, "Login failed"); + log_message( LOG_LEVEL_INFO, + "Login failed for user %s. Connection terminated", s->username); scp_session_destroy(s); return; - //break; - } - } - - if (!data) - { - scp_v1s_deny_connection(c, "Login failed"); - log_message( LOG_LEVEL_INFO, - "Login failed for user %s. Connection terminated", s->username); - scp_session_destroy(s); - return; - } - - /* testing if login is allowed*/ - if (0 == access_login_allowed(s->username)) - { - scp_v1s_deny_connection(c, "Access to Terminal Server not allowed."); - log_message(LOG_LEVEL_INFO, - "User %s not allowed on TS. Connection terminated", s->username); - scp_session_destroy(s); - return; - } - - //check if we need password change - - /* list disconnected sessions */ - slist = session_get_byuser(s->username, &scount, SESMAN_SESSION_STATUS_DISCONNECTED); - - if (scount == 0) - { - /* no disconnected sessions - start a new one */ - log_message(LOG_LEVEL_DEBUG,"No disconnected sessions for this user" - "- we create a new one"); - if (0 != s->client_ip) - { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip); - } - else - { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username); - } - if (SCP_SESSION_TYPE_XVNC == s->type) - { - log_message(LOG_LEVEL_INFO, "starting Xvnc session..."); - display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XVNC, - s->domain, s->program, s->directory, s->client_ip); - } - else - { - log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); - display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XRDP, - s->domain, s->program, s->directory, s->client_ip); } - e = scp_v1s_connect_new_session(c, display); - switch (e) + /* testing if login is allowed*/ + if (0 == access_login_allowed(s->username)) { - case SCP_SERVER_STATE_OK: - /* all ok, we got new username and password */ - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_connect_new_session()"); - break; + scp_v1s_deny_connection(c, "Access to Terminal Server not allowed."); + log_message(LOG_LEVEL_INFO, + "User %s not allowed on TS. Connection terminated", s->username); + scp_session_destroy(s); + return; } - } - else - { - /* one or more disconnected sessions - listing */ - e = scp_v1s_list_sessions(c, scount, slist, &sid); - switch (e) + //check if we need password change + + /* list disconnected sessions */ + slist = session_get_byuser(s->username, &scount, SESMAN_SESSION_STATUS_DISCONNECTED); + + if (scount == 0) { - /*case SCP_SERVER_STATE_FORCE_NEW:*/ - /* we should check for MaxSessions */ - case SCP_SERVER_STATE_SELECTION_CANCEL: - log_message( LOG_LEVEL_INFO, "Connection cancelled after session listing"); - break; - case SCP_SERVER_STATE_OK: - /* ok, reconnecting... */ - sitem=session_get_bypid(sid); - if (0 == sitem) + /* no disconnected sessions - start a new one */ + log_message(LOG_LEVEL_DEBUG, "No disconnected sessions for this user" + "- we create a new one"); + + if (0 != s->client_ip) { - e = scp_v1s_connection_error(c, "Internal error"); - log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain"); + log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip); } else { - display = sitem->display; - /*e=scp_v1s_reconnect_session(c, sitem, display);*/ - e=scp_v1s_reconnect_session(c, display); - if (0 != s->client_ip) - { - log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip); - } - else - { - log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid); - } - g_free(sitem); + log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username); + } + + if (SCP_SESSION_TYPE_XVNC == s->type) + { + log_message(LOG_LEVEL_INFO, "starting Xvnc session..."); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XVNC, + s->domain, s->program, s->directory, s->client_ip); + } + else + { + log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XRDP, + s->domain, s->program, s->directory, s->client_ip); + } + + e = scp_v1s_connect_new_session(c, display); + + switch (e) + { + case SCP_SERVER_STATE_OK: + /* all ok, we got new username and password */ + break; + default: + /* we check the other errors */ + parseCommonStates(e, "scp_v1s_connect_new_session()"); + break; } - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_list_sessions()"); - break; } - g_free(slist); - } + else + { + /* one or more disconnected sessions - listing */ + e = scp_v1s_list_sessions(c, scount, slist, &sid); - /* resource management */ - if ((e == SCP_SERVER_STATE_OK) && (s->rsr)) - { - /* here goes scp resource sharing code */ - } + switch (e) + { + /*case SCP_SERVER_STATE_FORCE_NEW:*/ + /* we should check for MaxSessions */ + case SCP_SERVER_STATE_SELECTION_CANCEL: + log_message( LOG_LEVEL_INFO, "Connection cancelled after session listing"); + break; + case SCP_SERVER_STATE_OK: + /* ok, reconnecting... */ + sitem = session_get_bypid(sid); - /* cleanup */ - scp_session_destroy(s); - auth_end(data); + if (0 == sitem) + { + e = scp_v1s_connection_error(c, "Internal error"); + log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain"); + } + else + { + display = sitem->display; + /*e=scp_v1s_reconnect_session(c, sitem, display);*/ + e = scp_v1s_reconnect_session(c, display); + + if (0 != s->client_ip) + { + log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip); + } + else + { + log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid); + } + + g_free(sitem); + } + + break; + default: + /* we check the other errors */ + parseCommonStates(e, "scp_v1s_list_sessions()"); + break; + } + + g_free(slist); + } + + /* resource management */ + if ((e == SCP_SERVER_STATE_OK) && (s->rsr)) + { + /* here goes scp resource sharing code */ + } + + /* cleanup */ + scp_session_destroy(s); + auth_end(data); } -static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f) +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f) { - switch (e) - { - case SCP_SERVER_STATE_VERSION_ERR: - LOG_DBG("version error") - case SCP_SERVER_STATE_SIZE_ERR: - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING, - "protocol violation. connection closed."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); - break; - case SCP_SERVER_STATE_SEQUENCE_ERR: - log_message(LOG_LEVEL_WARNING, "libscp sequence error."); - break; - case SCP_SERVER_STATE_INTERNAL_ERR: - /* internal error occurred (eg. malloc() error, ecc.) */ - log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); - break; - default: - /* dummy: scp_v1s_request_password won't generate any other */ - /* error other than the ones before */ - log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); - break; - } + switch (e) + { + case SCP_SERVER_STATE_VERSION_ERR: + LOG_DBG("version error") + case SCP_SERVER_STATE_SIZE_ERR: + /* an unknown scp version was requested, so we shut down the */ + /* connection (and log the fact) */ + log_message(LOG_LEVEL_WARNING, + "protocol violation. connection closed."); + break; + case SCP_SERVER_STATE_NETWORK_ERR: + log_message(LOG_LEVEL_WARNING, "libscp network error."); + break; + case SCP_SERVER_STATE_SEQUENCE_ERR: + log_message(LOG_LEVEL_WARNING, "libscp sequence error."); + break; + case SCP_SERVER_STATE_INTERNAL_ERR: + /* internal error occurred (eg. malloc() error, ecc.) */ + log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + break; + default: + /* dummy: scp_v1s_request_password won't generate any other */ + /* error other than the ones before */ + log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); + break; + } } diff --git a/sesman/scp_v1.h b/sesman/scp_v1.h index 648855f9..0d224129 100644 --- a/sesman/scp_v1.h +++ b/sesman/scp_v1.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file scp_v1.h * @brief scp version 1 declarations * @author Simone Fedele - * + * */ #ifndef SCP_V1_H @@ -36,7 +35,7 @@ * @param out_s output stream * */ -void DEFAULT_CC +void DEFAULT_CC scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s); #endif diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c index e4d97b77..0e20007d 100644 --- a/sesman/scp_v1_mng.c +++ b/sesman/scp_v1_mng.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -29,112 +28,113 @@ #include "libscp.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ -static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f); +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f); /******************************************************************************/ void DEFAULT_CC -scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - long data; - enum SCP_SERVER_STATES_E e; - struct SCP_DISCONNECTED_SESSION* slist = 0; - int scount; - int end = 0; + long data; + enum SCP_SERVER_STATES_E e; + struct SCP_DISCONNECTED_SESSION *slist = 0; + int scount; + int end = 0; - data = auth_userpass(s->username, s->password); - /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ + data = auth_userpass(s->username, s->password); + /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ - if (!data) - { - scp_v1s_mng_deny_connection(c, "Login failed"); - log_message(LOG_LEVEL_INFO, - "[MNG] Login failed for user %s. Connection terminated", s->username); + if (!data) + { + scp_v1s_mng_deny_connection(c, "Login failed"); + log_message(LOG_LEVEL_INFO, + "[MNG] Login failed for user %s. Connection terminated", s->username); + scp_session_destroy(s); + auth_end(data); + return; + } + + /* testing if login is allowed */ + if (0 == access_login_mng_allowed(s->username)) + { + scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed."); + log_message(LOG_LEVEL_INFO, + "[MNG] User %s not allowed on TS. Connection terminated", s->username); + scp_session_destroy(s); + auth_end(data); + return; + } + + e = scp_v1s_mng_allow_connection(c, s); + + end = 1; + + while (end) + { + switch (e) + { + case SCP_SERVER_STATE_MNG_ACTION: + log_message(LOG_LEVEL_INFO, "Connection cancelled after session listing"); + break; + + case SCP_SERVER_STATE_MNG_LISTREQ: + /* list disconnected sessions */ + slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL); + LOG_DBG("sessions on TS: %d (slist: %x)", scount, slist); + + if (0 == slist) + { + // e=scp_v1s_connection_error(c, "Internal error"); + log_message(LOG_LEVEL_INFO, "No sessions on Terminal Server"); + end = 0; + } + else + { + e = scp_v1s_mng_list_sessions(c, s, scount, slist); + g_free(slist); + } + + break; + default: + /* we check the other errors */ + parseCommonStates(e, "scp_v1s_mng_list_sessions()"); + end = 0; + break; + } + } + + /* cleanup */ scp_session_destroy(s); auth_end(data); - return; - } +} - /* testing if login is allowed */ - if (0 == access_login_mng_allowed(s->username)) - { - scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed."); - log_message(LOG_LEVEL_INFO, - "[MNG] User %s not allowed on TS. Connection terminated", s->username); - scp_session_destroy(s); - auth_end(data); - return; - } - - e = scp_v1s_mng_allow_connection(c, s); - - end = 1; - while (end) - { +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f) +{ switch (e) { - case SCP_SERVER_STATE_MNG_ACTION: - log_message(LOG_LEVEL_INFO, "Connection cancelled after session listing"); - break; - - case SCP_SERVER_STATE_MNG_LISTREQ: - /* list disconnected sessions */ - slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL); - LOG_DBG("sessions on TS: %d (slist: %x)", scount, slist); - - if (0 == slist) - { -// e=scp_v1s_connection_error(c, "Internal error"); - log_message(LOG_LEVEL_INFO, "No sessions on Terminal Server"); - end = 0; - } - else - { - e = scp_v1s_mng_list_sessions(c, s, scount, slist); - g_free(slist); - } - - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_mng_list_sessions()"); - end = 0; - break; + case SCP_SERVER_STATE_VERSION_ERR: + LOG_DBG("version error") + case SCP_SERVER_STATE_SIZE_ERR: + /* an unknown scp version was requested, so we shut down the */ + /* connection (and log the fact) */ + log_message(LOG_LEVEL_WARNING, + "protocol violation. connection closed."); + break; + case SCP_SERVER_STATE_NETWORK_ERR: + log_message(LOG_LEVEL_WARNING, "libscp network error."); + break; + case SCP_SERVER_STATE_SEQUENCE_ERR: + log_message(LOG_LEVEL_WARNING, "libscp sequence error."); + break; + case SCP_SERVER_STATE_INTERNAL_ERR: + /* internal error occurred (eg. malloc() error, ecc.) */ + log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + break; + default: + /* dummy: scp_v1s_request_password won't generate any other */ + /* error other than the ones before */ + log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); + break; } - } - - /* cleanup */ - scp_session_destroy(s); - auth_end(data); -} - -static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f) -{ - switch (e) - { - case SCP_SERVER_STATE_VERSION_ERR: - LOG_DBG("version error") - case SCP_SERVER_STATE_SIZE_ERR: - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING, - "protocol violation. connection closed."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); - break; - case SCP_SERVER_STATE_SEQUENCE_ERR: - log_message(LOG_LEVEL_WARNING, "libscp sequence error."); - break; - case SCP_SERVER_STATE_INTERNAL_ERR: - /* internal error occurred (eg. malloc() error, ecc.) */ - log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); - break; - default: - /* dummy: scp_v1s_request_password won't generate any other */ - /* error other than the ones before */ - log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); - break; - } } diff --git a/sesman/scp_v1_mng.h b/sesman/scp_v1_mng.h index d4ef88ae..0317ba5f 100644 --- a/sesman/scp_v1_mng.h +++ b/sesman/scp_v1_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/sesman.c b/sesman/sesman.c index b882c49d..50652b37 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -30,7 +29,7 @@ int g_sck; int g_pid; unsigned char g_fixedkey[8] = { 23, 82, 107, 6, 35, 78, 88, 7 }; -struct config_sesman* g_cfg; /* defined in config.h */ +struct config_sesman *g_cfg; /* defined in config.h */ tbus g_term_event = 0; tbus g_sync_event = 0; @@ -46,325 +45,346 @@ extern int g_thread_sck; /* in thread.c */ static void DEFAULT_CC sesman_main_loop(void) { - int in_sck; - int error; - int robjs_count; - int cont; - tbus sck_obj; - tbus robjs[8]; + int in_sck; + int error; + int robjs_count; + int cont; + tbus sck_obj; + tbus robjs[8]; + + /*main program loop*/ + log_message(LOG_LEVEL_INFO, "listening..."); + g_sck = g_tcp_socket(); + g_tcp_set_non_blocking(g_sck); + error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port); - /*main program loop*/ - log_message(LOG_LEVEL_INFO, "listening..."); - g_sck = g_tcp_socket(); - g_tcp_set_non_blocking(g_sck); - error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port); - if (error == 0) - { - error = g_tcp_listen(g_sck); if (error == 0) { - sck_obj = g_create_wait_obj_from_socket(g_sck, 0); - cont = 1; - while (cont) - { - /* build the wait obj list */ - robjs_count = 0; - robjs[robjs_count++] = sck_obj; - robjs[robjs_count++] = g_term_event; - robjs[robjs_count++] = g_sync_event; - /* wait */ - if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0) + error = g_tcp_listen(g_sck); + + if (error == 0) { - /* error, should not get here */ - g_sleep(100); + sck_obj = g_create_wait_obj_from_socket(g_sck, 0); + cont = 1; + + while (cont) + { + /* build the wait obj list */ + robjs_count = 0; + robjs[robjs_count++] = sck_obj; + robjs[robjs_count++] = g_term_event; + robjs[robjs_count++] = g_sync_event; + + /* wait */ + if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0) + { + /* error, should not get here */ + g_sleep(100); + } + + if (g_is_wait_obj_set(g_term_event)) /* term */ + { + break; + } + + if (g_is_wait_obj_set(g_sync_event)) /* sync */ + { + g_reset_wait_obj(g_sync_event); + session_sync_start(); + } + + if (g_is_wait_obj_set(sck_obj)) /* incoming connection */ + { + in_sck = g_tcp_accept(g_sck); + + if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck)) + { + /* should not get here */ + g_sleep(100); + } + else if (in_sck == -1) + { + /* error, should not get here */ + break; + } + else + { + /* we've got a connection, so we pass it to scp code */ + LOG_DBG("new connection"); + thread_scp_start(in_sck); + /* todo, do we have to wait here ? */ + } + } + } + + g_delete_wait_obj_from_socket(sck_obj); } - if (g_is_wait_obj_set(g_term_event)) /* term */ + else { - break; + log_message(LOG_LEVEL_ERROR, "listen error %d (%s)", + g_get_errno(), g_get_strerror()); } - if (g_is_wait_obj_set(g_sync_event)) /* sync */ - { - g_reset_wait_obj(g_sync_event); - session_sync_start(); - } - if (g_is_wait_obj_set(sck_obj)) /* incoming connection */ - { - in_sck = g_tcp_accept(g_sck); - if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck)) - { - /* should not get here */ - g_sleep(100); - } - else if (in_sck == -1) - { - /* error, should not get here */ - break; - } - else - { - /* we've got a connection, so we pass it to scp code */ - LOG_DBG("new connection"); - thread_scp_start(in_sck); - /* todo, do we have to wait here ? */ - } - } - } - g_delete_wait_obj_from_socket(sck_obj); } else { - log_message(LOG_LEVEL_ERROR, "listen error %d (%s)", - g_get_errno(), g_get_strerror()); + log_message(LOG_LEVEL_ERROR, "bind error on " + "port '%s': %d (%s)", g_cfg->listen_port, + g_get_errno(), g_get_strerror()); } - } - else - { - log_message(LOG_LEVEL_ERROR, "bind error on " - "port '%s': %d (%s)", g_cfg->listen_port, - g_get_errno(), g_get_strerror()); - } - g_tcp_close(g_sck); + + g_tcp_close(g_sck); } /******************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - int fd; - enum logReturns error; - int daemon = 1; - int pid; - char pid_s[8]; - char text[256]; - char pid_file[256]; - char cfg_file[256]; + int fd; + enum logReturns error; + int daemon = 1; + int pid; + char pid_s[8]; + char text[256]; + char pid_file[256]; + char cfg_file[256]; - g_init("xrdp-sesman"); - g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); - if (1 == argc) - { - /* no options on command line. normal startup */ - g_printf("starting sesman...\n"); - daemon = 1; - } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--nodaemon")) || - (0 == g_strcasecmp(argv[1], "-nodaemon")) || - (0 == g_strcasecmp(argv[1], "-n")) || - (0 == g_strcasecmp(argv[1], "-ns")))) - { - /* starts sesman not daemonized */ - g_printf("starting sesman in foregroud...\n"); - daemon = 0; - } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--help")) || - (0 == g_strcasecmp(argv[1], "-help")) || - (0 == g_strcasecmp(argv[1], "-h")))) - { - /* help screen */ - g_printf("sesman - xrdp session manager\n\n"); - g_printf("usage: sesman [command]\n\n"); - g_printf("command can be one of the following:\n"); - g_printf("-n, -ns, --nodaemon starts sesman in foreground\n"); - g_printf("-k, --kill kills running sesman\n"); - g_printf("-h, --help shows this help\n"); - g_printf("if no command is specified, sesman is started in background"); - g_deinit(); - g_exit(0); - } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--kill")) || - (0 == g_strcasecmp(argv[1], "-kill")) || - (0 == g_strcasecmp(argv[1], "-k")))) - { - /* killing running sesman */ - /* check if sesman is running */ - if (!g_file_exist(pid_file)) + g_init("xrdp-sesman"); + g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); + + if (1 == argc) { - g_printf("sesman is not running (pid file not found - %s)\n", pid_file); - g_deinit(); - g_exit(1); + /* no options on command line. normal startup */ + g_printf("starting sesman...\n"); + daemon = 1; } - - fd = g_file_open(pid_file); - - if (-1 == fd) + else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--nodaemon")) || + (0 == g_strcasecmp(argv[1], "-nodaemon")) || + (0 == g_strcasecmp(argv[1], "-n")) || + (0 == g_strcasecmp(argv[1], "-ns")))) { - g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror()); - return 1; + /* starts sesman not daemonized */ + g_printf("starting sesman in foregroud...\n"); + daemon = 0; } - - error = g_file_read(fd, pid_s, 7); - if (-1 == error) + else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--help")) || + (0 == g_strcasecmp(argv[1], "-help")) || + (0 == g_strcasecmp(argv[1], "-h")))) { - g_printf("error reading pid file: %s\n", g_get_strerror()); - g_file_close(fd); - g_deinit(); - g_exit(error); + /* help screen */ + g_printf("sesman - xrdp session manager\n\n"); + g_printf("usage: sesman [command]\n\n"); + g_printf("command can be one of the following:\n"); + g_printf("-n, -ns, --nodaemon starts sesman in foreground\n"); + g_printf("-k, --kill kills running sesman\n"); + g_printf("-h, --help shows this help\n"); + g_printf("if no command is specified, sesman is started in background"); + g_deinit(); + g_exit(0); } - g_file_close(fd); - pid = g_atoi(pid_s); - - error = g_sigterm(pid); - if (0 != error) + else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--kill")) || + (0 == g_strcasecmp(argv[1], "-kill")) || + (0 == g_strcasecmp(argv[1], "-k")))) { - g_printf("error killing sesman: %s\n", g_get_strerror()); + /* killing running sesman */ + /* check if sesman is running */ + if (!g_file_exist(pid_file)) + { + g_printf("sesman is not running (pid file not found - %s)\n", pid_file); + g_deinit(); + g_exit(1); + } + + fd = g_file_open(pid_file); + + if (-1 == fd) + { + g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror()); + return 1; + } + + error = g_file_read(fd, pid_s, 7); + + if (-1 == error) + { + g_printf("error reading pid file: %s\n", g_get_strerror()); + g_file_close(fd); + g_deinit(); + g_exit(error); + } + + g_file_close(fd); + pid = g_atoi(pid_s); + + error = g_sigterm(pid); + + if (0 != error) + { + g_printf("error killing sesman: %s\n", g_get_strerror()); + } + else + { + g_file_delete(pid_file); + } + + g_deinit(); + g_exit(error); } else { - g_file_delete(pid_file); + /* there's something strange on the command line */ + g_printf("sesman - xrdp session manager\n\n"); + g_printf("error: invalid command line\n"); + g_printf("usage: sesman [ --nodaemon | --kill | --help ]\n"); + g_deinit(); + g_exit(1); } - g_deinit(); - g_exit(error); - } - else - { - /* there's something strange on the command line */ - g_printf("sesman - xrdp session manager\n\n"); - g_printf("error: invalid command line\n"); - g_printf("usage: sesman [ --nodaemon | --kill | --help ]\n"); - g_deinit(); - g_exit(1); - } - if (g_file_exist(pid_file)) - { - g_printf("sesman is already running.\n"); - g_printf("if it's not running, try removing "); - g_printf(pid_file); - g_printf("\n"); - g_deinit(); - g_exit(1); - } - - /* reading config */ - g_cfg = g_malloc(sizeof(struct config_sesman), 1); - if (0 == g_cfg) - { - g_printf("error creating config: quitting.\n"); - g_deinit(); - g_exit(1); - } - //g_cfg->log.fd = -1; /* don't use logging before reading its config */ - if (0 != config_read(g_cfg)) - { - g_printf("error reading config: %s\nquitting.\n", g_get_strerror()); - g_deinit(); - g_exit(1); - } - - g_snprintf(cfg_file,255,"%s/sesman.ini",XRDP_CFG_PATH); - - /* starting logging subsystem */ - error = log_start(cfg_file,"XRDP-sesman"); - - if (error != LOG_STARTUP_OK) - { - switch (error) + if (g_file_exist(pid_file)) { - case LOG_ERROR_MALLOC: - g_writeln("error on malloc. cannot start logging. quitting."); - break; - case LOG_ERROR_FILE_OPEN: - g_writeln("error opening log file [%s]. quitting.", - getLogFile(text, 255)); - break; + g_printf("sesman is already running.\n"); + g_printf("if it's not running, try removing "); + g_printf(pid_file); + g_printf("\n"); + g_deinit(); + g_exit(1); } - g_deinit(); - g_exit(1); - } - /* libscp initialization */ - scp_init(); + /* reading config */ + g_cfg = g_malloc(sizeof(struct config_sesman), 1); - if (daemon) - { - /* start of daemonizing code */ - g_pid = g_fork(); - - if (0 != g_pid) + if (0 == g_cfg) { - g_deinit(); - g_exit(0); + g_printf("error creating config: quitting.\n"); + g_deinit(); + g_exit(1); } - g_file_close(0); - g_file_close(1); - g_file_close(2); + //g_cfg->log.fd = -1; /* don't use logging before reading its config */ + if (0 != config_read(g_cfg)) + { + g_printf("error reading config: %s\nquitting.\n", g_get_strerror()); + g_deinit(); + g_exit(1); + } - g_file_open("/dev/null"); - g_file_open("/dev/null"); - g_file_open("/dev/null"); - } + g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - /* initializing locks */ - lock_init(); + /* starting logging subsystem */ + error = log_start(cfg_file, "XRDP-sesman"); - /* signal handling */ - g_pid = g_getpid(); - /* old style signal handling is now managed synchronously by a - * separate thread. uncomment this block if you need old style - * signal handling and comment out thread_sighandler_start() - * going back to old style for the time being - * problem with the sigaddset functions in sig.c - jts */ + if (error != LOG_STARTUP_OK) + { + switch (error) + { + case LOG_ERROR_MALLOC: + g_writeln("error on malloc. cannot start logging. quitting."); + break; + case LOG_ERROR_FILE_OPEN: + g_writeln("error opening log file [%s]. quitting.", + getLogFile(text, 255)); + break; + } + + g_deinit(); + g_exit(1); + } + + /* libscp initialization */ + scp_init(); + + if (daemon) + { + /* start of daemonizing code */ + g_pid = g_fork(); + + if (0 != g_pid) + { + g_deinit(); + g_exit(0); + } + + g_file_close(0); + g_file_close(1); + g_file_close(2); + + g_file_open("/dev/null"); + g_file_open("/dev/null"); + g_file_open("/dev/null"); + } + + /* initializing locks */ + lock_init(); + + /* signal handling */ + g_pid = g_getpid(); + /* old style signal handling is now managed synchronously by a + * separate thread. uncomment this block if you need old style + * signal handling and comment out thread_sighandler_start() + * going back to old style for the time being + * problem with the sigaddset functions in sig.c - jts */ #if 1 - g_signal_hang_up(sig_sesman_reload_cfg); /* SIGHUP */ - g_signal_user_interrupt(sig_sesman_shutdown); /* SIGINT */ - g_signal_kill(sig_sesman_shutdown); /* SIGKILL */ - g_signal_terminate(sig_sesman_shutdown); /* SIGTERM */ - g_signal_child_stop(sig_sesman_session_end); /* SIGCHLD */ + g_signal_hang_up(sig_sesman_reload_cfg); /* SIGHUP */ + g_signal_user_interrupt(sig_sesman_shutdown); /* SIGINT */ + g_signal_kill(sig_sesman_shutdown); /* SIGKILL */ + g_signal_terminate(sig_sesman_shutdown); /* SIGTERM */ + g_signal_child_stop(sig_sesman_session_end); /* SIGCHLD */ #endif #if 0 - thread_sighandler_start(); + thread_sighandler_start(); #endif - if (daemon) - { - /* writing pid file */ - fd = g_file_open(pid_file); - if (-1 == fd) + + if (daemon) { - log_message(LOG_LEVEL_ERROR, - "error opening pid file[%s]: %s", - pid_file, g_get_strerror()); - log_end(); - g_deinit(); - g_exit(1); + /* writing pid file */ + fd = g_file_open(pid_file); + + if (-1 == fd) + { + log_message(LOG_LEVEL_ERROR, + "error opening pid file[%s]: %s", + pid_file, g_get_strerror()); + log_end(); + g_deinit(); + g_exit(1); + } + + g_sprintf(pid_s, "%d", g_pid); + g_file_write(fd, pid_s, g_strlen(pid_s)); + g_file_close(fd); } - g_sprintf(pid_s, "%d", g_pid); - g_file_write(fd, pid_s, g_strlen(pid_s)); - g_file_close(fd); - } - /* start program main loop */ - log_message(LOG_LEVEL_ALWAYS, - "starting sesman with pid %d", g_pid); + /* start program main loop */ + log_message(LOG_LEVEL_ALWAYS, + "starting sesman with pid %d", g_pid); - /* make sure the /tmp/.X11-unix directory exist */ - if (!g_directory_exist("/tmp/.X11-unix")) - { - g_create_dir("/tmp/.X11-unix"); - g_chmod_hex("/tmp/.X11-unix", 0x1777); - } + /* make sure the /tmp/.X11-unix directory exist */ + if (!g_directory_exist("/tmp/.X11-unix")) + { + g_create_dir("/tmp/.X11-unix"); + g_chmod_hex("/tmp/.X11-unix", 0x1777); + } - g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_term", g_pid); - g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_sync", g_pid); - g_sync_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_term", g_pid); + g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_sync", g_pid); + g_sync_event = g_create_wait_obj(text); - sesman_main_loop(); + sesman_main_loop(); - /* clean up PID file on exit */ - if (daemon) - { - g_file_delete(pid_file); - } + /* clean up PID file on exit */ + if (daemon) + { + g_file_delete(pid_file); + } - g_delete_wait_obj(g_term_event); - g_delete_wait_obj(g_sync_event); + g_delete_wait_obj(g_term_event); + g_delete_wait_obj(g_sync_event); - if (!daemon) - { - log_end(); - } + if (!daemon) + { + log_end(); + } - g_deinit(); - return 0; + g_deinit(); + return 0; } diff --git a/sesman/sesman.h b/sesman/sesman.h index 0344ccd5..2eb70df9 100644 --- a/sesman/sesman.h +++ b/sesman/sesman.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/session.c b/sesman/session.c index 94c5bf91..6f98fbc7 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,19 +32,19 @@ extern tbus g_sync_event; extern unsigned char g_fixedkey[8]; -extern struct config_sesman* g_cfg; /* in sesman.c */ -struct session_chain* g_sessions; +extern struct config_sesman *g_cfg; /* in sesman.c */ +struct session_chain *g_sessions; int g_session_count; static int g_sync_width; static int g_sync_height; static int g_sync_bpp; -static char* g_sync_username; -static char* g_sync_password; -static char* g_sync_domain; -static char* g_sync_program; -static char* g_sync_directory; -static char* g_sync_client_ip; +static char *g_sync_username; +static char *g_sync_password; +static char *g_sync_domain; +static char *g_sync_program; +static char *g_sync_directory; +static char *g_sync_client_ip; static tbus g_sync_data; static tui8 g_sync_type; static int g_sync_result; @@ -58,87 +57,92 @@ static int g_sync_cmd; * @param len the allocated len for outstr * @return */ -char* APP_CC -dumpItemsToString(struct list* self, char *outstr, int len) +char *APP_CC +dumpItemsToString(struct list *self, char *outstr, int len) { - g_memset(outstr,0,len); - int index; - tbus item; - int totalLen= 0; + g_memset(outstr, 0, len); + int index; + tbus item; + int totalLen = 0; - if (self->count == 0) - { - g_writeln("List is empty"); - } - for (index = 0; index < self->count; index++) - { - /* +1 = one space*/ - totalLen = totalLen + g_strlen((char*)list_get_item(self, index))+1; - if(len>totalLen) + if (self->count == 0) { - g_strcat(outstr,(char*)list_get_item(self, index)); - g_strcat(outstr," "); + g_writeln("List is empty"); } - } - return outstr ; + + for (index = 0; index < self->count; index++) + { + /* +1 = one space*/ + totalLen = totalLen + g_strlen((char *)list_get_item(self, index)) + 1; + + if (len > totalLen) + { + g_strcat(outstr, (char *)list_get_item(self, index)); + g_strcat(outstr, " "); + } + } + + return outstr ; } /******************************************************************************/ -struct session_item* DEFAULT_CC -session_get_bydata(char* name, int width, int height, int bpp, int type) +struct session_item *DEFAULT_CC +session_get_bydata(char *name, int width, int height, int bpp, int type) { - struct session_chain* tmp; + struct session_chain *tmp; - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); - tmp = g_sessions; + tmp = g_sessions; - /* convert from SCP_SESSION_TYPE namespace to SESMAN_SESSION_TYPE namespace */ - switch (type) - { - case SCP_SESSION_TYPE_XVNC: /* 0 */ - type = SESMAN_SESSION_TYPE_XVNC; /* 2 */ - break; - case SCP_SESSION_TYPE_XRDP: /* 1 */ - type = SESMAN_SESSION_TYPE_XRDP; /* 1 */ - break; - default: - lock_chain_release(); - return 0; - } - - while (tmp != 0) - { - if (type == SESMAN_SESSION_TYPE_XRDP) + /* convert from SCP_SESSION_TYPE namespace to SESMAN_SESSION_TYPE namespace */ + switch (type) { - /* only name and bpp need to match for X11rdp, it can resize */ - if (g_strncmp(name, tmp->item->name, 255) == 0 && - tmp->item->bpp == bpp && - tmp->item->type == type) - { - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return tmp->item; - } + case SCP_SESSION_TYPE_XVNC: /* 0 */ + type = SESMAN_SESSION_TYPE_XVNC; /* 2 */ + break; + case SCP_SESSION_TYPE_XRDP: /* 1 */ + type = SESMAN_SESSION_TYPE_XRDP; /* 1 */ + break; + default: + lock_chain_release(); + return 0; } - if (g_strncmp(name, tmp->item->name, 255) == 0 && - tmp->item->width == width && - tmp->item->height == height && - tmp->item->bpp == bpp && - tmp->item->type == type) - { - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return tmp->item; - } - tmp = tmp->next; - } - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; + while (tmp != 0) + { + if (type == SESMAN_SESSION_TYPE_XRDP) + { + /* only name and bpp need to match for X11rdp, it can resize */ + if (g_strncmp(name, tmp->item->name, 255) == 0 && + tmp->item->bpp == bpp && + tmp->item->type == type) + { + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return tmp->item; + } + } + + if (g_strncmp(name, tmp->item->name, 255) == 0 && + tmp->item->width == width && + tmp->item->height == height && + tmp->item->bpp == bpp && + tmp->item->type == type) + { + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return tmp->item; + } + + tmp = tmp->next; + } + + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return 0; } /******************************************************************************/ @@ -152,39 +156,44 @@ session_get_bydata(char* name, int width, int height, int bpp, int type) static int DEFAULT_CC x_server_running_check_ports(int display) { - char text[256]; - int x_running; - int sck; + char text[256]; + int x_running; + int sck; - g_sprintf(text, "/tmp/.X11-unix/X%d", display); - x_running = g_file_exist(text); - if (!x_running) - { - g_sprintf(text, "/tmp/.X%d-lock", display); + g_sprintf(text, "/tmp/.X11-unix/X%d", display); x_running = g_file_exist(text); - } - if (!x_running) /* check 59xx */ - { - sck = g_tcp_socket(); - g_sprintf(text, "59%2.2d", display); - x_running = g_tcp_bind(sck, text); - g_tcp_close(sck); - } - if (!x_running) /* check 60xx */ - { - sck = g_tcp_socket(); - g_sprintf(text, "60%2.2d", display); - x_running = g_tcp_bind(sck, text); - g_tcp_close(sck); - } - if (!x_running) /* check 62xx */ - { - sck = g_tcp_socket(); - g_sprintf(text, "62%2.2d", display); - x_running = g_tcp_bind(sck, text); - g_tcp_close(sck); - } - return x_running; + + if (!x_running) + { + g_sprintf(text, "/tmp/.X%d-lock", display); + x_running = g_file_exist(text); + } + + if (!x_running) /* check 59xx */ + { + sck = g_tcp_socket(); + g_sprintf(text, "59%2.2d", display); + x_running = g_tcp_bind(sck, text); + g_tcp_close(sck); + } + + if (!x_running) /* check 60xx */ + { + sck = g_tcp_socket(); + g_sprintf(text, "60%2.2d", display); + x_running = g_tcp_bind(sck, text); + g_tcp_close(sck); + } + + if (!x_running) /* check 62xx */ + { + sck = g_tcp_socket(); + g_sprintf(text, "62%2.2d", display); + x_running = g_tcp_bind(sck, text); + g_tcp_close(sck); + } + + return x_running; } /******************************************************************************/ @@ -198,83 +207,87 @@ x_server_running_check_ports(int display) static int DEFAULT_CC x_server_running(int display) { - char text[256]; - int x_running; - int sck; + char text[256]; + int x_running; + int sck; - g_sprintf(text, "/tmp/.X11-unix/X%d", display); - x_running = g_file_exist(text); - if (!x_running) - { - g_sprintf(text, "/tmp/.X%d-lock", display); + g_sprintf(text, "/tmp/.X11-unix/X%d", display); x_running = g_file_exist(text); - } - return x_running; + + if (!x_running) + { + g_sprintf(text, "/tmp/.X%d-lock", display); + x_running = g_file_exist(text); + } + + return x_running; } /******************************************************************************/ static void DEFAULT_CC -session_start_sessvc(int xpid, int wmpid, long data, char* username, int display) +session_start_sessvc(int xpid, int wmpid, long data, char *username, int display) { - struct list * sessvc_params = (struct list *)NULL; - char wmpid_str[25]; - char xpid_str[25]; - char exe_path[262]; - int i = 0; + struct list *sessvc_params = (struct list *)NULL; + char wmpid_str[25]; + char xpid_str[25]; + char exe_path[262]; + int i = 0; - /* initialize (zero out) local variables: */ - g_memset(wmpid_str,0,sizeof(char) * 25); - g_memset(xpid_str,0,sizeof(char) * 25); - g_memset(exe_path,0,sizeof(char) * 262); + /* initialize (zero out) local variables: */ + g_memset(wmpid_str, 0, sizeof(char) * 25); + g_memset(xpid_str, 0, sizeof(char) * 25); + g_memset(exe_path, 0, sizeof(char) * 262); - /* new style waiting for clients */ - g_sprintf(wmpid_str, "%d", wmpid); - g_sprintf(xpid_str, "%d", xpid); - log_message(LOG_LEVEL_INFO, - "starting xrdp-sessvc - xpid=%s - wmpid=%s", - xpid_str, wmpid_str); + /* new style waiting for clients */ + g_sprintf(wmpid_str, "%d", wmpid); + g_sprintf(xpid_str, "%d", xpid); + log_message(LOG_LEVEL_INFO, + "starting xrdp-sessvc - xpid=%s - wmpid=%s", + xpid_str, wmpid_str); - sessvc_params = list_create(); - sessvc_params->auto_free = 1; + sessvc_params = list_create(); + sessvc_params->auto_free = 1; - /* building parameters */ - g_snprintf(exe_path, 261, "%s/xrdp-sessvc", XRDP_SBIN_PATH); + /* building parameters */ + g_snprintf(exe_path, 261, "%s/xrdp-sessvc", XRDP_SBIN_PATH); - list_add_item(sessvc_params, (long)g_strdup(exe_path)); - list_add_item(sessvc_params, (long)g_strdup(xpid_str)); - list_add_item(sessvc_params, (long)g_strdup(wmpid_str)); - list_add_item(sessvc_params, 0); /* mandatory */ + list_add_item(sessvc_params, (long)g_strdup(exe_path)); + list_add_item(sessvc_params, (long)g_strdup(xpid_str)); + list_add_item(sessvc_params, (long)g_strdup(wmpid_str)); + list_add_item(sessvc_params, 0); /* mandatory */ - env_set_user(username, 0, display); + env_set_user(username, 0, display); - /* executing sessvc */ - g_execvp(exe_path, ((char**)sessvc_params->items)); + /* executing sessvc */ + g_execvp(exe_path, ((char **)sessvc_params->items)); - /* should not get here */ - log_message(LOG_LEVEL_ALWAYS, - "error starting xrdp-sessvc - pid %d - xpid=%s - wmpid=%s", - g_getpid(), xpid_str, wmpid_str); + /* should not get here */ + log_message(LOG_LEVEL_ALWAYS, + "error starting xrdp-sessvc - pid %d - xpid=%s - wmpid=%s", + g_getpid(), xpid_str, wmpid_str); - /* logging parameters */ - /* no problem calling strerror for thread safety: other threads - are blocked */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s", - errno, g_get_strerror()); - log_message(LOG_LEVEL_DEBUG, "execve parameter list:"); - for (i = 0; i < (sessvc_params->count); i++) - { - log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", i, - (char*)list_get_item(sessvc_params, i)); - } - list_delete(sessvc_params); + /* logging parameters */ + /* no problem calling strerror for thread safety: other threads + are blocked */ + log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s", + errno, g_get_strerror()); + log_message(LOG_LEVEL_DEBUG, "execve parameter list:"); - /* keep the old waitpid if some error occurs during execlp */ - g_waitpid(wmpid); - g_sigterm(xpid); - g_sigterm(wmpid); - g_sleep(1000); - auth_end(data); - g_exit(0); + for (i = 0; i < (sessvc_params->count); i++) + { + log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", i, + (char *)list_get_item(sessvc_params, i)); + } + + list_delete(sessvc_params); + + /* keep the old waitpid if some error occurs during execlp */ + g_waitpid(wmpid); + g_sigterm(xpid); + g_sigterm(wmpid); + g_sleep(1000); + auth_end(data); + g_exit(0); } /******************************************************************************/ @@ -283,20 +296,24 @@ session_start_sessvc(int xpid, int wmpid, long data, char* username, int display static int APP_CC session_is_display_in_chain(int display) { - struct session_chain* chain; - struct session_item* item; + struct session_chain *chain; + struct session_item *item; - chain = g_sessions; - while (chain != 0) - { - item = chain->item; - if (item->display == display) + chain = g_sessions; + + while (chain != 0) { - return 1; + item = chain->item; + + if (item->display == display) + { + return 1; + } + + chain = chain->next; } - chain = chain->next; - } - return 0; + + return 0; } /******************************************************************************/ @@ -304,412 +321,442 @@ session_is_display_in_chain(int display) static int APP_CC session_get_aval_display_from_chain(void) { - int display; + int display; - display = g_cfg->sess.x11_display_offset; - lock_chain_acquire(); - while ((display - g_cfg->sess.x11_display_offset) <= g_cfg->sess.max_sessions) - { - if (!session_is_display_in_chain(display)) + display = g_cfg->sess.x11_display_offset; + lock_chain_acquire(); + + while ((display - g_cfg->sess.x11_display_offset) <= g_cfg->sess.max_sessions) { - if (!x_server_running_check_ports(display)) - { - lock_chain_release(); - return display; - } + if (!session_is_display_in_chain(display)) + { + if (!x_server_running_check_ports(display)) + { + lock_chain_release(); + return display; + } + } + + display++; } - display++; - } - lock_chain_release(); - log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available"); - return 0; + + lock_chain_release(); + log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available"); + return 0; } /******************************************************************************/ static int APP_CC wait_for_xserver(int display) { - int i; + int i; - /* give X a bit to start */ - /* wait up to 10 secs for x server to start */ - i = 0; - while (!x_server_running(display)) - { - i++; - if (i > 40) + /* give X a bit to start */ + /* wait up to 10 secs for x server to start */ + i = 0; + + while (!x_server_running(display)) { - log_message(LOG_LEVEL_ERROR, - "X server for display %d startup timeout", - display); - break; + i++; + + if (i > 40) + { + log_message(LOG_LEVEL_ERROR, + "X server for display %d startup timeout", + display); + break; + } + + g_sleep(250); } - g_sleep(250); - } - return 0; + + return 0; } /******************************************************************************/ /* called with the main thread */ static int APP_CC -session_start_fork(int width, int height, int bpp, char* username, - char* password, tbus data, tui8 type, char* domain, - char* program, char* directory, char* client_ip) +session_start_fork(int width, int height, int bpp, char *username, + char *password, tbus data, tui8 type, char *domain, + char *program, char *directory, char *client_ip) { - int display = 0; - int pid = 0; - int wmpid = 0; - int xpid = 0; - int i = 0; - char geometry[32]; - char depth[32]; - char screen[32]; - char text[256]; - char passwd_file[256]; - char ** pp1 = (char **)NULL; - struct session_chain * temp = (struct session_chain *)NULL; - struct list * xserver_params = (struct list *)NULL; - time_t ltime; - struct tm stime; - char execvpparams[2048]; + int display = 0; + int pid = 0; + int wmpid = 0; + int xpid = 0; + int i = 0; + char geometry[32]; + char depth[32]; + char screen[32]; + char text[256]; + char passwd_file[256]; + char **pp1 = (char **)NULL; + struct session_chain *temp = (struct session_chain *)NULL; + struct list *xserver_params = (struct list *)NULL; + time_t ltime; + struct tm stime; + char execvpparams[2048]; - /* initialize (zero out) local variables: */ - g_memset(<ime,0,sizeof(time_t)); - g_memset(&stime,0,sizeof(struct tm)); - g_memset(geometry,0,sizeof(char) * 32); - g_memset(depth,0,sizeof(char) * 32); - g_memset(screen,0,sizeof(char) * 32); - g_memset(text,0,sizeof(char) * 256); - g_memset(passwd_file,0,sizeof(char) * 256); + /* initialize (zero out) local variables: */ + g_memset(<ime, 0, sizeof(time_t)); + g_memset(&stime, 0, sizeof(struct tm)); + g_memset(geometry, 0, sizeof(char) * 32); + g_memset(depth, 0, sizeof(char) * 32); + g_memset(screen, 0, sizeof(char) * 32); + g_memset(text, 0, sizeof(char) * 256); + g_memset(passwd_file, 0, sizeof(char) * 256); - /* check to limit concurrent sessions */ - if (g_session_count >= g_cfg->sess.max_sessions) - { - log_message(LOG_LEVEL_INFO, "max concurrent session limit " - "exceeded. login for user %s denied", username); - return 0; - } + /* check to limit concurrent sessions */ + if (g_session_count >= g_cfg->sess.max_sessions) + { + log_message(LOG_LEVEL_INFO, "max concurrent session limit " + "exceeded. login for user %s denied", username); + return 0; + } - temp = (struct session_chain*)g_malloc(sizeof(struct session_chain), 0); - if (temp == 0) - { - log_message(LOG_LEVEL_ERROR, "cannot create new chain " - "element - user %s", username); - return 0; - } - temp->item = (struct session_item*)g_malloc(sizeof(struct session_item), 0); - if (temp->item == 0) - { - g_free(temp); - log_message(LOG_LEVEL_ERROR, "cannot create new session " - "item - user %s", username); - return 0; - } - display = session_get_aval_display_from_chain(); - if (display == 0) - { - g_free(temp->item); - g_free(temp); - return 0; - } - pid = g_fork(); - if (pid == -1) - { - } - else if (pid == 0) /* child sesman */ - { - auth_start_session(data, display); - g_sprintf(geometry, "%dx%d", width, height); - g_sprintf(depth, "%d", bpp); - g_sprintf(screen, ":%d", display); - wmpid = g_fork(); - if (wmpid == -1) + temp = (struct session_chain *)g_malloc(sizeof(struct session_chain), 0); + + if (temp == 0) + { + log_message(LOG_LEVEL_ERROR, "cannot create new chain " + "element - user %s", username); + return 0; + } + + temp->item = (struct session_item *)g_malloc(sizeof(struct session_item), 0); + + if (temp->item == 0) + { + g_free(temp); + log_message(LOG_LEVEL_ERROR, "cannot create new session " + "item - user %s", username); + return 0; + } + + display = session_get_aval_display_from_chain(); + + if (display == 0) + { + g_free(temp->item); + g_free(temp); + return 0; + } + + pid = g_fork(); + + if (pid == -1) { } - else if (wmpid == 0) /* child (child sesman) xserver */ + else if (pid == 0) /* child sesman */ { - wait_for_xserver(display); - env_set_user(username, 0, display); - if (x_server_running(display)) - { - auth_set_env(data); - if (directory != 0) - { - if (directory[0] != 0) - { - g_set_current_dir(directory); - } - } - if (program != 0) - { - if (program[0] != 0) - { - g_execlp3(program, program, 0); - log_message(LOG_LEVEL_ALWAYS, - "error starting program %s for user %s - pid %d", - program, username, g_getpid()); - } - } - /* try to execute user window manager if enabled */ - if (g_cfg->enable_user_wm) - { - g_sprintf(text,"%s/%s", g_getenv("HOME"), g_cfg->user_wm); - if (g_file_exist(text)) - { - g_execlp3(text, g_cfg->user_wm, 0); - log_message(LOG_LEVEL_ALWAYS,"error starting user " - "wm for user %s - pid %d", username, g_getpid()); - /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, " - "description: %s", errno, g_get_strerror()); - log_message(LOG_LEVEL_DEBUG,"execlp3 parameter " - "list:"); - log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", - text); - log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", - g_cfg->user_wm); - } - } - /* if we're here something happened to g_execlp3 - so we try running the default window manager */ - g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm); - g_execlp3(text, g_cfg->default_wm, 0); + auth_start_session(data, display); + g_sprintf(geometry, "%dx%d", width, height); + g_sprintf(depth, "%d", bpp); + g_sprintf(screen, ":%d", display); + wmpid = g_fork(); - log_message( LOG_LEVEL_ALWAYS,"error starting default " - "wm for user %s - pid %d", username, g_getpid()); - /* logging parameters */ - log_message( LOG_LEVEL_DEBUG, "errno: %d, description: " - "%s", errno, g_get_strerror()); - log_message(LOG_LEVEL_DEBUG,"execlp3 parameter list:"); - log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", - text); - log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", - g_cfg->default_wm); + if (wmpid == -1) + { + } + else if (wmpid == 0) /* child (child sesman) xserver */ + { + wait_for_xserver(display); + env_set_user(username, 0, display); - /* still a problem starting window manager just start xterm */ - g_execlp3("xterm", "xterm", 0); + if (x_server_running(display)) + { + auth_set_env(data); - /* should not get here */ - log_message(LOG_LEVEL_ALWAYS,"error starting xterm " - "for user %s - pid %d", username, g_getpid()); - /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " - "%s", errno, g_get_strerror()); - } - else - { - log_message(LOG_LEVEL_ERROR, "another Xserver might " - "already be active on display %d - see log", display); - } - log_message(LOG_LEVEL_DEBUG,"aborting connection..."); - g_exit(0); + if (directory != 0) + { + if (directory[0] != 0) + { + g_set_current_dir(directory); + } + } + + if (program != 0) + { + if (program[0] != 0) + { + g_execlp3(program, program, 0); + log_message(LOG_LEVEL_ALWAYS, + "error starting program %s for user %s - pid %d", + program, username, g_getpid()); + } + } + + /* try to execute user window manager if enabled */ + if (g_cfg->enable_user_wm) + { + g_sprintf(text, "%s/%s", g_getenv("HOME"), g_cfg->user_wm); + + if (g_file_exist(text)) + { + g_execlp3(text, g_cfg->user_wm, 0); + log_message(LOG_LEVEL_ALWAYS, "error starting user " + "wm for user %s - pid %d", username, g_getpid()); + /* logging parameters */ + log_message(LOG_LEVEL_DEBUG, "errno: %d, " + "description: %s", errno, g_get_strerror()); + log_message(LOG_LEVEL_DEBUG, "execlp3 parameter " + "list:"); + log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", + text); + log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", + g_cfg->user_wm); + } + } + + /* if we're here something happened to g_execlp3 + so we try running the default window manager */ + g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm); + g_execlp3(text, g_cfg->default_wm, 0); + + log_message( LOG_LEVEL_ALWAYS, "error starting default " + "wm for user %s - pid %d", username, g_getpid()); + /* logging parameters */ + log_message( LOG_LEVEL_DEBUG, "errno: %d, description: " + "%s", errno, g_get_strerror()); + log_message(LOG_LEVEL_DEBUG, "execlp3 parameter list:"); + log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", + text); + log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", + g_cfg->default_wm); + + /* still a problem starting window manager just start xterm */ + g_execlp3("xterm", "xterm", 0); + + /* should not get here */ + log_message(LOG_LEVEL_ALWAYS, "error starting xterm " + "for user %s - pid %d", username, g_getpid()); + /* logging parameters */ + log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " + "%s", errno, g_get_strerror()); + } + else + { + log_message(LOG_LEVEL_ERROR, "another Xserver might " + "already be active on display %d - see log", display); + } + + log_message(LOG_LEVEL_DEBUG, "aborting connection..."); + g_exit(0); + } + else /* parent (child sesman) */ + { + xpid = g_fork(); + + if (xpid == -1) + { + } + else if (xpid == 0) /* child */ + { + env_set_user(username, passwd_file, display); + env_check_password_file(passwd_file, password); + + if (type == SESMAN_SESSION_TYPE_XVNC) + { + xserver_params = list_create(); + xserver_params->auto_free = 1; + /* these are the must have parameters */ + list_add_item(xserver_params, (long)g_strdup("Xvnc")); + list_add_item(xserver_params, (long)g_strdup(screen)); + list_add_item(xserver_params, (long)g_strdup("-geometry")); + list_add_item(xserver_params, (long)g_strdup(geometry)); + list_add_item(xserver_params, (long)g_strdup("-depth")); + list_add_item(xserver_params, (long)g_strdup(depth)); + list_add_item(xserver_params, (long)g_strdup("-rfbauth")); + list_add_item(xserver_params, (long)g_strdup(passwd_file)); + + /* additional parameters from sesman.ini file */ + //config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC, + // xserver_params); + list_append_list_strdup(g_cfg->vnc_params, xserver_params, 0); + + /* make sure it ends with a zero */ + list_add_item(xserver_params, 0); + pp1 = (char **)xserver_params->items; + log_message(LOG_LEVEL_INFO, "Xvnc start:%s", dumpItemsToString(xserver_params, execvpparams, 2048)); + g_execvp("Xvnc", pp1); + } + else if (type == SESMAN_SESSION_TYPE_XRDP) + { + xserver_params = list_create(); + xserver_params->auto_free = 1; + /* these are the must have parameters */ + list_add_item(xserver_params, (long)g_strdup("X11rdp")); + list_add_item(xserver_params, (long)g_strdup(screen)); + list_add_item(xserver_params, (long)g_strdup("-geometry")); + list_add_item(xserver_params, (long)g_strdup(geometry)); + list_add_item(xserver_params, (long)g_strdup("-depth")); + list_add_item(xserver_params, (long)g_strdup(depth)); + + /* additional parameters from sesman.ini file */ + //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP, + // xserver_params); + list_append_list_strdup(g_cfg->rdp_params, xserver_params, 0); + + /* make sure it ends with a zero */ + list_add_item(xserver_params, 0); + pp1 = (char **)xserver_params->items; + log_message(LOG_LEVEL_INFO, "X11rdp start:%s", dumpItemsToString(xserver_params, execvpparams, 2048)); + g_execvp("X11rdp", pp1); + } + else + { + log_message(LOG_LEVEL_ALWAYS, "bad session type - " + "user %s - pid %d", username, g_getpid()); + g_exit(1); + } + + /* should not get here */ + log_message(LOG_LEVEL_ALWAYS, "error starting X server " + "- user %s - pid %d", username, g_getpid()); + + /* logging parameters */ + log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " + "%s", errno, g_get_strerror()); + log_message(LOG_LEVEL_DEBUG, "execve parameter list size: " + "%d", (xserver_params)->count); + + for (i = 0; i < (xserver_params->count); i++) + { + log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", + i, (char *)list_get_item(xserver_params, i)); + } + + list_delete(xserver_params); + g_exit(1); + } + else /* parent (child sesman)*/ + { + wait_for_xserver(display); + g_snprintf(text, 255, "%d", display); + g_setenv("XRDP_SESSVC_DISPLAY", text, 1); + g_snprintf(text, 255, ":%d.0", display); + g_setenv("DISPLAY", text, 1); + /* new style waiting for clients */ + session_start_sessvc(xpid, wmpid, data, username, display); + } + } } - else /* parent (child sesman) */ + else /* parent sesman process */ { - xpid = g_fork(); - if (xpid == -1) - { - } - else if (xpid == 0) /* child */ - { - env_set_user(username, passwd_file, display); - env_check_password_file(passwd_file, password); - if (type == SESMAN_SESSION_TYPE_XVNC) - { - xserver_params = list_create(); - xserver_params->auto_free = 1; - /* these are the must have parameters */ - list_add_item(xserver_params, (long)g_strdup("Xvnc")); - list_add_item(xserver_params, (long)g_strdup(screen)); - list_add_item(xserver_params, (long)g_strdup("-geometry")); - list_add_item(xserver_params, (long)g_strdup(geometry)); - list_add_item(xserver_params, (long)g_strdup("-depth")); - list_add_item(xserver_params, (long)g_strdup(depth)); - list_add_item(xserver_params, (long)g_strdup("-rfbauth")); - list_add_item(xserver_params, (long)g_strdup(passwd_file)); + temp->item->pid = pid; + temp->item->display = display; + temp->item->width = width; + temp->item->height = height; + temp->item->bpp = bpp; + temp->item->data = data; + g_strncpy(temp->item->client_ip, client_ip, 255); /* store client ip data */ + g_strncpy(temp->item->name, username, 255); - /* additional parameters from sesman.ini file */ - //config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC, - // xserver_params); - list_append_list_strdup(g_cfg->vnc_params, xserver_params, 0); + ltime = g_time1(); + localtime_r(<ime, &stime); + temp->item->connect_time.year = (tui16)(stime.tm_year + 1900); + temp->item->connect_time.month = (tui8)stime.tm_mon; + temp->item->connect_time.day = (tui8)stime.tm_mday; + temp->item->connect_time.hour = (tui8)stime.tm_hour; + temp->item->connect_time.minute = (tui8)stime.tm_min; + zero_time(&(temp->item->disconnect_time)); + zero_time(&(temp->item->idle_time)); - /* make sure it ends with a zero */ - list_add_item(xserver_params, 0); - pp1 = (char**)xserver_params->items; - log_message(LOG_LEVEL_INFO,"Xvnc start:%s",dumpItemsToString(xserver_params, execvpparams, 2048)); - g_execvp("Xvnc", pp1); - } - else if (type == SESMAN_SESSION_TYPE_XRDP) - { - xserver_params = list_create(); - xserver_params->auto_free = 1; - /* these are the must have parameters */ - list_add_item(xserver_params, (long)g_strdup("X11rdp")); - list_add_item(xserver_params, (long)g_strdup(screen)); - list_add_item(xserver_params, (long)g_strdup("-geometry")); - list_add_item(xserver_params, (long)g_strdup(geometry)); - list_add_item(xserver_params, (long)g_strdup("-depth")); - list_add_item(xserver_params, (long)g_strdup(depth)); + temp->item->type = type; + temp->item->status = SESMAN_SESSION_STATUS_ACTIVE; - /* additional parameters from sesman.ini file */ - //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP, - // xserver_params); - list_append_list_strdup(g_cfg->rdp_params, xserver_params, 0); - - /* make sure it ends with a zero */ - list_add_item(xserver_params, 0); - pp1 = (char**)xserver_params->items; - log_message(LOG_LEVEL_INFO,"X11rdp start:%s",dumpItemsToString(xserver_params, execvpparams, 2048)); - g_execvp("X11rdp", pp1); - } - else - { - log_message(LOG_LEVEL_ALWAYS, "bad session type - " - "user %s - pid %d", username, g_getpid()); - g_exit(1); - } - - /* should not get here */ - log_message(LOG_LEVEL_ALWAYS, "error starting X server " - "- user %s - pid %d", username, g_getpid()); - - /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " - "%s", errno, g_get_strerror()); - log_message(LOG_LEVEL_DEBUG, "execve parameter list size: " - "%d", (xserver_params)->count); - - for (i=0; i<(xserver_params->count); i++) - { - log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", - i, (char*)list_get_item(xserver_params, i)); - } - list_delete(xserver_params); - g_exit(1); - } - else /* parent (child sesman)*/ - { - wait_for_xserver(display); - g_snprintf(text, 255, "%d", display); - g_setenv("XRDP_SESSVC_DISPLAY", text, 1); - g_snprintf(text, 255, ":%d.0", display); - g_setenv("DISPLAY", text, 1); - /* new style waiting for clients */ - session_start_sessvc(xpid, wmpid, data, username, display); - } + temp->next = g_sessions; + g_sessions = temp; + g_session_count++; } - } - else /* parent sesman process */ - { - temp->item->pid = pid; - temp->item->display = display; - temp->item->width = width; - temp->item->height = height; - temp->item->bpp = bpp; - temp->item->data = data; - g_strncpy(temp->item->client_ip, client_ip, 255); /* store client ip data */ - g_strncpy(temp->item->name, username, 255); - ltime = g_time1(); - localtime_r(<ime, &stime); - temp->item->connect_time.year = (tui16)(stime.tm_year + 1900); - temp->item->connect_time.month = (tui8)stime.tm_mon; - temp->item->connect_time.day = (tui8)stime.tm_mday; - temp->item->connect_time.hour = (tui8)stime.tm_hour; - temp->item->connect_time.minute = (tui8)stime.tm_min; - zero_time(&(temp->item->disconnect_time)); - zero_time(&(temp->item->idle_time)); - - temp->item->type=type; - temp->item->status=SESMAN_SESSION_STATUS_ACTIVE; - - temp->next=g_sessions; - g_sessions=temp; - g_session_count++; - } - return display; + return display; } /******************************************************************************/ /* called with the main thread */ static int APP_CC -session_reconnect_fork(int display, char* username) +session_reconnect_fork(int display, char *username) { - int pid; - char text[256]; + int pid; + char text[256]; - pid = g_fork(); - if (pid == -1) - { - } - else if (pid == 0) - { - env_set_user(username, 0, display); - g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh"); - if (g_file_exist(text)) + pid = g_fork(); + + if (pid == -1) { - g_execlp3(text, g_cfg->default_wm, 0); } - g_exit(0); - } - return display; + else if (pid == 0) + { + env_set_user(username, 0, display); + g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh"); + + if (g_file_exist(text)) + { + g_execlp3(text, g_cfg->default_wm, 0); + } + + g_exit(0); + } + + return display; } /******************************************************************************/ /* called by a worker thread, ask the main thread to call session_sync_start and wait till done */ int DEFAULT_CC -session_start(int width, int height, int bpp, char* username, char* password, - long data, tui8 type, char* domain, char* program, - char* directory, char* client_ip) +session_start(int width, int height, int bpp, char *username, char *password, + long data, tui8 type, char *domain, char *program, + char *directory, char *client_ip) { - int display; + int display; - /* lock mutex */ - lock_sync_acquire(); - /* set shared vars */ - g_sync_cmd = 0; - g_sync_width = width; - g_sync_height = height; - g_sync_bpp = bpp; - g_sync_username = username; - g_sync_password = password; - g_sync_domain = domain; - g_sync_program = program; - g_sync_directory = directory; - g_sync_client_ip = client_ip; - g_sync_data = data; - g_sync_type = type; - /* set event for main thread to see */ - g_set_wait_obj(g_sync_event); - /* wait for main thread to get done */ - lock_sync_sem_acquire(); - /* read result(display) from shared var */ - display = g_sync_result; - /* unlock mutex */ - lock_sync_release(); - return display; + /* lock mutex */ + lock_sync_acquire(); + /* set shared vars */ + g_sync_cmd = 0; + g_sync_width = width; + g_sync_height = height; + g_sync_bpp = bpp; + g_sync_username = username; + g_sync_password = password; + g_sync_domain = domain; + g_sync_program = program; + g_sync_directory = directory; + g_sync_client_ip = client_ip; + g_sync_data = data; + g_sync_type = type; + /* set event for main thread to see */ + g_set_wait_obj(g_sync_event); + /* wait for main thread to get done */ + lock_sync_sem_acquire(); + /* read result(display) from shared var */ + display = g_sync_result; + /* unlock mutex */ + lock_sync_release(); + return display; } /******************************************************************************/ /* called by a worker thread, ask the main thread to call session_sync_start and wait till done */ int DEFAULT_CC -session_reconnect(int display, char* username) +session_reconnect(int display, char *username) { - /* lock mutex */ - lock_sync_acquire(); - /* set shared vars */ - g_sync_cmd = 1; - g_sync_width = display; - g_sync_username = username; - /* set event for main thread to see */ - g_set_wait_obj(g_sync_event); - /* wait for main thread to get done */ - lock_sync_sem_acquire(); - /* unlock mutex */ - lock_sync_release(); - return 0; + /* lock mutex */ + lock_sync_acquire(); + /* set shared vars */ + g_sync_cmd = 1; + g_sync_width = display; + g_sync_username = username; + /* set event for main thread to see */ + g_set_wait_obj(g_sync_event); + /* wait for main thread to get done */ + lock_sync_sem_acquire(); + /* unlock mutex */ + lock_sync_release(); + return 0; } /******************************************************************************/ @@ -717,267 +764,279 @@ session_reconnect(int display, char* username) int APP_CC session_sync_start(void) { - if (g_sync_cmd == 0) - { - g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp, - g_sync_username, g_sync_password, - g_sync_data, g_sync_type, g_sync_domain, - g_sync_program, g_sync_directory, - g_sync_client_ip); - } - else - { - /* g_sync_width is really display */ - g_sync_result = session_reconnect_fork(g_sync_width, g_sync_username); - } - lock_sync_sem_release(); - return 0; + if (g_sync_cmd == 0) + { + g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp, + g_sync_username, g_sync_password, + g_sync_data, g_sync_type, g_sync_domain, + g_sync_program, g_sync_directory, + g_sync_client_ip); + } + else + { + /* g_sync_width is really display */ + g_sync_result = session_reconnect_fork(g_sync_width, g_sync_username); + } + + lock_sync_sem_release(); + return 0; } /******************************************************************************/ int DEFAULT_CC session_kill(int pid) { - struct session_chain* tmp; - struct session_chain* prev; + struct session_chain *tmp; + struct session_chain *prev; - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); - tmp=g_sessions; - prev=0; + tmp = g_sessions; + prev = 0; - while (tmp != 0) - { - if (tmp->item == 0) + while (tmp != 0) { - log_message(LOG_LEVEL_ERROR, "session descriptor for " - "pid %d is null!", pid); - if (prev == 0) - { - /* prev does no exist, so it's the first element - so we set - g_sessions */ - g_sessions = tmp->next; - } - else - { - prev->next = tmp->next; - } - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return SESMAN_SESSION_KILL_NULLITEM; + if (tmp->item == 0) + { + log_message(LOG_LEVEL_ERROR, "session descriptor for " + "pid %d is null!", pid); + + if (prev == 0) + { + /* prev does no exist, so it's the first element - so we set + g_sessions */ + g_sessions = tmp->next; + } + else + { + prev->next = tmp->next; + } + + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return SESMAN_SESSION_KILL_NULLITEM; + } + + if (tmp->item->pid == pid) + { + /* deleting the session */ + log_message(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip); + g_free(tmp->item); + + if (prev == 0) + { + /* prev does no exist, so it's the first element - so we set + g_sessions */ + g_sessions = tmp->next; + } + else + { + prev->next = tmp->next; + } + + g_free(tmp); + g_session_count--; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return SESMAN_SESSION_KILL_OK; + } + + /* go on */ + prev = tmp; + tmp = tmp->next; } - if (tmp->item->pid == pid) - { - /* deleting the session */ - log_message(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip); - g_free(tmp->item); - if (prev == 0) - { - /* prev does no exist, so it's the first element - so we set - g_sessions */ - g_sessions = tmp->next; - } - else - { - prev->next = tmp->next; - } - g_free(tmp); - g_session_count--; - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return SESMAN_SESSION_KILL_OK; - } - - /* go on */ - prev = tmp; - tmp=tmp->next; - } - - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return SESMAN_SESSION_KILL_NOTFOUND; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return SESMAN_SESSION_KILL_NOTFOUND; } /******************************************************************************/ void DEFAULT_CC session_sigkill_all() { - struct session_chain* tmp; + struct session_chain *tmp; - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); - tmp=g_sessions; + tmp = g_sessions; - while (tmp != 0) - { - if (tmp->item == 0) + while (tmp != 0) { - log_message(LOG_LEVEL_ERROR, "found null session " - "descriptor!"); - } - else - { - g_sigterm(tmp->item->pid); + if (tmp->item == 0) + { + log_message(LOG_LEVEL_ERROR, "found null session " + "descriptor!"); + } + else + { + g_sigterm(tmp->item->pid); + } + + /* go on */ + tmp = tmp->next; } - /* go on */ - tmp=tmp->next; - } - - /*THREAD-FIX release chain lock */ - lock_chain_release(); + /*THREAD-FIX release chain lock */ + lock_chain_release(); } /******************************************************************************/ -struct session_item* DEFAULT_CC +struct session_item *DEFAULT_CC session_get_bypid(int pid) { - struct session_chain* tmp; - struct session_item* dummy; + struct session_chain *tmp; + struct session_item *dummy; - dummy = g_malloc(sizeof(struct session_item), 1); - if (0 == dummy) - { - log_message(LOG_LEVEL_ERROR, "internal error", pid); + dummy = g_malloc(sizeof(struct session_item), 1); + + if (0 == dummy) + { + log_message(LOG_LEVEL_ERROR, "internal error", pid); + return 0; + } + + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); + + tmp = g_sessions; + + while (tmp != 0) + { + if (tmp->item == 0) + { + log_message(LOG_LEVEL_ERROR, "session descriptor for " + "pid %d is null!", pid); + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return 0; + } + + if (tmp->item->pid == pid) + { + /*THREAD-FIX release chain lock */ + g_memcpy(dummy, tmp->item, sizeof(struct session_item)); + lock_chain_release(); + /*return tmp->item;*/ + return dummy; + } + + /* go on */ + tmp = tmp->next; + } + + /*THREAD-FIX release chain lock */ + lock_chain_release(); return 0; - } - - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); - - tmp = g_sessions; - while (tmp != 0) - { - if (tmp->item == 0) - { - log_message(LOG_LEVEL_ERROR, "session descriptor for " - "pid %d is null!", pid); - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; - } - - if (tmp->item->pid == pid) - { - /*THREAD-FIX release chain lock */ - g_memcpy(dummy, tmp->item, sizeof(struct session_item)); - lock_chain_release(); - /*return tmp->item;*/ - return dummy; - } - - /* go on */ - tmp=tmp->next; - } - - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; } /******************************************************************************/ -struct SCP_DISCONNECTED_SESSION* -session_get_byuser(char* user, int* cnt, unsigned char flags) +struct SCP_DISCONNECTED_SESSION * +session_get_byuser(char *user, int *cnt, unsigned char flags) { - struct session_chain* tmp; - struct SCP_DISCONNECTED_SESSION* sess; - int count; - int index; + struct session_chain *tmp; + struct SCP_DISCONNECTED_SESSION *sess; + int count; + int index; - count = 0; + count = 0; - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); - tmp = g_sessions; - while (tmp != 0) - { - LOG_DBG("user: %s", user); - if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) + tmp = g_sessions; + + while (tmp != 0) { - LOG_DBG("session_get_byuser: status=%d, flags=%d, " - "result=%d", (tmp->item->status), flags, - ((tmp->item->status) & flags)); - if ((tmp->item->status) & flags) - { - count++; - } + LOG_DBG("user: %s", user); + + if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) + { + LOG_DBG("session_get_byuser: status=%d, flags=%d, " + "result=%d", (tmp->item->status), flags, + ((tmp->item->status) & flags)); + + if ((tmp->item->status) & flags) + { + count++; + } + } + + /* go on */ + tmp = tmp->next; } - /* go on */ - tmp=tmp->next; - } + if (count == 0) + { + (*cnt) = 0; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return 0; + } - if (count == 0) - { - (*cnt) = 0; - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; - } + /* malloc() an array of disconnected sessions */ + sess = g_malloc(count *sizeof(struct SCP_DISCONNECTED_SESSION), 1); - /* malloc() an array of disconnected sessions */ - sess=g_malloc(count * sizeof(struct SCP_DISCONNECTED_SESSION),1); - if (sess == 0) - { - (*cnt) = 0; - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; - } + if (sess == 0) + { + (*cnt) = 0; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return 0; + } - tmp = g_sessions; - index = 0; - while (tmp != 0) - { + tmp = g_sessions; + index = 0; + + while (tmp != 0) + { #warning FIXME: we should get only disconnected sessions! - if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) - { - if ((tmp->item->status) & flags) - { - (sess[index]).SID=tmp->item->pid; - (sess[index]).type=tmp->item->type; - (sess[index]).height=tmp->item->height; - (sess[index]).width=tmp->item->width; - (sess[index]).bpp=tmp->item->bpp; + if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) + { + if ((tmp->item->status) & flags) + { + (sess[index]).SID = tmp->item->pid; + (sess[index]).type = tmp->item->type; + (sess[index]).height = tmp->item->height; + (sess[index]).width = tmp->item->width; + (sess[index]).bpp = tmp->item->bpp; #warning FIXME: setting idle times and such - /*(sess[index]).connect_time.year = tmp->item->connect_time.year; - (sess[index]).connect_time.month = tmp->item->connect_time.month; - (sess[index]).connect_time.day = tmp->item->connect_time.day; - (sess[index]).connect_time.hour = tmp->item->connect_time.hour; - (sess[index]).connect_time.minute = tmp->item->connect_time.minute; - (sess[index]).disconnect_time.year = tmp->item->disconnect_time.year; - (sess[index]).disconnect_time.month = tmp->item->disconnect_time.month; - (sess[index]).disconnect_time.day = tmp->item->disconnect_time.day; - (sess[index]).disconnect_time.hour = tmp->item->disconnect_time.hour; - (sess[index]).disconnect_time.minute = tmp->item->disconnect_time.minute; - (sess[index]).idle_time.year = tmp->item->idle_time.year; - (sess[index]).idle_time.month = tmp->item->idle_time.month; - (sess[index]).idle_time.day = tmp->item->idle_time.day; - (sess[index]).idle_time.hour = tmp->item->idle_time.hour; - (sess[index]).idle_time.minute = tmp->item->idle_time.minute;*/ - (sess[index]).conn_year = tmp->item->connect_time.year; - (sess[index]).conn_month = tmp->item->connect_time.month; - (sess[index]).conn_day = tmp->item->connect_time.day; - (sess[index]).conn_hour = tmp->item->connect_time.hour; - (sess[index]).conn_minute = tmp->item->connect_time.minute; - (sess[index]).idle_days = tmp->item->idle_time.day; - (sess[index]).idle_hours = tmp->item->idle_time.hour; - (sess[index]).idle_minutes = tmp->item->idle_time.minute; + /*(sess[index]).connect_time.year = tmp->item->connect_time.year; + (sess[index]).connect_time.month = tmp->item->connect_time.month; + (sess[index]).connect_time.day = tmp->item->connect_time.day; + (sess[index]).connect_time.hour = tmp->item->connect_time.hour; + (sess[index]).connect_time.minute = tmp->item->connect_time.minute; + (sess[index]).disconnect_time.year = tmp->item->disconnect_time.year; + (sess[index]).disconnect_time.month = tmp->item->disconnect_time.month; + (sess[index]).disconnect_time.day = tmp->item->disconnect_time.day; + (sess[index]).disconnect_time.hour = tmp->item->disconnect_time.hour; + (sess[index]).disconnect_time.minute = tmp->item->disconnect_time.minute; + (sess[index]).idle_time.year = tmp->item->idle_time.year; + (sess[index]).idle_time.month = tmp->item->idle_time.month; + (sess[index]).idle_time.day = tmp->item->idle_time.day; + (sess[index]).idle_time.hour = tmp->item->idle_time.hour; + (sess[index]).idle_time.minute = tmp->item->idle_time.minute;*/ + (sess[index]).conn_year = tmp->item->connect_time.year; + (sess[index]).conn_month = tmp->item->connect_time.month; + (sess[index]).conn_day = tmp->item->connect_time.day; + (sess[index]).conn_hour = tmp->item->connect_time.hour; + (sess[index]).conn_minute = tmp->item->connect_time.minute; + (sess[index]).idle_days = tmp->item->idle_time.day; + (sess[index]).idle_hours = tmp->item->idle_time.hour; + (sess[index]).idle_minutes = tmp->item->idle_time.minute; - index++; - } + index++; + } + } + + /* go on */ + tmp = tmp->next; } - /* go on */ - tmp=tmp->next; - } - - /*THREAD-FIX release chain lock */ - lock_chain_release(); - (*cnt)=count; - return sess; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + (*cnt) = count; + return sess; } diff --git a/sesman/session.h b/sesman/session.h index a8de90d5..b62b2aee 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/sessvc/sessvc.c b/sesman/sessvc/sessvc.c index 1ca32b00..2344229c 100644 --- a/sesman/sessvc/sessvc.c +++ b/sesman/sessvc/sessvc.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file sessvc.c * @brief Session supervisor * @author Simone Fedele - * + * */ #if defined(HAVE_CONFIG_H) @@ -38,15 +37,15 @@ static int g_term = 0; void DEFAULT_CC term_signal_handler(int sig) { - g_writeln("xrdp-sessvc: term_signal_handler: got signal %d", sig); - g_term = 1; + g_writeln("xrdp-sessvc: term_signal_handler: got signal %d", sig); + g_term = 1; } /*****************************************************************************/ void DEFAULT_CC nil_signal_handler(int sig) { - g_writeln("xrdp-sessvc: nil_signal_handler: got signal %d", sig); + g_writeln("xrdp-sessvc: nil_signal_handler: got signal %d", sig); } /******************************************************************************/ @@ -54,101 +53,115 @@ nil_signal_handler(int sig) int APP_CC chansrv_cleanup(int pid) { - char text[256]; + char text[256]; - g_snprintf(text, 255, "/tmp/.xrdp/xrdp_chansrv_%8.8x_main_term", pid); - if (g_file_exist(text)) - { - g_file_delete(text); - } - g_snprintf(text, 255, "/tmp/.xrdp/xrdp_chansrv_%8.8x_thread_done", pid); - if (g_file_exist(text)) - { - g_file_delete(text); - } - return 0; + g_snprintf(text, 255, "/tmp/.xrdp/xrdp_chansrv_%8.8x_main_term", pid); + + if (g_file_exist(text)) + { + g_file_delete(text); + } + + g_snprintf(text, 255, "/tmp/.xrdp/xrdp_chansrv_%8.8x_thread_done", pid); + + if (g_file_exist(text)) + { + g_file_delete(text); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - int ret = 0; - int chansrv_pid = 0; - int wm_pid = 0; - int x_pid = 0; - int lerror = 0; - char exe_path[262]; + int ret = 0; + int chansrv_pid = 0; + int wm_pid = 0; + int x_pid = 0; + int lerror = 0; + char exe_path[262]; - g_init("xrdp-sessvc"); - g_memset(exe_path,0,sizeof(exe_path)); + g_init("xrdp-sessvc"); + g_memset(exe_path, 0, sizeof(exe_path)); - if (argc < 3) - { - g_writeln("xrdp-sessvc: exiting, not enough parameters"); - g_deinit(); - return 1; - } - g_signal_kill(term_signal_handler); /* SIGKILL */ - g_signal_terminate(term_signal_handler); /* SIGTERM */ - g_signal_user_interrupt(term_signal_handler); /* SIGINT */ - g_signal_pipe(nil_signal_handler); /* SIGPIPE */ - x_pid = g_atoi(argv[1]); - wm_pid = g_atoi(argv[2]); - g_writeln("xrdp-sessvc: waiting for X (pid %d) and WM (pid %d)", - x_pid, wm_pid); - /* run xrdp-chansrv as a seperate process */ - chansrv_pid = g_fork(); - if (chansrv_pid == -1) - { - g_writeln("xrdp-sessvc: fork error"); - g_deinit(); - return 1; - } - else if (chansrv_pid == 0) /* child */ - { - g_set_current_dir(XRDP_SBIN_PATH); - g_snprintf(exe_path, 261, "%s/xrdp-chansrv", XRDP_SBIN_PATH); - g_execlp3(exe_path, "xrdp-chansrv", 0); - /* should not get here */ - g_writeln("xrdp-sessvc: g_execlp3() failed"); - g_deinit(); - return 1; - } - lerror = 0; - /* wait for window manager to get done */ - ret = g_waitpid(wm_pid); - while ((ret == 0) && !g_term) - { + if (argc < 3) + { + g_writeln("xrdp-sessvc: exiting, not enough parameters"); + g_deinit(); + return 1; + } + + g_signal_kill(term_signal_handler); /* SIGKILL */ + g_signal_terminate(term_signal_handler); /* SIGTERM */ + g_signal_user_interrupt(term_signal_handler); /* SIGINT */ + g_signal_pipe(nil_signal_handler); /* SIGPIPE */ + x_pid = g_atoi(argv[1]); + wm_pid = g_atoi(argv[2]); + g_writeln("xrdp-sessvc: waiting for X (pid %d) and WM (pid %d)", + x_pid, wm_pid); + /* run xrdp-chansrv as a seperate process */ + chansrv_pid = g_fork(); + + if (chansrv_pid == -1) + { + g_writeln("xrdp-sessvc: fork error"); + g_deinit(); + return 1; + } + else if (chansrv_pid == 0) /* child */ + { + g_set_current_dir(XRDP_SBIN_PATH); + g_snprintf(exe_path, 261, "%s/xrdp-chansrv", XRDP_SBIN_PATH); + g_execlp3(exe_path, "xrdp-chansrv", 0); + /* should not get here */ + g_writeln("xrdp-sessvc: g_execlp3() failed"); + g_deinit(); + return 1; + } + + lerror = 0; + /* wait for window manager to get done */ ret = g_waitpid(wm_pid); - g_sleep(1); - } - if (ret < 0) - { - lerror = g_get_errno(); - } - g_writeln("xrdp-sessvc: WM is dead (waitpid said %d, errno is %d) " - "exiting...", ret, lerror); - /* kill channel server */ - g_writeln("xrdp-sessvc: stopping channel server"); - g_sigterm(chansrv_pid); - ret = g_waitpid(chansrv_pid); - while ((ret == 0) && !g_term) - { + + while ((ret == 0) && !g_term) + { + ret = g_waitpid(wm_pid); + g_sleep(1); + } + + if (ret < 0) + { + lerror = g_get_errno(); + } + + g_writeln("xrdp-sessvc: WM is dead (waitpid said %d, errno is %d) " + "exiting...", ret, lerror); + /* kill channel server */ + g_writeln("xrdp-sessvc: stopping channel server"); + g_sigterm(chansrv_pid); ret = g_waitpid(chansrv_pid); - g_sleep(1); - } - chansrv_cleanup(chansrv_pid); - /* kill X server */ - g_writeln("xrdp-sessvc: stopping X server"); - g_sigterm(x_pid); - ret = g_waitpid(x_pid); - while ((ret == 0) && !g_term) - { + + while ((ret == 0) && !g_term) + { + ret = g_waitpid(chansrv_pid); + g_sleep(1); + } + + chansrv_cleanup(chansrv_pid); + /* kill X server */ + g_writeln("xrdp-sessvc: stopping X server"); + g_sigterm(x_pid); ret = g_waitpid(x_pid); - g_sleep(1); - } - g_writeln("xrdp-sessvc: clean exit"); - g_deinit(); - return 0; + + while ((ret == 0) && !g_term) + { + ret = g_waitpid(x_pid); + g_sleep(1); + } + + g_writeln("xrdp-sessvc: clean exit"); + g_deinit(); + return 0; } diff --git a/sesman/sig.c b/sesman/sig.c index 151c0c57..b8f320f1 100644 --- a/sesman/sig.c +++ b/sesman/sig.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,170 +30,176 @@ extern int g_sck; extern int g_pid; -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ extern tbus g_term_event; /******************************************************************************/ void DEFAULT_CC sig_sesman_shutdown(int sig) { - char pid_file[256]; + char pid_file[256]; - log_message(LOG_LEVEL_INFO, "shutting down sesman %d", 1); + log_message(LOG_LEVEL_INFO, "shutting down sesman %d", 1); - if (g_getpid() != g_pid) - { - LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid); - return; - } + if (g_getpid() != g_pid) + { + LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid); + return; + } - LOG_DBG(" - getting signal %d pid %d", sig, g_getpid()); + LOG_DBG(" - getting signal %d pid %d", sig, g_getpid()); - g_set_wait_obj(g_term_event); + g_set_wait_obj(g_term_event); - g_tcp_close(g_sck); + g_tcp_close(g_sck); - session_sigkill_all(); + session_sigkill_all(); - g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); - g_file_delete(pid_file); + g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); + g_file_delete(pid_file); } /******************************************************************************/ void DEFAULT_CC sig_sesman_reload_cfg(int sig) { - int error; - struct config_sesman *cfg; - char cfg_file[256]; + int error; + struct config_sesman *cfg; + char cfg_file[256]; - log_message(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1); + log_message(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1); - if (g_getpid() != g_pid) - { - LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid); - return; - } - - cfg = g_malloc(sizeof(struct config_sesman), 1); - if (0 == cfg) - { - log_message(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg"); - return; - } - - if (config_read(cfg) != 0) - { - log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg"); - return; - } - - /* stop logging subsystem */ - log_end(); - - /* replace old config with new readed one */ - g_cfg = cfg; - - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - - /* start again logging subsystem */ - error = log_start(cfg_file,"XRDP-sesman"); - - if (error != LOG_STARTUP_OK) - { - char buf[256]; - switch (error) + if (g_getpid() != g_pid) { - case LOG_ERROR_MALLOC: - g_printf("error on malloc. cannot restart logging. log stops here, sorry.\n"); - break; - case LOG_ERROR_FILE_OPEN: - g_printf("error reopening log file [%s]. log stops here, sorry.\n", getLogFile(buf,255)); - break; + LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid); + return; } - } - log_message(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted"); + cfg = g_malloc(sizeof(struct config_sesman), 1); + + if (0 == cfg) + { + log_message(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg"); + return; + } + + if (config_read(cfg) != 0) + { + log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg"); + return; + } + + /* stop logging subsystem */ + log_end(); + + /* replace old config with new readed one */ + g_cfg = cfg; + + g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); + + /* start again logging subsystem */ + error = log_start(cfg_file, "XRDP-sesman"); + + if (error != LOG_STARTUP_OK) + { + char buf[256]; + + switch (error) + { + case LOG_ERROR_MALLOC: + g_printf("error on malloc. cannot restart logging. log stops here, sorry.\n"); + break; + case LOG_ERROR_FILE_OPEN: + g_printf("error reopening log file [%s]. log stops here, sorry.\n", getLogFile(buf, 255)); + break; + } + } + + log_message(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted"); } /******************************************************************************/ void DEFAULT_CC sig_sesman_session_end(int sig) { - int pid; + int pid; - if (g_getpid() != g_pid) - { - return; - } - pid = g_waitchild(); - if (pid > 0) - { - session_kill(pid); - } + if (g_getpid() != g_pid) + { + return; + } + + pid = g_waitchild(); + + if (pid > 0) + { + session_kill(pid); + } } /******************************************************************************/ -void* DEFAULT_CC -sig_handler_thread(void* arg) +void *DEFAULT_CC +sig_handler_thread(void *arg) { - int recv_signal; - sigset_t sigmask; - sigset_t oldmask; - sigset_t waitmask; + int recv_signal; + sigset_t sigmask; + sigset_t oldmask; + sigset_t waitmask; - /* mask signals to be able to wait for them... */ - sigfillset(&sigmask); - /* it is a good idea not to block SIGILL SIGSEGV */ - /* SIGFPE -- see sigaction(2) NOTES */ - pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); + /* mask signals to be able to wait for them... */ + sigfillset(&sigmask); + /* it is a good idea not to block SIGILL SIGSEGV */ + /* SIGFPE -- see sigaction(2) NOTES */ + pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); - /* building the signal wait mask... */ - sigemptyset(&waitmask); - sigaddset(&waitmask, SIGHUP); - sigaddset(&waitmask, SIGCHLD); - sigaddset(&waitmask, SIGTERM); - sigaddset(&waitmask, SIGKILL); - sigaddset(&waitmask, SIGINT); + /* building the signal wait mask... */ + sigemptyset(&waitmask); + sigaddset(&waitmask, SIGHUP); + sigaddset(&waitmask, SIGCHLD); + sigaddset(&waitmask, SIGTERM); + sigaddset(&waitmask, SIGKILL); + sigaddset(&waitmask, SIGINT); -// sigaddset(&waitmask, SIGFPE); -// sigaddset(&waitmask, SIGILL); -// sigaddset(&waitmask, SIGSEGV); + // sigaddset(&waitmask, SIGFPE); + // sigaddset(&waitmask, SIGILL); + // sigaddset(&waitmask, SIGSEGV); - do - { - LOG_DBG(&(g_cfg->log), "calling sigwait()",0); - sigwait(&waitmask, &recv_signal); - switch (recv_signal) + do { - case SIGHUP: - //reload cfg - //we must stop & restart logging, or copy logging cfg!!!! - LOG_DBG("sesman received SIGHUP", 0); - //return 0; - break; - case SIGCHLD: - /* a session died */ - LOG_DBG("sesman received SIGCHLD", 0); - sig_sesman_session_end(SIGCHLD); - break; - case SIGINT: - /* we die */ - LOG_DBG("sesman received SIGINT", 0); - sig_sesman_shutdown(recv_signal); - break; - case SIGKILL: - /* we die */ - LOG_DBG("sesman received SIGKILL", 0); - sig_sesman_shutdown(recv_signal); - break; - case SIGTERM: - /* we die */ - LOG_DBG("sesman received SIGTERM", 0); - sig_sesman_shutdown(recv_signal); - break; - } - } while (1); + LOG_DBG(&(g_cfg->log), "calling sigwait()", 0); + sigwait(&waitmask, &recv_signal); - return 0; + switch (recv_signal) + { + case SIGHUP: + //reload cfg + //we must stop & restart logging, or copy logging cfg!!!! + LOG_DBG("sesman received SIGHUP", 0); + //return 0; + break; + case SIGCHLD: + /* a session died */ + LOG_DBG("sesman received SIGCHLD", 0); + sig_sesman_session_end(SIGCHLD); + break; + case SIGINT: + /* we die */ + LOG_DBG("sesman received SIGINT", 0); + sig_sesman_shutdown(recv_signal); + break; + case SIGKILL: + /* we die */ + LOG_DBG("sesman received SIGKILL", 0); + sig_sesman_shutdown(recv_signal); + break; + case SIGTERM: + /* we die */ + LOG_DBG("sesman received SIGTERM", 0); + sig_sesman_shutdown(recv_signal); + break; + } + } + while (1); + + return 0; } diff --git a/sesman/sig.h b/sesman/sig.h index 7c6d2bfe..ac648da0 100644 --- a/sesman/sig.h +++ b/sesman/sig.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -64,4 +63,3 @@ void* DEFAULT_CC sig_handler_thread(void* arg); #endif - diff --git a/sesman/thread.c b/sesman/thread.c index 98a92533..a33b93d9 100644 --- a/sesman/thread.c +++ b/sesman/thread.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,7 +30,7 @@ #include #include -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ static pthread_t g_thread_sighandler; //static pthread_t g_thread_updater; @@ -43,53 +42,53 @@ int g_thread_sck; int DEFAULT_CC thread_sighandler_start(void) { - int ret; - sigset_t sigmask; - sigset_t oldmask; - sigset_t waitmask; + int ret; + sigset_t sigmask; + sigset_t oldmask; + sigset_t waitmask; - /* mask signals to be able to wait for them... */ - sigfillset(&sigmask); - pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); + /* mask signals to be able to wait for them... */ + sigfillset(&sigmask); + pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); - /* unblock some signals... */ - sigemptyset(&waitmask); + /* unblock some signals... */ + sigemptyset(&waitmask); - /* it is a good idea not to block SIGILL SIGSEGV */ - /* SIGFPE -- see sigaction(2) NOTES */ - sigaddset(&waitmask, SIGILL); - sigaddset(&waitmask, SIGSEGV); - sigaddset(&waitmask, SIGFPE); - pthread_sigmask(SIG_UNBLOCK, &waitmask, NULL); + /* it is a good idea not to block SIGILL SIGSEGV */ + /* SIGFPE -- see sigaction(2) NOTES */ + sigaddset(&waitmask, SIGILL); + sigaddset(&waitmask, SIGSEGV); + sigaddset(&waitmask, SIGFPE); + pthread_sigmask(SIG_UNBLOCK, &waitmask, NULL); - log_message(LOG_LEVEL_INFO,"starting signal handling thread..."); + log_message(LOG_LEVEL_INFO, "starting signal handling thread..."); - ret = pthread_create(&g_thread_sighandler, NULL, sig_handler_thread, ""); - pthread_detach(g_thread_sighandler); + ret = pthread_create(&g_thread_sighandler, NULL, sig_handler_thread, ""); + pthread_detach(g_thread_sighandler); - if (ret == 0) - { - log_message(LOG_LEVEL_INFO, "signal handler thread started successfully"); - return 0; - } + if (ret == 0) + { + log_message(LOG_LEVEL_INFO, "signal handler thread started successfully"); + return 0; + } - /* if something happened while starting a new thread... */ - switch (ret) - { - case EINVAL: - log_message(LOG_LEVEL_ERROR, "invalid attributes for signal handling thread (creation returned EINVAL)"); - break; - case EAGAIN: - log_message(LOG_LEVEL_ERROR, "not enough resources to start signal handling thread (creation returned EAGAIN)"); - break; - case EPERM: - log_message(LOG_LEVEL_ERROR, "invalid permissions for signal handling thread (creation returned EPERM)"); - break; - default: - log_message(LOG_LEVEL_ERROR, "unknown error starting signal handling thread"); - } + /* if something happened while starting a new thread... */ + switch (ret) + { + case EINVAL: + log_message(LOG_LEVEL_ERROR, "invalid attributes for signal handling thread (creation returned EINVAL)"); + break; + case EAGAIN: + log_message(LOG_LEVEL_ERROR, "not enough resources to start signal handling thread (creation returned EAGAIN)"); + break; + case EPERM: + log_message(LOG_LEVEL_ERROR, "invalid permissions for signal handling thread (creation returned EPERM)"); + break; + default: + log_message(LOG_LEVEL_ERROR, "unknown error starting signal handling thread"); + } - return 1; + return 1; } #ifdef JUST_TO_AVOID_COMPILER_ERRORS @@ -97,38 +96,38 @@ thread_sighandler_start(void) int DEFAULT_CC thread_session_update_start(void) { - int ret; - //starts the session update thread - //that checks for idle time, destroys sessions, ecc... + int ret; + //starts the session update thread + //that checks for idle time, destroys sessions, ecc... #warning this thread should always request lock_fork before read or write #warning (so we can Fork() In Peace) - ret = pthread_create(&g_thread_updater, NULL, , ""); - pthread_detach(g_thread_updater); + ret = pthread_create(&g_thread_updater, NULL, , ""); + pthread_detach(g_thread_updater); - if (ret == 0) - { - log_message(&(g_cfg->log), LOG_LEVEL_INFO, "session update thread started successfully"); - return 0; - } + if (ret == 0) + { + log_message(&(g_cfg->log), LOG_LEVEL_INFO, "session update thread started successfully"); + return 0; + } - /* if something happened while starting a new thread... */ - switch (ret) - { - case EINVAL: - log_message(LOG_LEVEL_ERROR, "invalid attributes for session update thread (creation returned EINVAL)"); - break; - case EAGAIN: - log_message(LOG_LEVEL_ERROR, "not enough resources to start session update thread (creation returned EAGAIN)"); - break; - case EPERM: - log_message(LOG_LEVEL_ERROR, "invalid permissions for session update thread (creation returned EPERM)"); - break; - default: - log_message(LOG_LEVEL_ERROR, "unknown error starting session update thread"); - } + /* if something happened while starting a new thread... */ + switch (ret) + { + case EINVAL: + log_message(LOG_LEVEL_ERROR, "invalid attributes for session update thread (creation returned EINVAL)"); + break; + case EAGAIN: + log_message(LOG_LEVEL_ERROR, "not enough resources to start session update thread (creation returned EAGAIN)"); + break; + case EPERM: + log_message(LOG_LEVEL_ERROR, "invalid permissions for session update thread (creation returned EPERM)"); + break; + default: + log_message(LOG_LEVEL_ERROR, "unknown error starting session update thread"); + } - return 1; + return 1; } #endif @@ -136,39 +135,39 @@ thread_session_update_start(void) int DEFAULT_CC thread_scp_start(int skt) { - int ret; - pthread_t th; + int ret; + pthread_t th; - /* blocking the use of thread_skt */ - lock_socket_acquire(); - g_thread_sck = skt; + /* blocking the use of thread_skt */ + lock_socket_acquire(); + g_thread_sck = skt; - /* start a thread that processes a connection */ - ret = pthread_create(&th, NULL, scp_process_start, ""); - //ret = pthread_create(&th, NULL, scp_process_start, (void*) (&g_thread_sck)); - pthread_detach(th); + /* start a thread that processes a connection */ + ret = pthread_create(&th, NULL, scp_process_start, ""); + //ret = pthread_create(&th, NULL, scp_process_start, (void*) (&g_thread_sck)); + pthread_detach(th); - if (ret == 0) - { - log_message(LOG_LEVEL_INFO, "scp thread on sck %d started successfully", skt); - return 0; - } + if (ret == 0) + { + log_message(LOG_LEVEL_INFO, "scp thread on sck %d started successfully", skt); + return 0; + } - /* if something happened while starting a new thread... */ - switch (ret) - { - case EINVAL: - log_message(LOG_LEVEL_ERROR, "invalid attributes for scp thread on sck %d (creation returned EINVAL)", skt); - break; - case EAGAIN: - log_message(LOG_LEVEL_ERROR, "not enough resources to start scp thread on sck %d (creation returned EAGAIN)", skt); - break; - case EPERM: - log_message(LOG_LEVEL_ERROR, "invalid permissions for scp thread on sck %d (creation returned EPERM)", skt); - break; - default: - log_message(LOG_LEVEL_ERROR, "unknown error starting scp thread on sck %d"); - } + /* if something happened while starting a new thread... */ + switch (ret) + { + case EINVAL: + log_message(LOG_LEVEL_ERROR, "invalid attributes for scp thread on sck %d (creation returned EINVAL)", skt); + break; + case EAGAIN: + log_message(LOG_LEVEL_ERROR, "not enough resources to start scp thread on sck %d (creation returned EAGAIN)", skt); + break; + case EPERM: + log_message(LOG_LEVEL_ERROR, "invalid permissions for scp thread on sck %d (creation returned EPERM)", skt); + break; + default: + log_message(LOG_LEVEL_ERROR, "unknown error starting scp thread on sck %d"); + } - return 1; + return 1; } diff --git a/sesman/thread.h b/sesman/thread.h index b3c12258..9dcb53b4 100644 --- a/sesman/thread.h +++ b/sesman/thread.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/tools/dis.c b/sesman/tools/dis.c index 0dbc74d8..52400847 100644 --- a/sesman/tools/dis.c +++ b/sesman/tools/dis.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2011 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #include @@ -24,42 +23,48 @@ #include #include -int main(int argc, char** argv) +int main(int argc, char **argv) { - int sck; - int dis; - struct sockaddr_un sa; - size_t len; - char* p; - char* display; + int sck; + int dis; + struct sockaddr_un sa; + size_t len; + char *p; + char *display; + + if (argc != 1) + { + printf("xrdp disconnect utility\n"); + printf("run with no parameters to disconnect you xrdp session\n"); + return 0; + } + + display = getenv("DISPLAY"); + + if (display == 0) + { + printf("display not set\n"); + return 1; + } + + dis = strtol(display + 1, &p, 10); + memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + sprintf(sa.sun_path, "/tmp/.xrdp/xrdp_disconnect_display_%d", dis); + + if (access(sa.sun_path, F_OK) != 0) + { + printf("not in an xrdp session\n"); + return 1; + } + + sck = socket(PF_UNIX, SOCK_DGRAM, 0); + len = sizeof(sa); + + if (sendto(sck, "sig", 4, 0, (struct sockaddr *)&sa, len) > 0) + { + printf("message sent ok\n"); + } - if (argc != 1) - { - printf("xrdp disconnect utility\n"); - printf("run with no parameters to disconnect you xrdp session\n"); return 0; - } - - display = getenv("DISPLAY"); - if (display == 0) - { - printf("display not set\n"); - return 1; - } - dis = strtol(display + 1, &p, 10); - memset(&sa, 0, sizeof(sa)); - sa.sun_family = AF_UNIX; - sprintf(sa.sun_path, "/tmp/.xrdp/xrdp_disconnect_display_%d", dis); - if (access(sa.sun_path, F_OK) != 0) - { - printf("not in an xrdp session\n"); - return 1; - } - sck = socket(PF_UNIX, SOCK_DGRAM, 0); - len = sizeof(sa); - if (sendto(sck, "sig", 4, 0, (struct sockaddr*)&sa, len) > 0) - { - printf("message sent ok\n"); - } - return 0; } diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c index 22f20c23..25af850b 100644 --- a/sesman/tools/sesadmin.c +++ b/sesman/tools/sesadmin.c @@ -22,174 +22,176 @@ char port[257]; struct log_config logging; -void cmndList(struct SCP_CONNECTION* c); -void cmndKill(struct SCP_CONNECTION* c, struct SCP_SESSION* s); +void cmndList(struct SCP_CONNECTION *c); +void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s); void cmndHelp(); -int inputSession(struct SCP_SESSION* s); +int inputSession(struct SCP_SESSION *s); unsigned int menuSelect(unsigned int choices); -int main(int argc, char** argv) +int main(int argc, char **argv) { - struct SCP_SESSION* s; - struct SCP_CONNECTION* c; - enum SCP_CLIENT_STATES_E e; - //int end; - int idx; - //int sel; - int sock; - char* pwd; + struct SCP_SESSION *s; + struct SCP_CONNECTION *c; + enum SCP_CLIENT_STATES_E e; + //int end; + int idx; + //int sel; + int sock; + char *pwd; - user[0]='\0'; - pass[0]='\0'; - cmnd[0]='\0'; - serv[0]='\0'; - port[0]='\0'; + user[0] = '\0'; + pass[0] = '\0'; + cmnd[0] = '\0'; + serv[0] = '\0'; + port[0] = '\0'; - logging.program_name = g_strdup("sesadmin"); - logging.log_file = g_strdup("xrdp-sesadmin.log"); - logging.log_level = LOG_LEVEL_DEBUG; - logging.enable_syslog = 0; - log_start_from_param(&logging); + logging.program_name = g_strdup("sesadmin"); + logging.log_file = g_strdup("xrdp-sesadmin.log"); + logging.log_level = LOG_LEVEL_DEBUG; + logging.enable_syslog = 0; + log_start_from_param(&logging); - for (idx = 0; idx < argc; idx++) - { - if (0 == g_strncmp(argv[idx], "-u=", 3)) + for (idx = 0; idx < argc; idx++) { - g_strncpy(user, (argv[idx])+3, 256); + if (0 == g_strncmp(argv[idx], "-u=", 3)) + { + g_strncpy(user, (argv[idx]) + 3, 256); + } + else if (0 == g_strncmp(argv[idx], "-p=", 3)) + { + g_strncpy(pass, (argv[idx]) + 3, 256); + } + else if (0 == g_strncmp(argv[idx], "-s=", 3)) + { + g_strncpy(serv, (argv[idx]) + 3, 256); + } + else if (0 == g_strncmp(argv[idx], "-i=", 3)) + { + g_strncpy(port, (argv[idx]) + 3, 256); + } + else if (0 == g_strncmp(argv[idx], "-c=", 3)) + { + g_strncpy(cmnd, (argv[idx]) + 3, 256); + } } - else if (0 == g_strncmp(argv[idx], "-p=", 3)) + + if (0 == g_strncmp(serv, "", 1)) { - g_strncpy(pass, (argv[idx])+3, 256); + g_strncpy(serv, "localhost", 256); } - else if (0 == g_strncmp(argv[idx], "-s=", 3)) + + if (0 == g_strncmp(port, "", 1)) { - g_strncpy(serv, (argv[idx])+3, 256); + g_strncpy(port, "3350", 256); } - else if (0 == g_strncmp(argv[idx], "-i=", 3)) + + if (0 == g_strncmp(user, "", 1)) { - g_strncpy(port, (argv[idx])+3, 256); + g_strncpy(user, "root", 256); } - else if (0 == g_strncmp(argv[idx], "-c=", 3)) + + if (0 == g_strncmp(pass, "", 1)) { - g_strncpy(cmnd, (argv[idx])+3, 256); + pwd = getpass("password:"); + g_strncpy(pass, pwd, 256); + + /* zeroing the password */ + while ((*pwd) != '\0') + { + (*pwd) = 0x00; + pwd++; + } } - } - if (0 == g_strncmp(serv, "", 1)) - { - g_strncpy(serv, "localhost", 256); - } + scp_init(&logging); - if (0 == g_strncmp(port, "", 1)) - { - g_strncpy(port, "3350", 256); - } + sock = g_tcp_socket(); + s = scp_session_create(); + c = scp_connection_create(sock); - if (0 == g_strncmp(user, "", 1)) - { - g_strncpy(user, "root", 256); - } + LOG_DBG("Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass); - if (0 == g_strncmp(pass, "", 1)) - { - pwd = getpass("password:"); - g_strncpy(pass, pwd, 256); - - /* zeroing the password */ - while ((*pwd) != '\0') + if (0 != g_tcp_connect(sock, serv, port)) { - (*pwd) = 0x00; - pwd++; + LOG_DBG("g_tcp_connect() error\n"); + return 1; } - } - scp_init(&logging); + scp_session_set_type(s, SCP_SESSION_TYPE_MANAGE); + scp_session_set_version(s, 1); + scp_session_set_username(s, user); + scp_session_set_password(s, pass); - sock = g_tcp_socket(); - s = scp_session_create(); - c = scp_connection_create(sock); + e = scp_v1c_mng_connect(c, s); - LOG_DBG("Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass); + if (SCP_CLIENT_STATE_OK != e) + { + LOG_DBG("libscp error connecting: %s %d\n", s->errstr, (int)e); + } - if (0 != g_tcp_connect(sock, serv, port)) - { - LOG_DBG("g_tcp_connect() error\n"); - return 1; - } + if (0 == g_strncmp(cmnd, "list", 5)) + { + cmndList(c); + } + else if (0 == g_strncmp(cmnd, "kill:", 5)) + { + cmndKill(c, s); + } - scp_session_set_type(s, SCP_SESSION_TYPE_MANAGE); - scp_session_set_version(s, 1); - scp_session_set_username(s, user); - scp_session_set_password(s, pass); + g_tcp_close(sock); + scp_session_destroy(s); + scp_connection_destroy(c); + log_end(); - e = scp_v1c_mng_connect(c,s); - - if (SCP_CLIENT_STATE_OK != e) - { - LOG_DBG("libscp error connecting: %s %d\n", s->errstr, (int)e); - } - - if (0 == g_strncmp(cmnd, "list", 5)) - { - cmndList(c); - } - else if (0 == g_strncmp(cmnd, "kill:", 5)) - { - cmndKill(c,s); - } - - g_tcp_close(sock); - scp_session_destroy(s); - scp_connection_destroy(c); - log_end(); - - return 0; + return 0; } void cmndHelp() { - fprintf(stderr, "sesadmin - a console sesman adminitration tool\n"); - fprintf(stderr, "sysntax: sesadmin [] COMMAND [OPTIONS]\n\n"); - fprintf(stderr, "-u=: username to connect to sesman [MANDATORY]\n"); - fprintf(stderr, "-p=: password to connect to sesman [MANDATORY]\n"); - fprintf(stderr, "-s=: sesman host (default is localhost)\n"); - fprintf(stderr, "-i= : sesman port (default 3350)\n"); - fprintf(stderr, "-c= : command to execute on the server [MANDATORY]\n"); - fprintf(stderr, " it can be one of those:\n"); - fprintf(stderr, " LIST\n"); - fprintf(stderr, " KILL:\n"); + fprintf(stderr, "sesadmin - a console sesman adminitration tool\n"); + fprintf(stderr, "sysntax: sesadmin [] COMMAND [OPTIONS]\n\n"); + fprintf(stderr, "-u=: username to connect to sesman [MANDATORY]\n"); + fprintf(stderr, "-p=: password to connect to sesman [MANDATORY]\n"); + fprintf(stderr, "-s=: sesman host (default is localhost)\n"); + fprintf(stderr, "-i= : sesman port (default 3350)\n"); + fprintf(stderr, "-c= : command to execute on the server [MANDATORY]\n"); + fprintf(stderr, " it can be one of those:\n"); + fprintf(stderr, " LIST\n"); + fprintf(stderr, " KILL:\n"); } -void cmndList(struct SCP_CONNECTION* c) +void cmndList(struct SCP_CONNECTION *c) { - struct SCP_DISCONNECTED_SESSION* dsl; - enum SCP_CLIENT_STATES_E e; - int scnt; - int idx; + struct SCP_DISCONNECTED_SESSION *dsl; + enum SCP_CLIENT_STATES_E e; + int scnt; + int idx; - e = scp_v1c_mng_get_session_list(c, &scnt, &dsl); - if ((SCP_CLIENT_STATE_LIST_OK == e) && (scnt > 0)) - { - for (idx = 0; idx < scnt; idx++) + e = scp_v1c_mng_get_session_list(c, &scnt, &dsl); + + if ((SCP_CLIENT_STATE_LIST_OK == e) && (scnt > 0)) { - printf("%d\t%d\t%dx%dx%d\t%d-%d-%d\t%04d/%02d/%02d@%02d:%02d\n", \ - (dsl[idx]).SID, (dsl[idx]).type, (dsl[idx]).width, (dsl[idx]).height, (dsl[idx]).bpp, \ - (dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \ - (dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute); + for (idx = 0; idx < scnt; idx++) + { + printf("%d\t%d\t%dx%dx%d\t%d-%d-%d\t%04d/%02d/%02d@%02d:%02d\n", \ + (dsl[idx]).SID, (dsl[idx]).type, (dsl[idx]).width, (dsl[idx]).height, (dsl[idx]).bpp, \ + (dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \ + (dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute); + } + + if (0 != dsl) + { + g_free(dsl); + } } - if (0 != dsl) + else { - g_free(dsl); + printf("No sessions.\n"); } - } - else - { - printf("No sessions.\n"); - } } -void cmndKill(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { } diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c index f22e5a30..5ad3b5cc 100644 --- a/sesman/tools/sesrun.c +++ b/sesman/tools/sesrun.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file sesrun.c * @brief An utility to start a session * @author Jay Sorg, Simone Fedele - * + * */ #include "sesman.h" @@ -34,93 +33,100 @@ struct config_sesman g_cfg; /* config.h */ /******************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - int sck; - int code; - int i; - int size; - int version; - int width; - int height; - int bpp; - int display; - struct stream* in_s; - struct stream* out_s; - char* username; - char* password; - long data; + int sck; + int code; + int i; + int size; + int version; + int width; + int height; + int bpp; + int display; + struct stream *in_s; + struct stream *out_s; + char *username; + char *password; + long data; - if (0 != config_read(&g_cfg)) - { - g_printf("sesrun: error reading config. quitting.\n"); - return 1; - } - - g_pid = g_getpid(); - if (argc == 1) - { - g_printf("xrdp session starter v0.1\n"); - g_printf("\nusage:\n"); - g_printf("sesrun \n"); - } - else if (argc == 7) - { - username = argv[2]; - password = argv[3]; - width = g_atoi(argv[4]); - height = g_atoi(argv[5]); - bpp = g_atoi(argv[6]); - make_stream(in_s); - init_stream(in_s, 8192); - make_stream(out_s); - init_stream(out_s, 8192); - sck = g_tcp_socket(); - if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0) + if (0 != config_read(&g_cfg)) { - s_push_layer(out_s, channel_hdr, 8); - out_uint16_be(out_s, 0); /* code */ - i = g_strlen(username); - out_uint16_be(out_s, i); - out_uint8a(out_s, username, i); - i = g_strlen(password); - out_uint16_be(out_s, i); - out_uint8a(out_s, password, i); - out_uint16_be(out_s, width); - out_uint16_be(out_s, height); - out_uint16_be(out_s, bpp); - s_mark_end(out_s); - s_pop_layer(out_s, channel_hdr); - out_uint32_be(out_s, 0); /* version */ - out_uint32_be(out_s, out_s->end - out_s->data); /* size */ - tcp_force_send(sck, out_s->data, out_s->end - out_s->data); - if (tcp_force_recv(sck, in_s->data, 8) == 0) - { - in_uint32_be(in_s, version); - in_uint32_be(in_s, size); + g_printf("sesrun: error reading config. quitting.\n"); + return 1; + } + + g_pid = g_getpid(); + + if (argc == 1) + { + g_printf("xrdp session starter v0.1\n"); + g_printf("\nusage:\n"); + g_printf("sesrun \n"); + } + else if (argc == 7) + { + username = argv[2]; + password = argv[3]; + width = g_atoi(argv[4]); + height = g_atoi(argv[5]); + bpp = g_atoi(argv[6]); + make_stream(in_s); init_stream(in_s, 8192); - if (tcp_force_recv(sck, in_s->data, size - 8) == 0) + make_stream(out_s); + init_stream(out_s, 8192); + sck = g_tcp_socket(); + + if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0) { - if (version == 0) - { - in_uint16_be(in_s, code); - if (code == 3) + s_push_layer(out_s, channel_hdr, 8); + out_uint16_be(out_s, 0); /* code */ + i = g_strlen(username); + out_uint16_be(out_s, i); + out_uint8a(out_s, username, i); + i = g_strlen(password); + out_uint16_be(out_s, i); + out_uint8a(out_s, password, i); + out_uint16_be(out_s, width); + out_uint16_be(out_s, height); + out_uint16_be(out_s, bpp); + s_mark_end(out_s); + s_pop_layer(out_s, channel_hdr); + out_uint32_be(out_s, 0); /* version */ + out_uint32_be(out_s, out_s->end - out_s->data); /* size */ + tcp_force_send(sck, out_s->data, out_s->end - out_s->data); + + if (tcp_force_recv(sck, in_s->data, 8) == 0) { - in_uint16_be(in_s, data); - in_uint16_be(in_s, display); - g_printf("ok %d display %d\n", data, display); + in_uint32_be(in_s, version); + in_uint32_be(in_s, size); + init_stream(in_s, 8192); + + if (tcp_force_recv(sck, in_s->data, size - 8) == 0) + { + if (version == 0) + { + in_uint16_be(in_s, code); + + if (code == 3) + { + in_uint16_be(in_s, data); + in_uint16_be(in_s, display); + g_printf("ok %d display %d\n", data, display); + } + } + } } - } } - } + else + { + g_printf("connect error\n"); + } + + g_tcp_close(sck); + free_stream(in_s); + free_stream(out_s); } - else - { - g_printf("connect error\n"); - } - g_tcp_close(sck); - free_stream(in_s); - free_stream(out_s); - } - return 0; + + return 0; } diff --git a/sesman/tools/sestest.c b/sesman/tools/sestest.c index c0784ba3..f2823eb6 100644 --- a/sesman/tools/sestest.c +++ b/sesman/tools/sestest.c @@ -12,205 +12,217 @@ #include -int inputSession(struct SCP_SESSION* s); +int inputSession(struct SCP_SESSION *s); unsigned int menuSelect(unsigned int choices); -int main(int argc, char** argv) +int main(int argc, char **argv) { - char buf[256]; - struct SCP_SESSION* s; - struct SCP_CONNECTION* c; - /*struct SCP_DISCONNECTED_SESSION ds;*/ - struct SCP_DISCONNECTED_SESSION* dsl; - enum SCP_CLIENT_STATES_E e; - struct log_config log; - int end; - int scnt; - int idx; - int sel; - int sock; + char buf[256]; + struct SCP_SESSION *s; + struct SCP_CONNECTION *c; + /*struct SCP_DISCONNECTED_SESSION ds;*/ + struct SCP_DISCONNECTED_SESSION *dsl; + enum SCP_CLIENT_STATES_E e; + struct log_config log; + int end; + int scnt; + int idx; + int sel; + int sock; - log.enable_syslog=0; - log.log_level=99; - log.program_name=g_strdup("sestest"); - log.log_file=g_strdup("sestest.log"); - log_start_from_param(&log); - scp_init(&log); + log.enable_syslog = 0; + log.log_level = 99; + log.program_name = g_strdup("sestest"); + log.log_file = g_strdup("sestest.log"); + log_start_from_param(&log); + scp_init(&log); - sock=g_tcp_socket(); - s = scp_session_create(); - c = scp_connection_create(sock); + sock = g_tcp_socket(); + s = scp_session_create(); + c = scp_connection_create(sock); - if (0!=g_tcp_connect(sock, "localhost", "3350")) - { - g_printf("error connecting"); - return 1; - } - - g_printf("001 - send connect request\n"); - - scp_session_set_type(s, SCP_SESSION_TYPE_XVNC); - scp_session_set_version(s, 1); - scp_session_set_height(s, 600); - scp_session_set_width(s, 800); - scp_session_set_bpp(s, 16); - scp_session_set_rsr(s, 0); - scp_session_set_locale(s, "it_IT"); - scp_session_set_username(s, "prog"); - scp_session_set_password(s, "prog"); - scp_session_set_hostname(s, "odin"); -// scp_session_set_addr(s, SCP_ADDRESS_TYPE_IPV4, "127.0.0.1"); -// scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display); -// scp_session_set_errstr(struct SCP_SESSION* s, char* str); - - /*s.type=SCP_SESSION_TYPE_XVNC; - s.version=1; - s.height=600; - s.width=800; - s.bpp=8; - s.rsr=0; - g_strncpy(s.locale,"it_IT 0123456789",18); - s.username=g_malloc(256, 1); - g_strncpy(s.username,"prog",255); - s.password=g_malloc(256,1); - g_strncpy(s.password, "prog", 255); - g_printf("%s - %s\n", s.username, s.password); - s.hostname=g_malloc(256,1); - g_strncpy(s.hostname, "odin", 255); - s.addr_type=SCP_ADDRESS_TYPE_IPV4; - s.ipv4addr=0; - s.errstr=0;*/ - - end=0; - e=scp_v1c_connect(c,s); - - while (!end) - { - switch (e) + if (0 != g_tcp_connect(sock, "localhost", "3350")) { - case SCP_CLIENT_STATE_OK: - g_printf("OK : display is %d\n", (short int)s->display); - end=1; - break; - case SCP_CLIENT_STATE_SESSION_LIST: - g_printf("OK : session list needed\n"); - e=scp_v1c_get_session_list(c, &scnt, &dsl); - break; - case SCP_CLIENT_STATE_LIST_OK: - g_printf("OK : selecting a session:\n"); - for (idx=0; idx errstr); - g_printf(" username:"); - if (scanf("%255s", buf) < 0) - { - g_writeln("error"); - } - scp_session_set_username(s, buf); - g_printf(" password:"); - if (scanf("%255s", buf) < 0) - { - g_writeln("error"); - } - scp_session_set_password(s, buf); - e=scp_v1c_resend_credentials(c,s); - break; - case SCP_CLIENT_STATE_CONNECTION_DENIED: - g_printf("ERR: connection denied: %s\n", s->errstr); - end=1; - break; - case SCP_CLIENT_STATE_PWD_CHANGE_REQ: - g_printf("OK : password change required\n"); - break; - /*case SCP_CLIENT_STATE_RECONNECT_SINGLE: - g_printf("OK : reconnect to 1 disconnected session\n"); - e=scp_v1c_retrieve_session(&c, &s, &ds); - g_printf("Session Type: %d on %d\n", ds.type, s.display); - g_printf("Session Screen: %dx%dx%d\n", ds.height, ds.width, ds.bpp);*/ - break; - default: - g_printf("protocol error: %d\n", e); - end=1; + g_printf("error connecting"); + return 1; } - } - g_tcp_close(sock); - scp_session_destroy(s); - scp_connection_destroy(c); - /*free_stream(c.in_s); - free_stream(c.out_s);*/ + g_printf("001 - send connect request\n"); - return 0; + scp_session_set_type(s, SCP_SESSION_TYPE_XVNC); + scp_session_set_version(s, 1); + scp_session_set_height(s, 600); + scp_session_set_width(s, 800); + scp_session_set_bpp(s, 16); + scp_session_set_rsr(s, 0); + scp_session_set_locale(s, "it_IT"); + scp_session_set_username(s, "prog"); + scp_session_set_password(s, "prog"); + scp_session_set_hostname(s, "odin"); + // scp_session_set_addr(s, SCP_ADDRESS_TYPE_IPV4, "127.0.0.1"); + // scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display); + // scp_session_set_errstr(struct SCP_SESSION* s, char* str); + + /*s.type=SCP_SESSION_TYPE_XVNC; + s.version=1; + s.height=600; + s.width=800; + s.bpp=8; + s.rsr=0; + g_strncpy(s.locale,"it_IT 0123456789",18); + s.username=g_malloc(256, 1); + g_strncpy(s.username,"prog",255); + s.password=g_malloc(256,1); + g_strncpy(s.password, "prog", 255); + g_printf("%s - %s\n", s.username, s.password); + s.hostname=g_malloc(256,1); + g_strncpy(s.hostname, "odin", 255); + s.addr_type=SCP_ADDRESS_TYPE_IPV4; + s.ipv4addr=0; + s.errstr=0;*/ + + end = 0; + e = scp_v1c_connect(c, s); + + while (!end) + { + switch (e) + { + case SCP_CLIENT_STATE_OK: + g_printf("OK : display is %d\n", (short int)s->display); + end = 1; + break; + case SCP_CLIENT_STATE_SESSION_LIST: + g_printf("OK : session list needed\n"); + e = scp_v1c_get_session_list(c, &scnt, &dsl); + break; + case SCP_CLIENT_STATE_LIST_OK: + g_printf("OK : selecting a session:\n"); + + for (idx = 0; idx < scnt; idx++) + { + printf("Session \t%d - %d - %dx%dx%d - %d %d %d - %4d/%2d/%2d@%2d:%2d\n", \ + (dsl[idx]).SID, (dsl[idx]).type, (dsl[idx]).width, (dsl[idx]).height, (dsl[idx]).bpp, \ + (dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \ + (dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute); + } + + sel = menuSelect(scnt); + e = scp_v1c_select_session(c, s, dsl[sel - 1].SID); + g_printf("\n return: %d \n", e); + break; + case SCP_CLIENT_STATE_RESEND_CREDENTIALS: + g_printf("ERR: resend credentials - %s\n", s->errstr); + g_printf(" username:"); + + if (scanf("%255s", buf) < 0) + { + g_writeln("error"); + } + + scp_session_set_username(s, buf); + g_printf(" password:"); + + if (scanf("%255s", buf) < 0) + { + g_writeln("error"); + } + + scp_session_set_password(s, buf); + e = scp_v1c_resend_credentials(c, s); + break; + case SCP_CLIENT_STATE_CONNECTION_DENIED: + g_printf("ERR: connection denied: %s\n", s->errstr); + end = 1; + break; + case SCP_CLIENT_STATE_PWD_CHANGE_REQ: + g_printf("OK : password change required\n"); + break; + /*case SCP_CLIENT_STATE_RECONNECT_SINGLE: + g_printf("OK : reconnect to 1 disconnected session\n"); + e=scp_v1c_retrieve_session(&c, &s, &ds); + g_printf("Session Type: %d on %d\n", ds.type, s.display); + g_printf("Session Screen: %dx%dx%d\n", ds.height, ds.width, ds.bpp);*/ + break; + default: + g_printf("protocol error: %d\n", e); + end = 1; + } + } + + g_tcp_close(sock); + scp_session_destroy(s); + scp_connection_destroy(c); + /*free_stream(c.in_s); + free_stream(c.out_s);*/ + + return 0; } -int inputSession(struct SCP_SESSION* s) +int inputSession(struct SCP_SESSION *s) { - unsigned int integer; + unsigned int integer; - g_printf("username: "); - if (scanf("%255s", s->username) < 0) - { - g_writeln("error"); - } - g_printf("password:"); - if (scanf("%255s", s->password) < 0) - { - g_writeln("error"); - } - g_printf("hostname:"); - if (scanf("%255s", s->hostname) < 0) - { - g_writeln("error"); - } + g_printf("username: "); - g_printf("session type:\n"); - g_printf("0: Xvnc\n", SCP_SESSION_TYPE_XVNC); - g_printf("1: x11rdp\n", SCP_SESSION_TYPE_XRDP); - integer=menuSelect(1); - if (integer==1) - { - s->type=SCP_SESSION_TYPE_XRDP; - } - else - { - s->type=SCP_SESSION_TYPE_XVNC; - } + if (scanf("%255s", s->username) < 0) + { + g_writeln("error"); + } - s->version=1; - s->height=600; - s->width=800; - s->bpp=8; + g_printf("password:"); - /* fixed for now */ - s->rsr=0; - g_strncpy(s->locale,"it_IT 0123456789",18); + if (scanf("%255s", s->password) < 0) + { + g_writeln("error"); + } - return 0; + g_printf("hostname:"); + + if (scanf("%255s", s->hostname) < 0) + { + g_writeln("error"); + } + + g_printf("session type:\n"); + g_printf("0: Xvnc\n", SCP_SESSION_TYPE_XVNC); + g_printf("1: x11rdp\n", SCP_SESSION_TYPE_XRDP); + integer = menuSelect(1); + + if (integer == 1) + { + s->type = SCP_SESSION_TYPE_XRDP; + } + else + { + s->type = SCP_SESSION_TYPE_XVNC; + } + + s->version = 1; + s->height = 600; + s->width = 800; + s->bpp = 8; + + /* fixed for now */ + s->rsr = 0; + g_strncpy(s->locale, "it_IT 0123456789", 18); + + return 0; } tui32 menuSelect(tui32 choices) { - tui32 sel; - int ret; + tui32 sel; + int ret; - ret = scanf("%u", &sel); - - while ((ret == 0) || (sel > choices)) - { - g_printf("invalid choice."); ret = scanf("%u", &sel); - } - return sel; + while ((ret == 0) || (sel > choices)) + { + g_printf("invalid choice."); + ret = scanf("%u", &sel); + } + + return sel; } diff --git a/sesman/tools/tcp.c b/sesman/tools/tcp.c index 1cba18d6..c8d01e96 100644 --- a/sesman/tools/tcp.c +++ b/sesman/tools/tcp.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -35,111 +34,113 @@ /*****************************************************************************/ int DEFAULT_CC -tcp_force_recv(int sck, char* data, int len) +tcp_force_recv(int sck, char *data, int len) { - int rcvd; + int rcvd; -//#ifndef LIBSCP_CLIENT -// int block; -// block = lock_fork_critical_section_start(); -//#endif + //#ifndef LIBSCP_CLIENT + // int block; + // block = lock_fork_critical_section_start(); + //#endif - while (len > 0) - { - rcvd = g_tcp_recv(sck, data, len, 0); - if (rcvd == -1) + while (len > 0) { - if (g_tcp_last_error_would_block(sck)) - { - g_sleep(1); - } - else - { -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif - return 1; - } - } - else if (rcvd == 0) - { -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif - return 1; - } - else - { - data += rcvd; - len -= rcvd; - } - } + rcvd = g_tcp_recv(sck, data, len, 0); -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif + if (rcvd == -1) + { + if (g_tcp_last_error_would_block(sck)) + { + g_sleep(1); + } + else + { + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + return 1; + } + } + else if (rcvd == 0) + { + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + return 1; + } + else + { + data += rcvd; + len -= rcvd; + } + } - return 0; + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + + return 0; } /*****************************************************************************/ int DEFAULT_CC -tcp_force_send(int sck, char* data, int len) +tcp_force_send(int sck, char *data, int len) { - int sent; + int sent; -//#ifndef LIBSCP_CLIENT -// int block; -// block = lock_fork_critical_section_start(); -//#endif + //#ifndef LIBSCP_CLIENT + // int block; + // block = lock_fork_critical_section_start(); + //#endif - while (len > 0) - { - sent = g_tcp_send(sck, data, len, 0); - if (sent == -1) + while (len > 0) { - if (g_tcp_last_error_would_block(sck)) - { - g_sleep(1); - } - else - { -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif - return 1; - } - } - else if (sent == 0) - { -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif - return 1; - } - else - { - data += sent; - len -= sent; - } - } + sent = g_tcp_send(sck, data, len, 0); -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif + if (sent == -1) + { + if (g_tcp_last_error_would_block(sck)) + { + g_sleep(1); + } + else + { + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + return 1; + } + } + else if (sent == 0) + { + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + return 1; + } + else + { + data += sent; + len -= sent; + } + } - return 0; + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + + return 0; } /*****************************************************************************/ int DEFAULT_CC -tcp_bind(int sck, char* addr, char* port) +tcp_bind(int sck, char *addr, char *port) { - struct sockaddr_in s; + struct sockaddr_in s; - memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons(atoi(port)); - s.sin_addr.s_addr = inet_addr(addr); - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); + memset(&s, 0, sizeof(struct sockaddr_in)); + s.sin_family = AF_INET; + s.sin_port = htons(atoi(port)); + s.sin_addr.s_addr = inet_addr(addr); + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_in)); } diff --git a/sesman/tools/tcp.h b/sesman/tools/tcp.h index 5de12f18..2fd7963e 100644 --- a/sesman/tools/tcp.h +++ b/sesman/tools/tcp.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/tools/xcon.c b/sesman/tools/xcon.c index 7a45a1cd..bb715054 100644 --- a/sesman/tools/xcon.c +++ b/sesman/tools/xcon.c @@ -1,35 +1,58 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #include #include #include -Display* g_display = 0; +Display *g_display = 0; int g_x_socket = 0; -int main(int argc, char** argv) +int main(int argc, char **argv) { - fd_set rfds; - int i1; - XEvent xevent; + fd_set rfds; + int i1; + XEvent xevent; - g_display = XOpenDisplay(0); - if (g_display == 0) - { - printf("XOpenDisplay failed\n"); - return 0; - } - g_x_socket = XConnectionNumber(g_display); - while (1) - { - FD_ZERO(&rfds); - FD_SET(g_x_socket, &rfds); - i1 = select(g_x_socket + 1, &rfds, 0, 0, 0); - if (i1 < 0) + g_display = XOpenDisplay(0); + + if (g_display == 0) { - break; + printf("XOpenDisplay failed\n"); + return 0; } - XNextEvent(g_display, &xevent); - } - return 0; + + g_x_socket = XConnectionNumber(g_display); + + while (1) + { + FD_ZERO(&rfds); + FD_SET(g_x_socket, &rfds); + i1 = select(g_x_socket + 1, &rfds, 0, 0, 0); + + if (i1 < 0) + { + break; + } + + XNextEvent(g_display, &xevent); + } + + return 0; } diff --git a/sesman/verify_user.c b/sesman/verify_user.c index aaa1515c..8765d7c2 100644 --- a/sesman/verify_user.c +++ b/sesman/verify_user.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -38,77 +37,89 @@ #define SECS_PER_DAY (24L*3600L) #endif -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ static int DEFAULT_CC -auth_crypt_pwd(char* pwd, char* pln, char* crp); +auth_crypt_pwd(char *pwd, char *pln, char *crp); static int DEFAULT_CC -auth_account_disabled(struct spwd* stp); +auth_account_disabled(struct spwd *stp); /******************************************************************************/ /* returns boolean */ long DEFAULT_CC -auth_userpass(char* user, char* pass) +auth_userpass(char *user, char *pass) { - char salt[13] = "$1$"; - char hash[35] = ""; - char* encr = 0; - struct passwd* spw; - struct spwd* stp; - int saltcnt = 0; + char salt[13] = "$1$"; + char hash[35] = ""; + char *encr = 0; + struct passwd *spw; + struct spwd *stp; + int saltcnt = 0; - spw = getpwnam(user); - if (spw == 0) - { - return 0; - } - if (g_strncmp(spw->pw_passwd, "x", 3) == 0) - { - /* the system is using shadow */ - stp = getspnam(user); - if (stp == 0) + spw = getpwnam(user); + + if (spw == 0) { - return 0; + return 0; } - if (1==auth_account_disabled(stp)) + + if (g_strncmp(spw->pw_passwd, "x", 3) == 0) { - log_message(&(g_cfg->log), LOG_LEVEL_INFO, "account %s is disabled", user); - return 0; + /* the system is using shadow */ + stp = getspnam(user); + + if (stp == 0) + { + return 0; + } + + if (1 == auth_account_disabled(stp)) + { + log_message(&(g_cfg->log), LOG_LEVEL_INFO, "account %s is disabled", user); + return 0; + } + + g_strncpy(hash, stp->sp_pwdp, 34); } - g_strncpy(hash, stp->sp_pwdp, 34); - } - else - { - /* old system with only passwd */ - g_strncpy(hash, spw->pw_passwd, 34); - } - hash[34] = '\0'; - if (g_strncmp(hash, "$1$", 3) == 0) - { - /* gnu style crypt(); */ - saltcnt = 3; - while ((hash[saltcnt] != '$') && (saltcnt < 11)) + else { - salt[saltcnt] = hash[saltcnt]; - saltcnt++; + /* old system with only passwd */ + g_strncpy(hash, spw->pw_passwd, 34); } - salt[saltcnt] = '$'; - salt[saltcnt + 1] = '\0'; - } - else - { - /* classic two char salt */ - salt[0] = hash[0]; - salt[1] = hash[1]; - salt[2] = '\0'; - } - encr = crypt(pass,salt); - if (g_strncmp(encr, hash, 34) != 0) - { - return 0; - } - return 1; + + hash[34] = '\0'; + + if (g_strncmp(hash, "$1$", 3) == 0) + { + /* gnu style crypt(); */ + saltcnt = 3; + + while ((hash[saltcnt] != '$') && (saltcnt < 11)) + { + salt[saltcnt] = hash[saltcnt]; + saltcnt++; + } + + salt[saltcnt] = '$'; + salt[saltcnt + 1] = '\0'; + } + else + { + /* classic two char salt */ + salt[0] = hash[0]; + salt[1] = hash[1]; + salt[2] = '\0'; + } + + encr = crypt(pass, salt); + + if (g_strncmp(encr, hash, 34) != 0) + { + return 0; + } + + return 1; } /******************************************************************************/ @@ -116,138 +127,144 @@ auth_userpass(char* user, char* pass) int DEFAULT_CC auth_start_session(long in_val, int in_display) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_end(long in_val) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_set_env(long in_val) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC -auth_check_pwd_chg(char* user) +auth_check_pwd_chg(char *user) { - struct passwd* spw; - struct spwd* stp; - int now; - long today; + struct passwd *spw; + struct spwd *stp; + int now; + long today; + + spw = getpwnam(user); + + if (spw == 0) + { + return AUTH_PWD_CHG_ERROR; + } + + if (g_strncmp(spw->pw_passwd, "x", 3) != 0) + { + /* old system with only passwd */ + return AUTH_PWD_CHG_OK; + } + + /* the system is using shadow */ + stp = getspnam(user); + + if (stp == 0) + { + return AUTH_PWD_CHG_ERROR; + } + + /* check if we need a pwd change */ + now = g_time1(); + today = now / SECS_PER_DAY; + + if (stp->sp_expire == -1) + { + return AUTH_PWD_CHG_OK; + } + + if (today >= (stp->sp_lstchg + stp->sp_max - stp->sp_warn)) + { + return AUTH_PWD_CHG_CHANGE; + } + + if (today >= (stp->sp_lstchg + stp->sp_max)) + { + return AUTH_PWD_CHG_CHANGE_MANDATORY; + } + + if (today < ((stp->sp_lstchg) + (stp->sp_min))) + { + /* cannot change pwd for now */ + return AUTH_PWD_CHG_NOT_NOW; + } - spw = getpwnam(user); - if (spw == 0) - { - return AUTH_PWD_CHG_ERROR; - } - if (g_strncmp(spw->pw_passwd, "x", 3) != 0) - { - /* old system with only passwd */ return AUTH_PWD_CHG_OK; - } - - /* the system is using shadow */ - stp = getspnam(user); - if (stp == 0) - { - return AUTH_PWD_CHG_ERROR; - } - - /* check if we need a pwd change */ - now=g_time1(); - today=now/SECS_PER_DAY; - - if (stp->sp_expire == -1) - { - return AUTH_PWD_CHG_OK; - } - if (today >= (stp->sp_lstchg + stp->sp_max - stp->sp_warn)) - { - return AUTH_PWD_CHG_CHANGE; - } - - if (today >= (stp->sp_lstchg + stp->sp_max)) - { - return AUTH_PWD_CHG_CHANGE_MANDATORY; - } - - if (today < ((stp->sp_lstchg)+(stp->sp_min))) - { - /* cannot change pwd for now */ - return AUTH_PWD_CHG_NOT_NOW; - } - - return AUTH_PWD_CHG_OK; } int DEFAULT_CC -auth_change_pwd(char* user, char* newpwd) +auth_change_pwd(char *user, char *newpwd) { - struct passwd* spw; - struct spwd* stp; - char hash[35] = ""; - long today; + struct passwd *spw; + struct spwd *stp; + char hash[35] = ""; + long today; - FILE* fd; + FILE *fd; - if (0 != lckpwdf()) - { - return 1; - } - - /* open passwd */ - spw = getpwnam(user); - if (spw == 0) - { - return 1; - } - - if (g_strncmp(spw->pw_passwd, "x", 3) != 0) - { - /* old system with only passwd */ - if (auth_crypt_pwd(spw->pw_passwd, newpwd, hash) != 0) + if (0 != lckpwdf()) { - ulckpwdf(); - return 1; + return 1; } - spw->pw_passwd=g_strdup(hash); - fd = fopen("/etc/passwd", "rw"); - putpwent(spw, fd); - } - else - { - /* the system is using shadow */ - stp = getspnam(user); - if (stp == 0) + /* open passwd */ + spw = getpwnam(user); + + if (spw == 0) { - return 1; + return 1; } - /* old system with only passwd */ - if (auth_crypt_pwd(stp->sp_pwdp, newpwd, hash) != 0) + if (g_strncmp(spw->pw_passwd, "x", 3) != 0) { - ulckpwdf(); - return 1; + /* old system with only passwd */ + if (auth_crypt_pwd(spw->pw_passwd, newpwd, hash) != 0) + { + ulckpwdf(); + return 1; + } + + spw->pw_passwd = g_strdup(hash); + fd = fopen("/etc/passwd", "rw"); + putpwent(spw, fd); + } + else + { + /* the system is using shadow */ + stp = getspnam(user); + + if (stp == 0) + { + return 1; + } + + /* old system with only passwd */ + if (auth_crypt_pwd(stp->sp_pwdp, newpwd, hash) != 0) + { + ulckpwdf(); + return 1; + } + + stp->sp_pwdp = g_strdup(hash); + today = g_time1() / SECS_PER_DAY; + stp->sp_lstchg = today; + stp->sp_expire = today + stp->sp_max + stp->sp_inact; + fd = fopen("/etc/shadow", "rw"); + putspent(stp, fd); } - stp->sp_pwdp = g_strdup(hash); - today = g_time1() / SECS_PER_DAY; - stp->sp_lstchg = today; - stp->sp_expire = today + stp->sp_max + stp->sp_inact; - fd = fopen("/etc/shadow", "rw"); - putspent(stp, fd); - } - - ulckpwdf(); - return 0; + ulckpwdf(); + return 0; } /** @@ -260,36 +277,38 @@ auth_change_pwd(char* user, char* newpwd) */ static int DEFAULT_CC -auth_crypt_pwd(char* pwd, char* pln, char* crp) +auth_crypt_pwd(char *pwd, char *pln, char *crp) { - char salt[13] = "$1$"; - int saltcnt = 0; - char* encr; + char salt[13] = "$1$"; + int saltcnt = 0; + char *encr; - if (g_strncmp(pwd, "$1$", 3) == 0) - { - /* gnu style crypt(); */ - saltcnt = 3; - while ((pwd[saltcnt] != '$') && (saltcnt < 11)) + if (g_strncmp(pwd, "$1$", 3) == 0) { - salt[saltcnt] = pwd[saltcnt]; - saltcnt++; + /* gnu style crypt(); */ + saltcnt = 3; + + while ((pwd[saltcnt] != '$') && (saltcnt < 11)) + { + salt[saltcnt] = pwd[saltcnt]; + saltcnt++; + } + + salt[saltcnt] = '$'; + salt[saltcnt + 1] = '\0'; + } + else + { + /* classic two char salt */ + salt[0] = pwd[0]; + salt[1] = pwd[1]; + salt[2] = '\0'; } - salt[saltcnt] = '$'; - salt[saltcnt + 1] = '\0'; - } - else - { - /* classic two char salt */ - salt[0] = pwd[0]; - salt[1] = pwd[1]; - salt[2] = '\0'; - } - encr = crypt(pln, salt); - g_strncpy(crp, encr, 34); + encr = crypt(pln, salt); + g_strncpy(crp, encr, 34); - return 0; + return 0; } /** @@ -298,35 +317,35 @@ auth_crypt_pwd(char* pwd, char* pln, char* crp) * */ static int DEFAULT_CC -auth_account_disabled(struct spwd* stp) +auth_account_disabled(struct spwd *stp) { - int today; + int today; - if (0 == stp) - { - /* if an invalid struct was passed we assume a disabled account */ - return 1; - } + if (0 == stp) + { + /* if an invalid struct was passed we assume a disabled account */ + return 1; + } - today = g_time1() / SECS_PER_DAY; + today = g_time1() / SECS_PER_DAY; - LOG_DBG("last %d",stp->sp_lstchg); - LOG_DBG("min %d",stp->sp_min); - LOG_DBG("max %d",stp->sp_max); - LOG_DBG("inact %d",stp->sp_inact); - LOG_DBG("warn %d",stp->sp_warn); - LOG_DBG("expire %d",stp->sp_expire); - LOG_DBG("today %d",today); + LOG_DBG("last %d", stp->sp_lstchg); + LOG_DBG("min %d", stp->sp_min); + LOG_DBG("max %d", stp->sp_max); + LOG_DBG("inact %d", stp->sp_inact); + LOG_DBG("warn %d", stp->sp_warn); + LOG_DBG("expire %d", stp->sp_expire); + LOG_DBG("today %d", today); - if ((stp->sp_expire != -1) && (today >= stp->sp_expire)) - { - return 1; - } + if ((stp->sp_expire != -1) && (today >= stp->sp_expire)) + { + return 1; + } - if (today >= (stp->sp_lstchg+stp->sp_max+stp->sp_inact)) - { - return 1; - } + if (today >= (stp->sp_lstchg + stp->sp_max + stp->sp_inact)) + { + return 1; + } - return 0; + return 0; } diff --git a/sesman/verify_user_kerberos.c b/sesman/verify_user_kerberos.c index 68b232af..c4a7ecde 100644 --- a/sesman/verify_user_kerberos.c +++ b/sesman/verify_user_kerberos.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file verify_user_kerberos.c * @brief Authenticate user using kerberos * @author Jay Sorg - * + * */ #include "arch.h" @@ -34,346 +33,393 @@ typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type; struct k_opts { - /* in seconds */ - krb5_deltat starttime; - krb5_deltat lifetime; - krb5_deltat rlife; + /* in seconds */ + krb5_deltat starttime; + krb5_deltat lifetime; + krb5_deltat rlife; - int forwardable; - int proxiable; - int addresses; + int forwardable; + int proxiable; + int addresses; - int not_forwardable; - int not_proxiable; - int no_addresses; + int not_forwardable; + int not_proxiable; + int no_addresses; - int verbose; + int verbose; - char* principal_name; - char* service_name; - char* keytab_name; - char* k5_cache_name; - char* k4_cache_name; + char *principal_name; + char *service_name; + char *keytab_name; + char *k5_cache_name; + char *k4_cache_name; - action_type action; + action_type action; }; struct k5_data { - krb5_context ctx; - krb5_ccache cc; - krb5_principal me; - char* name; + krb5_context ctx; + krb5_ccache cc; + krb5_principal me; + char *name; }; struct user_info { - char* name; - char* pass; + char *name; + char *pass; }; /******************************************************************************/ /* returns boolean */ static int DEFAULT_CC -k5_begin(struct k_opts* opts, struct k5_data* k5, struct user_info* u_info) +k5_begin(struct k_opts *opts, struct k5_data *k5, struct user_info *u_info) { - krb5_error_code code = 0; + krb5_error_code code = 0; + + code = krb5_init_context(&k5->ctx); - code = krb5_init_context(&k5->ctx); - if (code != 0) - { - g_printf("krb5_init_context failed in k5_begin\n"); - return 0; - } - if (opts->k5_cache_name) - { - code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc); if (code != 0) { - g_printf("krb5_cc_resolve failed in k5_begin\n"); - return 0; - } - } - else - { - code = krb5_cc_default(k5->ctx, &k5->cc); - if (code != 0) - { - g_printf("krb5_cc_default failed in k5_begin\n"); - return 0; - } - } - if (opts->principal_name) - { - /* Use specified name */ - code = krb5_parse_name(k5->ctx, opts->principal_name, &k5->me); - if (code != 0) - { - g_printf("krb5_parse_name failed in k5_begin\n"); - return 0; - } - } - else - { - /* No principal name specified */ - if (opts->action == INIT_KT) - { - /* Use the default host/service name */ - code = krb5_sname_to_principal(k5->ctx, NULL, NULL, - KRB5_NT_SRV_HST, &k5->me); - if (code != 0) - { - g_printf("krb5_sname_to_principal failed in k5_begin\n"); + g_printf("krb5_init_context failed in k5_begin\n"); return 0; - } + } + + if (opts->k5_cache_name) + { + code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc); + + if (code != 0) + { + g_printf("krb5_cc_resolve failed in k5_begin\n"); + return 0; + } } else { - /* Get default principal from cache if one exists */ - code = krb5_cc_get_principal(k5->ctx, k5->cc, &k5->me); - if (code != 0) - { - code = krb5_parse_name(k5->ctx, u_info->name, &k5->me); + code = krb5_cc_default(k5->ctx, &k5->cc); + if (code != 0) { - g_printf("krb5_parse_name failed in k5_begin\n"); - return 0; + g_printf("krb5_cc_default failed in k5_begin\n"); + return 0; } - } } - } - code = krb5_unparse_name(k5->ctx, k5->me, &k5->name); - if (code != 0) - { - g_printf("krb5_unparse_name failed in k5_begin\n"); - return 0; - } - opts->principal_name = k5->name; - return 1; + + if (opts->principal_name) + { + /* Use specified name */ + code = krb5_parse_name(k5->ctx, opts->principal_name, &k5->me); + + if (code != 0) + { + g_printf("krb5_parse_name failed in k5_begin\n"); + return 0; + } + } + else + { + /* No principal name specified */ + if (opts->action == INIT_KT) + { + /* Use the default host/service name */ + code = krb5_sname_to_principal(k5->ctx, NULL, NULL, + KRB5_NT_SRV_HST, &k5->me); + + if (code != 0) + { + g_printf("krb5_sname_to_principal failed in k5_begin\n"); + return 0; + } + } + else + { + /* Get default principal from cache if one exists */ + code = krb5_cc_get_principal(k5->ctx, k5->cc, &k5->me); + + if (code != 0) + { + code = krb5_parse_name(k5->ctx, u_info->name, &k5->me); + + if (code != 0) + { + g_printf("krb5_parse_name failed in k5_begin\n"); + return 0; + } + } + } + } + + code = krb5_unparse_name(k5->ctx, k5->me, &k5->name); + + if (code != 0) + { + g_printf("krb5_unparse_name failed in k5_begin\n"); + return 0; + } + + opts->principal_name = k5->name; + return 1; } /******************************************************************************/ static void DEFAULT_CC -k5_end(struct k5_data* k5) +k5_end(struct k5_data *k5) { - if (k5->name) - { - krb5_free_unparsed_name(k5->ctx, k5->name); - } - if (k5->me) - { - krb5_free_principal(k5->ctx, k5->me); - } - if (k5->cc) - { - krb5_cc_close(k5->ctx, k5->cc); - } - if (k5->ctx) - { - krb5_free_context(k5->ctx); - } - g_memset(k5, 0, sizeof(struct k5_data)); + if (k5->name) + { + krb5_free_unparsed_name(k5->ctx, k5->name); + } + + if (k5->me) + { + krb5_free_principal(k5->ctx, k5->me); + } + + if (k5->cc) + { + krb5_cc_close(k5->ctx, k5->cc); + } + + if (k5->ctx) + { + krb5_free_context(k5->ctx); + } + + g_memset(k5, 0, sizeof(struct k5_data)); } /******************************************************************************/ static krb5_error_code KRB5_CALLCONV -kinit_prompter(krb5_context ctx, void* data, const char* name, - const char* banner, int num_prompts, krb5_prompt prompts[]) +kinit_prompter(krb5_context ctx, void *data, const char *name, + const char *banner, int num_prompts, krb5_prompt prompts[]) { - int i; - krb5_prompt_type* types; - krb5_error_code rc; - struct user_info* u_info; + int i; + krb5_prompt_type *types; + krb5_error_code rc; + struct user_info *u_info; - u_info = (struct user_info*)data; - rc = 0; - types = krb5_get_prompt_types(ctx); - for (i = 0; i < num_prompts; i++) - { - if (types[i] == KRB5_PROMPT_TYPE_PASSWORD || - types[i] == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN) + u_info = (struct user_info *)data; + rc = 0; + types = krb5_get_prompt_types(ctx); + + for (i = 0; i < num_prompts; i++) { - g_strncpy(prompts[i].reply->data, u_info->pass, 255); + if (types[i] == KRB5_PROMPT_TYPE_PASSWORD || + types[i] == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN) + { + g_strncpy(prompts[i].reply->data, u_info->pass, 255); + } } - } - return rc; + + return rc; } /******************************************************************************/ /* returns boolean */ static int -k5_kinit(struct k_opts* opts, struct k5_data* k5, struct user_info* u_info) +k5_kinit(struct k_opts *opts, struct k5_data *k5, struct user_info *u_info) { - char* doing; - int notix = 1; - krb5_keytab keytab = 0; - krb5_creds my_creds; - krb5_error_code code = 0; - krb5_get_init_creds_opt options; - krb5_address** addresses; + char *doing; + int notix = 1; + krb5_keytab keytab = 0; + krb5_creds my_creds; + krb5_error_code code = 0; + krb5_get_init_creds_opt options; + krb5_address **addresses; - krb5_get_init_creds_opt_init(&options); - g_memset(&my_creds, 0, sizeof(my_creds)); - /* - From this point on, we can goto cleanup because my_creds is - initialized. - */ - if (opts->lifetime) - { - krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime); - } - if (opts->rlife) - { - krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife); - } - if (opts->forwardable) - { - krb5_get_init_creds_opt_set_forwardable(&options, 1); - } - if (opts->not_forwardable) - { - krb5_get_init_creds_opt_set_forwardable(&options, 0); - } - if (opts->proxiable) - { - krb5_get_init_creds_opt_set_proxiable(&options, 1); - } - if (opts->not_proxiable) - { - krb5_get_init_creds_opt_set_proxiable(&options, 0); - } - if (opts->addresses) - { - addresses = NULL; - code = krb5_os_localaddr(k5->ctx, &addresses); - if (code != 0) + krb5_get_init_creds_opt_init(&options); + g_memset(&my_creds, 0, sizeof(my_creds)); + + /* + From this point on, we can goto cleanup because my_creds is + initialized. + */ + if (opts->lifetime) { - g_printf("krb5_os_localaddr failed in k5_kinit\n"); - goto cleanup; + krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime); } - krb5_get_init_creds_opt_set_address_list(&options, addresses); - } - if (opts->no_addresses) - { - krb5_get_init_creds_opt_set_address_list(&options, NULL); - } - if ((opts->action == INIT_KT) && opts->keytab_name) - { - code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab); - if (code != 0) + + if (opts->rlife) { - g_printf("krb5_kt_resolve failed in k5_kinit\n"); - goto cleanup; + krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife); } - } - switch (opts->action) - { - case INIT_PW: - code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me, - 0, kinit_prompter, u_info, - opts->starttime, - opts->service_name, - &options); - break; - case INIT_KT: - code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me, - keytab, - opts->starttime, - opts->service_name, - &options); - break; - case VALIDATE: - code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc, - opts->service_name); - break; - case RENEW: - code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->cc, - opts->service_name); - break; - } - if (code != 0) - { - doing = 0; + + if (opts->forwardable) + { + krb5_get_init_creds_opt_set_forwardable(&options, 1); + } + + if (opts->not_forwardable) + { + krb5_get_init_creds_opt_set_forwardable(&options, 0); + } + + if (opts->proxiable) + { + krb5_get_init_creds_opt_set_proxiable(&options, 1); + } + + if (opts->not_proxiable) + { + krb5_get_init_creds_opt_set_proxiable(&options, 0); + } + + if (opts->addresses) + { + addresses = NULL; + code = krb5_os_localaddr(k5->ctx, &addresses); + + if (code != 0) + { + g_printf("krb5_os_localaddr failed in k5_kinit\n"); + goto cleanup; + } + + krb5_get_init_creds_opt_set_address_list(&options, addresses); + } + + if (opts->no_addresses) + { + krb5_get_init_creds_opt_set_address_list(&options, NULL); + } + + if ((opts->action == INIT_KT) && opts->keytab_name) + { + code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab); + + if (code != 0) + { + g_printf("krb5_kt_resolve failed in k5_kinit\n"); + goto cleanup; + } + } + switch (opts->action) { - case INIT_PW: - case INIT_KT: - doing = "getting initial credentials"; - break; - case VALIDATE: - doing = "validating credentials"; - break; - case RENEW: - doing = "renewing credentials"; - break; + case INIT_PW: + code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me, + 0, kinit_prompter, u_info, + opts->starttime, + opts->service_name, + &options); + break; + case INIT_KT: + code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me, + keytab, + opts->starttime, + opts->service_name, + &options); + break; + case VALIDATE: + code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc, + opts->service_name); + break; + case RENEW: + code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->cc, + opts->service_name); + break; } - if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) + + if (code != 0) { - g_printf("sesman: Password incorrect while %s in k5_kinit\n", doing); + doing = 0; + + switch (opts->action) + { + case INIT_PW: + case INIT_KT: + doing = "getting initial credentials"; + break; + case VALIDATE: + doing = "validating credentials"; + break; + case RENEW: + doing = "renewing credentials"; + break; + } + + if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) + { + g_printf("sesman: Password incorrect while %s in k5_kinit\n", doing); + } + else + { + g_printf("sesman: error while %s in k5_kinit\n", doing); + } + + goto cleanup; } - else + + if (!opts->lifetime) { - g_printf("sesman: error while %s in k5_kinit\n", doing); + /* We need to figure out what lifetime to use for Kerberos 4. */ + opts->lifetime = my_creds.times.endtime - my_creds.times.authtime; } - goto cleanup; - } - if (!opts->lifetime) - { - /* We need to figure out what lifetime to use for Kerberos 4. */ - opts->lifetime = my_creds.times.endtime - my_creds.times.authtime; - } - code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me); - if (code != 0) - { - g_printf("krb5_cc_initialize failed in k5_kinit\n"); - goto cleanup; - } - code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds); - if (code != 0) - { - g_printf("krb5_cc_store_cred failed in k5_kinit\n"); - goto cleanup; - } - notix = 0; + + code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me); + + if (code != 0) + { + g_printf("krb5_cc_initialize failed in k5_kinit\n"); + goto cleanup; + } + + code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds); + + if (code != 0) + { + g_printf("krb5_cc_store_cred failed in k5_kinit\n"); + goto cleanup; + } + + notix = 0; cleanup: - if (my_creds.client == k5->me) - { - my_creds.client = 0; - } - krb5_free_cred_contents(k5->ctx, &my_creds); - if (keytab) - { - krb5_kt_close(k5->ctx, keytab); - } - return notix ? 0 : 1; + + if (my_creds.client == k5->me) + { + my_creds.client = 0; + } + + krb5_free_cred_contents(k5->ctx, &my_creds); + + if (keytab) + { + krb5_kt_close(k5->ctx, keytab); + } + + return notix ? 0 : 1; } /******************************************************************************/ /* returns boolean */ int DEFAULT_CC -auth_userpass(char* user, char* pass) +auth_userpass(char *user, char *pass) { - struct k_opts opts; - struct k5_data k5; - struct user_info u_info; - int got_k5; - int authed_k5; + struct k_opts opts; + struct k5_data k5; + struct user_info u_info; + int got_k5; + int authed_k5; - g_memset(&opts, 0, sizeof(opts)); - opts.action = INIT_PW; - g_memset(&k5, 0, sizeof(k5)); - g_memset(&u_info, 0, sizeof(u_info)); - u_info.name = user; - u_info.pass = pass; - authed_k5 = 0; - got_k5 = k5_begin(&opts, &k5, &u_info); - if (got_k5) - { - authed_k5 = k5_kinit(&opts, &k5, &u_info); - k5_end(&k5); - } - return authed_k5; + g_memset(&opts, 0, sizeof(opts)); + opts.action = INIT_PW; + g_memset(&k5, 0, sizeof(k5)); + g_memset(&u_info, 0, sizeof(u_info)); + u_info.name = user; + u_info.pass = pass; + authed_k5 = 0; + got_k5 = k5_begin(&opts, &k5, &u_info); + + if (got_k5) + { + authed_k5 = k5_kinit(&opts, &k5, &u_info); + k5_end(&k5); + } + + return authed_k5; } /******************************************************************************/ @@ -381,19 +427,19 @@ auth_userpass(char* user, char* pass) int DEFAULT_CC auth_start_session(void) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_end(void) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_set_env(void) { - return 0; + return 0; } diff --git a/sesman/verify_user_pam.c b/sesman/verify_user_pam.c index e3d8596e..b81398de 100644 --- a/sesman/verify_user_pam.c +++ b/sesman/verify_user_pam.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file verify_user_pam.c * @brief Authenticate user using pam * @author Jay Sorg - * + * */ #include "arch.h" @@ -33,107 +32,116 @@ struct t_user_pass { - char user[256]; - char pass[256]; + char user[256]; + char pass[256]; }; struct t_auth_info { - struct t_user_pass user_pass; - int session_opened; - int did_setcred; - struct pam_conv pamc; - pam_handle_t* ph; + struct t_user_pass user_pass; + int session_opened; + int did_setcred; + struct pam_conv pamc; + pam_handle_t *ph; }; /******************************************************************************/ static int DEFAULT_CC -verify_pam_conv(int num_msg, const struct pam_message** msg, - struct pam_response** resp, void* appdata_ptr) +verify_pam_conv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) { - int i; - struct pam_response* reply; - struct t_user_pass* user_pass; + int i; + struct pam_response *reply; + struct t_user_pass *user_pass; - reply = g_malloc(sizeof(struct pam_response) * num_msg, 1); - for (i = 0; i < num_msg; i++) - { - switch (msg[i]->msg_style) + reply = g_malloc(sizeof(struct pam_response) * num_msg, 1); + + for (i = 0; i < num_msg; i++) { - case PAM_PROMPT_ECHO_ON: /* username */ - user_pass = appdata_ptr; - reply[i].resp = g_strdup(user_pass->user); - reply[i].resp_retcode = PAM_SUCCESS; - break; - case PAM_PROMPT_ECHO_OFF: /* password */ - user_pass = appdata_ptr; - reply[i].resp = g_strdup(user_pass->pass); - reply[i].resp_retcode = PAM_SUCCESS; - break; - default: - g_printf("unknown in verify_pam_conv\r\n"); - g_free(reply); - return PAM_CONV_ERR; + switch (msg[i]->msg_style) + { + case PAM_PROMPT_ECHO_ON: /* username */ + user_pass = appdata_ptr; + reply[i].resp = g_strdup(user_pass->user); + reply[i].resp_retcode = PAM_SUCCESS; + break; + case PAM_PROMPT_ECHO_OFF: /* password */ + user_pass = appdata_ptr; + reply[i].resp = g_strdup(user_pass->pass); + reply[i].resp_retcode = PAM_SUCCESS; + break; + default: + g_printf("unknown in verify_pam_conv\r\n"); + g_free(reply); + return PAM_CONV_ERR; + } } - } - *resp = reply; - return PAM_SUCCESS; + + *resp = reply; + return PAM_SUCCESS; } /******************************************************************************/ static void DEFAULT_CC -get_service_name(char* service_name) +get_service_name(char *service_name) { - service_name[0] = 0; - if (g_file_exist("/etc/pam.d/xrdp-sesman")) - { - g_strncpy(service_name, "xrdp-sesman", 255); - } - else - { - g_strncpy(service_name, "gdm", 255); - } + service_name[0] = 0; + + if (g_file_exist("/etc/pam.d/xrdp-sesman")) + { + g_strncpy(service_name, "xrdp-sesman", 255); + } + else + { + g_strncpy(service_name, "gdm", 255); + } } /******************************************************************************/ /* returns long, zero is no go */ long DEFAULT_CC -auth_userpass(char* user, char* pass) +auth_userpass(char *user, char *pass) { - int error; - struct t_auth_info* auth_info; - char service_name[256]; + int error; + struct t_auth_info *auth_info; + char service_name[256]; - get_service_name(service_name); - auth_info = g_malloc(sizeof(struct t_auth_info), 1); - g_strncpy(auth_info->user_pass.user, user, 255); - g_strncpy(auth_info->user_pass.pass, pass, 255); - auth_info->pamc.conv = &verify_pam_conv; - auth_info->pamc.appdata_ptr = &(auth_info->user_pass); - error = pam_start(service_name, 0, &(auth_info->pamc), &(auth_info->ph)); - if (error != PAM_SUCCESS) - { - g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error)); - g_free(auth_info); - return 0; - } - error = pam_authenticate(auth_info->ph, 0); - if (error != PAM_SUCCESS) - { - g_printf("pam_authenticate failed: %s\r\n", - pam_strerror(auth_info->ph, error)); - g_free(auth_info); - return 0; - } - error = pam_acct_mgmt(auth_info->ph, 0); - if (error != PAM_SUCCESS) - { - g_printf("pam_acct_mgmt failed: %s\r\n", - pam_strerror(auth_info->ph, error)); - g_free(auth_info); - return 0; - } - return (long)auth_info; + get_service_name(service_name); + auth_info = g_malloc(sizeof(struct t_auth_info), 1); + g_strncpy(auth_info->user_pass.user, user, 255); + g_strncpy(auth_info->user_pass.pass, pass, 255); + auth_info->pamc.conv = &verify_pam_conv; + auth_info->pamc.appdata_ptr = &(auth_info->user_pass); + error = pam_start(service_name, 0, &(auth_info->pamc), &(auth_info->ph)); + + if (error != PAM_SUCCESS) + { + g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error)); + g_free(auth_info); + return 0; + } + + error = pam_authenticate(auth_info->ph, 0); + + if (error != PAM_SUCCESS) + { + g_printf("pam_authenticate failed: %s\r\n", + pam_strerror(auth_info->ph, error)); + g_free(auth_info); + return 0; + } + + error = pam_acct_mgmt(auth_info->ph, 0); + + if (error != PAM_SUCCESS) + { + g_printf("pam_acct_mgmt failed: %s\r\n", + pam_strerror(auth_info->ph, error)); + g_free(auth_info); + return 0; + } + + return (long)auth_info; } /******************************************************************************/ @@ -141,34 +149,40 @@ auth_userpass(char* user, char* pass) int DEFAULT_CC auth_start_session(long in_val, int in_display) { - struct t_auth_info* auth_info; - int error; - char display[256]; + struct t_auth_info *auth_info; + int error; + char display[256]; - g_sprintf(display, ":%d", in_display); - auth_info = (struct t_auth_info*)in_val; - error = pam_set_item(auth_info->ph, PAM_TTY, display); - if (error != PAM_SUCCESS) - { - g_printf("pam_set_item failed: %s\r\n", pam_strerror(auth_info->ph, error)); - return 1; - } - error = pam_setcred(auth_info->ph, PAM_ESTABLISH_CRED); - if (error != PAM_SUCCESS) - { - g_printf("pam_setcred failed: %s\r\n", pam_strerror(auth_info->ph, error)); - return 1; - } - auth_info->did_setcred = 1; - error = pam_open_session(auth_info->ph, 0); - if (error != PAM_SUCCESS) - { - g_printf("pam_open_session failed: %s\r\n", - pam_strerror(auth_info->ph, error)); - return 1; - } - auth_info->session_opened = 1; - return 0; + g_sprintf(display, ":%d", in_display); + auth_info = (struct t_auth_info *)in_val; + error = pam_set_item(auth_info->ph, PAM_TTY, display); + + if (error != PAM_SUCCESS) + { + g_printf("pam_set_item failed: %s\r\n", pam_strerror(auth_info->ph, error)); + return 1; + } + + error = pam_setcred(auth_info->ph, PAM_ESTABLISH_CRED); + + if (error != PAM_SUCCESS) + { + g_printf("pam_setcred failed: %s\r\n", pam_strerror(auth_info->ph, error)); + return 1; + } + + auth_info->did_setcred = 1; + error = pam_open_session(auth_info->ph, 0); + + if (error != PAM_SUCCESS) + { + g_printf("pam_open_session failed: %s\r\n", + pam_strerror(auth_info->ph, error)); + return 1; + } + + auth_info->session_opened = 1; + return 0; } /******************************************************************************/ @@ -177,27 +191,31 @@ auth_start_session(long in_val, int in_display) int DEFAULT_CC auth_end(long in_val) { - struct t_auth_info* auth_info; + struct t_auth_info *auth_info; - auth_info = (struct t_auth_info*)in_val; - if (auth_info != 0) - { - if (auth_info->ph != 0) + auth_info = (struct t_auth_info *)in_val; + + if (auth_info != 0) { - if (auth_info->session_opened) - { - pam_close_session(auth_info->ph, 0); - } - if (auth_info->did_setcred) - { - pam_setcred(auth_info->ph, PAM_DELETE_CRED); - } - pam_end(auth_info->ph, PAM_SUCCESS); - auth_info->ph = 0; + if (auth_info->ph != 0) + { + if (auth_info->session_opened) + { + pam_close_session(auth_info->ph, 0); + } + + if (auth_info->did_setcred) + { + pam_setcred(auth_info->ph, PAM_DELETE_CRED); + } + + pam_end(auth_info->ph, PAM_SUCCESS); + auth_info->ph = 0; + } } - } - g_free(auth_info); - return 0; + + g_free(auth_info); + return 0; } /******************************************************************************/ @@ -206,33 +224,39 @@ auth_end(long in_val) int DEFAULT_CC auth_set_env(long in_val) { - struct t_auth_info* auth_info; - char** pam_envlist; - char** pam_env; - char item[256]; - char value[256]; - int eq_pos; + struct t_auth_info *auth_info; + char **pam_envlist; + char **pam_env; + char item[256]; + char value[256]; + int eq_pos; - auth_info = (struct t_auth_info*)in_val; - if (auth_info != 0) - { - /* export PAM environment */ - pam_envlist = pam_getenvlist(auth_info->ph); - if (pam_envlist != NULL) + auth_info = (struct t_auth_info *)in_val; + + if (auth_info != 0) { - for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) - { - eq_pos = g_pos(*pam_env, "="); - if (eq_pos >= 0 && eq_pos < 250) + /* export PAM environment */ + pam_envlist = pam_getenvlist(auth_info->ph); + + if (pam_envlist != NULL) { - g_strncpy(item, *pam_env, eq_pos); - g_strncpy(value, (*pam_env) + eq_pos + 1, 255); - g_setenv(item, value, 1); + for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) + { + eq_pos = g_pos(*pam_env, "="); + + if (eq_pos >= 0 && eq_pos < 250) + { + g_strncpy(item, *pam_env, eq_pos); + g_strncpy(value, (*pam_env) + eq_pos + 1, 255); + g_setenv(item, value, 1); + } + + g_free(*pam_env); + } + + g_free(pam_envlist); } - g_free(*pam_env); - } - g_free(pam_envlist); } - } - return 0; + + return 0; } diff --git a/sesman/verify_user_pam_userpass.c b/sesman/verify_user_pam_userpass.c index 0075afeb..9fa2d9e5 100644 --- a/sesman/verify_user_pam_userpass.c +++ b/sesman/verify_user_pam_userpass.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file verify_user_pam_userpass.c * @brief Authenticate user using pam_userpass module * @author Jay Sorg - * + * */ #include "arch.h" @@ -35,43 +34,52 @@ /******************************************************************************/ /* returns boolean */ int DEFAULT_CC -auth_userpass(char* user, char* pass) +auth_userpass(char *user, char *pass) { - pam_handle_t* pamh; - pam_userpass_t userpass; - struct pam_conv conv = {pam_userpass_conv, &userpass}; - const void* template1; - int status; + pam_handle_t *pamh; + pam_userpass_t userpass; + struct pam_conv conv = {pam_userpass_conv, &userpass}; + const void *template1; + int status; - userpass.user = user; - userpass.pass = pass; - if (pam_start(SERVICE, user, &conv, &pamh) != PAM_SUCCESS) - { - return 0; - } - status = pam_authenticate(pamh, 0); - if (status != PAM_SUCCESS) - { - pam_end(pamh, status); - return 0; - } - status = pam_acct_mgmt(pamh, 0); - if (status != PAM_SUCCESS) - { - pam_end(pamh, status); - return 0; - } - status = pam_get_item(pamh, PAM_USER, &template1); - if (status != PAM_SUCCESS) - { - pam_end(pamh, status); - return 0; - } - if (pam_end(pamh, PAM_SUCCESS) != PAM_SUCCESS) - { - return 0; - } - return 1; + userpass.user = user; + userpass.pass = pass; + + if (pam_start(SERVICE, user, &conv, &pamh) != PAM_SUCCESS) + { + return 0; + } + + status = pam_authenticate(pamh, 0); + + if (status != PAM_SUCCESS) + { + pam_end(pamh, status); + return 0; + } + + status = pam_acct_mgmt(pamh, 0); + + if (status != PAM_SUCCESS) + { + pam_end(pamh, status); + return 0; + } + + status = pam_get_item(pamh, PAM_USER, &template1); + + if (status != PAM_SUCCESS) + { + pam_end(pamh, status); + return 0; + } + + if (pam_end(pamh, PAM_SUCCESS) != PAM_SUCCESS) + { + return 0; + } + + return 1; } /******************************************************************************/ @@ -79,19 +87,19 @@ auth_userpass(char* user, char* pass) int DEFAULT_CC auth_start_session(void) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_end(void) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_set_env(void) { - return 0; + return 0; } diff --git a/tests/nx/client.sh b/tests/nx/client.sh deleted file mode 100755 index dc264560..00000000 --- a/tests/nx/client.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -xhost + - -if ! [ -d .nx ] -then - mkdir .nx -fi - -export LD_LIBRARY_PATH=$PWD - -./nxproxy -S nx/nx,session=session,id=jay,root=.nx,connect=127.0.0.1:10,delta=1,stream=1,data=1 - diff --git a/tests/nx/server.sh b/tests/nx/server.sh deleted file mode 100755 index df6e894b..00000000 --- a/tests/nx/server.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -export LD_LIBRARY_PATH=$PWD - -#./nxagent -R -bs -dpi 96 -geometry 1024x768 -noshpix -display nx/nx,link=adsl,delta=1,stream=1,data=1,a8taint=0,cache=4M:9 :9 - -# with cache -#./nxagent -D -bs -ac -dpi 96 -geometry 1024x768 -noshpix -display nx/nx,link=adsl,delta=1,stream=1,data=1,cache=4M:9 :9 - -# without cache -./nxagent -D -bs -ac -dpi 96 -geometry 1024x768 -noshpix -display nx/nx,link=adsl,delta=1,stream=1,data=1,cache=0M:9 :9 - diff --git a/tests/tcp_proxy/Makefile b/tests/tcp_proxy/Makefile new file mode 100644 index 00000000..d19b4818 --- /dev/null +++ b/tests/tcp_proxy/Makefile @@ -0,0 +1,12 @@ +CFLAGS = -O2 -Wall -I../../common +LDFLAGS = -Wl +OBJS = main.o ../../common/os_calls.o +LIBS = -ldl + +all: tcp_proxy + +tcp_proxy: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o tcp_proxy $(OBJS) $(LIBS) + +.PHONY clean: + rm -f $(OBJS) tcp_proxy diff --git a/tests/tcp_proxy/arch.h b/tests/tcp_proxy/arch.h deleted file mode 100644 index 2f3c51a2..00000000 --- a/tests/tcp_proxy/arch.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (c) 2004-2007 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - -*/ - -#if !defined(ARCH_H) -#define ARCH_H - -/* check endianess */ -#if defined(__sparc__) || defined(__PPC__) || defined(__ppc__) -#define B_ENDIAN -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define L_ENDIAN -#elif __BYTE_ORDER == __BIG_ENDIAN -#define B_ENDIAN -#endif -/* check if we need to align data */ -#if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \ - defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \ - defined(__ia64__) || defined(__ppc__) -#define NEED_ALIGN -#endif - -/* defines for thread creation factory functions */ -#if defined(_WIN32) -#define THREAD_RV unsigned long -#define THREAD_CC __stdcall -#else -#define THREAD_RV void* -#define THREAD_CC -#endif - -#if defined(__BORLANDC__) || defined(_WIN32) -#define APP_CC __fastcall -#define DEFAULT_CC __cdecl -#else -#define APP_CC -#define DEFAULT_CC -#endif - -#if defined(_WIN32) -#if defined(__BORLANDC__) -#define EXPORT_CC _export __cdecl -#else -#define EXPORT_CC -#endif -#else -#define EXPORT_CC -#endif - -typedef char ti8; -typedef unsigned char tui8; -typedef signed char tsi8; -typedef short ti16; -typedef unsigned short tui16; -typedef signed short tsi16; -typedef int ti32; -typedef unsigned int tui32; -typedef signed int tsi32; -typedef long tbus; - -#endif diff --git a/tests/tcp_proxy/main.c b/tests/tcp_proxy/main.c index 7bfc747e..301f79a5 100644 --- a/tests/tcp_proxy/main.c +++ b/tests/tcp_proxy/main.c @@ -1,15 +1,32 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -#include "os_calls.h" +#include -int g_loc_io_count = 0; // bytes read from local port -int g_rem_io_count = 0; // bytes read from remote port +int g_loc_io_count = 0; // bytes read from local port +int g_rem_io_count = 0; // bytes read from remote port static int g_terminated = 0; static char g_buf[1024 * 32]; /*****************************************************************************/ static int -main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) +main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump) { int lis_sck; int acc_sck; @@ -30,6 +47,7 @@ main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) lis_sck = g_tcp_socket(); g_tcp_set_non_blocking(lis_sck); error = g_tcp_bind(lis_sck, local_port); + if (error != 0) { g_writeln("bind failed"); @@ -39,6 +57,7 @@ main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) if (error == 0) { error = g_tcp_listen(lis_sck); + if (error == 0) { g_writeln("listening for connection"); @@ -51,6 +70,7 @@ main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) while ((!g_terminated) && (error == 0)) { acc_sck = g_tcp_accept(lis_sck); + if ((acc_sck == -1) && g_tcp_last_error_would_block(lis_sck)) { g_sleep(100); @@ -64,6 +84,7 @@ main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) break; } } + if (error == 0) { error = g_terminated; @@ -72,6 +93,7 @@ main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) /* stop listening */ g_tcp_close(lis_sck); lis_sck = 0; + if (error == 0) { g_writeln("got connection"); @@ -80,65 +102,79 @@ main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) /* connect outgoing socket */ con_sck = 0; + if (error == 0) { con_sck = g_tcp_socket(); g_tcp_set_non_blocking(con_sck); error = g_tcp_connect(con_sck, remote_ip, remote_port); + if ((error == -1) && g_tcp_last_error_would_block(con_sck)) { error = 0; i = 0; + while ((!g_tcp_can_send(con_sck, 100)) && (!g_terminated) && (i < 100)) { g_sleep(100); i++; } + if (i > 99) { g_writeln("timout connecting"); error = 1; } + if (g_terminated) { error = 1; } } + if ((error != 0) && (!g_terminated)) { g_writeln("error connecting to remote\r\n"); } } + while ((!g_terminated) && (error == 0)) { sel = g_tcp_select(con_sck, acc_sck); + if (sel == 0) { g_sleep(10); continue; } + if (sel & 1) { // can read from con_sck w/o blocking count = g_tcp_recv(con_sck, g_buf, 1024 * 16, 0); error = count < 1; + if (error == 0) { g_loc_io_count += count; con_to_acc += count; + if (hexdump) { g_writeln("from remove, the socket from connect"); g_hexdump(g_buf, count); } + #if 0 g_writeln("local_io_count: %d\tremote_io_count: %d", - g_loc_io_count, g_rem_io_count); + g_loc_io_count, g_rem_io_count); #endif sent = 0; + while ((sent < count) && (error == 0) && (!g_terminated)) { i = g_tcp_send(acc_sck, g_buf + sent, count - sent, 0); + if ((i == -1) && g_tcp_last_error_would_block(acc_sck)) { g_tcp_can_send(acc_sck, 1000); @@ -154,28 +190,34 @@ main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) } } } + if (sel & 2) { // can read from acc_sck w/o blocking count = g_tcp_recv(acc_sck, g_buf, 1024 * 16, 0); error = count < 1; + if (error == 0) { g_rem_io_count += count; acc_to_con += count; + if (hexdump) { g_writeln("from accepted, the socket from accept"); g_hexdump(g_buf, count); } + #if 0 g_writeln("local_io_count: %d\tremote_io_count: %d", - g_loc_io_count, g_rem_io_count); + g_loc_io_count, g_rem_io_count); #endif sent = 0; + while ((sent < count) && (error == 0) && (!g_terminated)) { i = g_tcp_send(con_sck, g_buf + sent, count - sent, 0); + if ((i == -1) && g_tcp_last_error_would_block(con_sck)) { g_tcp_can_send(con_sck, 1000); @@ -192,6 +234,7 @@ main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) } } } + g_tcp_close(lis_sck); g_tcp_close(con_sck); g_tcp_close(acc_sck); @@ -221,7 +264,7 @@ proxy_shutdown(int sig) void clear_counters(int sig) { - g_writeln("cleared counters at: local_io_count: %d remote_io_count: %d", + g_writeln("cleared counters at: local_io_count: %d remote_io_count: %d", g_loc_io_count, g_rem_io_count); g_loc_io_count = 0; g_rem_io_count = 0; @@ -229,7 +272,7 @@ clear_counters(int sig) /*****************************************************************************/ int -main(int argc, char** argv) +main(int argc, char **argv) { int dump; @@ -238,11 +281,13 @@ main(int argc, char** argv) usage(); return 0; } - g_init(); - g_signal(2, proxy_shutdown); /* SIGINT */ - g_signal(9, proxy_shutdown); /* SIGKILL */ - g_signal(10, clear_counters);/* SIGUSR1*/ - g_signal(15, proxy_shutdown);/* SIGTERM */ + + g_init("tcp_proxy"); + g_signal_user_interrupt(proxy_shutdown); /* SIGINT */ + g_signal_kill(proxy_shutdown); /* SIGKILL */ + g_signal_usr1(clear_counters); /* SIGUSR1 */ + g_signal_terminate(proxy_shutdown); /* SIGTERM */ + if (argc < 5) { while (!g_terminated) @@ -255,11 +300,13 @@ main(int argc, char** argv) else { dump = g_strcasecmp(argv[4], "dump") == 0; + while (!g_terminated) { main_loop(argv[1], argv[2], argv[3], dump); } } + g_deinit(); return 0; } diff --git a/tests/tcp_proxy/os_calls.c b/tests/tcp_proxy/os_calls.c deleted file mode 100644 index b17856bc..00000000 --- a/tests/tcp_proxy/os_calls.c +++ /dev/null @@ -1,1449 +0,0 @@ -/* - Copyright (c) 2004-2007 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - generic operating system calls - - put all the os / arch define in here you want -*/ - -#if defined(_WIN32) -#include -#include -#else -/* fix for solaris 10 with gcc 3.3.2 problem */ -#if defined(sun) || defined(__sun) -#define ctid_t id_t -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#include -#include -#include -#include - -#include "os_calls.h" -#include "arch.h" - -/* for clearenv() */ -#if defined(_WIN32) -#else -extern char** environ; -#endif - -/* for solaris */ -#if !defined(PF_LOCAL) -#define PF_LOCAL AF_UNIX -#endif -#if !defined(INADDR_NONE) -#define INADDR_NONE ((unsigned long)-1) -#endif - -/*****************************************************************************/ -void APP_CC -g_init(void) -{ - #if defined(_WIN32) - WSADATA wsadata; - - WSAStartup(2, &wsadata); - #endif -} - - -/*****************************************************************************/ -void APP_CC -g_deinit(void) -{ - #if defined(_WIN32) - WSACleanup(); - #endif -} - - -/*****************************************************************************/ -/* allocate memory, returns a pointer to it, size bytes are allocated, - if zero is non zero, each byte will be set to zero */ -void* APP_CC -g_malloc(int size, int zero) -{ - char* rv; - - rv = (char*)malloc(size); - if (zero) - { - memset(rv, 0, size); - } - return rv; -} - - -/*****************************************************************************/ -/* free the memory pointed to by ptr, ptr can be zero */ -void APP_CC -g_free(void* ptr) -{ - if (ptr != 0) - { - free(ptr); - } -} - - -/*****************************************************************************/ -/* output text to stdout, try to use g_write / g_writeln instead to avoid - linux / windows EOL problems */ -void DEFAULT_CC -g_printf(const char* format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); -} - - -/*****************************************************************************/ -void DEFAULT_CC -g_sprintf(char* dest, const char* format, ...) -{ - va_list ap; - - va_start(ap, format); - vsprintf(dest, format, ap); - va_end(ap); -} - - -/*****************************************************************************/ -void DEFAULT_CC -g_snprintf(char* dest, int len, const char* format, ...) -{ - va_list ap; - - va_start(ap, format); - vsnprintf(dest, len, format, ap); - va_end(ap); -} - - -/*****************************************************************************/ -void DEFAULT_CC -g_writeln(const char* format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - #if defined(_WIN32) - g_printf("\r\n"); - #else - g_printf("\n"); - #endif -} - - -/*****************************************************************************/ -void DEFAULT_CC -g_write(const char* format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); -} - - -/*****************************************************************************/ -/* produce a hex dump */ -void APP_CC -g_hexdump(char* p, int len) -{ - unsigned char* line; - int i; - int thisline; - int offset; - - line = (unsigned char*)p; - offset = 0; - while (offset < len) - { - g_printf("%04x ", offset); - thisline = len - offset; - if (thisline > 16) - { - thisline = 16; - } - for (i = 0; i < thisline; i++) - { - g_printf("%02x ", line[i]); - } - for (; i < 16; i++) - { - g_printf(" "); - } - for (i = 0; i < thisline; i++) - { - g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); - } - g_writeln(""); - offset += thisline; - line += thisline; - } -} - - -/*****************************************************************************/ -void APP_CC -g_memset(void* ptr, int val, int size) -{ - memset(ptr, val, size); -} - - -/*****************************************************************************/ -void APP_CC -g_memcpy(void* d_ptr, const void* s_ptr, int size) -{ - memcpy(d_ptr, s_ptr, size); -} - - -/*****************************************************************************/ -int APP_CC -g_getchar(void) -{ - return getchar(); -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_set_no_delay(int sck) -{ - int i; - - i = 1; - #if defined(_WIN32) - setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&i, sizeof(i)); - #else - setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (void*)&i, sizeof(i)); - #endif - return 0; -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_socket(void) -{ - int rv; - int i; - - rv = socket(PF_INET, SOCK_STREAM, 0); - #if defined(_WIN32) - i = 1; - setsockopt(rv, IPPROTO_TCP, TCP_NODELAY, (char*)&i, sizeof(i)); - i = 1; - setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char*)&i, sizeof(i)); - i = 8192 * 2; - setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char*)&i, sizeof(i)); - #else - i = 1; - setsockopt(rv, IPPROTO_TCP, TCP_NODELAY, (void*)&i, sizeof(i)); - i = 1; - setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (void*)&i, sizeof(i)); - i = 8192 * 2; - setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (void*)&i, sizeof(i)); - #endif - return rv; -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_local_socket(void) -{ - #if defined(_WIN32) - return 0; - #else - return socket(PF_LOCAL, SOCK_STREAM, 0); - #endif -} - - -/*****************************************************************************/ -void APP_CC -g_tcp_close(int sck) -{ - if (sck == 0) - { - return; - } - shutdown(sck, 2); - #if defined(_WIN32) - closesocket(sck); - #else - close(sck); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_connect(int sck, const char* address, const char* port) -{ - struct sockaddr_in s; - struct hostent* h; - - g_memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons(atoi(port)); - s.sin_addr.s_addr = inet_addr(address); - if (s.sin_addr.s_addr == INADDR_NONE) - { - h = gethostbyname(address); - if (h != 0) - { - if (h->h_name != 0) - { - if (h->h_addr_list != 0) - { - if ((*(h->h_addr_list)) != 0) - { - s.sin_addr.s_addr = *((int*)(*(h->h_addr_list))); - } - } - } - } - } - return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_set_non_blocking(int sck) -{ - unsigned long i; - - #if defined(_WIN32) - i = 1; - ioctlsocket(sck, FIONBIO, &i); - #else - i = fcntl(sck, F_GETFL); - i = i | O_NONBLOCK; - fcntl(sck, F_SETFL, i); - #endif - return 0; -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_bind(int sck, char* port) -{ - struct sockaddr_in s; - - memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons(atoi(port)); - s.sin_addr.s_addr = INADDR_ANY; - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_local_bind(int sck, char* port) -{ - #if defined(_WIN32) - return -1; - #else - struct sockaddr_un s; - - memset(&s, 0, sizeof(struct sockaddr_un)); - s.sun_family = AF_UNIX; - strcpy(s.sun_path, port); - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_un)); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_listen(int sck) -{ - return listen(sck, 2); -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_accept(int sck) -{ - struct sockaddr_in s; - #if defined(_WIN32) - signed int i; - #else - unsigned int i; - #endif - - i = sizeof(struct sockaddr_in); - memset(&s, 0, i); - return accept(sck, (struct sockaddr*)&s, &i); -} - - -/*****************************************************************************/ -void APP_CC -g_sleep(int msecs) -{ - #if defined(_WIN32) - Sleep(msecs); - #else - usleep(msecs * 1000); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_last_error_would_block(int sck) -{ - #if defined(_WIN32) - return WSAGetLastError() == WSAEWOULDBLOCK; - #else - return (errno == EWOULDBLOCK) || (errno == EINPROGRESS); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_recv(int sck, void* ptr, int len, int flags) -{ - #if defined(_WIN32) - return recv(sck, (char*)ptr, len, flags); - #else - return recv(sck, ptr, len, flags); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_send(int sck, const void* ptr, int len, int flags) -{ - #if defined(_WIN32) - return send(sck, (const char*)ptr, len, flags); - #else - return send(sck, ptr, len, flags); - #endif -} - - -/*****************************************************************************/ -/* wait 'millis' milliseconds for the socket to be able to write */ -/* returns boolean */ -int APP_CC -g_tcp_can_send(int sck, int millis) -{ - fd_set wfds; - struct timeval time; - int rv; - - time.tv_sec = millis / 1000; - time.tv_usec = (millis * 1000) % 1000000; - FD_ZERO(&wfds); - if (sck > 0) - { - FD_SET(((unsigned int)sck), &wfds); - rv = select(sck + 1, 0, &wfds, 0, &time); - if (rv > 0) - { - return 1; - } - } - return 0; -} - - -/*****************************************************************************/ -/* wait 'millis' milliseconds for the socket to be able to receive */ -/* returns boolean */ -int APP_CC -g_tcp_can_recv(int sck, int millis) -{ - fd_set rfds; - struct timeval time; - int rv; - - time.tv_sec = millis / 1000; - time.tv_usec = (millis * 1000) % 1000000; - FD_ZERO(&rfds); - if (sck > 0) - { - FD_SET(((unsigned int)sck), &rfds); - rv = select(sck + 1, &rfds, 0, 0, &time); - if (rv > 0) - { - return 1; - } - } - return 0; -} - - -/*****************************************************************************/ -int APP_CC -g_tcp_select(int sck1, int sck2) -{ - fd_set rfds; - struct timeval time; - int max; - int rv; - - time.tv_sec = 0; - time.tv_usec = 0; - FD_ZERO(&rfds); - if (sck1 > 0) - { - FD_SET(((unsigned int)sck1), &rfds); - } - if (sck2 > 0) - { - FD_SET(((unsigned int)sck2), &rfds); - } - max = sck1; - if (sck2 > max) - { - max = sck2; - } - rv = select(max + 1, &rfds, 0, 0, &time); - if (rv > 0) - { - rv = 0; - if (FD_ISSET(((unsigned int)sck1), &rfds)) - { - rv = rv | 1; - } - if (FD_ISSET(((unsigned int)sck2), &rfds)) - { - rv = rv | 2; - } - } - else - { - rv = 0; - } - return rv; -} - - -/*****************************************************************************/ -void APP_CC -g_random(char* data, int len) -{ - #if defined(_WIN32) - memset(data, 0x44, len); - #else - int fd; - - memset(data, 0x44, len); - fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) - { - fd = open("/dev/random", O_RDONLY); - } - if (fd != -1) - { - read(fd, data, len); - close(fd); - } - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_abs(int i) -{ - return abs(i); -} - - -/*****************************************************************************/ -int APP_CC -g_memcmp(const void* s1, const void* s2, int len) -{ - return memcmp(s1, s2, len); -} - - -/*****************************************************************************/ -/* returns -1 on error, else return handle or file descriptor */ -int APP_CC -g_file_open(const char* file_name) -{ - #if defined(_WIN32) - return (int)CreateFile(file_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - #else - int rv; - - rv = open(file_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (rv == -1) - { - /* can't open read / write, try to open read only */ - rv = open(file_name, O_RDONLY); - } - return rv; - #endif -} - - -/*****************************************************************************/ -/* returns error, always 0 */ -int APP_CC -g_file_close(int fd) -{ - #if defined(_WIN32) - CloseHandle((HANDLE)fd); - #else - close(fd); - #endif - return 0; -} - - -/*****************************************************************************/ -/* read from file, returns the number of bytes read or -1 on error */ -int APP_CC -g_file_read(int fd, char* ptr, int len) -{ - #if defined(_WIN32) - if (ReadFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0)) - { - return len; - } - else - { - return -1; - } - #else - return read(fd, ptr, len); - #endif -} - - -/*****************************************************************************/ -/* write to file, returns the number of bytes writen or -1 on error */ -int APP_CC -g_file_write(int fd, char* ptr, int len) -{ - #if defined(_WIN32) - if (WriteFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0)) - { - return len; - } - else - { - return -1; - } - #else - return write(fd, ptr, len); - #endif -} - - -/*****************************************************************************/ -/* move file pointer, returns offset on success, -1 on failure */ -int APP_CC -g_file_seek(int fd, int offset) -{ - #if defined(_WIN32) - int rv; - - rv = (int)SetFilePointer((HANDLE)fd, offset, 0, FILE_BEGIN); - if (rv == (int)INVALID_SET_FILE_POINTER) - { - return -1; - } - else - { - return rv; - } - #else - return (int)lseek(fd, offset, SEEK_SET); - #endif -} - - -/*****************************************************************************/ -/* do a write lock on a file */ -/* return boolean */ -int APP_CC -g_file_lock(int fd, int start, int len) -{ - #if defined(_WIN32) - return LockFile((HANDLE)fd, start, 0, len, 0); - #else - struct flock lock; - - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = start; - lock.l_len = len; - if (fcntl(fd, F_SETLK, &lock) == -1) - { - return 0; - } - return 1; - #endif -} - - -/*****************************************************************************/ -/* returns error, always zero */ -int APP_CC -g_set_file_rights(const char* filename, int read, int write) -{ - #if defined(_WIN32) - return 0; - #else - int flags; - - flags = read ? S_IRUSR : 0; - flags |= write ? S_IWUSR : 0; - chmod(filename, flags); - return 0; - #endif -} - - -/*****************************************************************************/ -/* returns error */ -int APP_CC -g_chmod_hex(const char* filename, int flags) -{ - #if defined(_WIN32) - return 0; - #else - int fl; - - fl = 0; - fl |= (flags & 0x4000) ? S_ISUID : 0; - fl |= (flags & 0x2000) ? S_ISGID : 0; - fl |= (flags & 0x1000) ? S_ISVTX : 0; - fl |= (flags & 0x0400) ? S_IRUSR : 0; - fl |= (flags & 0x0200) ? S_IWUSR : 0; - fl |= (flags & 0x0100) ? S_IXUSR : 0; - fl |= (flags & 0x0040) ? S_IRGRP : 0; - fl |= (flags & 0x0020) ? S_IWGRP : 0; - fl |= (flags & 0x0010) ? S_IXGRP : 0; - fl |= (flags & 0x0004) ? S_IROTH : 0; - fl |= (flags & 0x0002) ? S_IWOTH : 0; - fl |= (flags & 0x0001) ? S_IXOTH : 0; - return chmod(filename, fl); - #endif -} - - -/*****************************************************************************/ -/* returns error, always zero */ -int APP_CC -g_mkdir(const char* dirname) -{ - #if defined(_WIN32) - return 0; - #else - mkdir(dirname, S_IRWXU); - return 0; - #endif -} - - -/*****************************************************************************/ -/* gets the current working directory and puts up to maxlen chars in - dirname - always returns 0 */ -char* APP_CC -g_get_current_dir(char* dirname, int maxlen) -{ - #if defined(_WIN32) - GetCurrentDirectory(maxlen, dirname); - return 0; - #else - getcwd(dirname, maxlen); - return 0; - #endif -} - - -/*****************************************************************************/ -/* returns error, zero on success and -1 on failure */ -int APP_CC -g_set_current_dir(char* dirname) -{ - #if defined(_WIN32) - if (SetCurrentDirectory(dirname)) - { - return 0; - } - else - { - return -1; - } - #else - return chdir(dirname); - #endif -} - - -/*****************************************************************************/ -/* returns boolean, non zero if the file exists */ -int APP_CC -g_file_exist(const char* filename) -{ - #if defined(_WIN32) - return 0; // use FileAge(filename) <> -1 - #else - return access(filename, F_OK) == 0; - #endif -} - - -/*****************************************************************************/ -/* returns boolean, non zero if the directory exists */ -int APP_CC -g_directory_exist(const char* dirname) -{ - #if defined(_WIN32) - return 0; // use GetFileAttributes and check return value - // is not -1 and FILE_ATTRIBUT_DIRECTORY bit is set - #else - struct stat st; - - if (stat(dirname, &st) == 0) - { - return S_ISDIR(st.st_mode); - } - else - { - return 0; - } - #endif -} - - -/*****************************************************************************/ -/* returns boolean */ -int APP_CC -g_create_dir(const char* dirname) -{ - #if defined(_WIN32) - // test this - return CreateDirectory(dirname, 0); - #else - return mkdir(dirname, (mode_t)-1) == 0; - #endif -} - - -/*****************************************************************************/ -/* returns boolean */ -int APP_CC -g_remove_dir(const char* dirname) -{ - #if defined(_WIN32) - // test this - return RemoveDirectory(dirname); - #else - return rmdir(dirname) == 0; - #endif -} - - -/*****************************************************************************/ -/* returns non zero if the file was deleted */ -int APP_CC -g_file_delete(const char* filename) -{ - #if defined(_WIN32) - return DeleteFile(filename); - #else - return unlink(filename) != -1; - #endif -} - - -/*****************************************************************************/ -/* returns length of text */ -int APP_CC -g_strlen(const char* text) -{ - if (text == 0) - { - return 0; - } - return strlen(text); -} - - -/*****************************************************************************/ -/* returns dest */ -char* APP_CC -g_strcpy(char* dest, const char* src) -{ - if (src == 0 && dest != 0) - { - dest[0] = 0; - return dest; - } - if (dest == 0 || src == 0) - { - return 0; - } - return strcpy(dest, src); -} - - -/*****************************************************************************/ -/* returns dest */ -char* APP_CC -g_strncpy(char* dest, const char* src, int len) -{ - char* rv; - - if (src == 0 && dest != 0) - { - dest[0] = 0; - return dest; - } - if (dest == 0 || src == 0) - { - return 0; - } - rv = strncpy(dest, src, len); - dest[len] = 0; - return rv; -} - - -/*****************************************************************************/ -/* returns dest */ -char* APP_CC -g_strcat(char* dest, const char* src) -{ - if (dest == 0 || src == 0) - { - return dest; - } - return strcat(dest, src); -} - - -/*****************************************************************************/ -/* if in = 0, return 0 else return newly alloced copy of in */ -char* APP_CC -g_strdup(const char* in) -{ - int len; - char* p; - - if (in == 0) - { - return 0; - } - len = g_strlen(in); - p = (char*)g_malloc(len + 1, 0); - g_strcpy(p, in); - return p; -} - - -/*****************************************************************************/ -int APP_CC -g_strcmp(const char* c1, const char* c2) -{ - return strcmp(c1, c2); -} - - -/*****************************************************************************/ -int APP_CC -g_strncmp(const char* c1, const char* c2, int len) -{ - return strncmp(c1, c2, len); -} - - -/*****************************************************************************/ -int APP_CC -g_strcasecmp(const char* c1, const char* c2) -{ - #if defined(_WIN32) - return stricmp(c1, c2); - #else - return strcasecmp(c1, c2); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_strncasecmp(const char* c1, const char* c2, int len) -{ - #if defined(_WIN32) - return strnicmp(c1, c2, len); - #else - return strncasecmp(c1, c2, len); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_atoi(char* str) -{ - return atoi(str); -} - - -/*****************************************************************************/ -int APP_CC -g_pos(char* str, const char* to_find) -{ - char* pp; - - pp = strstr(str, to_find); - if (pp == 0) - { - return -1; - } - return (pp - str); -} - - -/*****************************************************************************/ -long APP_CC -g_load_library(char* in) -{ - #if defined(_WIN32) - return (long)LoadLibrary(in); - #else - return (long)dlopen(in, RTLD_LOCAL | RTLD_LAZY); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_free_library(long lib) -{ - if (lib == 0) - { - return 0; - } - #if defined(_WIN32) - return FreeLibrary((HMODULE)lib); - #else - return dlclose((void*)lib); - #endif -} - - -/*****************************************************************************/ -/* returns NULL if not found */ -void* APP_CC -g_get_proc_address(long lib, const char* name) -{ - if (lib == 0) - { - return 0; - } - #if defined(_WIN32) - return GetProcAddress((HMODULE)lib, name); - #else - return dlsym((void*)lib, name); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_system(char* aexec) -{ - #if defined(_WIN32) - return 0; - #else - return system(aexec); - #endif -} - - -/*****************************************************************************/ -char* APP_CC -g_get_strerror(void) -{ - #if defined(_WIN32) - return 0; - #else - return strerror(errno); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_execvp(const char* p1, char* args[]) -{ - #if defined(_WIN32) - return 0; - #else - return execvp(p1, args); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_execlp3(const char* a1, const char* a2, const char* a3) -{ - #if defined(_WIN32) - return 0; - #else - return execlp(a1, a2, a3, (void*)0); - #endif -} - - -/*****************************************************************************/ -void APP_CC -g_signal(int sig_num, void (*func)(int)) -{ - #if defined(_WIN32) - #else - signal(sig_num, func); - #endif -} - - -/*****************************************************************************/ -void APP_CC -g_signal_child_stop(void (*func)(int)) -{ - #if defined(_WIN32) - #else - signal(SIGCHLD, func); - #endif -} - - -/*****************************************************************************/ -void APP_CC -g_unset_signals(void) -{ - #if defined(_WIN32) - #else - sigset_t mask; - - sigemptyset(&mask); - sigprocmask(SIG_SETMASK, &mask, NULL); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_fork(void) -{ - #if defined(_WIN32) - return 0; - #else - return fork(); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_setgid(int pid) -{ - #if defined(_WIN32) - return 0; - #else - return setgid(pid); - #endif -} - - -/*****************************************************************************/ -/* returns error, zero is success, non zero is error */ -int APP_CC -g_initgroups(const char* user, int gid) -{ - #if defined(_WIN32) - return 0; - #else - return initgroups(user ,gid); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_setuid(int pid) -{ - #if defined(_WIN32) - return 0; - #else - return setuid(pid); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_waitchild(void) -{ - #if defined(_WIN32) - return 0; - #else - int wstat; - - return waitpid(0, &wstat, WNOHANG); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_waitpid(int pid) -{ - #if defined(_WIN32) - return 0; - #else - return waitpid(pid, 0, 0); - #endif -} - - -/*****************************************************************************/ -void APP_CC -g_clearenv(void) -{ - #if defined(_WIN32) - #else - environ = 0; - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_setenv(const char* name, const char* value, int rewrite) -{ - #if defined(_WIN32) - return 0; - #else - return setenv(name, value, rewrite); - #endif -} - - -/*****************************************************************************/ -char* APP_CC -g_getenv(const char* name) -{ - #if defined(_WIN32) - return 0; - #else - return getenv(name); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_exit(int exit_code) -{ - _exit(exit_code); - return 0; -} - - -/*****************************************************************************/ -int APP_CC -g_getpid(void) -{ - #if defined(_WIN32) - return 0; - #else - return getpid(); - #endif -} - - -/*****************************************************************************/ -int APP_CC -g_sigterm(int pid) -{ - #if defined(_WIN32) - return 0; - #else - return kill(pid, SIGTERM); - #endif -} - - -/*****************************************************************************/ -/* returns 0 if ok */ -int APP_CC -g_getuser_info(const char* username, int* gid, int* uid, char* shell, -char* dir, char* gecos) -{ - #if defined(_WIN32) - return 1; - #else - struct passwd* pwd_1; - - pwd_1 = getpwnam(username); - if (pwd_1 != 0) - { - if (gid != 0) - { - *gid = pwd_1->pw_gid; - } - if (uid != 0) - { - *uid = pwd_1->pw_uid; - } - if (dir != 0) - { - g_strcpy(dir, pwd_1->pw_dir); - } - if (shell != 0) - { - g_strcpy(shell, pwd_1->pw_shell); - } - if (gecos != 0) - { - g_strcpy(gecos, pwd_1->pw_gecos); - } - return 0; - } - return 1; - #endif -} - - -/*****************************************************************************/ -/* returns 0 if ok */ -int APP_CC -g_getgroup_info(const char* groupname, int* gid) -{ - #if defined(_WIN32) - return 1; - #else - struct group* g; - - g = getgrnam(groupname); - if (g != 0) - { - if (gid != 0) - { - *gid = g->gr_gid; - } - return 0; - } - return 1; - #endif -} - - -/*****************************************************************************/ -/* returns error */ -/* if zero is returned, then ok is set */ -int APP_CC -g_check_user_in_group(const char* username, int gid, int* ok) -{ - #if defined(_WIN32) - return 1; - #else - struct group* groups; - int i; - - groups = getgrgid(gid); - if (groups == 0) - { - return 1; - } - *ok = 0; - i = 0; - while (0 != groups->gr_mem[i]) - { - if (0 == g_strcmp(groups->gr_mem[i], username)) - { - *ok = 1; - break; - } - i++; - } - return 0; - #endif -} - - -/*****************************************************************************/ -/* returns the time since the Epoch (00:00:00 UTC, January 1, 1970), - measured in seconds. */ -int APP_CC -g_time1(void) -{ - #if defined(_WIN32) - return GetTickCount() / 1000; - #else - return time(0); - #endif -} diff --git a/tests/tcp_proxy/os_calls.h b/tests/tcp_proxy/os_calls.h deleted file mode 100644 index 768cc38c..00000000 --- a/tests/tcp_proxy/os_calls.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - Copyright (c) 2004-2007 Jay Sorg - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - generic operating system calls -*/ - -#if !defined(OS_CALLS_H) -#define OS_CALLS_H - -#include "arch.h" - -void APP_CC -g_init(void); -void APP_CC -g_deinit(void); -void* APP_CC -g_malloc(int size, int zero); -void APP_CC -g_free(void* ptr); -void DEFAULT_CC -g_printf(const char *format, ...); -void DEFAULT_CC -g_sprintf(char* dest, const char* format, ...); -void DEFAULT_CC -g_snprintf(char* dest, int len, const char* format, ...); -void DEFAULT_CC -g_writeln(const char* format, ...); -void DEFAULT_CC -g_write(const char* format, ...); -void APP_CC -g_hexdump(char* p, int len); -void APP_CC -g_memset(void* ptr, int val, int size); -void APP_CC -g_memcpy(void* d_ptr, const void* s_ptr, int size); -int APP_CC -g_getchar(void); -int APP_CC -g_tcp_set_no_delay(int sck); -int APP_CC -g_tcp_socket(void); -int APP_CC -g_tcp_local_socket(void); -void APP_CC -g_tcp_close(int sck); -int APP_CC -g_tcp_connect(int sck, const char* address, const char* port); -int APP_CC -g_tcp_force_send(int sck, char* data, int len); -int APP_CC -g_tcp_force_recv(int sck, char* data, int len); -int APP_CC -g_tcp_set_non_blocking(int sck); -int APP_CC -g_tcp_bind(int sck, char* port); -int APP_CC -g_tcp_local_bind(int sck, char* port); -int APP_CC -g_tcp_listen(int sck); -int APP_CC -g_tcp_accept(int sck); -int APP_CC -g_tcp_recv(int sck, void* ptr, int len, int flags); -int APP_CC -g_tcp_send(int sck, const void* ptr, int len, int flags); -int APP_CC -g_tcp_last_error_would_block(int sck); -int APP_CC -g_tcp_can_send(int sck, int millis); -int APP_CC -g_tcp_can_recv(int sck, int millis); -int APP_CC -g_tcp_select(int sck1, int sck2); -void APP_CC -g_sleep(int msecs); -void APP_CC -g_random(char* data, int len); -int APP_CC -g_abs(int i); -int APP_CC -g_memcmp(const void* s1, const void* s2, int len); -int APP_CC -g_file_open(const char* file_name); -int APP_CC -g_file_close(int fd); -int APP_CC -g_file_read(int fd, char* ptr, int len); -int APP_CC -g_file_write(int fd, char* ptr, int len); -int APP_CC -g_file_seek(int fd, int offset); -int APP_CC -g_file_lock(int fd, int start, int len); -int APP_CC -g_set_file_rights(const char* filename, int read, int write); -int APP_CC -g_chmod_hex(const char* filename, int flags); -int APP_CC -g_mkdir(const char* dirname); -char* APP_CC -g_get_current_dir(char* dirname, int maxlen); -int APP_CC -g_set_current_dir(char* dirname); -int APP_CC -g_file_exist(const char* filename); -int APP_CC -g_directory_exist(const char* dirname); -int APP_CC -g_create_dir(const char* dirname); -int APP_CC -g_remove_dir(const char* dirname); -int APP_CC -g_file_delete(const char* filename); -int APP_CC -g_strlen(const char* text); -char* APP_CC -g_strcpy(char* dest, const char* src); -char* APP_CC -g_strncpy(char* dest, const char* src, int len); -char* APP_CC -g_strcat(char* dest, const char* src); -char* APP_CC -g_strdup(const char* in); -int APP_CC -g_strcmp(const char* c1, const char* c2); -int APP_CC -g_strncmp(const char* c1, const char* c2, int len); -int APP_CC -g_strcasecmp(const char* c1, const char* c2); -int APP_CC -g_strncasecmp(const char* c1, const char* c2, int len); -int APP_CC -g_atoi(char* str); -int APP_CC -g_pos(char* str, const char* to_find); -long APP_CC -g_load_library(char* in); -int APP_CC -g_free_library(long lib); -void* APP_CC -g_get_proc_address(long lib, const char* name); -int APP_CC -g_system(char* aexec); -char* APP_CC -g_get_strerror(void); -int APP_CC -g_execvp(const char* p1, char* args[]); -int APP_CC -g_execlp3(const char* a1, const char* a2, const char* a3); -void APP_CC -g_signal(int sig_num, void (*func)(int)); -void APP_CC -g_signal_child_stop(void (*func)(int)); -void APP_CC -g_unset_signals(void); -int APP_CC -g_fork(void); -int APP_CC -g_setgid(int pid); -int APP_CC -g_initgroups(const char* user, int gid); -int APP_CC -g_setuid(int pid); -int APP_CC -g_waitchild(void); -int APP_CC -g_waitpid(int pid); -void APP_CC -g_clearenv(void); -int APP_CC -g_setenv(const char* name, const char* value, int rewrite); -char* APP_CC -g_getenv(const char* name); -int APP_CC -g_exit(int exit_code); -int APP_CC -g_getpid(void); -int APP_CC -g_sigterm(int pid); -int APP_CC -g_getuser_info(const char* username, int* gid, int* uid, char* shell, - char* dir, char* gecos); -int APP_CC -g_getgroup_info(const char* groupname, int* gid); -int APP_CC -g_check_user_in_group(const char* username, int gid, int* ok); -int APP_CC -g_time1(void); - -#endif diff --git a/tests/xdemo/README.txt b/tests/xdemo/README.txt deleted file mode 100644 index 52bda08c..00000000 --- a/tests/xdemo/README.txt +++ /dev/null @@ -1,3 +0,0 @@ - -this is a project to develope a program to test xwindows - diff --git a/tests/xdemo/bmp_parser.c b/tests/xdemo/bmp_parser.c deleted file mode 100644 index 9d3e43c8..00000000 --- a/tests/xdemo/bmp_parser.c +++ /dev/null @@ -1,204 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "common.h" - -// multi byte values are stored in little endian - -struct bmp_magic -{ - char magic[2]; -}; - -struct bmp_hdr -{ - uint32_t size; // file size in bytes - uint16_t reserved1; - uint16_t reserved2; - uint32_t offset; // offset to image data, in bytes -}; - -struct dib_hdr -{ - uint32_t hdr_size; - int32_t width; - int32_t height; - uint16_t nplanes; - uint16_t bpp; - uint32_t compress_type; - uint32_t image_size; - int32_t hres; - int32_t vres; - uint32_t ncolors; - uint32_t nimpcolors; -}; - -// forward declarations -int parse_bmp(char *filename, struct pic_info *pic_info); -int parse_bmp_24(struct bmp_hdr *bmp_hdr, struct dib_hdr *dib_hdr, int fd, struct pic_info *pic_info); - -int parse_bmp(char *filename, struct pic_info *pic_info) -{ - int got_magic; - int fd; - int rval; - - struct bmp_magic magic; - struct bmp_hdr bmp_hdr; - struct dib_hdr dib_hdr; - - if ((fd = open(filename, O_RDONLY)) < 0) { - printf("error opeing %s\n", filename); - return -1; - } - - // read BMP magic... - if ((rval = read(fd, magic.magic, 2)) != 2) { - fprintf(stderr, "error reading BMP signature from file %s\n", filename); - return -1; - } - - got_magic = 0; - - // ...and confirm that this is indeed a BMP file - if ((magic.magic[0] == 'B') && (magic.magic[1] == 'M')) { - // BM – Windows 3.1x, 95, NT, ... etc - got_magic = 1; - } - else if ((magic.magic[0] == 'B') && (magic.magic[1] == 'A')) { - // BA – OS/2 struct Bitmap Array - got_magic = 1; - } - else if ((magic.magic[0] == 'C') && (magic.magic[1] == 'I')) { - // CI – OS/2 struct Color Icon - got_magic = 1; - } - else if ((magic.magic[0] == 'C') && (magic.magic[1] == 'P')) { - // CP – OS/2 const Color Pointer - got_magic = 1; - } - else if ((magic.magic[0] == 'I') && (magic.magic[1] == 'C')) { - // IC – OS/2 struct Icon - got_magic = 1; - } - else if ((magic.magic[0] == 'P') && (magic.magic[1] == 'T')) { - // PT – OS/2 Pointer - got_magic = 1; - } - - if (!got_magic) { - fprintf(stderr, "%s is not a valid BMP file\n", filename); - return -1; - } - - // read BMP header - if ((rval = read(fd, &bmp_hdr, sizeof(bmp_hdr))) < sizeof(bmp_hdr)) { - fprintf(stderr, "error BMP header from file %s\n", filename); - return -1; - } - - // read DIB header - if ((rval = read(fd, &dib_hdr, sizeof(dib_hdr))) < sizeof(dib_hdr)) { - fprintf(stderr, "error reading DIB header from file %s\n", filename); - return -1; - } - -#if 0 - printf("header size: %d\n", dib_hdr.hdr_size); - printf("width: %d\n", dib_hdr.width); - printf("height: %d\n", dib_hdr.height); - printf("num planes: %d\n", dib_hdr.nplanes); - printf("bpp: %d\n", dib_hdr.bpp); - printf("comp type: %d\n", dib_hdr.compress_type); - printf("image size: %d\n", dib_hdr.image_size); - printf("hres: %d\n", dib_hdr.hres); - printf("vres: %d\n", dib_hdr.vres); - printf("ncolors: %d\n", dib_hdr.ncolors); - printf("nimpcolors: %d\n", dib_hdr.nimpcolors); -#endif - - if (dib_hdr.compress_type) { - printf("TODO: compressed images not yet supported\n"); - return -1; - } - - pic_info->width = dib_hdr.width; - pic_info->height = dib_hdr.height; - - if (dib_hdr.bpp == 24) { - rval = parse_bmp_24(&bmp_hdr, &dib_hdr, fd, pic_info); - } - close(fd); - return rval; -} - -/** - * extract 24bit BMP data from image file - * - * @return 0 on success - * @return -1 on failure - */ - -int parse_bmp_24( - struct bmp_hdr *bmp_hdr, - struct dib_hdr *dib_hdr, - int fd, - struct pic_info *pic_info -) -{ - char *file_data; - char *ptr_file_data; - char *mem_data; - char *ptr_mem_data; - char *cptr; - - int w = dib_hdr->width; // picture width - int h = dib_hdr->height; // picture height - int bpl; // bytes per line - int bytes; - int i; - int j; - - // bytes per image line = width x bytes_per_pixel + padding - i = (w * 3) % 4; - j = (i == 0) ? 0 : 4 - i; - bpl = w * 3 + j; - - // 24 bit depth, no alpha channel - file_data = (char *) malloc(h * bpl); - - // point to first line in image data, which is stored in reverse order - ptr_file_data = (file_data + dib_hdr->image_size) - bpl; - - // 24 bit depth, with alpha channel - mem_data = (char *) malloc(w * h * 4); - ptr_mem_data = mem_data; - - pic_info->pixel_data = ptr_mem_data; - - // seek to beginning of pixel data - lseek(fd, bmp_hdr->offset, SEEK_SET); - - // read all pixel data - bytes = read(fd, file_data, dib_hdr->image_size); - - // convert 24bit to 24 bit with alpha and store in reverse - for (i = 0; i < h; i ++) - { - cptr = ptr_file_data; - for (j = 0; j < w; j++) - { - *ptr_mem_data++ = *cptr++; // blue value - *ptr_mem_data++ = *cptr++; // green value - *ptr_mem_data++ = *cptr++; // red value - *ptr_mem_data++ = 0; // alpha channel - } - ptr_file_data -= bpl; - } - - free(file_data); - return 0; -} diff --git a/tests/xdemo/commit.txt b/tests/xdemo/commit.txt deleted file mode 100644 index 4ad4fffe..00000000 --- a/tests/xdemo/commit.txt +++ /dev/null @@ -1 +0,0 @@ -First commit for the project Ver 1.0 diff --git a/tests/xdemo/common.h b/tests/xdemo/common.h deleted file mode 100644 index 2ce75bba..00000000 --- a/tests/xdemo/common.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __XDEMO_H -#define __XDEMO_H - -#define DEBUG - -#ifdef DEBUG -#define dprint(x...) printf(x) -#else -#define dprint(x...) -#endif - -struct pic_info -{ - int width; - int height; - char *pixel_data; -}; - -#endif diff --git a/tests/xdemo/xdemo.c b/tests/xdemo/xdemo.c deleted file mode 100644 index 073516f0..00000000 --- a/tests/xdemo/xdemo.c +++ /dev/null @@ -1,674 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common.h" - -// LK_TODO -// http://tronche.com/gui/x/xlib/GC/convenience-functions/fill-tile-and-stipple.html -// fill stipple - -// drawfonts: XDrawString, XDrawImageString XDrawText XLoadFont XTextExtents -// http://www.ac3.edu.au/SGI_Developer/books/XLib_PG/sgi_html/apa.html -// http://www.ac3.edu.au/SGI_Developer/books/XLib_PG/sgi_html/index.html - -// use jpg lib to convert bmp to jpg and vice versa - -#define MAX_COLORS 5 -#define SCROLL_JUMP 1 // scroll in increments of g_winHeight -#define SCROLL_SMOOTH1 2 // scroll using XPutImage + XCopyArea -#define SCROLL_SMOOTH2 3 // scroll using XPutImage only - -int parse_bmp(char *filename, struct pic_info *); -int drawBMP(char *filename, int scroll_type); -int signal_tcp_proxy(char *proxy_app); - -// globals -Display *g_disp; -Window g_win; -XColor g_colors[MAX_COLORS]; -GC g_gc; -int g_winWidth; -int g_winHeight; -int g_delay_dur; - -void start_timer(struct timeval *tv) -{ - gettimeofday(tv, NULL); -} - - -uint32_t time_elapsed_ms(struct timeval tv) -{ - struct timeval tv_now; - uint32_t dur; - - gettimeofday(&tv_now, NULL); - dur = ((tv_now.tv_sec - tv.tv_sec) * 1000) + ((tv_now.tv_usec - tv.tv_usec) / 1000); - return dur; -} - - -uint32_t time_elapsed_us(struct timeval tv) -{ - struct timeval tv_now; - uint32_t dur; - - gettimeofday(&tv_now, NULL); - dur = ((tv_now.tv_sec - tv.tv_sec) * 1000000) + (tv_now.tv_usec - tv.tv_usec); - return dur; -} - -int drawLines(int count) -{ - int x1; - int y1; - int x2; - int y2; - int i; - int index; - - if (count <= 0) { - return 0; // nothing to do - } - - srandom(time(NULL)); - XClearArea(g_disp, g_win, 0, 0, g_winWidth, g_winHeight, 0); - - for (i = 0, index = 0; i < count; i++) - { - x1 = random() % g_winWidth; - y1 = random() % g_winHeight; - x2 = random() % g_winWidth; - y2 = random() % g_winHeight; - XSetForeground(g_disp, g_gc, g_colors[index++].pixel); - if (index == MAX_COLORS) { - index = 0; - } - // from-to - XDrawLine(g_disp, g_win, g_gc, x1, y1, x2, y2); - XFlush(g_disp); - usleep(g_delay_dur); - } - return 0; -} - -// LK_TODO support user defined w and h - -int drawRectangles(int count) -{ - int x1; - int y1; - int w; - int h; - int i; - int index; - - if (count <= 0) { - return 0; // nothing to do - } - - srandom(time(NULL)); - XClearArea(g_disp, g_win, 0, 0, g_winWidth, g_winHeight, 0); - - for (i = 0, index = 0; i < count; i++) - { - x1 = random() % g_winWidth; - y1 = random() % g_winHeight; - w = 160; - h = 140; - XSetForeground(g_disp, g_gc, g_colors[index++].pixel); - if (index == MAX_COLORS) { - index = 0; - } - //XDrawRectangle(g_disp, g_win, g_gc, x1, y1, w, h); - XFillRectangle(g_disp, g_win, g_gc, x1, y1, w, h); - XFlush(g_disp); - usleep(g_delay_dur); - } - return 0; -} - -int drawFont(int count, char *msg) -{ - int x1; - int y1; - int i; - int index; - -#ifdef CHANGE_FONT_SIZE - int w; - int h; - int actual_count; - char **font_list; -#endif - - if (count <= 0) { - return 0; // nothing to do - } - - srandom(time(NULL)); - XClearArea(g_disp, g_win, 0, 0, g_winWidth, g_winHeight, 0); - -#ifdef CHANGE_FONT_SIZE - font_list = XListFonts(g_disp, "−*−courier−*−*−*−*−0−0−*−*−*−0−*−*", 2000, &actual_count); - if (!font_list) { - printf("actual_count=%d\n", actual_count); - for (i = 0; i < actual_count; i++) - { - printf("%s\n", font_list[i]); - } - XFreeFontNames(font_list); - } - else { - printf("XListFonts() reted NULL\n"); - } -#endif - - srandom(time(NULL)); - - for (i = 0, index = 0; i < count; i++) - { - x1 = random() % g_winWidth; - y1 = random() % g_winHeight; - XSetForeground(g_disp, g_gc, g_colors[index++].pixel); - if (index == MAX_COLORS) { - index = 0; - } - XDrawString(g_disp, g_win, g_gc, x1, y1, msg, strlen(msg)); - XFlush(g_disp); - usleep(g_delay_dur); - } - return 0; // nothing to do -} - -/** - * display a usage message - */ - -void -usage() -{ - printf("usage: xdemo [-l] [-r] [-s] [-f ] [-i ] [-g ] [-c ] [-o ] [-d ] -z\n"); - printf(" -l draw lines\n"); - printf(" -r draw fill rectangles\n"); - printf(" -s draw stipple rectangles\n"); - printf(" -f draw string using fonts\n"); - printf(" -i draw image\n"); - printf(" -g geometry, default is 640x480\n"); - printf(" -c iteration count, default is 5000\n"); - printf(" -d loop delay in micro seconds, default 1000\n"); - printf(" -o define scrolling method\n"); - printf(" -z zero proxy counters for specified application\n\n"); -} - -int main(int argc, char **argv) -{ - XEvent evt; - Colormap colormap; - struct timeval tv; - int screenNumber; - long eventMask; - unsigned long white; - unsigned long black; - Status rc; - int iters; - int opt; - int draw_lines; - int draw_rects; - int draw_stipples; - int draw_fonts; - int draw_image; - int zero_counters; - int scroll_type; - char image_file[256]; - char proxy_app[256]; - char msg[4096]; - - // set some defaults - g_winWidth = 640; - g_winHeight = 480; - iters = 5000; - draw_lines = 1; - draw_rects = 1; - draw_stipples = 1; - draw_fonts = 1; - draw_image = 1; - g_delay_dur = 1000; - scroll_type = SCROLL_SMOOTH1; - zero_counters = 0; - strcpy(image_file, "yosemite.bmp"); - strcpy(msg, "To be or not to be!"); - - // process cmd line args - opterr = 0; - while ((opt = getopt(argc, argv, "lrsg:c:f:i:d:o:z:")) != -1) - { - switch (opt) - { - case 'g': - if (sscanf(optarg, "%dx%d", &g_winWidth, &g_winHeight) != 2) { - fprintf(stderr, "\nerror: invalid geometry specified\n\n"); - usage(); - return -1; - } - break; - - case 'c': - if (sscanf(optarg, "%d", &iters) != 1) { - fprintf(stderr, "\nerror: invalid count specified\n\n"); - usage(); - return -1; - } - break; - - case 'l': - draw_lines = 1; - draw_rects = 0; - draw_stipples = 0; - draw_fonts = 0; - draw_image = 0; - break; - - case 'r': - draw_rects = 1; - draw_lines = 0; - draw_stipples = 0; - draw_fonts = 0; - draw_image = 0; - break; - - case 's': - draw_stipples = 1; - draw_lines = 0; - draw_rects = 0; - draw_fonts = 0; - draw_image = 0; - break; - - case 'f': - if (strlen(optarg) <= 0) { - fprintf(stderr, "\nerror: -f option requires an argument\n\n"); - usage(); - return -1; - } - draw_fonts = 1; - strncpy(msg, optarg, 4096); - draw_lines = 0; - draw_rects = 0; - draw_stipples = 0; - draw_image = 0; - break; - - case 'i': - if (strlen(optarg) <= 0) { - fprintf(stderr, "\nerror: -i option requires an argument\n\n"); - usage(); - return -1; - } - draw_image = 1; - strncpy(image_file, optarg, 255); - draw_lines = 0; - draw_rects = 0; - draw_stipples = 0; - draw_fonts = 0; - break; - - case 'h': - usage(); - return 0; - break; - - case 'v': - printf("xdemo Ver 1.0\n"); - return 0; - break; - - case 'd': - if (sscanf(optarg, "%d", &g_delay_dur) != 1) { - fprintf(stderr, "\nerror: -d option requires an argument\n\n"); - usage(); - return -1; - } - break; - - case 'z': - if (strlen(optarg) <= 0) { - fprintf(stderr, "\nerror: invalid proxy application specified\n\n"); - usage(); - return -1; - } - strcpy(proxy_app, optarg); - printf("##### LK_TODO: proxy_app=%s\n", proxy_app); - zero_counters = 1; - break; - - case 'o': - if (strcmp(optarg, "jump") == 0) { - scroll_type = SCROLL_JUMP; - } - else if (strcmp(optarg, "smooth1") == 0) { - scroll_type = SCROLL_SMOOTH1; - } - else if (strcmp(optarg, "smooth2") == 0) { - scroll_type = SCROLL_SMOOTH2; - } - else { - fprintf(stderr, "\ninvalid scroll type specified\n\n"); - usage(); - return -1; - } - break; - - default: - usage(); - return -1; - } - } - - // must have at least one operation - if ((!draw_lines) && (!draw_rects) && (!draw_stipples) && - (!draw_fonts) && (!draw_image)) { - usage(); - return -1; - } - - g_disp = XOpenDisplay(NULL); - if (!g_disp) { - dprint("error opening X display\n"); - exit(-1); - } - - screenNumber = DefaultScreen(g_disp); - white = WhitePixel(g_disp, screenNumber); - black = BlackPixel(g_disp, screenNumber); - - g_win = XCreateSimpleWindow(g_disp, - DefaultRootWindow(g_disp), - 50, 50, // origin - g_winWidth, g_winHeight, // size - 0, black, // border - white ); // backgd - - XMapWindow(g_disp, g_win); - //eventMask = StructureNotifyMask | MapNotify | VisibilityChangeMask; - eventMask = StructureNotifyMask | VisibilityChangeMask; - XSelectInput(g_disp, g_win, eventMask); - - g_gc = XCreateGC(g_disp, g_win, - 0, // mask of values - NULL ); // array of values - #if 0 - do - { - dprint("about to call XNextEvent(...)\n"); - XNextEvent(g_disp, &evt);// calls XFlush - dprint("returned from XNextEvent(...)\n"); - } - //while(evt.type != MapNotify); - while(evt.type != VisibilityNotify); - #endif - - // get access to the screen's color map - colormap = DefaultColormap(g_disp, screenNumber); - - // alloc red color - rc = XAllocNamedColor(g_disp, colormap, "red", &g_colors[0], &g_colors[0]); - if (rc == 0) { - printf("XAllocNamedColor - failed to allocated 'red' color.\n"); - exit(1); - } - - rc = XAllocNamedColor(g_disp, colormap, "green", &g_colors[1], &g_colors[1]); - if (rc == 0) { - printf("XAllocNamedColor - failed to allocated 'green' color.\n"); - exit(1); - } - - rc = XAllocNamedColor(g_disp, colormap, "blue", &g_colors[2], &g_colors[2]); - if (rc == 0) { - printf("XAllocNamedColor - failed to allocated 'blue' color.\n"); - exit(1); - } - rc = XAllocNamedColor(g_disp, colormap, "yellow", &g_colors[3], &g_colors[3]); - if (rc == 0) { - printf("XAllocNamedColor - failed to allocated 'yellow' color.\n"); - exit(1); - } - rc = XAllocNamedColor(g_disp, colormap, "orange", &g_colors[4], &g_colors[4]); - if (rc == 0) { - printf("XAllocNamedColor - failed to allocated 'orange' color.\n"); - exit(1); - } - - if (zero_counters) { - signal_tcp_proxy(proxy_app); - } - - if (draw_lines) { - start_timer(&tv); - drawLines(iters); - printf("drew %d lines in %d ms\n", iters, time_elapsed_ms(tv)); - } - - if (draw_rects) { - start_timer(&tv); - drawRectangles(iters); - printf("drew %d rects in %d ms\n", iters, time_elapsed_ms(tv)); - } - - if (draw_stipples) { - start_timer(&tv); - // LK_TODO - } - - if (draw_fonts) { - start_timer(&tv); - drawFont(iters, msg); - printf("drew %d strings in %d ms\n", iters, time_elapsed_ms(tv)); - } - - if (draw_image) { - start_timer(&tv); - drawBMP(image_file, scroll_type); - printf("drew BMP in %d ms\n", time_elapsed_ms(tv)); - } - - if (zero_counters) { - signal_tcp_proxy(proxy_app); - } - - eventMask = ButtonPressMask|ButtonReleaseMask; - - XSelectInput(g_disp, g_win, eventMask); - - do - { - XNextEvent(g_disp, &evt); // calls XFlush() - } - while(evt.type != ButtonRelease); - - XDestroyWindow(g_disp, g_win); - XCloseDisplay(g_disp); - - return 0; -} - -int drawBMP(char *filename, int scroll_type) -{ - struct pic_info pic_info; - XImage *image; - Visual *visual; - Pixmap pixmap; - int depth; - int i; - int j; - - if (parse_bmp(filename, &pic_info) < 0) { - exit(-1); - } - XClearArea(g_disp, g_win, 0, 0, g_winWidth, g_winHeight, 0); - - depth = DefaultDepth(g_disp, DefaultScreen(g_disp)); - visual = DefaultVisual(g_disp, DefaultScreen(g_disp)); - - // create empty pixmap - pixmap = XCreatePixmap(g_disp, g_win, pic_info.width, pic_info.height, depth); - - // create an image from pixel data - image = XCreateImage(g_disp, visual, depth, ZPixmap, 0, pic_info.pixel_data, - pic_info.width, pic_info.height, 32, 0); - - if (pic_info.height <= g_winHeight) { - // image is too small to scroll - XFlush(g_disp); - XPutImage(g_disp, g_win, g_gc, image, 0, 0, 0, 0, pic_info.width, pic_info.height); - XFlush(g_disp); - return 0; - } - - if (scroll_type == SCROLL_JUMP) { - // copy image to pixelmap - XPutImage(g_disp, pixmap, g_gc, image, 0, 0, 0, 0, pic_info.width, pic_info.height); - - if (pic_info.height <= g_winHeight) { - // image too small - no scrolling required - XFlush(g_disp); - XCopyArea(g_disp, // connection to X server - pixmap, // source drawable - g_win, // dest drawable - g_gc, // graphics context - 0, 0, // source x,y - pic_info.width, // width - pic_info.height, // height - 0, 0); // dest x,y - XFlush(g_disp); - return 0; - } - - j = pic_info.height / g_winHeight; - if (pic_info.height % g_winHeight != 0) { - // need to include the last part of the image - j++; - } - XFlush(g_disp); - for (i = 0; i < j; i++) - { - XCopyArea(g_disp, // connection to X server - pixmap, // source drawable - g_win, // dest drawable - g_gc, // graphics context - 0, i * g_winHeight, // source x,y - pic_info.width, // width - pic_info.height, // height - 0, 0); // dest x,y - XFlush(g_disp); - sleep(3); - } - } - - /* - ** smooth scroll the image - */ - - // number of lines to be scrolled - j = pic_info.height - g_winHeight; - - if (scroll_type == SCROLL_SMOOTH1) { - XFlush(g_disp); - XPutImage(g_disp, g_win, g_gc, image, 0, 0, 0, 0, pic_info.width, pic_info.height); - XFlush(g_disp); - usleep(10000); - for (i = 0; i < j; i++) - { - XCopyArea(g_disp, g_win, g_win, g_gc, 0, 1, g_winWidth, g_winHeight - 1, 0, 0); - XPutImage(g_disp, g_win, g_gc, image, 0, g_winHeight + i, 0, g_winHeight -1 , pic_info.width, 1); - XFlush(g_disp); - usleep(10000); - } - return 0; - } - - if (scroll_type == SCROLL_SMOOTH2) { - XFlush(g_disp); - for (i = 0; i < j; i++) - { - XPutImage(g_disp, g_win, g_gc, image, 0, i, 0, 0, pic_info.width, pic_info.height - i); - XFlush(g_disp); - usleep(10000); - } - } - return 0; -} - -int process_bmp_event() -{ - XEvent ev; - long event_mask; - - event_mask = ExposureMask|ButtonPressMask|ButtonReleaseMask|StructureNotifyMask; - XSelectInput(g_disp, g_win, event_mask); - XNextEvent(g_disp, &ev); - switch(ev.type) - { - case Expose: - printf("got expose event\n"); - break; - - default: - printf("did not get expose event\n"); - break; - } - return 0; -} - -/** - * send a SIGUSR1 to process tcp_proxy, causing it to clear counters - * - * @return 0 on success, -1 on failure - */ - -int signal_tcp_proxy(char *proc_name) -{ - FILE *fp; - char *cptr; - char buf[2048]; - int pids[10]; - int status = 0; - int num_procs; - int i; - - sprintf(buf, "pidof %s", proc_name); - if ((fp = popen(buf, "r")) == NULL ) { - printf("xdemo: popen() failed\n"); - return -1; - } - - cptr = fgets(buf, 2047, fp); - if (cptr == NULL) { - pclose(fp); - return -1; - } - - num_procs = sscanf(buf, "%d %d %d %d %d %d %d %d %d %d", - &pids[0], &pids[1], &pids[2], &pids[3], &pids[4], - &pids[5], &pids[6], &pids[7], &pids[8], &pids[9]); - if (num_procs > 0) { - for (i = 0; i < num_procs; i++) { - kill(pids[i], SIGUSR1); - printf("sent SIGUSR1 to process %d\n", pids[i]); - } - } - - pclose(fp); - return status; -} - diff --git a/tests/xdemo/yosemite.bmp b/tests/xdemo/yosemite.bmp deleted file mode 100644 index c64aba75..00000000 Binary files a/tests/xdemo/yosemite.bmp and /dev/null differ diff --git a/vnc/vnc.c b/vnc/vnc.c index fd5ba25f..3d155a21 100644 --- a/vnc/vnc.c +++ b/vnc/vnc.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - libvnc - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * libvnc + */ #include "vnc.h" #include "log.h" @@ -26,814 +24,909 @@ /******************************************************************************/ /* taken from vncauth.c */ void DEFAULT_CC -rfbEncryptBytes(char* bytes, char* passwd) +rfbEncryptBytes(char *bytes, char *passwd) { - char key[12]; + char key[12]; - /* key is simply password padded with nulls */ - g_memset(key, 0, sizeof(key)); - g_strncpy(key, passwd, 8); - rfbDesKey((unsigned char*)key, EN0); /* 0, encrypt */ - rfbDes((unsigned char*)bytes, (unsigned char*)bytes); - rfbDes((unsigned char*)(bytes + 8), (unsigned char*)(bytes + 8)); + /* key is simply password padded with nulls */ + g_memset(key, 0, sizeof(key)); + g_strncpy(key, passwd, 8); + rfbDesKey((unsigned char *)key, EN0); /* 0, encrypt */ + rfbDes((unsigned char *)bytes, (unsigned char *)bytes); + rfbDes((unsigned char *)(bytes + 8), (unsigned char *)(bytes + 8)); } /******************************************************************************/ /* returns error */ int DEFAULT_CC -lib_recv(struct vnc* v, char* data, int len) +lib_recv(struct vnc *v, char *data, int len) { - int rcvd; + int rcvd; - if (v->sck_closed) - { - return 1; - } - while (len > 0) - { - rcvd = g_tcp_recv(v->sck, data, len, 0); - if (rcvd == -1) + if (v->sck_closed) { - if (g_tcp_last_error_would_block(v->sck)) - { - if (v->server_is_term(v)) - { - return 1; - } - g_tcp_can_recv(v->sck, 10); - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC lib_recv return 1"); return 1; - } } - else if (rcvd == 0) + + while (len > 0) { - v->sck_closed = 1; - return 1; + rcvd = g_tcp_recv(v->sck, data, len, 0); + + if (rcvd == -1) + { + if (g_tcp_last_error_would_block(v->sck)) + { + if (v->server_is_term(v)) + { + return 1; + } + + g_tcp_can_recv(v->sck, 10); + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC lib_recv return 1"); + return 1; + } + } + else if (rcvd == 0) + { + v->sck_closed = 1; + return 1; + } + else + { + data += rcvd; + len -= rcvd; + } } - else - { - data += rcvd; - len -= rcvd; - } - } - return 0; + + return 0; } /*****************************************************************************/ /* returns error */ int DEFAULT_CC -lib_send(struct vnc* v, char* data, int len) +lib_send(struct vnc *v, char *data, int len) { - int sent; + int sent; - if (v->sck_closed) - { - return 1; - } - while (len > 0) - { - sent = g_tcp_send(v->sck, data, len, 0); - if (sent == -1) + if (v->sck_closed) { - if (g_tcp_last_error_would_block(v->sck)) - { - if (v->server_is_term(v)) - { - return 1; - } - g_tcp_can_send(v->sck, 10); - } - else - { return 1; - } } - else if (sent == 0) + + while (len > 0) { - v->sck_closed = 1; - return 1; + sent = g_tcp_send(v->sck, data, len, 0); + + if (sent == -1) + { + if (g_tcp_last_error_would_block(v->sck)) + { + if (v->server_is_term(v)) + { + return 1; + } + + g_tcp_can_send(v->sck, 10); + } + else + { + return 1; + } + } + else if (sent == 0) + { + v->sck_closed = 1; + return 1; + } + else + { + data += sent; + len -= sent; + } } - else - { - data += sent; - len -= sent; - } - } - return 0; + + return 0; } /******************************************************************************/ static int DEFAULT_CC -lib_process_channel_data(struct vnc* v, int chanid, int flags, int size, - struct stream* s, int total_size) +lib_process_channel_data(struct vnc *v, int chanid, int flags, int size, + struct stream *s, int total_size) { - int type; - int status; - int length; - int index; - int format; - struct stream* out_s; + int type; + int status; + int length; + int index; + int format; + struct stream *out_s; - if (chanid == v->clip_chanid) - { - in_uint16_le(s, type); - in_uint16_le(s, status); - in_uint32_le(s, length); - //g_writeln("clip data type %d status %d length %d", type, status, length); - //g_hexdump(s->p, s->end - s->p); - switch (type) + if (chanid == v->clip_chanid) { - case 2: /* CLIPRDR_FORMAT_ANNOUNCE */ - make_stream(out_s); - init_stream(out_s, 8192); - out_uint16_le(out_s, 3); - out_uint16_le(out_s, 1); - out_uint32_le(out_s, 0); - out_uint8s(out_s, 4); /* pad */ - s_mark_end(out_s); - length = (int)(out_s->end - out_s->data); - v->server_send_to_channel(v, v->clip_chanid, out_s->data, length, length, 3); - free_stream(out_s); - break; - case 3: /* CLIPRDR_FORMAT_ACK */ - break; - case 4: /* CLIPRDR_DATA_REQUEST */ - format = 0; - if (length >= 4) + in_uint16_le(s, type); + in_uint16_le(s, status); + in_uint32_le(s, length); + + //g_writeln("clip data type %d status %d length %d", type, status, length); + //g_hexdump(s->p, s->end - s->p); + switch (type) { - in_uint32_le(s, format); + case 2: /* CLIPRDR_FORMAT_ANNOUNCE */ + make_stream(out_s); + init_stream(out_s, 8192); + out_uint16_le(out_s, 3); + out_uint16_le(out_s, 1); + out_uint32_le(out_s, 0); + out_uint8s(out_s, 4); /* pad */ + s_mark_end(out_s); + length = (int)(out_s->end - out_s->data); + v->server_send_to_channel(v, v->clip_chanid, out_s->data, length, length, 3); + free_stream(out_s); + break; + case 3: /* CLIPRDR_FORMAT_ACK */ + break; + case 4: /* CLIPRDR_DATA_REQUEST */ + format = 0; + + if (length >= 4) + { + in_uint32_le(s, format); + } + + /* only support CF_TEXT and CF_UNICODETEXT */ + if ((format != 1) && (format != 13)) + { + break; + } + + make_stream(out_s); + init_stream(out_s, 8192); + out_uint16_le(out_s, 5); + out_uint16_le(out_s, 1); + + if (format == 13) /* CF_UNICODETEXT */ + { + out_uint32_le(out_s, v->clip_data_size * 2 + 2); + + for (index = 0; index < v->clip_data_size; index++) + { + out_uint8(out_s, v->clip_data[index]); + out_uint8(out_s, 0); + } + + out_uint8s(out_s, 2); + } + else if (format == 1) /* CF_TEXT */ + { + out_uint32_le(out_s, v->clip_data_size + 1); + + for (index = 0; index < v->clip_data_size; index++) + { + out_uint8(out_s, v->clip_data[index]); + } + + out_uint8s(out_s, 1); + } + + out_uint8s(out_s, 4); /* pad */ + s_mark_end(out_s); + length = (int)(out_s->end - out_s->data); + v->server_send_to_channel(v, v->clip_chanid, out_s->data, length, + length, 3); + free_stream(out_s); + break; + default: + { + log_message(LOG_LEVEL_DEBUG, "VNC clip information unhandled"); + break; + } } - /* only support CF_TEXT and CF_UNICODETEXT */ - if ((format != 1) && (format != 13)) - { - break; - } - make_stream(out_s); - init_stream(out_s, 8192); - out_uint16_le(out_s, 5); - out_uint16_le(out_s, 1); - if (format == 13) /* CF_UNICODETEXT */ - { - out_uint32_le(out_s, v->clip_data_size * 2 + 2); - for (index = 0; index < v->clip_data_size; index++) - { - out_uint8(out_s, v->clip_data[index]); - out_uint8(out_s, 0); - } - out_uint8s(out_s, 2); - } - else if (format == 1) /* CF_TEXT */ - { - out_uint32_le(out_s, v->clip_data_size + 1); - for (index = 0; index < v->clip_data_size; index++) - { - out_uint8(out_s, v->clip_data[index]); - } - out_uint8s(out_s, 1); - } - out_uint8s(out_s, 4); /* pad */ - s_mark_end(out_s); - length = (int)(out_s->end - out_s->data); - v->server_send_to_channel(v, v->clip_chanid, out_s->data, length, - length, 3); - free_stream(out_s); - break; - default:{ - log_message(LOG_LEVEL_DEBUG, "VNC clip information unhandled"); - break; - } } - } - else - { - log_message(LOG_LEVEL_DEBUG, "lib_process_channel_data: unknown chanid:", - "%d :(v->clip_chanid) %d",chanid,v->clip_chanid); - } - return 0; + else + { + log_message(LOG_LEVEL_DEBUG, "lib_process_channel_data: unknown chanid:", + "%d :(v->clip_chanid) %d", chanid, v->clip_chanid); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC -lib_mod_event(struct vnc* v, int msg, long param1, long param2, +lib_mod_event(struct vnc *v, int msg, long param1, long param2, long param3, long param4) { - struct stream* s; - int key; - int error; - int x; - int y; - int cx; - int cy; - int size; - int total_size; - int chanid; - int flags; - char* data; - char text[256]; + struct stream *s; + int key; + int error; + int x; + int y; + int cx; + int cy; + int size; + int total_size; + int chanid; + int flags; + char *data; + char text[256]; - error = 0; - make_stream(s); - if (msg == 0x5555) /* channel data */ - { - chanid = LOWORD(param1); - flags = HIWORD(param1); - size = (int)param2; - data = (char*)param3; - total_size = (int)param4; - if ((size >= 0) && (size <= (32 * 1024)) && (data != 0)) + error = 0; + make_stream(s); + + if (msg == 0x5555) /* channel data */ { - init_stream(s, size); - out_uint8a(s, data, size); - s_mark_end(s); - s->p = s->data; - error = lib_process_channel_data(v, chanid, flags, size, s, total_size); - } - else - { - error = 1; - } - } - else if ((msg >= 15) && (msg <= 16)) /* key events */ - { - key = param2; - if (key > 0) - { - if (key == 65027) /* altgr */ - { - if (v->shift_state) + chanid = LOWORD(param1); + flags = HIWORD(param1); + size = (int)param2; + data = (char *)param3; + total_size = (int)param4; + + if ((size >= 0) && (size <= (32 * 1024)) && (data != 0)) { - /* fix for mstsc sending left control down with altgr */ - init_stream(s, 8192); - out_uint8(s, 4); - out_uint8(s, 0); /* down flag */ - out_uint8s(s, 2); - out_uint32_be(s, 65507); /* left control */ - lib_send(v, s->data, 8); + init_stream(s, size); + out_uint8a(s, data, size); + s_mark_end(s); + s->p = s->data; + error = lib_process_channel_data(v, chanid, flags, size, s, total_size); + } + else + { + error = 1; } - } - init_stream(s, 8192); - out_uint8(s, 4); - out_uint8(s, msg == 15); /* down flag */ - out_uint8s(s, 2); - out_uint32_be(s, key); - error = lib_send(v, s->data, 8); - if (key == 65507) /* left control */ - { - v->shift_state = msg == 15; - } } - } - else if (msg >= 100 && msg <= 110) /* mouse events */ - { - switch (msg) + else if ((msg >= 15) && (msg <= 16)) /* key events */ { - case 100: break; /* WM_MOUSEMOVE */ - case 101: v->mod_mouse_state &= ~1; break; /* WM_LBUTTONUP */ - case 102: v->mod_mouse_state |= 1; break; /* WM_LBUTTONDOWN */ - case 103: v->mod_mouse_state &= ~4; break; /* WM_RBUTTONUP */ - case 104: v->mod_mouse_state |= 4; break; /* WM_RBUTTONDOWN */ - case 105: v->mod_mouse_state &= ~2; break; - case 106: v->mod_mouse_state |= 2; break; - case 107: v->mod_mouse_state &= ~8; break; - case 108: v->mod_mouse_state |= 8; break; - case 109: v->mod_mouse_state &= ~16; break; - case 110: v->mod_mouse_state |= 16; break; + key = param2; + + if (key > 0) + { + if (key == 65027) /* altgr */ + { + if (v->shift_state) + { + /* fix for mstsc sending left control down with altgr */ + init_stream(s, 8192); + out_uint8(s, 4); + out_uint8(s, 0); /* down flag */ + out_uint8s(s, 2); + out_uint32_be(s, 65507); /* left control */ + lib_send(v, s->data, 8); + } + } + + init_stream(s, 8192); + out_uint8(s, 4); + out_uint8(s, msg == 15); /* down flag */ + out_uint8s(s, 2); + out_uint32_be(s, key); + error = lib_send(v, s->data, 8); + + if (key == 65507) /* left control */ + { + v->shift_state = msg == 15; + } + } } - init_stream(s, 8192); - out_uint8(s, 5); - out_uint8(s, v->mod_mouse_state); - out_uint16_be(s, param1); - out_uint16_be(s, param2); - error = lib_send(v, s->data, 6); - } - else if (msg == 200) /* invalidate */ - { - /* FrambufferUpdateRequest */ - init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 0); - x = (param1 >> 16) & 0xffff; - out_uint16_be(s, x); - y = param1 & 0xffff; - out_uint16_be(s, y); - cx = (param2 >> 16) & 0xffff; - out_uint16_be(s, cx); - cy = param2 & 0xffff; - out_uint16_be(s, cy); - error = lib_send(v, s->data, 10); - } - free_stream(s); - return error; + else if (msg >= 100 && msg <= 110) /* mouse events */ + { + switch (msg) + { + case 100: + break; /* WM_MOUSEMOVE */ + case 101: + v->mod_mouse_state &= ~1; + break; /* WM_LBUTTONUP */ + case 102: + v->mod_mouse_state |= 1; + break; /* WM_LBUTTONDOWN */ + case 103: + v->mod_mouse_state &= ~4; + break; /* WM_RBUTTONUP */ + case 104: + v->mod_mouse_state |= 4; + break; /* WM_RBUTTONDOWN */ + case 105: + v->mod_mouse_state &= ~2; + break; + case 106: + v->mod_mouse_state |= 2; + break; + case 107: + v->mod_mouse_state &= ~8; + break; + case 108: + v->mod_mouse_state |= 8; + break; + case 109: + v->mod_mouse_state &= ~16; + break; + case 110: + v->mod_mouse_state |= 16; + break; + } + + init_stream(s, 8192); + out_uint8(s, 5); + out_uint8(s, v->mod_mouse_state); + out_uint16_be(s, param1); + out_uint16_be(s, param2); + error = lib_send(v, s->data, 6); + } + else if (msg == 200) /* invalidate */ + { + /* FrambufferUpdateRequest */ + init_stream(s, 8192); + out_uint8(s, 3); + out_uint8(s, 0); + x = (param1 >> 16) & 0xffff; + out_uint16_be(s, x); + y = param1 & 0xffff; + out_uint16_be(s, y); + cx = (param2 >> 16) & 0xffff; + out_uint16_be(s, cx); + cy = param2 & 0xffff; + out_uint16_be(s, cy); + error = lib_send(v, s->data, 10); + } + + free_stream(s); + return error; } //****************************************************************************** int DEFAULT_CC -get_pixel_safe(char* data, int x, int y, int width, int height, int bpp) +get_pixel_safe(char *data, int x, int y, int width, int height, int bpp) { - int start = 0; - int shift = 0; + int start = 0; + int shift = 0; - if (x < 0) - { - return 0; - } - if (y < 0) - { - return 0; - } - if (x >= width) - { - return 0; - } - if (y >= height) - { - return 0; - } - if (bpp == 1) - { - width = (width + 7) / 8; - start = (y * width) + x / 8; - shift = x % 8; - return (data[start] & (0x80 >> shift)) != 0; - } - else if (bpp == 4) - { - width = (width + 1) / 2; - start = y * width + x / 2; - shift = x % 2; - if (shift == 0) + if (x < 0) { - return (data[start] & 0xf0) >> 4; + return 0; + } + + if (y < 0) + { + return 0; + } + + if (x >= width) + { + return 0; + } + + if (y >= height) + { + return 0; + } + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + return (data[start] & (0x80 >> shift)) != 0; + } + else if (bpp == 4) + { + width = (width + 1) / 2; + start = y * width + x / 2; + shift = x % 2; + + if (shift == 0) + { + return (data[start] & 0xf0) >> 4; + } + else + { + return data[start] & 0x0f; + } + } + else if (bpp == 8) + { + return *(((unsigned char *)data) + (y * width + x)); + } + else if (bpp == 15 || bpp == 16) + { + return *(((unsigned short *)data) + (y * width + x)); + } + else if (bpp == 24 || bpp == 32) + { + return *(((unsigned int *)data) + (y * width + x)); } else { - return data[start] & 0x0f; + log_message(LOG_LEVEL_ERROR, "error in get_pixel_safe bpp %d", bpp); } - } - else if (bpp == 8) - { - return *(((unsigned char*)data) + (y * width + x)); - } - else if (bpp == 15 || bpp == 16) - { - return *(((unsigned short*)data) + (y * width + x)); - } - else if (bpp == 24 || bpp == 32) - { - return *(((unsigned int*)data) + (y * width + x)); - } - else - { - log_message(LOG_LEVEL_ERROR, "error in get_pixel_safe bpp %d", bpp); - } - return 0; + + return 0; } /******************************************************************************/ void DEFAULT_CC -set_pixel_safe(char* data, int x, int y, int width, int height, int bpp, +set_pixel_safe(char *data, int x, int y, int width, int height, int bpp, int pixel) { - int start = 0; - int shift = 0; + int start = 0; + int shift = 0; - if (x < 0) - { - return; - } - if (y < 0) - { - return; - } - if (x >= width) - { - return; - } - if (y >= height) - { - return; - } - if (bpp == 1) - { - width = (width + 7) / 8; - start = (y * width) + x / 8; - shift = x % 8; - if (pixel & 1) + if (x < 0) { - data[start] = data[start] | (0x80 >> shift); + return; + } + + if (y < 0) + { + return; + } + + if (x >= width) + { + return; + } + + if (y >= height) + { + return; + } + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + + if (pixel & 1) + { + data[start] = data[start] | (0x80 >> shift); + } + else + { + data[start] = data[start] & ~(0x80 >> shift); + } + } + else if (bpp == 15 || bpp == 16) + { + *(((unsigned short *)data) + (y * width + x)) = pixel; + } + else if (bpp == 24) + { + *(data + (3 * (y * width + x)) + 0) = pixel >> 0; + *(data + (3 * (y * width + x)) + 1) = pixel >> 8; + *(data + (3 * (y * width + x)) + 2) = pixel >> 16; } else { - data[start] = data[start] & ~(0x80 >> shift); + log_message(LOG_LEVEL_ERROR, "error in set_pixel_safe bpp %d", bpp); } - } - else if (bpp == 15 || bpp == 16) - { - *(((unsigned short*)data) + (y * width + x)) = pixel; - } - else if (bpp == 24) - { - *(data + (3 * (y * width + x)) + 0) = pixel >> 0; - *(data + (3 * (y * width + x)) + 1) = pixel >> 8; - *(data + (3 * (y * width + x)) + 2) = pixel >> 16; - } - else - { - log_message(LOG_LEVEL_ERROR, "error in set_pixel_safe bpp %d", bpp); - } } /******************************************************************************/ int DEFAULT_CC -split_color(int pixel, int* r, int* g, int* b, int bpp, int* palette) +split_color(int pixel, int *r, int *g, int *b, int bpp, int *palette) { - if (bpp == 8) - { - if (pixel >= 0 && pixel < 256 && palette != 0) + if (bpp == 8) { - *r = (palette[pixel] >> 16) & 0xff; - *g = (palette[pixel] >> 8) & 0xff; - *b = (palette[pixel] >> 0) & 0xff; + if (pixel >= 0 && pixel < 256 && palette != 0) + { + *r = (palette[pixel] >> 16) & 0xff; + *g = (palette[pixel] >> 8) & 0xff; + *b = (palette[pixel] >> 0) & 0xff; + } } - } - else if (bpp == 15) - { - *r = ((pixel >> 7) & 0xf8) | ((pixel >> 12) & 0x7); - *g = ((pixel >> 2) & 0xf8) | ((pixel >> 8) & 0x7); - *b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7); - } - else if (bpp == 16) - { - *r = ((pixel >> 8) & 0xf8) | ((pixel >> 13) & 0x7); - *g = ((pixel >> 3) & 0xfc) | ((pixel >> 9) & 0x3); - *b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7); - } - else if (bpp == 24 || bpp == 32) - { - *r = (pixel >> 16) & 0xff; - *g = (pixel >> 8) & 0xff; - *b = pixel & 0xff; - } - else - { - log_message(LOG_LEVEL_ERROR, "error in split_color bpp %d", bpp); - } - return 0; + else if (bpp == 15) + { + *r = ((pixel >> 7) & 0xf8) | ((pixel >> 12) & 0x7); + *g = ((pixel >> 2) & 0xf8) | ((pixel >> 8) & 0x7); + *b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7); + } + else if (bpp == 16) + { + *r = ((pixel >> 8) & 0xf8) | ((pixel >> 13) & 0x7); + *g = ((pixel >> 3) & 0xfc) | ((pixel >> 9) & 0x3); + *b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7); + } + else if (bpp == 24 || bpp == 32) + { + *r = (pixel >> 16) & 0xff; + *g = (pixel >> 8) & 0xff; + *b = pixel & 0xff; + } + else + { + log_message(LOG_LEVEL_ERROR, "error in split_color bpp %d", bpp); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC make_color(int r, int g, int b, int bpp) { - if (bpp == 24) - { - return (r << 16) | (g << 8) | b; - } - else - { - log_message(LOG_LEVEL_ERROR, "error in make_color bpp %d", bpp); - } - return 0; -} - -/******************************************************************************/ -int DEFAULT_CC -lib_framebuffer_update(struct vnc* v) -{ - char* data; - char* d1; - char* d2; - char cursor_data[32 * (32 * 3)]; - char cursor_mask[32 * (32 / 8)]; - char text[256]; - int num_recs; - int i; - int j; - int k; - int x; - int y; - int cx; - int cy; - int srcx; - int srcy; - int encoding; - int Bpp; - int pixel; - int r; - int g; - int b; - int data_size; - int need_size; - int error; - struct stream* s; - - data_size = 0; - data = 0; - num_recs = 0; - Bpp = (v->mod_bpp + 7) / 8; - if (Bpp == 3) - { - Bpp = 4; - } - make_stream(s); - init_stream(s, 8192); - error = lib_recv(v, s->data, 3); - if (error == 0) - { - in_uint8s(s, 1); - in_uint16_be(s, num_recs); - error = v->server_begin_update(v); - } - for (i = 0; i < num_recs; i++) - { - if (error != 0) + if (bpp == 24) { - break; - } - init_stream(s, 8192); - error = lib_recv(v, s->data, 12); - if (error == 0) - { - in_uint16_be(s, x); - in_uint16_be(s, y); - in_uint16_be(s, cx); - in_uint16_be(s, cy); - in_uint32_be(s, encoding); - if (encoding == 0) /* raw */ - { - need_size = cx * cy * Bpp; - if (need_size > data_size) - { - g_free(data); - data = (char*)g_malloc(need_size, 0); - data_size = need_size; - } - error = lib_recv(v, data, need_size); - if (error == 0) - { - error = v->server_paint_rect(v, x, y, cx, cy, data, cx, cy, 0, 0); - } - } - else if (encoding == 1) /* copy rect */ - { - init_stream(s, 8192); - error = lib_recv(v, s->data, 4); - if (error == 0) - { - in_uint16_be(s, srcx); - in_uint16_be(s, srcy); - error = v->server_screen_blt(v, x, y, cx, cy, srcx, srcy); - } - } - else if (encoding == 0xffffff11) /* cursor */ - { - g_memset(cursor_data, 0, 32 * (32 * 3)); - g_memset(cursor_mask, 0, 32 * (32 / 8)); - j = cx * cy * Bpp; - k = ((cx + 7) / 8) * cy; - init_stream(s, j + k); - error = lib_recv(v, s->data, j + k); - if (error == 0) - { - in_uint8p(s, d1, j); - in_uint8p(s, d2, k); - for (j = 0; j < 32; j++) - { - for (k = 0; k < 32; k++) - { - pixel = get_pixel_safe(d2, k, 31 - j, cx, cy, 1); - set_pixel_safe(cursor_mask, k, j, 32, 32, 1, !pixel); - if (pixel) - { - pixel = get_pixel_safe(d1, k, 31 - j, cx, cy, v->mod_bpp); - split_color(pixel, &r, &g, &b, v->mod_bpp, v->palette); - pixel = make_color(r, g, b, 24); - set_pixel_safe(cursor_data, k, j, 32, 32, 24, pixel); - } - } - } - /* keep these in 32x32, vnc cursor can be alot bigger */ - if (x > 31) - { - x = 31; - } - if (y > 31) - { - y = 31; - } - error = v->server_set_cursor(v, x, y, cursor_data, cursor_mask); - } - } - else if (encoding == 0xffffff21) /* desktop size */ - { - v->mod_width = cx; - v->mod_height = cy; - error = v->server_reset(v, cx, cy, v->mod_bpp); - } - else - { - g_sprintf(text, "VNC error in lib_framebuffer_update encoding = %8.8x", - encoding); - v->server_msg(v, text, 1); - } - } - } - if (error == 0) - { - error = v->server_end_update(v); - } - g_free(data); - if (error == 0) - { - /* FrambufferUpdateRequest */ - init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 1); - out_uint16_be(s, 0); - out_uint16_be(s, 0); - out_uint16_be(s, v->mod_width); - out_uint16_be(s, v->mod_height); - error = lib_send(v, s->data, 10); - } - free_stream(s); - return error; -} - -/******************************************************************************/ -int DEFAULT_CC -lib_clip_data(struct vnc* v) -{ - struct stream* s; - struct stream* out_s; - int size; - int error; - - g_free(v->clip_data); - v->clip_data = 0; - v->clip_data_size = 0; - make_stream(s); - init_stream(s, 8192); - error = lib_recv(v, s->data, 7); - if (error == 0) - { - in_uint8s(s, 3); - in_uint32_be(s, size); - v->clip_data = (char*)g_malloc(size, 0); - v->clip_data_size = size; - error = lib_recv(v, v->clip_data, size); - } - if (error == 0) - { - make_stream(out_s); - init_stream(out_s, 8192); - out_uint16_le(out_s, 2); - out_uint16_le(out_s, 0); - out_uint32_le(out_s, 0x90); - out_uint8(out_s, 0x0d); - out_uint8s(out_s, 35); - out_uint8(out_s, 0x10); - out_uint8s(out_s, 35); - out_uint8(out_s, 0x01); - out_uint8s(out_s, 35); - out_uint8(out_s, 0x07); - out_uint8s(out_s, 35); - out_uint8s(out_s, 4); - s_mark_end(out_s); - size = (int)(out_s->end - out_s->data); - error = v->server_send_to_channel(v, v->clip_chanid, out_s->data, size, size, 3); - free_stream(out_s); - } - free_stream(s); - return error; -} - -/******************************************************************************/ -int DEFAULT_CC -lib_palette_update(struct vnc* v) -{ - struct stream* s; - int first_color; - int num_colors; - int i; - int r; - int g; - int b; - int error; - - make_stream(s); - init_stream(s, 8192); - error = lib_recv(v, s->data, 5); - if (error == 0) - { - in_uint8s(s, 1); - in_uint16_be(s, first_color); - in_uint16_be(s, num_colors); - init_stream(s, 8192); - error = lib_recv(v, s->data, num_colors * 6); - } - if (error == 0) - { - for (i = 0; i < num_colors; i++) - { - in_uint16_be(s, r); - in_uint16_be(s, g); - in_uint16_be(s, b); - r = r >> 8; - g = g >> 8; - b = b >> 8; - v->palette[first_color + i] = (r << 16) | (g << 8) | b; - } - error = v->server_begin_update(v); - } - if (error == 0) - { - error = v->server_palette(v, v->palette); - } - if (error == 0) - { - error = v->server_end_update(v); - } - free_stream(s); - return error; -} - -/******************************************************************************/ -int DEFAULT_CC -lib_bell_trigger(struct vnc* v) -{ - struct stream* s; - int error; - - error = v->server_bell_trigger(v); - return error; -} - -/******************************************************************************/ -int DEFAULT_CC -lib_mod_signal(struct vnc* v) -{ - char type; - int error; - char text[256]; - - error = lib_recv(v, &type, 1); - if (error == 0) - { - if (type == 0) /* framebuffer update */ - { - error = lib_framebuffer_update(v); - } - else if (type == 1) /* palette */ - { - error = lib_palette_update(v); - } - else if (type == 2) /* bell */ - { - error = lib_bell_trigger(v); - } - else if (type == 3) /* clipboard */ - { - log_message(LOG_LEVEL_DEBUG, "VNC got clip data"); - error = lib_clip_data(v); + return (r << 16) | (g << 8) | b; } else { - g_sprintf(text, "VNC unknown in lib_mod_signal %d", type); - v->server_msg(v, text, 1); + log_message(LOG_LEVEL_ERROR, "error in make_color bpp %d", bpp); } - } - return error; + + return 0; } /******************************************************************************/ int DEFAULT_CC -lib_mod_start(struct vnc* v, int w, int h, int bpp) +lib_framebuffer_update(struct vnc *v) { - v->server_begin_update(v); - v->server_set_fgcolor(v, 0); - v->server_fill_rect(v, 0, 0, w, h); - v->server_end_update(v); - v->server_width = w; - v->server_height = h; - v->server_bpp = bpp; - return 0; + char *data; + char *d1; + char *d2; + char cursor_data[32 * (32 * 3)]; + char cursor_mask[32 * (32 / 8)]; + char text[256]; + int num_recs; + int i; + int j; + int k; + int x; + int y; + int cx; + int cy; + int srcx; + int srcy; + int encoding; + int Bpp; + int pixel; + int r; + int g; + int b; + int data_size; + int need_size; + int error; + struct stream *s; + + data_size = 0; + data = 0; + num_recs = 0; + Bpp = (v->mod_bpp + 7) / 8; + + if (Bpp == 3) + { + Bpp = 4; + } + + make_stream(s); + init_stream(s, 8192); + error = lib_recv(v, s->data, 3); + + if (error == 0) + { + in_uint8s(s, 1); + in_uint16_be(s, num_recs); + error = v->server_begin_update(v); + } + + for (i = 0; i < num_recs; i++) + { + if (error != 0) + { + break; + } + + init_stream(s, 8192); + error = lib_recv(v, s->data, 12); + + if (error == 0) + { + in_uint16_be(s, x); + in_uint16_be(s, y); + in_uint16_be(s, cx); + in_uint16_be(s, cy); + in_uint32_be(s, encoding); + + if (encoding == 0) /* raw */ + { + need_size = cx * cy * Bpp; + + if (need_size > data_size) + { + g_free(data); + data = (char *)g_malloc(need_size, 0); + data_size = need_size; + } + + error = lib_recv(v, data, need_size); + + if (error == 0) + { + error = v->server_paint_rect(v, x, y, cx, cy, data, cx, cy, 0, 0); + } + } + else if (encoding == 1) /* copy rect */ + { + init_stream(s, 8192); + error = lib_recv(v, s->data, 4); + + if (error == 0) + { + in_uint16_be(s, srcx); + in_uint16_be(s, srcy); + error = v->server_screen_blt(v, x, y, cx, cy, srcx, srcy); + } + } + else if (encoding == 0xffffff11) /* cursor */ + { + g_memset(cursor_data, 0, 32 * (32 * 3)); + g_memset(cursor_mask, 0, 32 * (32 / 8)); + j = cx * cy * Bpp; + k = ((cx + 7) / 8) * cy; + init_stream(s, j + k); + error = lib_recv(v, s->data, j + k); + + if (error == 0) + { + in_uint8p(s, d1, j); + in_uint8p(s, d2, k); + + for (j = 0; j < 32; j++) + { + for (k = 0; k < 32; k++) + { + pixel = get_pixel_safe(d2, k, 31 - j, cx, cy, 1); + set_pixel_safe(cursor_mask, k, j, 32, 32, 1, !pixel); + + if (pixel) + { + pixel = get_pixel_safe(d1, k, 31 - j, cx, cy, v->mod_bpp); + split_color(pixel, &r, &g, &b, v->mod_bpp, v->palette); + pixel = make_color(r, g, b, 24); + set_pixel_safe(cursor_data, k, j, 32, 32, 24, pixel); + } + } + } + + /* keep these in 32x32, vnc cursor can be alot bigger */ + if (x > 31) + { + x = 31; + } + + if (y > 31) + { + y = 31; + } + + error = v->server_set_cursor(v, x, y, cursor_data, cursor_mask); + } + } + else if (encoding == 0xffffff21) /* desktop size */ + { + v->mod_width = cx; + v->mod_height = cy; + error = v->server_reset(v, cx, cy, v->mod_bpp); + } + else + { + g_sprintf(text, "VNC error in lib_framebuffer_update encoding = %8.8x", + encoding); + v->server_msg(v, text, 1); + } + } + } + + if (error == 0) + { + error = v->server_end_update(v); + } + + g_free(data); + + if (error == 0) + { + /* FrambufferUpdateRequest */ + init_stream(s, 8192); + out_uint8(s, 3); + out_uint8(s, 1); + out_uint16_be(s, 0); + out_uint16_be(s, 0); + out_uint16_be(s, v->mod_width); + out_uint16_be(s, v->mod_height); + error = lib_send(v, s->data, 10); + } + + free_stream(s); + return error; +} + +/******************************************************************************/ +int DEFAULT_CC +lib_clip_data(struct vnc *v) +{ + struct stream *s; + struct stream *out_s; + int size; + int error; + + g_free(v->clip_data); + v->clip_data = 0; + v->clip_data_size = 0; + make_stream(s); + init_stream(s, 8192); + error = lib_recv(v, s->data, 7); + + if (error == 0) + { + in_uint8s(s, 3); + in_uint32_be(s, size); + v->clip_data = (char *)g_malloc(size, 0); + v->clip_data_size = size; + error = lib_recv(v, v->clip_data, size); + } + + if (error == 0) + { + make_stream(out_s); + init_stream(out_s, 8192); + out_uint16_le(out_s, 2); + out_uint16_le(out_s, 0); + out_uint32_le(out_s, 0x90); + out_uint8(out_s, 0x0d); + out_uint8s(out_s, 35); + out_uint8(out_s, 0x10); + out_uint8s(out_s, 35); + out_uint8(out_s, 0x01); + out_uint8s(out_s, 35); + out_uint8(out_s, 0x07); + out_uint8s(out_s, 35); + out_uint8s(out_s, 4); + s_mark_end(out_s); + size = (int)(out_s->end - out_s->data); + error = v->server_send_to_channel(v, v->clip_chanid, out_s->data, size, size, 3); + free_stream(out_s); + } + + free_stream(s); + return error; +} + +/******************************************************************************/ +int DEFAULT_CC +lib_palette_update(struct vnc *v) +{ + struct stream *s; + int first_color; + int num_colors; + int i; + int r; + int g; + int b; + int error; + + make_stream(s); + init_stream(s, 8192); + error = lib_recv(v, s->data, 5); + + if (error == 0) + { + in_uint8s(s, 1); + in_uint16_be(s, first_color); + in_uint16_be(s, num_colors); + init_stream(s, 8192); + error = lib_recv(v, s->data, num_colors * 6); + } + + if (error == 0) + { + for (i = 0; i < num_colors; i++) + { + in_uint16_be(s, r); + in_uint16_be(s, g); + in_uint16_be(s, b); + r = r >> 8; + g = g >> 8; + b = b >> 8; + v->palette[first_color + i] = (r << 16) | (g << 8) | b; + } + + error = v->server_begin_update(v); + } + + if (error == 0) + { + error = v->server_palette(v, v->palette); + } + + if (error == 0) + { + error = v->server_end_update(v); + } + + free_stream(s); + return error; +} + +/******************************************************************************/ +int DEFAULT_CC +lib_bell_trigger(struct vnc *v) +{ + struct stream *s; + int error; + + error = v->server_bell_trigger(v); + return error; +} + +/******************************************************************************/ +int DEFAULT_CC +lib_mod_signal(struct vnc *v) +{ + char type; + int error; + char text[256]; + + error = lib_recv(v, &type, 1); + + if (error == 0) + { + if (type == 0) /* framebuffer update */ + { + error = lib_framebuffer_update(v); + } + else if (type == 1) /* palette */ + { + error = lib_palette_update(v); + } + else if (type == 2) /* bell */ + { + error = lib_bell_trigger(v); + } + else if (type == 3) /* clipboard */ + { + log_message(LOG_LEVEL_DEBUG, "VNC got clip data"); + error = lib_clip_data(v); + } + else + { + g_sprintf(text, "VNC unknown in lib_mod_signal %d", type); + v->server_msg(v, text, 1); + } + } + + return error; +} + +/******************************************************************************/ +int DEFAULT_CC +lib_mod_start(struct vnc *v, int w, int h, int bpp) +{ + v->server_begin_update(v); + v->server_set_fgcolor(v, 0); + v->server_fill_rect(v, 0, 0, w, h); + v->server_end_update(v); + v->server_width = w; + v->server_height = h; + v->server_bpp = bpp; + return 0; } /******************************************************************************/ static int APP_CC -lib_open_clip_channel(struct vnc* v) +lib_open_clip_channel(struct vnc *v) { - char init_data[12] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + char init_data[12] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - v->clip_chanid = v->server_get_channel_id(v, "cliprdr"); - if (v->clip_chanid >= 0) - { - v->server_send_to_channel(v, v->clip_chanid, init_data, 12, 12, 3); - } - return 0; + v->clip_chanid = v->server_get_channel_id(v, "cliprdr"); + + if (v->clip_chanid >= 0) + { + v->server_send_to_channel(v, v->clip_chanid, init_data, 12, 12, 3); + } + + return 0; } /******************************************************************************/ @@ -841,440 +934,478 @@ lib_open_clip_channel(struct vnc* v) return error */ int DEFAULT_CC -lib_mod_connect(struct vnc* v) +lib_mod_connect(struct vnc *v) { - char cursor_data[32 * (32 * 3)]; - char cursor_mask[32 * (32 / 8)]; - char con_port[256]; - char text[256]; - struct stream* s; - struct stream* pixel_format; - int error; - int i; - int check_sec_result; + char cursor_data[32 * (32 * 3)]; + char cursor_mask[32 * (32 / 8)]; + char con_port[256]; + char text[256]; + struct stream *s; + struct stream *pixel_format; + int error; + int i; + int check_sec_result; - v->server_msg(v, "VNC started connecting", 0); - check_sec_result = 1; - /* only support 8 and 16 bpp connections from rdp client */ - if ((v->server_bpp != 8) && (v->server_bpp != 15) && - (v->server_bpp != 16) && (v->server_bpp != 24)) - { - v->server_msg(v, "VNC error - only supporting 8, 15, 16 and 24 bpp rdp " - "connections", 0); - return 1; - } - if (g_strcmp(v->ip, "") == 0) - { - v->server_msg(v, "VNC error - no ip set", 0); - return 1; - } - make_stream(s); - g_sprintf(con_port, "%s", v->port); - make_stream(pixel_format); - v->sck = g_tcp_socket(); - v->sck_obj = g_create_wait_obj_from_socket(v->sck, 0); - v->sck_closed = 0; - g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port); - v->server_msg(v, text, 0); - error = g_tcp_connect(v->sck, v->ip, con_port); - if (error == 0) - { - v->server_msg(v, "VNC tcp connected", 0); - g_tcp_set_non_blocking(v->sck); - g_tcp_set_no_delay(v->sck); - /* protocal version */ - init_stream(s, 8192); - error = lib_recv(v, s->data, 12); - if (error == 0) + v->server_msg(v, "VNC started connecting", 0); + check_sec_result = 1; + + /* only support 8 and 16 bpp connections from rdp client */ + if ((v->server_bpp != 8) && (v->server_bpp != 15) && + (v->server_bpp != 16) && (v->server_bpp != 24)) { - error = lib_send(v, "RFB 003.003\n", 12); + v->server_msg(v, "VNC error - only supporting 8, 15, 16 and 24 bpp rdp " + "connections", 0); + return 1; } - /* sec type */ - if (error == 0) + + if (g_strcmp(v->ip, "") == 0) { - init_stream(s, 8192); - error = lib_recv(v, s->data, 4); + v->server_msg(v, "VNC error - no ip set", 0); + return 1; } + + make_stream(s); + g_sprintf(con_port, "%s", v->port); + make_stream(pixel_format); + v->sck = g_tcp_socket(); + v->sck_obj = g_create_wait_obj_from_socket(v->sck, 0); + v->sck_closed = 0; + g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port); + v->server_msg(v, text, 0); + error = g_tcp_connect(v->sck, v->ip, con_port); + if (error == 0) { - in_uint32_be(s, i); - g_sprintf(text, "VNC security level is %d (1 = none, 2 = standard)", i); - v->server_msg(v, text, 0); - if (i == 1) /* none */ - { - check_sec_result = 0; - } - else if (i == 2) /* dec the password and the server random */ - { + v->server_msg(v, "VNC tcp connected", 0); + g_tcp_set_non_blocking(v->sck); + g_tcp_set_no_delay(v->sck); + /* protocal version */ init_stream(s, 8192); - error = lib_recv(v, s->data, 16); + error = lib_recv(v, s->data, 12); + if (error == 0) { - rfbEncryptBytes(s->data, v->password); - error = lib_send(v, s->data, 16); - check_sec_result = 1; // not needed + error = lib_send(v, "RFB 003.003\n", 12); + } + + /* sec type */ + if (error == 0) + { + init_stream(s, 8192); + error = lib_recv(v, s->data, 4); + } + + if (error == 0) + { + in_uint32_be(s, i); + g_sprintf(text, "VNC security level is %d (1 = none, 2 = standard)", i); + v->server_msg(v, text, 0); + + if (i == 1) /* none */ + { + check_sec_result = 0; + } + else if (i == 2) /* dec the password and the server random */ + { + init_stream(s, 8192); + error = lib_recv(v, s->data, 16); + + if (error == 0) + { + rfbEncryptBytes(s->data, v->password); + error = lib_send(v, s->data, 16); + check_sec_result = 1; // not needed + } + } + else if (i == 0) + { + log_message(LOG_LEVEL_DEBUG, "VNC Server will disconnect"); + error = 1; + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC unsupported security level"); + error = 1; + } } - } - else if (i == 0) - { - log_message(LOG_LEVEL_DEBUG, "VNC Server will disconnect"); - error = 1; - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC unsupported security level"); - error = 1; - } } - } - if (error!=0) - { - log_message(LOG_LEVEL_DEBUG, "VNC Error after security negotiation"); - } - if (error == 0 && check_sec_result) - { - /* sec result */ - init_stream(s, 8192); - error = lib_recv(v, s->data, 4); + + if (error != 0) + { + log_message(LOG_LEVEL_DEBUG, "VNC Error after security negotiation"); + } + + if (error == 0 && check_sec_result) + { + /* sec result */ + init_stream(s, 8192); + error = lib_recv(v, s->data, 4); + + if (error == 0) + { + in_uint32_be(s, i); + + if (i != 0) + { + v->server_msg(v, "VNC password failed", 0); + error = 2; + } + else + { + v->server_msg(v, "VNC password ok", 0); + } + } + } + if (error == 0) { - in_uint32_be(s, i); - if (i != 0) - { - v->server_msg(v, "VNC password failed", 0); - error = 2; - } - else - { - v->server_msg(v, "VNC password ok", 0); - } - } - } - if (error == 0) - { - v->server_msg(v, "VNC sending share flag", 0); - init_stream(s, 8192); - s->data[0] = 1; - error = lib_send(v, s->data, 1); /* share flag */ - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before sending share flag"); - } - if (error == 0) - { - v->server_msg(v, "VNC receiving server init", 0); - error = lib_recv(v, s->data, 4); /* server init */ - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before receiving server init"); - } - if (error == 0) - { - in_uint16_be(s, v->mod_width); - in_uint16_be(s, v->mod_height); - init_stream(pixel_format, 8192); - v->server_msg(v, "VNC receiving pixel format", 0); - error = lib_recv(v, pixel_format->data, 16); - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before receiving pixel format"); - } - if (error == 0) - { - v->mod_bpp = v->server_bpp; - init_stream(s, 8192); - v->server_msg(v, "VNC receiving name length", 0); - error = lib_recv(v, s->data, 4); /* name len */ - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name length"); - } - if (error == 0) - { - in_uint32_be(s, i); - if (i > 255 || i < 0) - { - error = 3; + v->server_msg(v, "VNC sending share flag", 0); + init_stream(s, 8192); + s->data[0] = 1; + error = lib_send(v, s->data, 1); /* share flag */ } else { - v->server_msg(v, "VNC receiving name", 0); - error = lib_recv(v, v->mod_name, i); - v->mod_name[i] = 0; + log_message(LOG_LEVEL_DEBUG, "VNC error before sending share flag"); } - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name"); - } - /* should be connected */ - if (error == 0) - { - /* SetPixelFormat */ - init_stream(s, 8192); - out_uint8(s, 0); - out_uint8(s, 0); - out_uint8(s, 0); - out_uint8(s, 0); - init_stream(pixel_format, 8192); - if (v->mod_bpp == 8) + + if (error == 0) { - out_uint8(pixel_format, 8); /* bits per pixel */ - out_uint8(pixel_format, 8); /* depth */ + v->server_msg(v, "VNC receiving server init", 0); + error = lib_recv(v, s->data, 4); /* server init */ + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC error before receiving server init"); + } + + if (error == 0) + { + in_uint16_be(s, v->mod_width); + in_uint16_be(s, v->mod_height); + init_stream(pixel_format, 8192); + v->server_msg(v, "VNC receiving pixel format", 0); + error = lib_recv(v, pixel_format->data, 16); + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC error before receiving pixel format"); + } + + if (error == 0) + { + v->mod_bpp = v->server_bpp; + init_stream(s, 8192); + v->server_msg(v, "VNC receiving name length", 0); + error = lib_recv(v, s->data, 4); /* name len */ + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name length"); + } + + if (error == 0) + { + in_uint32_be(s, i); + + if (i > 255 || i < 0) + { + error = 3; + } + else + { + v->server_msg(v, "VNC receiving name", 0); + error = lib_recv(v, v->mod_name, i); + v->mod_name[i] = 0; + } + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name"); + } + + /* should be connected */ + if (error == 0) + { + /* SetPixelFormat */ + init_stream(s, 8192); + out_uint8(s, 0); + out_uint8(s, 0); + out_uint8(s, 0); + out_uint8(s, 0); + init_stream(pixel_format, 8192); + + if (v->mod_bpp == 8) + { + out_uint8(pixel_format, 8); /* bits per pixel */ + out_uint8(pixel_format, 8); /* depth */ #if defined(B_ENDIAN) - out_uint8(pixel_format, 1); /* big endian */ + out_uint8(pixel_format, 1); /* big endian */ #else - out_uint8(pixel_format, 0); /* big endian */ + out_uint8(pixel_format, 0); /* big endian */ #endif - out_uint8(pixel_format, 0); /* true color flag */ - out_uint16_be(pixel_format, 0); /* red max */ - out_uint16_be(pixel_format, 0); /* green max */ - out_uint16_be(pixel_format, 0); /* blue max */ - out_uint8(pixel_format, 0); /* red shift */ - out_uint8(pixel_format, 0); /* green shift */ - out_uint8(pixel_format, 0); /* blue shift */ - out_uint8s(pixel_format, 3); /* pad */ - } - else if (v->mod_bpp == 15) - { - out_uint8(pixel_format, 16); /* bits per pixel */ - out_uint8(pixel_format, 15); /* depth */ + out_uint8(pixel_format, 0); /* true color flag */ + out_uint16_be(pixel_format, 0); /* red max */ + out_uint16_be(pixel_format, 0); /* green max */ + out_uint16_be(pixel_format, 0); /* blue max */ + out_uint8(pixel_format, 0); /* red shift */ + out_uint8(pixel_format, 0); /* green shift */ + out_uint8(pixel_format, 0); /* blue shift */ + out_uint8s(pixel_format, 3); /* pad */ + } + else if (v->mod_bpp == 15) + { + out_uint8(pixel_format, 16); /* bits per pixel */ + out_uint8(pixel_format, 15); /* depth */ #if defined(B_ENDIAN) - out_uint8(pixel_format, 1); /* big endian */ + out_uint8(pixel_format, 1); /* big endian */ #else - out_uint8(pixel_format, 0); /* big endian */ + out_uint8(pixel_format, 0); /* big endian */ #endif - out_uint8(pixel_format, 1); /* true color flag */ - out_uint16_be(pixel_format, 31); /* red max */ - out_uint16_be(pixel_format, 31); /* green max */ - out_uint16_be(pixel_format, 31); /* blue max */ - out_uint8(pixel_format, 10); /* red shift */ - out_uint8(pixel_format, 5); /* green shift */ - out_uint8(pixel_format, 0); /* blue shift */ - out_uint8s(pixel_format, 3); /* pad */ - } - else if (v->mod_bpp == 16) - { - out_uint8(pixel_format, 16); /* bits per pixel */ - out_uint8(pixel_format, 16); /* depth */ + out_uint8(pixel_format, 1); /* true color flag */ + out_uint16_be(pixel_format, 31); /* red max */ + out_uint16_be(pixel_format, 31); /* green max */ + out_uint16_be(pixel_format, 31); /* blue max */ + out_uint8(pixel_format, 10); /* red shift */ + out_uint8(pixel_format, 5); /* green shift */ + out_uint8(pixel_format, 0); /* blue shift */ + out_uint8s(pixel_format, 3); /* pad */ + } + else if (v->mod_bpp == 16) + { + out_uint8(pixel_format, 16); /* bits per pixel */ + out_uint8(pixel_format, 16); /* depth */ #if defined(B_ENDIAN) - out_uint8(pixel_format, 1); /* big endian */ + out_uint8(pixel_format, 1); /* big endian */ #else - out_uint8(pixel_format, 0); /* big endian */ + out_uint8(pixel_format, 0); /* big endian */ #endif - out_uint8(pixel_format, 1); /* true color flag */ - out_uint16_be(pixel_format, 31); /* red max */ - out_uint16_be(pixel_format, 63); /* green max */ - out_uint16_be(pixel_format, 31); /* blue max */ - out_uint8(pixel_format, 11); /* red shift */ - out_uint8(pixel_format, 5); /* green shift */ - out_uint8(pixel_format, 0); /* blue shift */ - out_uint8s(pixel_format, 3); /* pad */ - } - else if (v->mod_bpp == 24) - { - out_uint8(pixel_format, 32); /* bits per pixel */ - out_uint8(pixel_format, 24); /* depth */ + out_uint8(pixel_format, 1); /* true color flag */ + out_uint16_be(pixel_format, 31); /* red max */ + out_uint16_be(pixel_format, 63); /* green max */ + out_uint16_be(pixel_format, 31); /* blue max */ + out_uint8(pixel_format, 11); /* red shift */ + out_uint8(pixel_format, 5); /* green shift */ + out_uint8(pixel_format, 0); /* blue shift */ + out_uint8s(pixel_format, 3); /* pad */ + } + else if (v->mod_bpp == 24) + { + out_uint8(pixel_format, 32); /* bits per pixel */ + out_uint8(pixel_format, 24); /* depth */ #if defined(B_ENDIAN) - out_uint8(pixel_format, 1); /* big endian */ + out_uint8(pixel_format, 1); /* big endian */ #else - out_uint8(pixel_format, 0); /* big endian */ + out_uint8(pixel_format, 0); /* big endian */ #endif - out_uint8(pixel_format, 1); /* true color flag */ - out_uint16_be(pixel_format, 255); /* red max */ - out_uint16_be(pixel_format, 255); /* green max */ - out_uint16_be(pixel_format, 255); /* blue max */ - out_uint8(pixel_format, 16); /* red shift */ - out_uint8(pixel_format, 8); /* green shift */ - out_uint8(pixel_format, 0); /* blue shift */ - out_uint8s(pixel_format, 3); /* pad */ + out_uint8(pixel_format, 1); /* true color flag */ + out_uint16_be(pixel_format, 255); /* red max */ + out_uint16_be(pixel_format, 255); /* green max */ + out_uint16_be(pixel_format, 255); /* blue max */ + out_uint8(pixel_format, 16); /* red shift */ + out_uint8(pixel_format, 8); /* green shift */ + out_uint8(pixel_format, 0); /* blue shift */ + out_uint8s(pixel_format, 3); /* pad */ + } + + out_uint8a(s, pixel_format->data, 16); + v->server_msg(v, "VNC sending pixel format", 0); + error = lib_send(v, s->data, 20); } - out_uint8a(s, pixel_format->data, 16); - v->server_msg(v, "VNC sending pixel format", 0); - error = lib_send(v, s->data, 20); - } - if (error == 0) - { - /* SetEncodings */ - init_stream(s, 8192); - out_uint8(s, 2); - out_uint8(s, 0); - out_uint16_be(s, 4); - out_uint32_be(s, 0); /* raw */ - out_uint32_be(s, 1); /* copy rect */ - out_uint32_be(s, 0xffffff11); /* cursor */ - out_uint32_be(s, 0xffffff21); /* desktop size */ - v->server_msg(v, "VNC sending encodings", 0); - error = lib_send(v, s->data, 4 + 4 * 4); - } - if (error == 0) - { - error = v->server_reset(v, v->mod_width, v->mod_height, v->mod_bpp); - } - if (error == 0) - { - /* FrambufferUpdateRequest */ - init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, 0); - out_uint16_be(s, 0); - out_uint16_be(s, v->mod_width); - out_uint16_be(s, v->mod_height); - v->server_msg(v, "VNC sending framebuffer update request", 0); - error = lib_send(v, s->data, 10); - } - if (error == 0) - { - if (v->server_bpp != v->mod_bpp) + + if (error == 0) { - v->server_msg(v, "VNC error - server bpp and client bpp do not match", 0); - error = 1; + /* SetEncodings */ + init_stream(s, 8192); + out_uint8(s, 2); + out_uint8(s, 0); + out_uint16_be(s, 4); + out_uint32_be(s, 0); /* raw */ + out_uint32_be(s, 1); /* copy rect */ + out_uint32_be(s, 0xffffff11); /* cursor */ + out_uint32_be(s, 0xffffff21); /* desktop size */ + v->server_msg(v, "VNC sending encodings", 0); + error = lib_send(v, s->data, 4 + 4 * 4); } - } - if (error == 0) - { - /* set almost null cursor, this is the little dot cursor */ - g_memset(cursor_data, 0, 32 * (32 * 3)); - g_memset(cursor_data + (32 * (32 * 3) - 1 * 32 * 3), 0xff, 9); - g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9); - g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9); - g_memset(cursor_mask, 0xff, 32 * (32 / 8)); - v->server_msg(v, "VNC sending cursor", 0); - error = v->server_set_cursor(v, 3, 3, cursor_data, cursor_mask); - } - free_stream(s); - free_stream(pixel_format); - if (error == 0) - { - v->server_msg(v, "VNC connection complete, connected ok", 0); - lib_open_clip_channel(v); - } - else - { - v->server_msg(v, "VNC error - problem connecting", 0); - } - return error; + + if (error == 0) + { + error = v->server_reset(v, v->mod_width, v->mod_height, v->mod_bpp); + } + + if (error == 0) + { + /* FrambufferUpdateRequest */ + init_stream(s, 8192); + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, 0); + out_uint16_be(s, 0); + out_uint16_be(s, v->mod_width); + out_uint16_be(s, v->mod_height); + v->server_msg(v, "VNC sending framebuffer update request", 0); + error = lib_send(v, s->data, 10); + } + + if (error == 0) + { + if (v->server_bpp != v->mod_bpp) + { + v->server_msg(v, "VNC error - server bpp and client bpp do not match", 0); + error = 1; + } + } + + if (error == 0) + { + /* set almost null cursor, this is the little dot cursor */ + g_memset(cursor_data, 0, 32 * (32 * 3)); + g_memset(cursor_data + (32 * (32 * 3) - 1 * 32 * 3), 0xff, 9); + g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9); + g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9); + g_memset(cursor_mask, 0xff, 32 * (32 / 8)); + v->server_msg(v, "VNC sending cursor", 0); + error = v->server_set_cursor(v, 3, 3, cursor_data, cursor_mask); + } + + free_stream(s); + free_stream(pixel_format); + + if (error == 0) + { + v->server_msg(v, "VNC connection complete, connected ok", 0); + lib_open_clip_channel(v); + } + else + { + v->server_msg(v, "VNC error - problem connecting", 0); + } + + return error; } /******************************************************************************/ int DEFAULT_CC -lib_mod_end(struct vnc* v) +lib_mod_end(struct vnc *v) { - if (v->vnc_desktop != 0) - { - } - g_free(v->clip_data); - v->clip_data = 0; - v->clip_data_size = 0; - return 0; + if (v->vnc_desktop != 0) + { + } + + g_free(v->clip_data); + v->clip_data = 0; + v->clip_data_size = 0; + return 0; } /******************************************************************************/ int DEFAULT_CC -lib_mod_set_param(struct vnc* v, char* name, char* value) +lib_mod_set_param(struct vnc *v, char *name, char *value) { - if (g_strcasecmp(name, "username") == 0) - { - g_strncpy(v->username, value, 255); - } - else if (g_strcasecmp(name, "password") == 0) - { - g_strncpy(v->password, value, 255); - } - else if (g_strcasecmp(name, "ip") == 0) - { - g_strncpy(v->ip, value, 255); - } - else if (g_strcasecmp(name, "port") == 0) - { - g_strncpy(v->port, value, 255); - } - else if (g_strcasecmp(name, "keylayout") == 0) - { - v->keylayout = g_atoi(value); - } - return 0; + if (g_strcasecmp(name, "username") == 0) + { + g_strncpy(v->username, value, 255); + } + else if (g_strcasecmp(name, "password") == 0) + { + g_strncpy(v->password, value, 255); + } + else if (g_strcasecmp(name, "ip") == 0) + { + g_strncpy(v->ip, value, 255); + } + else if (g_strcasecmp(name, "port") == 0) + { + g_strncpy(v->port, value, 255); + } + else if (g_strcasecmp(name, "keylayout") == 0) + { + v->keylayout = g_atoi(value); + } + + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_get_wait_objs(struct vnc* v, tbus* read_objs, int* rcount, - tbus* write_objs, int* wcount, int* timeout) +lib_mod_get_wait_objs(struct vnc *v, tbus *read_objs, int *rcount, + tbus *write_objs, int *wcount, int *timeout) { - int i; + int i; - i = *rcount; - if (v != 0) - { - if (v->sck_obj != 0) + i = *rcount; + + if (v != 0) { - read_objs[i++] = v->sck_obj; + if (v->sck_obj != 0) + { + read_objs[i++] = v->sck_obj; + } } - } - *rcount = i; - return 0; + + *rcount = i; + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_check_wait_objs(struct vnc* v) +lib_mod_check_wait_objs(struct vnc *v) { - int rv; + int rv; - rv = 0; - if (v != 0) - { - if (v->sck_obj != 0) + rv = 0; + + if (v != 0) { - if (g_is_wait_obj_set(v->sck_obj)) - { - rv = lib_mod_signal(v); - } + if (v->sck_obj != 0) + { + if (g_is_wait_obj_set(v->sck_obj)) + { + rv = lib_mod_signal(v); + } + } } - } - return rv; + + return rv; } /******************************************************************************/ -struct vnc* EXPORT_CC +struct vnc *EXPORT_CC mod_init(void) { - struct vnc* v; + struct vnc *v; - v = (struct vnc*)g_malloc(sizeof(struct vnc), 1); - /* set client functions */ - v->size = sizeof(struct vnc); - v->version = CURRENT_MOD_VER; - v->handle = (long)v; - v->mod_connect = lib_mod_connect; - v->mod_start = lib_mod_start; - v->mod_event = lib_mod_event; - v->mod_signal = lib_mod_signal; - v->mod_end = lib_mod_end; - v->mod_set_param = lib_mod_set_param; - v->mod_get_wait_objs = lib_mod_get_wait_objs; - v->mod_check_wait_objs = lib_mod_check_wait_objs; - return v; + v = (struct vnc *)g_malloc(sizeof(struct vnc), 1); + /* set client functions */ + v->size = sizeof(struct vnc); + v->version = CURRENT_MOD_VER; + v->handle = (long)v; + v->mod_connect = lib_mod_connect; + v->mod_start = lib_mod_start; + v->mod_event = lib_mod_event; + v->mod_signal = lib_mod_signal; + v->mod_end = lib_mod_end; + v->mod_set_param = lib_mod_set_param; + v->mod_get_wait_objs = lib_mod_get_wait_objs; + v->mod_check_wait_objs = lib_mod_check_wait_objs; + return v; } /******************************************************************************/ int EXPORT_CC -mod_exit(struct vnc* v) +mod_exit(struct vnc *v) { - log_message(LOG_LEVEL_DEBUG, "VNC mod_exit"); - if (v == 0) - { + log_message(LOG_LEVEL_DEBUG, "VNC mod_exit"); + + if (v == 0) + { + return 0; + } + + g_delete_wait_obj_from_socket(v->sck_obj); + g_tcp_close(v->sck); + g_free(v); return 0; - } - g_delete_wait_obj_from_socket(v->sck_obj); - g_tcp_close(v->sck); - g_free(v); - return 0; } diff --git a/vnc/vnc.h b/vnc/vnc.h index b9886be4..94d29a30 100644 --- a/vnc/vnc.h +++ b/vnc/vnc.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - libvnc - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * libvnc + */ /* include other h files */ #include "arch.h" diff --git a/xorg/X11R7.6/buildx.sh b/xorg/X11R7.6/buildx.sh index 279f72cb..5a593f1a 100755 --- a/xorg/X11R7.6/buildx.sh +++ b/xorg/X11R7.6/buildx.sh @@ -1,6 +1,7 @@ #!/bin/sh -# build.sh: a script for building X11R7.6 X server for use with xrdp # +# buildx.sh: a script for building X11R7.6 X server for use with xrdp +# # Copyright 2011-2012 Jay Sorg Jay.Sorg@gmail.com # # Authors @@ -26,7 +27,7 @@ download_file() { file=$1 - # if we already have the file, don't re-download it + # if we already have the file, don't download it if [ -r downloads/$file ]; then return 0 fi @@ -277,10 +278,10 @@ count=0 if [ $# -lt 1 ]; then echo "" - echo "usage: build.sh " - echo "usage: build.sh " - echo "usage: build.sh default" - echo "usage: build.sh drop - set env and run bash in rdp dir" + echo "usage: buildx.sh " + echo "usage: buildx.sh " + echo "usage: buildx.sh default" + echo "usage: buildx.sh drop - set env and run bash in rdp dir" echo "" exit 1 fi diff --git a/xorg/X11R7.6/rdp/rdpCopyArea.c b/xorg/X11R7.6/rdp/rdpCopyArea.c index 4b35d9fb..cc4d0fe4 100644 --- a/xorg/X11R7.6/rdp/rdpCopyArea.c +++ b/xorg/X11R7.6/rdp/rdpCopyArea.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -49,14 +49,14 @@ static RegionPtr rdpCopyAreaOrg(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { - rdpGCPtr priv; - GCFuncs* oldFuncs; - RegionPtr rv; + rdpGCPtr priv; + GCFuncs *oldFuncs; + RegionPtr rv; - GC_OP_PROLOGUE(pGC); - rv = pGC->ops->CopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); - GC_OP_EPILOGUE(pGC); - return rv; + GC_OP_PROLOGUE(pGC); + rv = pGC->ops->CopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); + GC_OP_EPILOGUE(pGC); + return rv; } /******************************************************************************/ @@ -65,262 +65,282 @@ rdpCopyAreaWndToWnd(WindowPtr pSrcWnd, WindowPtr pDstWnd, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { - int cd; - int lsrcx; - int lsrcy; - int ldstx; - int ldsty; - int num_clips; - int dx; - int dy; - int j; - BoxRec box; - RegionPtr rv; - RegionRec clip_reg; + int cd; + int lsrcx; + int lsrcy; + int ldstx; + int ldsty; + int num_clips; + int dx; + int dy; + int j; + BoxRec box; + RegionPtr rv; + RegionRec clip_reg; - LLOGLN(10, ("rdpCopyAreaWndToWnd:")); + LLOGLN(10, ("rdpCopyAreaWndToWnd:")); - rv = rdpCopyAreaOrg(&(pSrcWnd->drawable), &(pDstWnd->drawable), - pGC, srcx, srcy, w, h, dstx, dsty); - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, &(pDstWnd->drawable), pGC); - lsrcx = pSrcWnd->drawable.x + srcx; - lsrcy = pSrcWnd->drawable.y + srcy; - ldstx = pDstWnd->drawable.x + dstx; - ldsty = pDstWnd->drawable.y + dsty; - if (cd == 1) - { - rdpup_begin_update(); - rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); - rdpup_end_update(); - } - else if (cd == 2) - { - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) + rv = rdpCopyAreaOrg(&(pSrcWnd->drawable), &(pDstWnd->drawable), + pGC, srcx, srcy, w, h, dstx, dsty); + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, &(pDstWnd->drawable), pGC); + lsrcx = pSrcWnd->drawable.x + srcx; + lsrcy = pSrcWnd->drawable.y + srcy; + ldstx = pDstWnd->drawable.x + dstx; + ldsty = pDstWnd->drawable.y + dsty; + + if (cd == 1) { - rdpup_begin_update(); - dx = dstx - srcx; - dy = dsty - srcy; - if ((dy < 0) || ((dy == 0) && (dx < 0))) - { - for (j = 0; j < num_clips; j++) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); - } - } - else - { - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); - } - } - rdpup_reset_clip(); - rdpup_end_update(); + rdpup_begin_update(); + rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); + rdpup_end_update(); } - } - RegionUninit(&clip_reg); - return rv; + else if (cd == 2) + { + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips > 0) + { + rdpup_begin_update(); + dx = dstx - srcx; + dy = dsty - srcy; + + if ((dy < 0) || ((dy == 0) && (dx < 0))) + { + for (j = 0; j < num_clips; j++) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); + } + } + else + { + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); + } + } + + rdpup_reset_clip(); + rdpup_end_update(); + } + } + + RegionUninit(&clip_reg); + return rv; } /******************************************************************************/ static RegionPtr rdpCopyAreaWndToPixmap(WindowPtr pSrcWnd, - PixmapPtr pDstPixmap, rdpPixmapRec* pDstPriv, + PixmapPtr pDstPixmap, rdpPixmapRec *pDstPriv, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { - int cd; - int lsrcx; - int lsrcy; - int ldstx; - int ldsty; - int num_clips; - int dx; - int dy; - int j; - BoxRec box; - RegionPtr rv; - RegionRec clip_reg; + int cd; + int lsrcx; + int lsrcy; + int ldstx; + int ldsty; + int num_clips; + int dx; + int dy; + int j; + BoxRec box; + RegionPtr rv; + RegionRec clip_reg; - LLOGLN(10, ("rdpCopyAreaWndToPixmap:")); + LLOGLN(10, ("rdpCopyAreaWndToPixmap:")); - rv = rdpCopyAreaOrg(&(pSrcWnd->drawable), &(pDstPixmap->drawable), - pGC, srcx, srcy, w, h, dstx, dsty); - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, &(pDstPixmap->drawable), pGC); - lsrcx = pSrcWnd->drawable.x + srcx; - lsrcy = pSrcWnd->drawable.y + srcy; - ldstx = pDstPixmap->drawable.x + dstx; - ldsty = pDstPixmap->drawable.y + dsty; - if (cd == 1) - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_begin_update(); - rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); - rdpup_end_update(); - rdpup_switch_os_surface(-1); - } - else if (cd == 2) - { - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) + rv = rdpCopyAreaOrg(&(pSrcWnd->drawable), &(pDstPixmap->drawable), + pGC, srcx, srcy, w, h, dstx, dsty); + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, &(pDstPixmap->drawable), pGC); + lsrcx = pSrcWnd->drawable.x + srcx; + lsrcy = pSrcWnd->drawable.y + srcy; + ldstx = pDstPixmap->drawable.x + dstx; + ldsty = pDstPixmap->drawable.y + dsty; + + if (cd == 1) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_begin_update(); - dx = dstx - srcx; - dy = dsty - srcy; - if ((dy < 0) || ((dy == 0) && (dx < 0))) - { - for (j = 0; j < num_clips; j++) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); - } - } - else - { - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); - } - } - rdpup_reset_clip(); - rdpup_end_update(); - rdpup_switch_os_surface(-1); + rdpup_switch_os_surface(pDstPriv->rdpindex); + rdpup_begin_update(); + rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); + rdpup_end_update(); + rdpup_switch_os_surface(-1); } - } - RegionUninit(&clip_reg); - return rv; + else if (cd == 2) + { + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips > 0) + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + rdpup_begin_update(); + dx = dstx - srcx; + dy = dsty - srcy; + + if ((dy < 0) || ((dy == 0) && (dx < 0))) + { + for (j = 0; j < num_clips; j++) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); + } + } + else + { + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy); + } + } + + rdpup_reset_clip(); + rdpup_end_update(); + rdpup_switch_os_surface(-1); + } + } + + RegionUninit(&clip_reg); + return rv; } /******************************************************************************/ /* draw from an off screen pixmap to a visible window */ static RegionPtr -rdpCopyAreaPixmapToWnd(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv, +rdpCopyAreaPixmapToWnd(PixmapPtr pSrcPixmap, rdpPixmapRec *pSrcPriv, WindowPtr pDstWnd, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { - int lsrcx; - int lsrcy; - int ldstx; - int ldsty; - int cd; - int j; - int num_clips; - RegionPtr rv; - RegionRec clip_reg; - BoxRec box; + int lsrcx; + int lsrcy; + int ldstx; + int ldsty; + int cd; + int j; + int num_clips; + RegionPtr rv; + RegionRec clip_reg; + BoxRec box; - LLOGLN(10, ("rdpCopyAreaPixmapToWnd:")); + LLOGLN(10, ("rdpCopyAreaPixmapToWnd:")); - rv = rdpCopyAreaOrg(&(pSrcPixmap->drawable), &(pDstWnd->drawable), - pGC, srcx, srcy, w, h, dstx, dsty); - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, &(pDstWnd->drawable), pGC); - ldstx = pDstWnd->drawable.x + dstx; - ldsty = pDstWnd->drawable.y + dsty; - lsrcx = pSrcPixmap->drawable.x + srcx; - lsrcy = pSrcPixmap->drawable.y + srcy; - if (cd == 1) - { - rdpup_begin_update(); - rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy); - rdpup_end_update(); - } - else if (cd == 2) - { - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) + rv = rdpCopyAreaOrg(&(pSrcPixmap->drawable), &(pDstWnd->drawable), + pGC, srcx, srcy, w, h, dstx, dsty); + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, &(pDstWnd->drawable), pGC); + ldstx = pDstWnd->drawable.x + dstx; + ldsty = pDstWnd->drawable.y + dsty; + lsrcx = pSrcPixmap->drawable.x + srcx; + lsrcy = pSrcPixmap->drawable.y + srcy; + + if (cd == 1) { - rdpup_begin_update(); - LLOGLN(10, ("rdpCopyAreaPixmapToWnd: num_clips %d", num_clips)); - for (j = 0; j < num_clips; j++) - { - box = REGION_RECTS(&clip_reg)[j]; - LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d", w, h)); + rdpup_begin_update(); rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy); - } - rdpup_reset_clip(); - rdpup_end_update(); + rdpup_end_update(); } - } - RegionUninit(&clip_reg); - return rv; + else if (cd == 2) + { + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips > 0) + { + rdpup_begin_update(); + LLOGLN(10, ("rdpCopyAreaPixmapToWnd: num_clips %d", num_clips)); + + for (j = 0; j < num_clips; j++) + { + box = REGION_RECTS(&clip_reg)[j]; + LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d", w, h)); + rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy); + } + + rdpup_reset_clip(); + rdpup_end_update(); + } + } + + RegionUninit(&clip_reg); + return rv; } /******************************************************************************/ /* draw from an off screen pixmap to an off screen pixmap */ static RegionPtr -rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv, - PixmapPtr pDstPixmap, rdpPixmapRec* pDstPriv, +rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec *pSrcPriv, + PixmapPtr pDstPixmap, rdpPixmapRec *pDstPriv, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { - int lsrcx; - int lsrcy; - int ldstx; - int ldsty; - int cd; - int j; - int num_clips; - RegionPtr rv; - RegionRec clip_reg; - BoxRec box; + int lsrcx; + int lsrcy; + int ldstx; + int ldsty; + int cd; + int j; + int num_clips; + RegionPtr rv; + RegionRec clip_reg; + BoxRec box; - LLOGLN(10, ("rdpCopyAreaPixmapToPixmap:")); + LLOGLN(10, ("rdpCopyAreaPixmapToPixmap:")); - rv = rdpCopyAreaOrg(&(pSrcPixmap->drawable), &(pDstPixmap->drawable), - pGC, srcx, srcy, w, h, dstx, dsty); - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, &(pDstPixmap->drawable), pGC); - LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: cd %d", cd)); - ldstx = pDstPixmap->drawable.x + dstx; - ldsty = pDstPixmap->drawable.y + dsty; - lsrcx = pSrcPixmap->drawable.x + srcx; - lsrcy = pSrcPixmap->drawable.y + srcy; - if (cd == 1) - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_begin_update(); - rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy); - LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy)); - rdpup_end_update(); - rdpup_switch_os_surface(-1); - } - else if (cd == 2) - { - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) + rv = rdpCopyAreaOrg(&(pSrcPixmap->drawable), &(pDstPixmap->drawable), + pGC, srcx, srcy, w, h, dstx, dsty); + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, &(pDstPixmap->drawable), pGC); + LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: cd %d", cd)); + ldstx = pDstPixmap->drawable.x + dstx; + ldsty = pDstPixmap->drawable.y + dsty; + lsrcx = pSrcPixmap->drawable.x + srcx; + lsrcy = pSrcPixmap->drawable.y + srcy; + + if (cd == 1) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_begin_update(); - LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: num_clips %d", num_clips)); - for (j = 0; j < num_clips; j++) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_switch_os_surface(pDstPriv->rdpindex); + rdpup_begin_update(); rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy); LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy)); - } - rdpup_reset_clip(); - rdpup_end_update(); - rdpup_switch_os_surface(-1); + rdpup_end_update(); + rdpup_switch_os_surface(-1); } - } - RegionUninit(&clip_reg); - return rv; + else if (cd == 2) + { + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips > 0) + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + rdpup_begin_update(); + LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: num_clips %d", num_clips)); + + for (j = 0; j < num_clips; j++) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy); + LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy)); + } + + rdpup_reset_clip(); + rdpup_end_update(); + rdpup_switch_os_surface(-1); + } + } + + RegionUninit(&clip_reg); + return rv; } /******************************************************************************/ @@ -328,222 +348,243 @@ RegionPtr rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { - RegionPtr rv; - RegionRec clip_reg; - RegionRec box_reg; - RegionRec reg1; - int num_clips; - int cd; - int j; - int can_do_screen_blt; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - struct image_data id; - BoxRec box; - BoxPtr pbox; - PixmapPtr pSrcPixmap; - PixmapPtr pDstPixmap; - rdpPixmapRec* pSrcPriv; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; - WindowPtr pDstWnd; - WindowPtr pSrcWnd; + RegionPtr rv; + RegionRec clip_reg; + RegionRec box_reg; + RegionRec reg1; + int num_clips; + int cd; + int j; + int can_do_screen_blt; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + struct image_data id; + BoxRec box; + BoxPtr pbox; + PixmapPtr pSrcPixmap; + PixmapPtr pDstPixmap; + rdpPixmapRec *pSrcPriv; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; + WindowPtr pDstWnd; + WindowPtr pSrcWnd; - LLOGLN(10, ("rdpCopyArea:")); + LLOGLN(10, ("rdpCopyArea:")); - if (pSrc->type == DRAWABLE_WINDOW) - { - pSrcWnd = (WindowPtr)pSrc; - if (pSrcWnd->viewable) + if (pSrc->type == DRAWABLE_WINDOW) { - if (pDst->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDst; - if (pDstWnd->viewable) + pSrcWnd = (WindowPtr)pSrc; + + if (pSrcWnd->viewable) { - can_do_screen_blt = pGC->alu == GXcopy; - if (can_do_screen_blt) - { - return rdpCopyAreaWndToWnd(pSrcWnd, pDstWnd, pGC, - srcx, srcy, w, h, dstx, dsty); - } + if (pDst->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDst; + + if (pDstWnd->viewable) + { + can_do_screen_blt = pGC->alu == GXcopy; + + if (can_do_screen_blt) + { + return rdpCopyAreaWndToWnd(pSrcWnd, pDstWnd, pGC, + srcx, srcy, w, h, dstx, dsty); + } + } + } + else if (pDst->type == DRAWABLE_PIXMAP) + { + pDstPixmap = (PixmapPtr)pDst; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + can_do_screen_blt = pGC->alu == GXcopy; + + if (can_do_screen_blt) + { + rdpup_check_dirty(pDstPixmap, pDstPriv); + return rdpCopyAreaWndToPixmap(pSrcWnd, pDstPixmap, pDstPriv, pGC, + srcx, srcy, w, h, dstx, dsty); + } + } + } } - } - else if (pDst->type == DRAWABLE_PIXMAP) - { + } + + if (pSrc->type == DRAWABLE_PIXMAP) + { + pSrcPixmap = (PixmapPtr)pSrc; + pSrcPriv = GETPIXPRIV(pSrcPixmap); + + if (XRDP_IS_OS(pSrcPriv)) + { + if (pDst->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDst; + + if (pDstWnd->viewable) + { + rdpup_check_dirty(pSrcPixmap, pSrcPriv); + return rdpCopyAreaPixmapToWnd(pSrcPixmap, pSrcPriv, pDstWnd, pGC, + srcx, srcy, w, h, dstx, dsty); + } + } + else if (pDst->type == DRAWABLE_PIXMAP) + { + pDstPixmap = (PixmapPtr)pDst; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + if (g_can_do_pix_to_pix) + { + rdpup_check_dirty(pSrcPixmap, pSrcPriv); + rdpup_check_dirty(pDstPixmap, pDstPriv); + return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv, + pDstPixmap, pDstPriv, + pGC, srcx, srcy, w, h, + dstx, dsty); + } + } + } + } + } + + /* do original call */ + rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDst->type == DRAWABLE_PIXMAP) + { pDstPixmap = (PixmapPtr)pDst; pDstPriv = GETPIXPRIV(pDstPixmap); + if (XRDP_IS_OS(pDstPriv)) { - can_do_screen_blt = pGC->alu == GXcopy; - if (can_do_screen_blt) - { - rdpup_check_dirty(pDstPixmap, pDstPriv); - return rdpCopyAreaWndToPixmap(pSrcWnd, pDstPixmap, pDstPriv, pGC, - srcx, srcy, w, h, dstx, dsty); - } + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpCopyArea: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - } } - } - if (pSrc->type == DRAWABLE_PIXMAP) - { - pSrcPixmap = (PixmapPtr)pSrc; - pSrcPriv = GETPIXPRIV(pSrcPixmap); - if (XRDP_IS_OS(pSrcPriv)) + else { - if (pDst->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDst; - if (pDstWnd->viewable) + if (pDst->type == DRAWABLE_WINDOW) { - rdpup_check_dirty(pSrcPixmap, pSrcPriv); - return rdpCopyAreaPixmapToWnd(pSrcPixmap, pSrcPriv, pDstWnd, pGC, - srcx, srcy, w, h, dstx, dsty); + pDstWnd = (WindowPtr)pDst; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } } - } - else if (pDst->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDst; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + } + + if (!post_process) + { + return rv; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDst, pGC); + + if (cd == 1) + { + if (dirty_type != 0) { - if (g_can_do_pix_to_pix) - { - rdpup_check_dirty(pSrcPixmap, pSrcPriv); - rdpup_check_dirty(pDstPixmap, pDstPriv); - return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv, - pDstPixmap, pDstPriv, - pGC, srcx, srcy, w, h, - dstx, dsty); - } + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h); + rdpup_end_update(); } - } } - } - - /* do original call */ - rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); - - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDst->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDst; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + else if (cd == 2) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpCopyArea: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } - } - } - else - { - if (pDst->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDst; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return rv; - } - - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDst, pGC); - if (cd == 1) - { - if (dirty_type != 0) - { - box.x1 = pDst->x + dstx; - box.y1 = pDst->y + dsty; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h); - rdpup_end_update(); - } - } - else if (cd == 2) - { - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) - { - if (dirty_type != 0) - { - box.x1 = pDst->x + dstx; - box.y1 = pDst->y + dsty; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(&box_reg, &box, 0); - RegionIntersect(&clip_reg, &clip_reg, &box_reg); - draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); - RegionUninit(&box_reg); - } - else if (got_id) - { - rdpup_begin_update(); - box.x1 = pDst->x + dstx; - box.y1 = pDst->y + dsty; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(&box_reg, &box, 0); - RegionIntersect(&clip_reg, &clip_reg, &box_reg); num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips < 10) + + if (num_clips > 0) { - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); - } + if (dirty_type != 0) + { + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(&box_reg, &box, 0); + RegionIntersect(&clip_reg, &clip_reg, &box_reg); + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); + RegionUninit(&box_reg); + } + else if (got_id) + { + rdpup_begin_update(); + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(&box_reg, &box, 0); + RegionIntersect(&clip_reg, &clip_reg, &box_reg); + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips < 10) + { + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + } + else + { + pbox = RegionExtents(&clip_reg); + rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + } + + RegionUninit(&box_reg); + rdpup_end_update(); + } } - else - { - pbox = RegionExtents(&clip_reg); - rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - } - RegionUninit(&box_reg); - rdpup_end_update(); - } } - } - RegionUninit(&clip_reg); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } - return rv; + + RegionUninit(&clip_reg); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } + + return rv; } diff --git a/xorg/X11R7.6/rdp/rdpCopyPlane.c b/xorg/X11R7.6/rdp/rdpCopyPlane.c index 389dc6e1..aa0e2c29 100644 --- a/xorg/X11R7.6/rdp/rdpCopyPlane.c +++ b/xorg/X11R7.6/rdp/rdpCopyPlane.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -49,15 +49,15 @@ rdpCopyPlaneOrg(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane) { - RegionPtr rv; - rdpGCPtr priv; - GCFuncs* oldFuncs; + RegionPtr rv; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - rv = pGC->ops->CopyPlane(pSrc, pDst, pGC, srcx, srcy, - w, h, dstx, dsty, bitPlane); - GC_OP_EPILOGUE(pGC); - return rv; + GC_OP_PROLOGUE(pGC); + rv = pGC->ops->CopyPlane(pSrc, pDst, pGC, srcx, srcy, + w, h, dstx, dsty, bitPlane); + GC_OP_EPILOGUE(pGC); + return rv; } /******************************************************************************/ @@ -66,151 +66,163 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane) { - RegionPtr rv; - RegionRec clip_reg; - RegionRec box_reg; - RegionRec reg1; - RegionRec reg2; - int cd; - int num_clips; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - BoxPtr pbox; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionPtr rv; + RegionRec clip_reg; + RegionRec box_reg; + RegionRec reg1; + RegionRec reg2; + int cd; + int num_clips; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + BoxPtr pbox; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpCopyPlane:")); + LLOGLN(10, ("rdpCopyPlane:")); - /* do original call */ - rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, bitPlane); + /* do original call */ + rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h, + dstx, dsty, bitPlane); - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDst->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDst; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpCopyPlane: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } - } - } - else - { - if (pDst->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDst; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return rv; - } + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDst, pGC); - if (cd == 1) - { - if (dirty_type != 0) + if (pDst->type == DRAWABLE_PIXMAP) { - box.x1 = pDst->x + dstx; - box.y1 = pDst->y + dsty; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); + pDstPixmap = (PixmapPtr)pDst; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpCopyPlane: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } + } } - else if (got_id) + else { - rdpup_begin_update(); - rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h); - rdpup_end_update(); + if (pDst->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDst; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } } - } - else if (cd == 2) - { - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) + + if (!post_process) + { + return rv; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDst, pGC); + + if (cd == 1) + { + if (dirty_type != 0) + { + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h); + rdpup_end_update(); + } + } + else if (cd == 2) { - if (dirty_type != 0) - { - box.x1 = pDst->x + dstx; - box.y1 = pDst->y + dsty; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(®1, &box, 0); - RegionInit(®2, NullBox, 0); - RegionCopy(®2, &clip_reg); - RegionIntersect(®1, ®1, ®2); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - RegionUninit(®2); - } - else if (got_id) - { - rdpup_begin_update(); - box.x1 = pDst->x + dstx; - box.y1 = pDst->y + dsty; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(&box_reg, &box, 0); - RegionIntersect(&clip_reg, &clip_reg, &box_reg); num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips < 10) + + if (num_clips > 0) { - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } + if (dirty_type != 0) + { + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + RegionInit(®2, NullBox, 0); + RegionCopy(®2, &clip_reg); + RegionIntersect(®1, ®1, ®2); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + RegionUninit(®2); + } + else if (got_id) + { + rdpup_begin_update(); + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(&box_reg, &box, 0); + RegionIntersect(&clip_reg, &clip_reg, &box_reg); + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips < 10) + { + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + } + else + { + pbox = RegionExtents(&clip_reg); + rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + } + + RegionUninit(&box_reg); + rdpup_end_update(); + } } - else - { - pbox = RegionExtents(&clip_reg); - rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - } - RegionUninit(&box_reg); - rdpup_end_update(); - } } - } - RegionUninit(&clip_reg); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } - return rv; + + RegionUninit(&clip_reg); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } + + return rv; } diff --git a/xorg/X11R7.6/rdp/rdpFillPolygon.c b/xorg/X11R7.6/rdp/rdpFillPolygon.c index bf71c094..d1ea89ea 100644 --- a/xorg/X11R7.6/rdp/rdpFillPolygon.c +++ b/xorg/X11R7.6/rdp/rdpFillPolygon.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -49,12 +49,12 @@ rdpFillPolygonOrg(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode, int count, DDXPointPtr pPts) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->FillPolygon(pDrawable, pGC, shape, mode, count, pPts); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->FillPolygon(pDrawable, pGC, shape, mode, count, pPts); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ @@ -63,158 +63,176 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode, int count, DDXPointPtr pPts) { - RegionRec clip_reg; - RegionRec box_reg; - RegionRec reg1; - int num_clips; - int cd; - int maxx; - int maxy; - int minx; - int miny; - int i; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec clip_reg; + RegionRec box_reg; + RegionRec reg1; + int num_clips; + int cd; + int maxx; + int maxy; + int minx; + int miny; + int i; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpFillPolygon:")); + LLOGLN(10, ("rdpFillPolygon:")); - box.x1 = 0; - box.y1 = 0; - box.x2 = 0; - box.y2 = 0; - if (count > 0) - { - maxx = pPts[0].x; - maxy = pPts[0].y; - minx = maxx; - miny = maxy; - for (i = 1; i < count; i++) - { - if (pPts[i].x > maxx) - { - maxx = pPts[i].x; - } - if (pPts[i].x < minx) - { - minx = pPts[i].x; - } - if (pPts[i].y > maxy) - { - maxy = pPts[i].y; - } - if (pPts[i].y < miny) - { - miny = pPts[i].y; - } - } - box.x1 = pDrawable->x + minx; - box.y1 = pDrawable->y + miny; - box.x2 = pDrawable->x + maxx + 1; - box.y2 = pDrawable->y + maxy + 1; - } + box.x1 = 0; + box.y1 = 0; + box.x2 = 0; + box.y2 = 0; - /* do original call */ - rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts); + if (count > 0) + { + maxx = pPts[0].x; + maxy = pPts[0].y; + minx = maxx; + miny = maxy; - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpFillPolygon: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } - } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return; - } - - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - if (cd == 1) - { - if (dirty_type != 0) - { - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); - } - } - else if (cd == 2) - { - RegionInit(&box_reg, &box, 0); - RegionIntersect(&clip_reg, &clip_reg, &box_reg); - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + for (i = 1; i < count; i++) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + if (pPts[i].x > maxx) + { + maxx = pPts[i].x; + } + + if (pPts[i].x < minx) + { + minx = pPts[i].x; + } + + if (pPts[i].y > maxy) + { + maxy = pPts[i].y; + } + + if (pPts[i].y < miny) + { + miny = pPts[i].y; + } } - rdpup_end_update(); - } + + box.x1 = pDrawable->x + minx; + box.y1 = pDrawable->y + miny; + box.x2 = pDrawable->x + maxx + 1; + box.y2 = pDrawable->y + maxy + 1; + } + + /* do original call */ + rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) + { + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpFillPolygon: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } + } + } + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + return; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + + if (cd == 1) + { + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } + } + else if (cd == 2) + { + RegionInit(&box_reg, &box, 0); + RegionIntersect(&clip_reg, &clip_reg, &box_reg); + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionUninit(&box_reg); + } + + RegionUninit(&clip_reg); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); } - RegionUninit(&box_reg); - } - RegionUninit(&clip_reg); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } } diff --git a/xorg/X11R7.6/rdp/rdpFillSpans.c b/xorg/X11R7.6/rdp/rdpFillSpans.c index 5c3dcc67..b647dabc 100644 --- a/xorg/X11R7.6/rdp/rdpFillSpans.c +++ b/xorg/X11R7.6/rdp/rdpFillSpans.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -45,70 +45,77 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ static void rdpFillSpansOrg(DrawablePtr pDrawable, GCPtr pGC, int nInit, - DDXPointPtr pptInit, int* pwidthInit, int fSorted) + DDXPointPtr pptInit, int *pwidthInit, int fSorted) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->FillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->FillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void rdpFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit, - DDXPointPtr pptInit, int* pwidthInit, int fSorted) + DDXPointPtr pptInit, int *pwidthInit, int fSorted) { - RegionRec clip_reg; - int cd; - int got_id; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; + RegionRec clip_reg; + int cd; + int got_id; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; - LLOGLN(10, ("rdpFillSpans: todo")); + LLOGLN(10, ("rdpFillSpans: todo")); - /* do original call */ - rdpFillSpansOrg(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); + /* do original call */ + rdpFillSpansOrg(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) + else { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - rdpup_get_screen_image_rect(&id); - got_id = 1; - } + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } } - } - if (!got_id) - { - return; - } - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - if (cd == 1) - { - } - else if (cd == 2) - { - } - RegionUninit(&clip_reg); - rdpup_switch_os_surface(-1); + + if (!got_id) + { + return; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + + if (cd == 1) + { + } + else if (cd == 2) + { + } + + RegionUninit(&clip_reg); + rdpup_switch_os_surface(-1); } diff --git a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c index 25d23a51..8de4af22 100644 --- a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c +++ b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -47,146 +47,160 @@ extern int g_con_number; /* in rdpup.c */ void rdpImageGlyphBltOrg(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, - CharInfoPtr* ppci, pointer pglyphBase) + CharInfoPtr *ppci, pointer pglyphBase) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, - CharInfoPtr* ppci, pointer pglyphBase) + CharInfoPtr *ppci, pointer pglyphBase) { - RegionRec reg; - RegionRec reg1; - int num_clips; - int cd; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec reg; + RegionRec reg1; + int num_clips; + int cd; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpImageGlyphBlt:")); + LLOGLN(10, ("rdpImageGlyphBlt:")); - if (nglyph != 0) - { - GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); - } - - /* do original call */ - rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + if (nglyph != 0) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpImageGlyphBlt: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return; - } - RegionInit(®, NullBox, 0); - if (nglyph == 0) - { - cd = 0; - } - else - { - cd = rdp_get_clip(®, pDrawable, pGC); - } - if (cd == 1) - { - if (dirty_type != 0) + /* do original call */ + rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); - } - } - else if (cd == 2) - { - RegionInit(®1, &box, 0); - RegionIntersect(®, ®, ®1); - num_clips = REGION_NUM_RECTS(®); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpImageGlyphBlt: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - rdpup_end_update(); - } } - RegionUninit(®1); - } - RegionUninit(®); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } - return; + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + return; + } + + RegionInit(®, NullBox, 0); + + if (nglyph == 0) + { + cd = 0; + } + else + { + cd = rdp_get_clip(®, pDrawable, pGC); + } + + if (cd == 1) + { + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } + } + else if (cd == 2) + { + RegionInit(®1, &box, 0); + RegionIntersect(®, ®, ®1); + num_clips = REGION_NUM_RECTS(®); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionUninit(®1); + } + + RegionUninit(®); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } + + return; } diff --git a/xorg/X11R7.6/rdp/rdpImageText16.c b/xorg/X11R7.6/rdp/rdpImageText16.c index 103344c6..0ba18564 100644 --- a/xorg/X11R7.6/rdp/rdpImageText16.c +++ b/xorg/X11R7.6/rdp/rdpImageText16.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -46,146 +46,160 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ void rdpImageText16Org(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, unsigned short* chars) + int x, int y, int count, unsigned short *chars) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->ImageText16(pDrawable, pGC, x, y, count, chars); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->ImageText16(pDrawable, pGC, x, y, count, chars); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, unsigned short* chars) + int x, int y, int count, unsigned short *chars) { - RegionRec reg; - RegionRec reg1; - int num_clips; - int cd; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec reg; + RegionRec reg1; + int num_clips; + int cd; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpImageText16:")); + LLOGLN(10, ("rdpImageText16:")); - if (count != 0) - { - GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); - } - - /* do original call */ - rdpImageText16Org(pDrawable, pGC, x, y, count, chars); - - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + if (count != 0) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpImageText16: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return; - } - RegionInit(®, NullBox, 0); - if (count == 0) - { - cd = 0; - } - else - { - cd = rdp_get_clip(®, pDrawable, pGC); - } - if (cd == 1) - { - if (dirty_type != 0) + /* do original call */ + rdpImageText16Org(pDrawable, pGC, x, y, count, chars); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); - } - } - else if (cd == 2) - { - RegionInit(®1, &box, 0); - RegionIntersect(®, ®, ®1); - num_clips = REGION_NUM_RECTS(®); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpImageText16: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - rdpup_end_update(); - } } - RegionUninit(®1); - } - RegionUninit(®); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } - return; + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + return; + } + + RegionInit(®, NullBox, 0); + + if (count == 0) + { + cd = 0; + } + else + { + cd = rdp_get_clip(®, pDrawable, pGC); + } + + if (cd == 1) + { + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } + } + else if (cd == 2) + { + RegionInit(®1, &box, 0); + RegionIntersect(®, ®, ®1); + num_clips = REGION_NUM_RECTS(®); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionUninit(®1); + } + + RegionUninit(®); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } + + return; } diff --git a/xorg/X11R7.6/rdp/rdpImageText8.c b/xorg/X11R7.6/rdp/rdpImageText8.c index ba958a21..3d27731a 100644 --- a/xorg/X11R7.6/rdp/rdpImageText8.c +++ b/xorg/X11R7.6/rdp/rdpImageText8.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -46,146 +46,160 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ void rdpImageText8Org(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, char* chars) + int x, int y, int count, char *chars) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->ImageText8(pDrawable, pGC, x, y, count, chars); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->ImageText8(pDrawable, pGC, x, y, count, chars); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, char* chars) + int x, int y, int count, char *chars) { - RegionRec reg; - RegionRec reg1; - int num_clips; - int cd; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec reg; + RegionRec reg1; + int num_clips; + int cd; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpImageText8:")); + LLOGLN(10, ("rdpImageText8:")); - if (count != 0) - { - GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); - } - - /* do original call */ - rdpImageText8Org(pDrawable, pGC, x, y, count, chars); - - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + if (count != 0) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpImageText8: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return; - } - RegionInit(®, NullBox, 0); - if (count == 0) - { - cd = 0; - } - else - { - cd = rdp_get_clip(®, pDrawable, pGC); - } - if (cd == 1) - { - if (dirty_type != 0) + /* do original call */ + rdpImageText8Org(pDrawable, pGC, x, y, count, chars); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); - } - } - else if (cd == 2) - { - RegionInit(®1, &box, 0); - RegionIntersect(®, ®, ®1); - num_clips = REGION_NUM_RECTS(®); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpImageText8: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - rdpup_end_update(); - } } - RegionUninit(®1); - } - RegionUninit(®); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } - return; + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + return; + } + + RegionInit(®, NullBox, 0); + + if (count == 0) + { + cd = 0; + } + else + { + cd = rdp_get_clip(®, pDrawable, pGC); + } + + if (cd == 1) + { + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } + } + else if (cd == 2) + { + RegionInit(®1, &box, 0); + RegionIntersect(®, ®, ®1); + num_clips = REGION_NUM_RECTS(®); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionUninit(®1); + } + + RegionUninit(®); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } + + return; } diff --git a/xorg/X11R7.6/rdp/rdpPolyArc.c b/xorg/X11R7.6/rdp/rdpPolyArc.c index ba890f0c..4b5212a6 100644 --- a/xorg/X11R7.6/rdp/rdpPolyArc.c +++ b/xorg/X11R7.6/rdp/rdpPolyArc.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -45,171 +45,191 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ void -rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) +rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->PolyArc(pDrawable, pGC, narcs, parcs); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->PolyArc(pDrawable, pGC, narcs, parcs); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void -rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) +rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { - RegionRec clip_reg; - RegionPtr tmpRegion; - int cd; - int lw; - int extra; - int i; - int num_clips; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - xRectangle* rects; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec clip_reg; + RegionPtr tmpRegion; + int cd; + int lw; + int extra; + int i; + int num_clips; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + xRectangle *rects; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolyArc:")); + LLOGLN(10, ("rdpPolyArc:")); - rects = 0; - if (narcs > 0) - { - rects = (xRectangle*)g_malloc(narcs * sizeof(xRectangle), 0); - lw = pGC->lineWidth; - if (lw == 0) - { - lw = 1; - } - extra = lw / 2; - for (i = 0; i < narcs; i++) - { - rects[i].x = (parcs[i].x - extra) + pDrawable->x; - rects[i].y = (parcs[i].y - extra) + pDrawable->y; - rects[i].width = parcs[i].width + lw; - rects[i].height = parcs[i].height + lw; - } - } + rects = 0; - /* do original call */ - rdpPolyArcOrg(pDrawable, pGC, narcs, parcs); + if (narcs > 0) + { + rects = (xRectangle *)g_malloc(narcs * sizeof(xRectangle), 0); + lw = pGC->lineWidth; - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPolyArc: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + if (lw == 0) + { + lw = 1; + } + + extra = lw / 2; + + for (i = 0; i < narcs; i++) + { + rects[i].x = (parcs[i].x - extra) + pDrawable->x; + rects[i].y = (parcs[i].y - extra) + pDrawable->y; + rects[i].width = parcs[i].width + lw; + rects[i].height = parcs[i].height + lw; + } } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) + + /* do original call */ + rdpPolyArcOrg(pDrawable, pGC, narcs, parcs); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyArc: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } + } } - } - if (!post_process) - { + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + g_free(rects); + return; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + + if (cd == 1) + { + if (rects != 0) + { + tmpRegion = RegionFromRects(narcs, rects, CT_NONE); + num_clips = REGION_NUM_RECTS(tmpRegion); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (i = num_clips - 1; i >= 0; i--) + { + box = REGION_RECTS(tmpRegion)[i]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionDestroy(tmpRegion); + } + } + else if (cd == 2) + { + if (rects != 0) + { + tmpRegion = RegionFromRects(narcs, rects, CT_NONE); + RegionIntersect(tmpRegion, tmpRegion, &clip_reg); + num_clips = REGION_NUM_RECTS(tmpRegion); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (i = num_clips - 1; i >= 0; i--) + { + box = REGION_RECTS(tmpRegion)[i]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionDestroy(tmpRegion); + } + } + + RegionUninit(&clip_reg); g_free(rects); - return; - } - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - if (cd == 1) - { - if (rects != 0) + if (reset_surface) { - tmpRegion = RegionFromRects(narcs, rects, CT_NONE); - num_clips = REGION_NUM_RECTS(tmpRegion); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (i = num_clips - 1; i >= 0; i--) - { - box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); - } - rdpup_end_update(); - } - } - RegionDestroy(tmpRegion); + rdpup_switch_os_surface(-1); } - } - else if (cd == 2) - { - if (rects != 0) - { - tmpRegion = RegionFromRects(narcs, rects, CT_NONE); - RegionIntersect(tmpRegion, tmpRegion, &clip_reg); - num_clips = REGION_NUM_RECTS(tmpRegion); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (i = num_clips - 1; i >= 0; i--) - { - box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); - } - rdpup_end_update(); - } - } - RegionDestroy(tmpRegion); - } - } - RegionUninit(&clip_reg); - g_free(rects); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } } diff --git a/xorg/X11R7.6/rdp/rdpPolyFillArc.c b/xorg/X11R7.6/rdp/rdpPolyFillArc.c index cb8f2801..5fd568ad 100644 --- a/xorg/X11R7.6/rdp/rdpPolyFillArc.c +++ b/xorg/X11R7.6/rdp/rdpPolyFillArc.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -45,171 +45,191 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ void -rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) +rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->PolyFillArc(pDrawable, pGC, narcs, parcs); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->PolyFillArc(pDrawable, pGC, narcs, parcs); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void -rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) +rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { - RegionRec clip_reg; - RegionPtr tmpRegion; - int cd; - int lw; - int extra; - int i; - int num_clips; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - xRectangle* rects; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec clip_reg; + RegionPtr tmpRegion; + int cd; + int lw; + int extra; + int i; + int num_clips; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + xRectangle *rects; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolyFillArc:")); + LLOGLN(10, ("rdpPolyFillArc:")); - rects = 0; - if (narcs > 0) - { - rects = (xRectangle*)g_malloc(narcs * sizeof(xRectangle), 0); - lw = pGC->lineWidth; - if (lw == 0) - { - lw = 1; - } - extra = lw / 2; - for (i = 0; i < narcs; i++) - { - rects[i].x = (parcs[i].x - extra) + pDrawable->x; - rects[i].y = (parcs[i].y - extra) + pDrawable->y; - rects[i].width = parcs[i].width + lw; - rects[i].height = parcs[i].height + lw; - } - } + rects = 0; - /* do original call */ - rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs); + if (narcs > 0) + { + rects = (xRectangle *)g_malloc(narcs * sizeof(xRectangle), 0); + lw = pGC->lineWidth; - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPolyFillArc: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + if (lw == 0) + { + lw = 1; + } + + extra = lw / 2; + + for (i = 0; i < narcs; i++) + { + rects[i].x = (parcs[i].x - extra) + pDrawable->x; + rects[i].y = (parcs[i].y - extra) + pDrawable->y; + rects[i].width = parcs[i].width + lw; + rects[i].height = parcs[i].height + lw; + } } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) + + /* do original call */ + rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyFillArc: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } + } } - } - if (!post_process) - { + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + g_free(rects); + return; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + + if (cd == 1) + { + if (rects != 0) + { + tmpRegion = RegionFromRects(narcs, rects, CT_NONE); + num_clips = REGION_NUM_RECTS(tmpRegion); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (i = num_clips - 1; i >= 0; i--) + { + box = REGION_RECTS(tmpRegion)[i]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionDestroy(tmpRegion); + } + } + else if (cd == 2) + { + if (rects != 0) + { + tmpRegion = RegionFromRects(narcs, rects, CT_NONE); + RegionIntersect(tmpRegion, tmpRegion, &clip_reg); + num_clips = REGION_NUM_RECTS(tmpRegion); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (i = num_clips - 1; i >= 0; i--) + { + box = REGION_RECTS(tmpRegion)[i]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionDestroy(tmpRegion); + } + } + + RegionUninit(&clip_reg); g_free(rects); - return; - } - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - if (cd == 1) - { - if (rects != 0) + if (reset_surface) { - tmpRegion = RegionFromRects(narcs, rects, CT_NONE); - num_clips = REGION_NUM_RECTS(tmpRegion); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (i = num_clips - 1; i >= 0; i--) - { - box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); - } - rdpup_end_update(); - } - } - RegionDestroy(tmpRegion); + rdpup_switch_os_surface(-1); } - } - else if (cd == 2) - { - if (rects != 0) - { - tmpRegion = RegionFromRects(narcs, rects, CT_NONE); - RegionIntersect(tmpRegion, tmpRegion, &clip_reg); - num_clips = REGION_NUM_RECTS(tmpRegion); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (i = num_clips - 1; i >= 0; i--) - { - box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); - } - rdpup_end_update(); - } - } - RegionDestroy(tmpRegion); - } - } - RegionUninit(&clip_reg); - g_free(rects); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } } diff --git a/xorg/X11R7.6/rdp/rdpPolyFillRect.c b/xorg/X11R7.6/rdp/rdpPolyFillRect.c index 5dda6b7e..7a860623 100644 --- a/xorg/X11R7.6/rdp/rdpPolyFillRect.c +++ b/xorg/X11R7.6/rdp/rdpPolyFillRect.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -46,210 +46,228 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ static void rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, - xRectangle* prectInit) + xRectangle *prectInit) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->PolyFillRect(pDrawable, pGC, nrectFill, prectInit); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->PolyFillRect(pDrawable, pGC, nrectFill, prectInit); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, - xRectangle* prectInit) + xRectangle *prectInit) { - int j; - int cd; - int num_clips; - RegionRec clip_reg; - RegionPtr fill_reg; - BoxRec box; + int j; + int cd; + int num_clips; + RegionRec clip_reg; + RegionPtr fill_reg; + BoxRec box; - int got_id; - int dirty_type; - int post_process; - int reset_surface; + int got_id; + int dirty_type; + int post_process; + int reset_surface; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolyFillRect:")); + LLOGLN(10, ("rdpPolyFillRect:")); - /* make a copy of rects */ - fill_reg = RegionFromRects(nrectFill, prectInit, CT_NONE); + /* make a copy of rects */ + fill_reg = RegionFromRects(nrectFill, prectInit, CT_NONE); - /* do original call */ - rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit); + /* do original call */ + rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit); - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - post_process = 1; - if (g_do_dirty_os) - { - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_FILL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + post_process = 1; + + if (g_do_dirty_os) + { + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_FILL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } + } } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) + else { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } } - } - if (!post_process) - { + + if (!post_process) + { + RegionDestroy(fill_reg); + return; + } + + RegionTranslate(fill_reg, pDrawable->x, pDrawable->y); + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + + if (cd == 1) /* no clip */ + { + if (dirty_type != 0) + { + if (pGC->fillStyle == 0 && /* solid fill */ + (pGC->alu == GXclear || + pGC->alu == GXset || + pGC->alu == GXinvert || + pGC->alu == GXnoop || + pGC->alu == GXand || + pGC->alu == GXcopy /*|| + pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ + { + draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel, + pGC->alu); + } + else + { + draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, RDI_IMGLL); + } + } + else if (got_id) + { + rdpup_begin_update(); + + if (pGC->fillStyle == 0 && /* solid fill */ + (pGC->alu == GXclear || + pGC->alu == GXset || + pGC->alu == GXinvert || + pGC->alu == GXnoop || + pGC->alu == GXand || + pGC->alu == GXcopy /*|| + pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ + { + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + + for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--) + { + box = REGION_RECTS(fill_reg)[j]; + rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_set_opcode(GXcopy); + } + else /* non solid fill */ + { + for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--) + { + box = REGION_RECTS(fill_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + } + + rdpup_end_update(); + } + } + else if (cd == 2) /* clip */ + { + RegionIntersect(&clip_reg, &clip_reg, fill_reg); + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + if (pGC->fillStyle == 0 && /* solid fill */ + (pGC->alu == GXclear || + pGC->alu == GXset || + pGC->alu == GXinvert || + pGC->alu == GXnoop || + pGC->alu == GXand || + pGC->alu == GXcopy /*|| + pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ + { + draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu); + } + else + { + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, RDI_IMGLL); + } + } + else if (got_id) + { + rdpup_begin_update(); + + if (pGC->fillStyle == 0 && /* solid fill */ + (pGC->alu == GXclear || + pGC->alu == GXset || + pGC->alu == GXinvert || + pGC->alu == GXnoop || + pGC->alu == GXand || + pGC->alu == GXcopy /*|| + pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ + { + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_set_opcode(GXcopy); + } + else /* non solid fill */ + { + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + } + + rdpup_end_update(); + } + } + } + + RegionUninit(&clip_reg); RegionDestroy(fill_reg); - return; - } - RegionTranslate(fill_reg, pDrawable->x, pDrawable->y); - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - if (cd == 1) /* no clip */ - { - if (dirty_type != 0) + + if (reset_surface) { - if (pGC->fillStyle == 0 && /* solid fill */ - (pGC->alu == GXclear || - pGC->alu == GXset || - pGC->alu == GXinvert || - pGC->alu == GXnoop || - pGC->alu == GXand || - pGC->alu == GXcopy /*|| - pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ - { - draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel, - pGC->alu); - } - else - { - draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, RDI_IMGLL); - } + rdpup_switch_os_surface(-1); } - else if (got_id) - { - rdpup_begin_update(); - if (pGC->fillStyle == 0 && /* solid fill */ - (pGC->alu == GXclear || - pGC->alu == GXset || - pGC->alu == GXinvert || - pGC->alu == GXnoop || - pGC->alu == GXand || - pGC->alu == GXcopy /*|| - pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ - { - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--) - { - box = REGION_RECTS(fill_reg)[j]; - rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } - rdpup_set_opcode(GXcopy); - } - else /* non solid fill */ - { - for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--) - { - box = REGION_RECTS(fill_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); - } - } - rdpup_end_update(); - } - } - else if (cd == 2) /* clip */ - { - RegionIntersect(&clip_reg, &clip_reg, fill_reg); - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) - { - if (dirty_type != 0) - { - if (pGC->fillStyle == 0 && /* solid fill */ - (pGC->alu == GXclear || - pGC->alu == GXset || - pGC->alu == GXinvert || - pGC->alu == GXnoop || - pGC->alu == GXand || - pGC->alu == GXcopy /*|| - pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ - { - draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel, - pGC->alu); - } - else - { - draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, RDI_IMGLL); - } - } - else if (got_id) - { - rdpup_begin_update(); - if (pGC->fillStyle == 0 && /* solid fill */ - (pGC->alu == GXclear || - pGC->alu == GXset || - pGC->alu == GXinvert || - pGC->alu == GXnoop || - pGC->alu == GXand || - pGC->alu == GXcopy /*|| - pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ - { - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } - rdpup_set_opcode(GXcopy); - } - else /* non solid fill */ - { - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } - } - rdpup_end_update(); - } - } - } - RegionUninit(&clip_reg); - RegionDestroy(fill_reg); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } } diff --git a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c index 89ae85b4..62fc6e8e 100644 --- a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c +++ b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -47,147 +47,161 @@ extern int g_con_number; /* in rdpup.c */ void rdpPolyGlyphBltOrg(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, - CharInfoPtr* ppci, pointer pglyphBase) + CharInfoPtr *ppci, pointer pglyphBase) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, - CharInfoPtr* ppci, pointer pglyphBase) + CharInfoPtr *ppci, pointer pglyphBase) { - RegionRec reg; - RegionRec reg1; - int num_clips; - int cd; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec reg; + RegionRec reg1; + int num_clips; + int cd; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolyGlyphBlt:")); + LLOGLN(10, ("rdpPolyGlyphBlt:")); - if (nglyph != 0) - { - GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); - } - - /* do original call */ - rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + if (nglyph != 0) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPolyGlyphBlt: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return; - } - RegionInit(®, NullBox, 0); - if (nglyph == 0) - { - cd = 0; - } - else - { - cd = rdp_get_clip(®, pDrawable, pGC); - } - if (cd == 1) - { - if (dirty_type != 0) + /* do original call */ + rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); - } - } - else if (cd == 2) - { - RegionInit(®1, &box, 0); - RegionIntersect(®, ®, ®1); - num_clips = REGION_NUM_RECTS(®); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyGlyphBlt: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - rdpup_end_update(); - } } - RegionUninit(®1); - } - RegionUninit(®); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } - return; + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + return; + } + + RegionInit(®, NullBox, 0); + + if (nglyph == 0) + { + cd = 0; + } + else + { + cd = rdp_get_clip(®, pDrawable, pGC); + } + + if (cd == 1) + { + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } + } + else if (cd == 2) + { + RegionInit(®1, &box, 0); + RegionIntersect(®, ®, ®1); + num_clips = REGION_NUM_RECTS(®); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionUninit(®1); + } + + RegionUninit(®); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } + + return; } diff --git a/xorg/X11R7.6/rdp/rdpPolyPoint.c b/xorg/X11R7.6/rdp/rdpPolyPoint.c index cbbc4a98..ff112782 100644 --- a/xorg/X11R7.6/rdp/rdpPolyPoint.c +++ b/xorg/X11R7.6/rdp/rdpPolyPoint.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -48,12 +48,12 @@ void rdpPolyPointOrg(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr in_pts) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->PolyPoint(pDrawable, pGC, mode, npt, in_pts); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->PolyPoint(pDrawable, pGC, mode, npt, in_pts); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ @@ -61,209 +61,234 @@ void rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr in_pts) { - RegionRec clip_reg; - RegionRec reg1; - RegionRec reg2; - int num_clips; - int cd; - int x; - int y; - int i; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - BoxRec total_box; - DDXPointPtr pts; - DDXPointRec stack_pts[32]; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec clip_reg; + RegionRec reg1; + RegionRec reg2; + int num_clips; + int cd; + int x; + int y; + int i; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + BoxRec total_box; + DDXPointPtr pts; + DDXPointRec stack_pts[32]; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolyPoint:")); - LLOGLN(10, ("rdpPolyPoint: npt %d", npt)); + LLOGLN(10, ("rdpPolyPoint:")); + LLOGLN(10, ("rdpPolyPoint: npt %d", npt)); - if (npt > 32) - { - pts = (DDXPointPtr)g_malloc(sizeof(DDXPointRec) * npt, 0); - } - else - { - pts = stack_pts; - } - for (i = 0; i < npt; i++) - { - pts[i].x = pDrawable->x + in_pts[i].x; - pts[i].y = pDrawable->y + in_pts[i].y; - if (i == 0) + if (npt > 32) { - total_box.x1 = pts[0].x; - total_box.y1 = pts[0].y; - total_box.x2 = pts[0].x; - total_box.y2 = pts[0].y; + pts = (DDXPointPtr)g_malloc(sizeof(DDXPointRec) * npt, 0); } else { - if (pts[i].x < total_box.x1) - { - total_box.x1 = pts[i].x; - } - if (pts[i].y < total_box.y1) - { - total_box.y1 = pts[i].y; - } - if (pts[i].x > total_box.x2) - { - total_box.x2 = pts[i].x; - } - if (pts[i].y > total_box.y2) - { - total_box.y2 = pts[i].y; - } + pts = stack_pts; } - /* todo, use this total_box */ - } - /* do original call */ - rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts); + for (i = 0; i < npt; i++) + { + pts[i].x = pDrawable->x + in_pts[i].x; + pts[i].y = pDrawable->y + in_pts[i].y; - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPolyPoint: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } - } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return; - } + if (i == 0) + { + total_box.x1 = pts[0].x; + total_box.y1 = pts[0].y; + total_box.x2 = pts[0].x; + total_box.y2 = pts[0].y; + } + else + { + if (pts[i].x < total_box.x1) + { + total_box.x1 = pts[i].x; + } - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - if (cd == 1) - { - if (npt > 0) - { - if (dirty_type != 0) - { - RegionInit(®1, NullBox, 0); - for (i = 0; i < npt; i++) - { - box.x1 = pts[i].x; - box.y1 = pts[i].y; - box.x2 = box.x1 + 1; - box.y2 = box.y1 + 1; - RegionInit(®2, &box, 0); - RegionUnion(®1, ®1, ®2); - RegionUninit(®2); + if (pts[i].y < total_box.y1) + { + total_box.y1 = pts[i].y; + } + + if (pts[i].x > total_box.x2) + { + total_box.x2 = pts[i].x; + } + + if (pts[i].y > total_box.y2) + { + total_box.y2 = pts[i].y; + } } - draw_item_add_fill_region(pDirtyPriv, ®1, pGC->fgPixel, - pGC->alu); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - for (i = 0; i < npt; i++) - { - x = pts[i].x; - y = pts[i].y; - rdpup_fill_rect(x, y, 1, 1); - } - rdpup_end_update(); - } + + /* todo, use this total_box */ } - } - else if (cd == 2) - { - num_clips = REGION_NUM_RECTS(&clip_reg); - if (npt > 0 && num_clips > 0) + + /* do original call */ + rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - if (dirty_type != 0) - { - RegionInit(®1, NullBox, 0); - for (i = 0; i < npt; i++) + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - box.x1 = pts[i].x; - box.y1 = pts[i].y; - box.x2 = box.x1 + 1; - box.y2 = box.y1 + 1; - RegionInit(®2, &box, 0); - RegionUnion(®1, ®1, ®2); - RegionUninit(®2); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyPoint: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - RegionIntersect(®1, ®1, &clip_reg); - draw_item_add_fill_region(pDirtyPriv, ®1, pGC->fgPixel, - pGC->alu); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - for (i = 0; i < npt; i++) - { - x = pts[i].x; - y = pts[i].y; - rdpup_fill_rect(x, y, 1, 1); - } - } - rdpup_reset_clip(); - rdpup_end_update(); - } } - } - RegionUninit(&clip_reg); - if (pts != stack_pts) - { - g_free(pts); - } - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + return; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + + if (cd == 1) + { + if (npt > 0) + { + if (dirty_type != 0) + { + RegionInit(®1, NullBox, 0); + + for (i = 0; i < npt; i++) + { + box.x1 = pts[i].x; + box.y1 = pts[i].y; + box.x2 = box.x1 + 1; + box.y2 = box.y1 + 1; + RegionInit(®2, &box, 0); + RegionUnion(®1, ®1, ®2); + RegionUninit(®2); + } + + draw_item_add_fill_region(pDirtyPriv, ®1, pGC->fgPixel, + pGC->alu); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + + for (i = 0; i < npt; i++) + { + x = pts[i].x; + y = pts[i].y; + rdpup_fill_rect(x, y, 1, 1); + } + + rdpup_end_update(); + } + } + } + else if (cd == 2) + { + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (npt > 0 && num_clips > 0) + { + if (dirty_type != 0) + { + RegionInit(®1, NullBox, 0); + + for (i = 0; i < npt; i++) + { + box.x1 = pts[i].x; + box.y1 = pts[i].y; + box.x2 = box.x1 + 1; + box.y2 = box.y1 + 1; + RegionInit(®2, &box, 0); + RegionUnion(®1, ®1, ®2); + RegionUninit(®2); + } + + RegionIntersect(®1, ®1, &clip_reg); + draw_item_add_fill_region(pDirtyPriv, ®1, pGC->fgPixel, + pGC->alu); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + + for (i = 0; i < npt; i++) + { + x = pts[i].x; + y = pts[i].y; + rdpup_fill_rect(x, y, 1, 1); + } + } + + rdpup_reset_clip(); + rdpup_end_update(); + } + } + } + + RegionUninit(&clip_reg); + + if (pts != stack_pts) + { + g_free(pts); + } + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPolyRectangle.c b/xorg/X11R7.6/rdp/rdpPolyRectangle.c index e2b38394..9f8a32fb 100644 --- a/xorg/X11R7.6/rdp/rdpPolyRectangle.c +++ b/xorg/X11R7.6/rdp/rdpPolyRectangle.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -46,240 +46,265 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ static void rdpPolyRectangleOrg(DrawablePtr pDrawable, GCPtr pGC, int nrects, - xRectangle* rects) + xRectangle *rects) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->PolyRectangle(pDrawable, pGC, nrects, rects); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->PolyRectangle(pDrawable, pGC, nrects, rects); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ /* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */ void rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, - xRectangle* rects) + xRectangle *rects) { - RegionRec clip_reg; - RegionPtr fill_reg; - int num_clips; - int cd; - int lw; - int i; - int j; - int up; - int down; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - xRectangle* regRects; - xRectangle* r; - xRectangle* rect1; - BoxRec box; - struct image_data id; + RegionRec clip_reg; + RegionPtr fill_reg; + int num_clips; + int cd; + int lw; + int i; + int j; + int up; + int down; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + xRectangle *regRects; + xRectangle *r; + xRectangle *rect1; + BoxRec box; + struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolyRectangle:")); + LLOGLN(10, ("rdpPolyRectangle:")); - /* make a copy of rects */ - rect1 = (xRectangle*)g_malloc(sizeof(xRectangle) * nrects, 0); - for (i = 0; i < nrects; i++) - { - rect1[i] = rects[i]; - } + /* make a copy of rects */ + rect1 = (xRectangle *)g_malloc(sizeof(xRectangle) * nrects, 0); - /* do original call */ - rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects); - - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPolyRectangle: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } - } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - g_free(rect1); - return; - } - - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - regRects = 0; - if ((cd != 0) && (nrects > 0)) - { - regRects = (xRectangle*)g_malloc(nrects * 4 * sizeof(xRectangle), 0); - lw = pGC->lineWidth; - if (lw < 1) - { - lw = 1; - } - up = lw / 2; - down = 1 + (lw - 1) / 2; for (i = 0; i < nrects; i++) { - r = regRects + i * 4; - r->x = (rect1[i].x + pDrawable->x) - up; - r->y = (rect1[i].y + pDrawable->y) - up; - r->width = rect1[i].width + up + down; - r->height = lw; - r++; - r->x = (rect1[i].x + pDrawable->x) - up; - r->y = (rect1[i].y + pDrawable->y) + down; - r->width = lw; - r->height = MAX(rect1[i].height - (up + down), 0); - r++; - r->x = ((rect1[i].x + rect1[i].width) + pDrawable->x) - up; - r->y = (rect1[i].y + pDrawable->y) + down; - r->width = lw; - r->height = MAX(rect1[i].height - (up + down), 0); - r++; - r->x = (rect1[i].x + pDrawable->x) - up; - r->y = ((rect1[i].y + rect1[i].height) + pDrawable->y) - up; - r->width = rect1[i].width + up + down; - r->height = lw; + rect1[i] = rects[i]; } - } - if (cd == 1) - { - if (regRects != 0) + + /* do original call */ + rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - if (dirty_type != 0) - { - fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE); - if (pGC->lineStyle == LineSolid) + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel, - pGC->alu); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyRectangle: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - else - { - draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, dirty_type); - } - RegionDestroy(fill_reg); - } - else if (got_id) - { - rdpup_begin_update(); - if (pGC->lineStyle == LineSolid) - { - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - for (i = 0; i < nrects * 4; i++) - { - r = regRects + i; - rdpup_fill_rect(r->x, r->y, r->width, r->height); - } - rdpup_set_opcode(GXcopy); - } - else - { - for (i = 0; i < nrects * 4; i++) - { - r = regRects + i; - rdpup_send_area(&id, r->x, r->y, r->width, r->height); - } - } - rdpup_end_update(); - } } - } - else if (cd == 2) - { - if (regRects != 0) + else { - fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE); - RegionIntersect(&clip_reg, &clip_reg, fill_reg); - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) - { - if (dirty_type != 0) + if (pDrawable->type == DRAWABLE_WINDOW) { - if (pGC->lineStyle == LineSolid) - { - draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel, - pGC->alu); - } - else - { - draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); - } - } - else if (got_id) - { - rdpup_begin_update(); - if (pGC->lineStyle == LineSolid) - { - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - for (j = num_clips - 1; j >= 0; j--) + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; } - rdpup_set_opcode(GXcopy); - } - else - { - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } - } - rdpup_end_update(); } - } - RegionDestroy(fill_reg); } - } - RegionUninit(&clip_reg); - g_free(regRects); - g_free(rect1); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } + + if (!post_process) + { + g_free(rect1); + return; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + regRects = 0; + + if ((cd != 0) && (nrects > 0)) + { + regRects = (xRectangle *)g_malloc(nrects * 4 * sizeof(xRectangle), 0); + lw = pGC->lineWidth; + + if (lw < 1) + { + lw = 1; + } + + up = lw / 2; + down = 1 + (lw - 1) / 2; + + for (i = 0; i < nrects; i++) + { + r = regRects + i * 4; + r->x = (rect1[i].x + pDrawable->x) - up; + r->y = (rect1[i].y + pDrawable->y) - up; + r->width = rect1[i].width + up + down; + r->height = lw; + r++; + r->x = (rect1[i].x + pDrawable->x) - up; + r->y = (rect1[i].y + pDrawable->y) + down; + r->width = lw; + r->height = MAX(rect1[i].height - (up + down), 0); + r++; + r->x = ((rect1[i].x + rect1[i].width) + pDrawable->x) - up; + r->y = (rect1[i].y + pDrawable->y) + down; + r->width = lw; + r->height = MAX(rect1[i].height - (up + down), 0); + r++; + r->x = (rect1[i].x + pDrawable->x) - up; + r->y = ((rect1[i].y + rect1[i].height) + pDrawable->y) - up; + r->width = rect1[i].width + up + down; + r->height = lw; + } + } + + if (cd == 1) + { + if (regRects != 0) + { + if (dirty_type != 0) + { + fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE); + + if (pGC->lineStyle == LineSolid) + { + draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel, + pGC->alu); + } + else + { + draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, dirty_type); + } + + RegionDestroy(fill_reg); + } + else if (got_id) + { + rdpup_begin_update(); + + if (pGC->lineStyle == LineSolid) + { + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + + for (i = 0; i < nrects * 4; i++) + { + r = regRects + i; + rdpup_fill_rect(r->x, r->y, r->width, r->height); + } + + rdpup_set_opcode(GXcopy); + } + else + { + for (i = 0; i < nrects * 4; i++) + { + r = regRects + i; + rdpup_send_area(&id, r->x, r->y, r->width, r->height); + } + } + + rdpup_end_update(); + } + } + } + else if (cd == 2) + { + if (regRects != 0) + { + fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE); + RegionIntersect(&clip_reg, &clip_reg, fill_reg); + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + if (pGC->lineStyle == LineSolid) + { + draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu); + } + else + { + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); + } + } + else if (got_id) + { + rdpup_begin_update(); + + if (pGC->lineStyle == LineSolid) + { + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_set_opcode(GXcopy); + } + else + { + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + } + + rdpup_end_update(); + } + } + + RegionDestroy(fill_reg); + } + } + + RegionUninit(&clip_reg); + g_free(regRects); + g_free(rect1); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPolySegment.c b/xorg/X11R7.6/rdp/rdpPolySegment.c index efab3cc0..c748c892 100644 --- a/xorg/X11R7.6/rdp/rdpPolySegment.c +++ b/xorg/X11R7.6/rdp/rdpPolySegment.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -45,168 +45,183 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ void -rdpPolySegmentOrg(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) +rdpPolySegmentOrg(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->PolySegment(pDrawable, pGC, nseg, pSegs); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->PolySegment(pDrawable, pGC, nseg, pSegs); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void -rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) +rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs) { - RegionRec clip_reg; - int cd; - int i; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - xSegment* segs; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec clip_reg; + int cd; + int i; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + xSegment *segs; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolySegment:")); - LLOGLN(10, (" nseg %d", nseg)); + LLOGLN(10, ("rdpPolySegment:")); + LLOGLN(10, (" nseg %d", nseg)); - segs = 0; - if (nseg) /* get the rects */ - { - segs = (xSegment*)g_malloc(nseg * sizeof(xSegment), 0); - for (i = 0; i < nseg; i++) + segs = 0; + + if (nseg) /* get the rects */ { - segs[i].x1 = pSegs[i].x1 + pDrawable->x; - segs[i].y1 = pSegs[i].y1 + pDrawable->y; - segs[i].x2 = pSegs[i].x2 + pDrawable->x; - segs[i].y2 = pSegs[i].y2 + pDrawable->y; - } - } + segs = (xSegment *)g_malloc(nseg * sizeof(xSegment), 0); - /* do original call */ - rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs); - - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPolySegment: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } - } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - g_free(segs); - return; - } - - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - LLOGLN(10, ("rdpPolySegment: cd %d", cd)); - if (cd == 1) /* no clip */ - { - if (segs != 0) - { - if (dirty_type != 0) - { - RegionUninit(&clip_reg); - RegionInit(&clip_reg, NullBox, 0); - RegionAroundSegs(&clip_reg, segs, nseg); - draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, - pGC->alu, pGC->lineWidth, segs, nseg, 1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - rdpup_set_pen(0, pGC->lineWidth); for (i = 0; i < nseg; i++) { - rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + segs[i].x1 = pSegs[i].x1 + pDrawable->x; + segs[i].y1 = pSegs[i].y1 + pDrawable->y; + segs[i].x2 = pSegs[i].x2 + pDrawable->x; + segs[i].y2 = pSegs[i].y2 + pDrawable->y; } - rdpup_set_opcode(GXcopy); - rdpup_end_update(); - } } - } - else if (cd == 2) /* clip */ - { - if (segs != 0) + + /* do original call */ + rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - if (dirty_type != 0) - { - draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, - pGC->alu, pGC->lineWidth, segs, nseg, 1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - rdpup_set_pen(0, pGC->lineWidth); - for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--) + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - for (i = 0; i < nseg; i++) - { - rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); - LLOGLN(10, (" %d %d %d %d", segs[i].x1, segs[i].y1, - segs[i].x2, segs[i].y2)); - } + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolySegment: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - rdpup_reset_clip(); - rdpup_set_opcode(GXcopy); - rdpup_end_update(); - } } - } - g_free(segs); - RegionUninit(&clip_reg); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + g_free(segs); + return; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolySegment: cd %d", cd)); + + if (cd == 1) /* no clip */ + { + if (segs != 0) + { + if (dirty_type != 0) + { + RegionUninit(&clip_reg); + RegionInit(&clip_reg, NullBox, 0); + RegionAroundSegs(&clip_reg, segs, nseg); + draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu, pGC->lineWidth, segs, nseg, 1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + rdpup_set_pen(0, pGC->lineWidth); + + for (i = 0; i < nseg; i++) + { + rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + } + + rdpup_set_opcode(GXcopy); + rdpup_end_update(); + } + } + } + else if (cd == 2) /* clip */ + { + if (segs != 0) + { + if (dirty_type != 0) + { + draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu, pGC->lineWidth, segs, nseg, 1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + rdpup_set_pen(0, pGC->lineWidth); + + for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + + for (i = 0; i < nseg; i++) + { + rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + LLOGLN(10, (" %d %d %d %d", segs[i].x1, segs[i].y1, + segs[i].x2, segs[i].y2)); + } + } + + rdpup_reset_clip(); + rdpup_set_opcode(GXcopy); + rdpup_end_update(); + } + } + } + + g_free(segs); + RegionUninit(&clip_reg); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPolyText16.c b/xorg/X11R7.6/rdp/rdpPolyText16.c index aaea2434..34f8aa82 100644 --- a/xorg/X11R7.6/rdp/rdpPolyText16.c +++ b/xorg/X11R7.6/rdp/rdpPolyText16.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -46,148 +46,162 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ int rdpPolyText16Org(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, unsigned short* chars) + int x, int y, int count, unsigned short *chars) { - int rv; - rdpGCPtr priv; - GCFuncs* oldFuncs; + int rv; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - rv = pGC->ops->PolyText16(pDrawable, pGC, x, y, count, chars); - GC_OP_EPILOGUE(pGC); - return rv; + GC_OP_PROLOGUE(pGC); + rv = pGC->ops->PolyText16(pDrawable, pGC, x, y, count, chars); + GC_OP_EPILOGUE(pGC); + return rv; } /******************************************************************************/ int rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, unsigned short* chars) + int x, int y, int count, unsigned short *chars) { - RegionRec reg; - RegionRec reg1; - int num_clips; - int cd; - int j; - int rv; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec reg; + RegionRec reg1; + int num_clips; + int cd; + int j; + int rv; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolyText16:")); + LLOGLN(10, ("rdpPolyText16:")); - if (count != 0) - { - GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); - } - - /* do original call */ - rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars); - - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + if (count != 0) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPolyText16: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return rv; - } - RegionInit(®, NullBox, 0); - if (count == 0) - { - cd = 0; - } - else - { - cd = rdp_get_clip(®, pDrawable, pGC); - } - if (cd == 1) - { - if (dirty_type != 0) + /* do original call */ + rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); - } - } - else if (cd == 2) - { - RegionInit(®1, &box, 0); - RegionIntersect(®, ®, ®1); - num_clips = REGION_NUM_RECTS(®); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyText16: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - rdpup_end_update(); - } } - RegionUninit(®1); - } - RegionUninit(®); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } - return rv; + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + return rv; + } + + RegionInit(®, NullBox, 0); + + if (count == 0) + { + cd = 0; + } + else + { + cd = rdp_get_clip(®, pDrawable, pGC); + } + + if (cd == 1) + { + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } + } + else if (cd == 2) + { + RegionInit(®1, &box, 0); + RegionIntersect(®, ®, ®1); + num_clips = REGION_NUM_RECTS(®); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionUninit(®1); + } + + RegionUninit(®); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } + + return rv; } diff --git a/xorg/X11R7.6/rdp/rdpPolyText8.c b/xorg/X11R7.6/rdp/rdpPolyText8.c index 0b16cf26..39245ce1 100644 --- a/xorg/X11R7.6/rdp/rdpPolyText8.c +++ b/xorg/X11R7.6/rdp/rdpPolyText8.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -46,148 +46,162 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ int rdpPolyText8Org(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, char* chars) + int x, int y, int count, char *chars) { - int rv; - rdpGCPtr priv; - GCFuncs* oldFuncs; + int rv; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - rv = pGC->ops->PolyText8(pDrawable, pGC, x, y, count, chars); - GC_OP_EPILOGUE(pGC); - return rv; + GC_OP_PROLOGUE(pGC); + rv = pGC->ops->PolyText8(pDrawable, pGC, x, y, count, chars); + GC_OP_EPILOGUE(pGC); + return rv; } /******************************************************************************/ int rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, char* chars) + int x, int y, int count, char *chars) { - RegionRec reg; - RegionRec reg1; - int num_clips; - int cd; - int j; - int rv; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec reg; + RegionRec reg1; + int num_clips; + int cd; + int j; + int rv; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolyText8:")); + LLOGLN(10, ("rdpPolyText8:")); - if (count != 0) - { - GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); - } - - /* do original call */ - rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars); - - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + if (count != 0) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPolyText8: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return rv; - } - RegionInit(®, NullBox, 0); - if (count == 0) - { - cd = 0; - } - else - { - cd = rdp_get_clip(®, pDrawable, pGC); - } - if (cd == 1) - { - if (dirty_type != 0) + /* do original call */ + rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); - } - } - else if (cd == 2) - { - RegionInit(®1, &box, 0); - RegionIntersect(®, ®, ®1); - num_clips = REGION_NUM_RECTS(®); - if (num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); - } - else if (got_id) - { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyText8: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - rdpup_end_update(); - } } - RegionUninit(®1); - } - RegionUninit(®); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } - return rv; + else + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + return rv; + } + + RegionInit(®, NullBox, 0); + + if (count == 0) + { + cd = 0; + } + else + { + cd = rdp_get_clip(®, pDrawable, pGC); + } + + if (cd == 1) + { + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } + } + else if (cd == 2) + { + RegionInit(®1, &box, 0); + RegionIntersect(®, ®, ®1); + num_clips = REGION_NUM_RECTS(®); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionUninit(®1); + } + + RegionUninit(®); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } + + return rv; } diff --git a/xorg/X11R7.6/rdp/rdpPolylines.c b/xorg/X11R7.6/rdp/rdpPolylines.c index cbaf9c3e..d5208e42 100644 --- a/xorg/X11R7.6/rdp/rdpPolylines.c +++ b/xorg/X11R7.6/rdp/rdpPolylines.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -48,12 +48,12 @@ static void rdpPolylinesOrg(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->Polylines(pDrawable, pGC, mode, npt, pptInit); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->Polylines(pDrawable, pGC, mode, npt, pptInit); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ @@ -61,194 +61,217 @@ void rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { - RegionRec clip_reg; - int num_clips; - int cd; - int i; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - xSegment* segs; - int nseg; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec clip_reg; + int num_clips; + int cd; + int i; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + xSegment *segs; + int nseg; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPolylines:")); - LLOGLN(10, (" npt %d mode %d x %d y %d", npt, mode, - pDrawable->x, pDrawable->y)); + LLOGLN(10, ("rdpPolylines:")); + LLOGLN(10, (" npt %d mode %d x %d y %d", npt, mode, + pDrawable->x, pDrawable->y)); #if 0 - LLOGLN(0, (" points")); - for (i = 0; i < npt; i++) - { - LLOGLN(0, (" %d %d", pptInit[i].x, pptInit[i].y)); - } -#endif - /* convert lines to line segments */ - nseg = npt - 1; - segs = 0; - if (npt > 1) - { - segs = (xSegment*)g_malloc(sizeof(xSegment) * nseg, 0); - segs[0].x1 = pptInit[0].x + pDrawable->x; - segs[0].y1 = pptInit[0].y + pDrawable->y; - if (mode == CoordModeOrigin) + LLOGLN(0, (" points")); + + for (i = 0; i < npt; i++) { - segs[0].x2 = pptInit[1].x + pDrawable->x; - segs[0].y2 = pptInit[1].y + pDrawable->y; - for (i = 2; i < npt; i++) - { - segs[i - 1].x1 = segs[i - 2].x2; - segs[i - 1].y1 = segs[i - 2].y2; - segs[i - 1].x2 = pptInit[i].x + pDrawable->x; - segs[i - 1].y2 = pptInit[i].y + pDrawable->y; - } + LLOGLN(0, (" %d %d", pptInit[i].x, pptInit[i].y)); + } + +#endif + /* convert lines to line segments */ + nseg = npt - 1; + segs = 0; + + if (npt > 1) + { + segs = (xSegment *)g_malloc(sizeof(xSegment) * nseg, 0); + segs[0].x1 = pptInit[0].x + pDrawable->x; + segs[0].y1 = pptInit[0].y + pDrawable->y; + + if (mode == CoordModeOrigin) + { + segs[0].x2 = pptInit[1].x + pDrawable->x; + segs[0].y2 = pptInit[1].y + pDrawable->y; + + for (i = 2; i < npt; i++) + { + segs[i - 1].x1 = segs[i - 2].x2; + segs[i - 1].y1 = segs[i - 2].y2; + segs[i - 1].x2 = pptInit[i].x + pDrawable->x; + segs[i - 1].y2 = pptInit[i].y + pDrawable->y; + } + } + else + { + segs[0].x2 = segs[0].x1 + pptInit[1].x; + segs[0].y2 = segs[0].y1 + pptInit[1].y; + + for (i = 2; i < npt; i++) + { + segs[i - 1].x1 = segs[i - 2].x2; + segs[i - 1].y1 = segs[i - 2].y2; + segs[i - 1].x2 = segs[i - 1].x1 + pptInit[i].x; + segs[i - 1].y2 = segs[i - 1].y1 + pptInit[i].y; + } + } } else { - segs[0].x2 = segs[0].x1 + pptInit[1].x; - segs[0].y2 = segs[0].y1 + pptInit[1].y; - for (i = 2; i < npt; i++) - { - segs[i - 1].x1 = segs[i - 2].x2; - segs[i - 1].y1 = segs[i - 2].y2; - segs[i - 1].x2 = segs[i - 1].x1 + pptInit[i].x; - segs[i - 1].y2 = segs[i - 1].y1 + pptInit[i].y; - } + LLOGLN(0, ("rdpPolylines: weird npt [%d]", npt)); } - } - else - { - LLOGLN(0, ("rdpPolylines: weird npt [%d]", npt)); - } + #if 0 - LLOGLN(0, (" segments")); - for (i = 0; i < nseg; i++) - { - LLOGLN(0, (" %d %d %d %d", segs[i].x1, segs[i].y1, - segs[i].x2, segs[i].y2)); - } + LLOGLN(0, (" segments")); + + for (i = 0; i < nseg; i++) + { + LLOGLN(0, (" %d %d %d %d", segs[i].x1, segs[i].y1, + segs[i].x2, segs[i].y2)); + } + #endif - /* do original call */ - rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit); + /* do original call */ + rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit); - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPolylines: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolylines: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } + } } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) + else { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } } - } - if (!post_process) - { + + if (!post_process) + { + g_free(segs); + return; + } + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + + if (cd == 1) + { + if (segs != 0) + { + if (dirty_type != 0) + { + RegionUninit(&clip_reg); + RegionInit(&clip_reg, NullBox, 0); + RegionAroundSegs(&clip_reg, segs, nseg); + draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu, pGC->lineWidth, segs, nseg, 0); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + rdpup_set_pen(0, pGC->lineWidth); + + for (i = 0; i < nseg; i++) + { + rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + } + + rdpup_set_opcode(GXcopy); + rdpup_end_update(); + } + } + } + else if (cd == 2) + { + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (nseg != 0 && num_clips > 0) + { + if (dirty_type != 0) + { + draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu, pGC->lineWidth, segs, nseg, 0); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + rdpup_set_pen(0, pGC->lineWidth); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + + for (i = 0; i < nseg; i++) + { + rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + } + } + + rdpup_reset_clip(); + rdpup_set_opcode(GXcopy); + rdpup_end_update(); + } + } + } + g_free(segs); - return; - } + RegionUninit(&clip_reg); - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - if (cd == 1) - { - if (segs != 0) + if (reset_surface) { - if (dirty_type != 0) - { - RegionUninit(&clip_reg); - RegionInit(&clip_reg, NullBox, 0); - RegionAroundSegs(&clip_reg, segs, nseg); - draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, - pGC->alu, pGC->lineWidth, segs, nseg, 0); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - rdpup_set_pen(0, pGC->lineWidth); - for (i = 0; i < nseg; i++) - { - rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); - } - rdpup_set_opcode(GXcopy); - rdpup_end_update(); - } + rdpup_switch_os_surface(-1); } - } - else if (cd == 2) - { - num_clips = REGION_NUM_RECTS(&clip_reg); - if (nseg != 0 && num_clips > 0) - { - if (dirty_type != 0) - { - draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, - pGC->alu, pGC->lineWidth, segs, nseg, 0); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - rdpup_set_pen(0, pGC->lineWidth); - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - for (i = 0; i < nseg; i++) - { - rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); - } - } - rdpup_reset_clip(); - rdpup_set_opcode(GXcopy); - rdpup_end_update(); - } - } - } - g_free(segs); - RegionUninit(&clip_reg); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } } diff --git a/xorg/X11R7.6/rdp/rdpPushPixels.c b/xorg/X11R7.6/rdp/rdpPushPixels.c index 06c5ba9f..d990d6cb 100644 --- a/xorg/X11R7.6/rdp/rdpPushPixels.c +++ b/xorg/X11R7.6/rdp/rdpPushPixels.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -48,12 +48,12 @@ void rdpPushPixelsOrg(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h, int x, int y) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->PushPixels(pGC, pBitMap, pDst, w, h, x, y); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->PushPixels(pGC, pBitMap, pDst, w, h, x, y); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ @@ -61,129 +61,141 @@ void rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h, int x, int y) { - RegionRec clip_reg; - RegionRec box_reg; - RegionRec reg1; - int num_clips; - int cd; - int j; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - BoxRec box; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec clip_reg; + RegionRec box_reg; + RegionRec reg1; + int num_clips; + int cd; + int j; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + BoxRec box; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpPushPixels:")); + LLOGLN(10, ("rdpPushPixels:")); - /* do original call */ - rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y); + /* do original call */ + rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y); - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDst->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDst; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPutImage: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } - } - } - else - { - if (pDst->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)pDst; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } - } - } - if (!post_process) - { - return; - } + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; - memset(&box, 0, sizeof(box)); - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDst, pGC); - if (cd == 1) - { - if (dirty_type != 0) + if (pDst->type == DRAWABLE_PIXMAP) { - box.x1 = pDst->x + x; - box.y1 = pDst->y + y; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - rdpup_send_area(0, pDst->x + x, pDst->y + y, w, h); - rdpup_end_update(); - } - } - else if (cd == 2) - { - box.x1 = pDst->x + x; - box.y1 = pDst->y + y; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(&box_reg, &box, 0); - RegionIntersect(&clip_reg, &clip_reg, &box_reg); - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) - { - if (dirty_type != 0) - { - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); - RegionUninit(®1); - } - else if (got_id) - { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + pDstPixmap = (PixmapPtr)pDst; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPutImage: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } - rdpup_end_update(); - } } - RegionUninit(&box_reg); - } - RegionUninit(&clip_reg); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } + else + { + if (pDst->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDst; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } + } + + if (!post_process) + { + return; + } + + memset(&box, 0, sizeof(box)); + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDst, pGC); + + if (cd == 1) + { + if (dirty_type != 0) + { + box.x1 = pDst->x + x; + box.y1 = pDst->y + y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(0, pDst->x + x, pDst->y + y, w, h); + rdpup_end_update(); + } + } + else if (cd == 2) + { + box.x1 = pDst->x + x; + box.y1 = pDst->y + y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(&box_reg, &box, 0); + RegionIntersect(&clip_reg, &clip_reg, &box_reg); + num_clips = REGION_NUM_RECTS(&clip_reg); + + if (num_clips > 0) + { + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionUninit(&box_reg); + } + + RegionUninit(&clip_reg); + + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPutImage.c b/xorg/X11R7.6/rdp/rdpPutImage.c index 798016f3..5fb28516 100644 --- a/xorg/X11R7.6/rdp/rdpPutImage.c +++ b/xorg/X11R7.6/rdp/rdpPutImage.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -46,143 +46,154 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ static void rdpPutImageOrg(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, - int w, int h, int leftPad, int format, char* pBits) + int w, int h, int leftPad, int format, char *pBits) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->PutImage(pDst, pGC, depth, x, y, w, h, leftPad, - format, pBits); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->PutImage(pDst, pGC, depth, x, y, w, h, leftPad, + format, pBits); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, - int w, int h, int leftPad, int format, char* pBits) + int w, int h, int leftPad, int format, char *pBits) { - RegionRec clip_reg; - int cd; - int j; - int reset_surface; - int post_process; - int got_id; - int dirty_type; - BoxRec box; - struct image_data id; + RegionRec clip_reg; + int cd; + int j; + int reset_surface; + int post_process; + int got_id; + int dirty_type; + BoxRec box; + struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; - RegionRec reg1; - RegionRec reg2; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; + RegionRec reg1; + RegionRec reg2; - LLOGLN(10, ("rdpPutImage:")); - LLOGLN(10, ("rdpPutImage: drawable id 0x%x", (int)(pDst->id))); + LLOGLN(10, ("rdpPutImage:")); + LLOGLN(10, ("rdpPutImage: drawable id 0x%x", (int)(pDst->id))); - /* do original call */ - rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits); + /* do original call */ + rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits); - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDst->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDst; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDst->type == DRAWABLE_PIXMAP) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpPutImage: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + pDstPixmap = (PixmapPtr)pDst; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPutImage: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } + } } - } - else - { - if (pDst->type == DRAWABLE_WINDOW) + else { - pDstWnd = (WindowPtr)pDst; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } + if (pDst->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDst; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } } - } - if (!post_process) - { - return; - } - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDst, pGC); - if (cd == 1) - { - if (dirty_type != 0) + + if (!post_process) { - box.x1 = pDst->x + x; - box.y1 = pDst->y + y; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); + return; } - else if (got_id) + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDst, pGC); + + if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h); - rdpup_end_update(); + if (dirty_type != 0) + { + box.x1 = pDst->x + x; + box.y1 = pDst->y + y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h); + rdpup_end_update(); + } } - } - else if (cd == 2) - { - if (dirty_type != 0) + else if (cd == 2) { - box.x1 = pDst->x + x; - box.y1 = pDst->y + y; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(®1, &box, 0); - RegionInit(®2, NullBox, 0); - RegionCopy(®2, &clip_reg); - RegionIntersect(®1, ®1, ®2); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); - RegionUninit(®2); + if (dirty_type != 0) + { + box.x1 = pDst->x + x; + box.y1 = pDst->y + y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + RegionInit(®2, NullBox, 0); + RegionCopy(®2, &clip_reg); + RegionIntersect(®1, ®1, ®2); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + RegionUninit(®2); + } + else if (got_id) + { + rdpup_begin_update(); + + for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, (box.x2 - box.x1), (box.y2 - box.y1)); + rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h); + } + + rdpup_reset_clip(); + rdpup_end_update(); + } } - else if (got_id) + + RegionUninit(&clip_reg); + + if (reset_surface) { - rdpup_begin_update(); - for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, (box.x2 - box.x1), (box.y2 - box.y1)); - rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h); - } - rdpup_reset_clip(); - rdpup_end_update(); + rdpup_switch_os_surface(-1); } - } - RegionUninit(&clip_reg); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } } diff --git a/xorg/X11R7.6/rdp/rdpSetSpans.c b/xorg/X11R7.6/rdp/rdpSetSpans.c index aab36f88..734d67ac 100644 --- a/xorg/X11R7.6/rdp/rdpSetSpans.c +++ b/xorg/X11R7.6/rdp/rdpSetSpans.c @@ -26,9 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -45,107 +45,116 @@ extern int g_con_number; /* in rdpup.c */ /******************************************************************************/ void -rdpSetSpansOrg(DrawablePtr pDrawable, GCPtr pGC, char* psrc, - DDXPointPtr ppt, int* pwidth, int nspans, int fSorted) +rdpSetSpansOrg(DrawablePtr pDrawable, GCPtr pGC, char *psrc, + DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) { - rdpGCPtr priv; - GCFuncs* oldFuncs; + rdpGCPtr priv; + GCFuncs *oldFuncs; - GC_OP_PROLOGUE(pGC); - pGC->ops->SetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); - GC_OP_EPILOGUE(pGC); + GC_OP_PROLOGUE(pGC); + pGC->ops->SetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); + GC_OP_EPILOGUE(pGC); } /******************************************************************************/ void -rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc, - DDXPointPtr ppt, int* pwidth, int nspans, int fSorted) +rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, + DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) { - RegionRec clip_reg; - int cd; - int got_id; - int dirty_type; - int post_process; - int reset_surface; - struct image_data id; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; + RegionRec clip_reg; + int cd; + int got_id; + int dirty_type; + int post_process; + int reset_surface; + struct image_data id; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; - LLOGLN(10, ("rdpSetSpans: todo")); + LLOGLN(10, ("rdpSetSpans: todo")); - /* do original call */ - rdpSetSpansOrg(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); + /* do original call */ + rdpSetSpansOrg(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDrawable; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpSetSpans: gettig dirty")); - pDstPriv->is_dirty = 1; - pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - } + pDstPixmap = (PixmapPtr)pDrawable; + pDstPriv = GETPIXPRIV(pDstPixmap); + + if (XRDP_IS_OS(pDstPriv)) + { + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpSetSpans: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } + } } - } - else - { - if (pDrawable->type == DRAWABLE_WINDOW) + else { - pDstWnd = (WindowPtr)pDrawable; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - } + if (pDrawable->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)pDrawable; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + } + } } - } - if (!post_process) - { - return; - } - RegionInit(&clip_reg, NullBox, 0); - cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - if (cd == 1) - { - if (dirty_type != 0) + + if (!post_process) { + return; } - else if (got_id) + + RegionInit(&clip_reg, NullBox, 0); + cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + + if (cd == 1) { + if (dirty_type != 0) + { + } + else if (got_id) + { + } } - } - else if (cd == 2) - { - if (dirty_type != 0) + else if (cd == 2) { + if (dirty_type != 0) + { + } + else if (got_id) + { + } } - else if (got_id) + + RegionUninit(&clip_reg); + + if (reset_surface) { + rdpup_switch_os_surface(-1); } - } - RegionUninit(&clip_reg); - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } } diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c index 78b2aa3d..20876048 100644 --- a/xorg/X11R7.6/rdp/rdpdraw.c +++ b/xorg/X11R7.6/rdp/rdpdraw.c @@ -48,9 +48,9 @@ Xserver drawing ops and funcs #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */ @@ -69,17 +69,17 @@ static int g_doing_font = 0; GCFuncs g_rdpGCFuncs = { - rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip, - rdpDestroyClip, rdpCopyClip + rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip, + rdpDestroyClip, rdpCopyClip }; GCOps g_rdpGCOps = { - rdpFillSpans, rdpSetSpans, rdpPutImage, rdpCopyArea, rdpCopyPlane, - rdpPolyPoint, rdpPolylines, rdpPolySegment, rdpPolyRectangle, - rdpPolyArc, rdpFillPolygon, rdpPolyFillRect, rdpPolyFillArc, - rdpPolyText8, rdpPolyText16, rdpImageText8, rdpImageText16, - rdpImageGlyphBlt, rdpPolyGlyphBlt, rdpPushPixels + rdpFillSpans, rdpSetSpans, rdpPutImage, rdpCopyArea, rdpCopyPlane, + rdpPolyPoint, rdpPolylines, rdpPolySegment, rdpPolyRectangle, + rdpPolyArc, rdpFillPolygon, rdpPolyFillRect, rdpPolyFillArc, + rdpPolyText8, rdpPolyText16, rdpImageText8, rdpImageText16, + rdpImageGlyphBlt, rdpPolyGlyphBlt, rdpPushPixels }; /******************************************************************************/ @@ -89,87 +89,95 @@ GCOps g_rdpGCOps = int rdp_get_clip(RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC) { - WindowPtr pWindow; - RegionPtr temp; - BoxRec box; - int rv; + WindowPtr pWindow; + RegionPtr temp; + BoxRec box; + int rv; - rv = 0; - if (pDrawable->type == DRAWABLE_PIXMAP) - { - switch (pGC->clientClipType) + rv = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) { - case CT_NONE: - rv = 1; - break; - case CT_REGION: - rv = 2; - RegionCopy(pRegion, pGC->clientClip); - break; - default: - rdpLog("unimp clip type %d\n", pGC->clientClipType); - break; - } - if (rv == 2) /* check if the clip is the entire pixmap */ - { - box.x1 = 0; - box.y1 = 0; - box.x2 = pDrawable->width; - box.y2 = pDrawable->height; - if (RegionContainsRect(pRegion, &box) == rgnIN) - { - rv = 1; - } - } - } - else if (pDrawable->type == DRAWABLE_WINDOW) - { - pWindow = (WindowPtr)pDrawable; - if (pWindow->viewable) - { - if (pGC->subWindowMode == IncludeInferiors) - { - temp = &pWindow->borderClip; - } - else - { - temp = &pWindow->clipList; - } - if (RegionNotEmpty(temp)) - { switch (pGC->clientClipType) { - case CT_NONE: - rv = 2; - RegionCopy(pRegion, temp); - break; - case CT_REGION: - rv = 2; - RegionCopy(pRegion, pGC->clientClip); - RegionTranslate(pRegion, - pDrawable->x + pGC->clipOrg.x, - pDrawable->y + pGC->clipOrg.y); - RegionIntersect(pRegion, pRegion, temp); - break; - default: - rdpLog("unimp clip type %d\n", pGC->clientClipType); - break; + case CT_NONE: + rv = 1; + break; + case CT_REGION: + rv = 2; + RegionCopy(pRegion, pGC->clientClip); + break; + default: + rdpLog("unimp clip type %d\n", pGC->clientClipType); + break; } - if (rv == 2) /* check if the clip is the entire screen */ + + if (rv == 2) /* check if the clip is the entire pixmap */ { - box.x1 = 0; - box.y1 = 0; - box.x2 = g_rdpScreen.width; - box.y2 = g_rdpScreen.height; - if (RegionContainsRect(pRegion, &box) == rgnIN) - { - rv = 1; - } + box.x1 = 0; + box.y1 = 0; + box.x2 = pDrawable->width; + box.y2 = pDrawable->height; + + if (RegionContainsRect(pRegion, &box) == rgnIN) + { + rv = 1; + } } - } } - } - return rv; + else if (pDrawable->type == DRAWABLE_WINDOW) + { + pWindow = (WindowPtr)pDrawable; + + if (pWindow->viewable) + { + if (pGC->subWindowMode == IncludeInferiors) + { + temp = &pWindow->borderClip; + } + else + { + temp = &pWindow->clipList; + } + + if (RegionNotEmpty(temp)) + { + switch (pGC->clientClipType) + { + case CT_NONE: + rv = 2; + RegionCopy(pRegion, temp); + break; + case CT_REGION: + rv = 2; + RegionCopy(pRegion, pGC->clientClip); + RegionTranslate(pRegion, + pDrawable->x + pGC->clipOrg.x, + pDrawable->y + pGC->clipOrg.y); + RegionIntersect(pRegion, pRegion, temp); + break; + default: + rdpLog("unimp clip type %d\n", pGC->clientClipType); + break; + } + + if (rv == 2) /* check if the clip is the entire screen */ + { + box.x1 = 0; + box.y1 = 0; + box.x2 = g_rdpScreen.width; + box.y2 = g_rdpScreen.height; + + if (RegionContainsRect(pRegion, &box) == rgnIN) + { + rv = 1; + } + } + } + } + } + + return rv; } /******************************************************************************/ @@ -177,426 +185,456 @@ void GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y, int n, BoxPtr pbox) { - int maxAscent; - int maxDescent; - int maxCharWidth; + int maxAscent; + int maxDescent; + int maxCharWidth; - if (FONTASCENT(font) > FONTMAXBOUNDS(font, ascent)) - { - maxAscent = FONTASCENT(font); - } - else - { - maxAscent = FONTMAXBOUNDS(font, ascent); - } - if (FONTDESCENT(font) > FONTMAXBOUNDS(font, descent)) - { - maxDescent = FONTDESCENT(font); - } - else - { - maxDescent = FONTMAXBOUNDS(font, descent); - } - if (FONTMAXBOUNDS(font, rightSideBearing) > - FONTMAXBOUNDS(font, characterWidth)) - { - maxCharWidth = FONTMAXBOUNDS(font, rightSideBearing); - } - else - { - maxCharWidth = FONTMAXBOUNDS(font, characterWidth); - } - pbox->x1 = pDrawable->x + x; - pbox->y1 = pDrawable->y + y - maxAscent; - pbox->x2 = pbox->x1 + maxCharWidth * n; - pbox->y2 = pbox->y1 + maxAscent + maxDescent; - if (FONTMINBOUNDS(font, leftSideBearing) < 0) - { - pbox->x1 += FONTMINBOUNDS(font, leftSideBearing); - } + if (FONTASCENT(font) > FONTMAXBOUNDS(font, ascent)) + { + maxAscent = FONTASCENT(font); + } + else + { + maxAscent = FONTMAXBOUNDS(font, ascent); + } + + if (FONTDESCENT(font) > FONTMAXBOUNDS(font, descent)) + { + maxDescent = FONTDESCENT(font); + } + else + { + maxDescent = FONTMAXBOUNDS(font, descent); + } + + if (FONTMAXBOUNDS(font, rightSideBearing) > + FONTMAXBOUNDS(font, characterWidth)) + { + maxCharWidth = FONTMAXBOUNDS(font, rightSideBearing); + } + else + { + maxCharWidth = FONTMAXBOUNDS(font, characterWidth); + } + + pbox->x1 = pDrawable->x + x; + pbox->y1 = pDrawable->y + y - maxAscent; + pbox->x2 = pbox->x1 + maxCharWidth * n; + pbox->y2 = pbox->y1 + maxAscent + maxDescent; + + if (FONTMINBOUNDS(font, leftSideBearing) < 0) + { + pbox->x1 += FONTMINBOUNDS(font, leftSideBearing); + } } /******************************************************************************/ #define GC_FUNC_PROLOGUE(_pGC) \ -{ \ - priv = (rdpGCPtr)(dixGetPrivateAddr(&(_pGC->devPrivates), &g_rdpGCIndex)); \ - (_pGC)->funcs = priv->funcs; \ - if (priv->ops != 0) \ - { \ - (_pGC)->ops = priv->ops; \ - } \ -} + { \ + priv = (rdpGCPtr)(dixGetPrivateAddr(&(_pGC->devPrivates), &g_rdpGCIndex)); \ + (_pGC)->funcs = priv->funcs; \ + if (priv->ops != 0) \ + { \ + (_pGC)->ops = priv->ops; \ + } \ + } /******************************************************************************/ #define GC_FUNC_EPILOGUE(_pGC) \ -{ \ - priv->funcs = (_pGC)->funcs; \ - (_pGC)->funcs = &g_rdpGCFuncs; \ - if (priv->ops != 0) \ - { \ - priv->ops = (_pGC)->ops; \ - (_pGC)->ops = &g_rdpGCOps; \ - } \ -} + { \ + priv->funcs = (_pGC)->funcs; \ + (_pGC)->funcs = &g_rdpGCFuncs; \ + if (priv->ops != 0) \ + { \ + priv->ops = (_pGC)->ops; \ + (_pGC)->ops = &g_rdpGCOps; \ + } \ + } /******************************************************************************/ static void rdpValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr d) { - rdpGCRec* priv; - int wrap; - RegionPtr pRegion; + rdpGCRec *priv; + int wrap; + RegionPtr pRegion; + + LLOGLN(10, ("rdpValidateGC:")); + GC_FUNC_PROLOGUE(pGC); + pGC->funcs->ValidateGC(pGC, changes, d); + + if (g_wrapPixmap) + { + wrap = 1; + } + else + { + wrap = (d->type == DRAWABLE_WINDOW) && ((WindowPtr)d)->viewable; + + if (wrap) + { + if (pGC->subWindowMode == IncludeInferiors) + { + pRegion = &(((WindowPtr)d)->borderClip); + } + else + { + pRegion = &(((WindowPtr)d)->clipList); + } + + wrap = RegionNotEmpty(pRegion); + } + } + + priv->ops = 0; - LLOGLN(10, ("rdpValidateGC:")); - GC_FUNC_PROLOGUE(pGC); - pGC->funcs->ValidateGC(pGC, changes, d); - if (g_wrapPixmap) - { - wrap = 1; - } - else - { - wrap = (d->type == DRAWABLE_WINDOW) && ((WindowPtr)d)->viewable; if (wrap) { - if (pGC->subWindowMode == IncludeInferiors) - { - pRegion = &(((WindowPtr)d)->borderClip); - } - else - { - pRegion = &(((WindowPtr)d)->clipList); - } - wrap = RegionNotEmpty(pRegion); + priv->ops = pGC->ops; } - } - priv->ops = 0; - if (wrap) - { - priv->ops = pGC->ops; - } - GC_FUNC_EPILOGUE(pGC); + + GC_FUNC_EPILOGUE(pGC); } /******************************************************************************/ static void rdpChangeGC(GCPtr pGC, unsigned long mask) { - rdpGCRec* priv; + rdpGCRec *priv; - LLOGLN(10, ("in rdpChangeGC")); - GC_FUNC_PROLOGUE(pGC); - pGC->funcs->ChangeGC(pGC, mask); - GC_FUNC_EPILOGUE(pGC); + LLOGLN(10, ("in rdpChangeGC")); + GC_FUNC_PROLOGUE(pGC); + pGC->funcs->ChangeGC(pGC, mask); + GC_FUNC_EPILOGUE(pGC); } /******************************************************************************/ static void rdpCopyGC(GCPtr src, unsigned long mask, GCPtr dst) { - rdpGCRec* priv; + rdpGCRec *priv; - LLOGLN(10, ("in rdpCopyGC")); - GC_FUNC_PROLOGUE(dst); - dst->funcs->CopyGC(src, mask, dst); - GC_FUNC_EPILOGUE(dst); + LLOGLN(10, ("in rdpCopyGC")); + GC_FUNC_PROLOGUE(dst); + dst->funcs->CopyGC(src, mask, dst); + GC_FUNC_EPILOGUE(dst); } /******************************************************************************/ static void rdpDestroyGC(GCPtr pGC) { - rdpGCRec* priv; + rdpGCRec *priv; - LLOGLN(10, ("in rdpDestroyGC")); - GC_FUNC_PROLOGUE(pGC); - pGC->funcs->DestroyGC(pGC); - GC_FUNC_EPILOGUE(pGC); + LLOGLN(10, ("in rdpDestroyGC")); + GC_FUNC_PROLOGUE(pGC); + pGC->funcs->DestroyGC(pGC); + GC_FUNC_EPILOGUE(pGC); } /******************************************************************************/ static void rdpChangeClip(GCPtr pGC, int type, pointer pValue, int nrects) { - rdpGCRec* priv; + rdpGCRec *priv; - LLOGLN(10, ("in rdpChangeClip")); - GC_FUNC_PROLOGUE(pGC); - pGC->funcs->ChangeClip(pGC, type, pValue, nrects); - GC_FUNC_EPILOGUE(pGC); + LLOGLN(10, ("in rdpChangeClip")); + GC_FUNC_PROLOGUE(pGC); + pGC->funcs->ChangeClip(pGC, type, pValue, nrects); + GC_FUNC_EPILOGUE(pGC); } /******************************************************************************/ static void rdpDestroyClip(GCPtr pGC) { - rdpGCRec* priv; + rdpGCRec *priv; - LLOGLN(10, ("in rdpDestroyClip")); - GC_FUNC_PROLOGUE(pGC); - pGC->funcs->DestroyClip(pGC); - GC_FUNC_EPILOGUE(pGC); + LLOGLN(10, ("in rdpDestroyClip")); + GC_FUNC_PROLOGUE(pGC); + pGC->funcs->DestroyClip(pGC); + GC_FUNC_EPILOGUE(pGC); } /******************************************************************************/ static void rdpCopyClip(GCPtr dst, GCPtr src) { - rdpGCRec* priv; + rdpGCRec *priv; - LLOGLN(0, ("in rdpCopyClip")); - GC_FUNC_PROLOGUE(dst); - dst->funcs->CopyClip(dst, src); - GC_FUNC_EPILOGUE(dst); + LLOGLN(0, ("in rdpCopyClip")); + GC_FUNC_PROLOGUE(dst); + dst->funcs->CopyClip(dst, src); + GC_FUNC_EPILOGUE(dst); } /******************************************************************************/ #define GC_OP_PROLOGUE(_pGC) \ -{ \ - priv = (rdpGCPtr)dixGetPrivateAddr(&(pGC->devPrivates), &g_rdpGCIndex); \ - oldFuncs = _pGC->funcs; \ - (_pGC)->funcs = priv->funcs; \ - (_pGC)->ops = priv->ops; \ -} + { \ + priv = (rdpGCPtr)dixGetPrivateAddr(&(pGC->devPrivates), &g_rdpGCIndex); \ + oldFuncs = _pGC->funcs; \ + (_pGC)->funcs = priv->funcs; \ + (_pGC)->ops = priv->ops; \ + } /******************************************************************************/ #define GC_OP_EPILOGUE(_pGC) \ -{ \ - priv->ops = (_pGC)->ops; \ - (_pGC)->funcs = oldFuncs; \ - (_pGC)->ops = &g_rdpGCOps; \ -} + { \ + priv->ops = (_pGC)->ops; \ + (_pGC)->funcs = oldFuncs; \ + (_pGC)->ops = &g_rdpGCOps; \ + } /******************************************************************************/ Bool rdpCloseScreen(int i, ScreenPtr pScreen) { - LLOGLN(10, ("in rdpCloseScreen")); - pScreen->CloseScreen = g_rdpScreen.CloseScreen; - pScreen->CreateGC = g_rdpScreen.CreateGC; - //pScreen->PaintWindowBackground = g_rdpScreen.PaintWindowBackground; - //pScreen->PaintWindowBorder = g_rdpScreen.PaintWindowBorder; - pScreen->CopyWindow = g_rdpScreen.CopyWindow; - pScreen->ClearToBackground = g_rdpScreen.ClearToBackground; - pScreen->RestoreAreas = g_rdpScreen.RestoreAreas; - return 1; + LLOGLN(10, ("in rdpCloseScreen")); + pScreen->CloseScreen = g_rdpScreen.CloseScreen; + pScreen->CreateGC = g_rdpScreen.CreateGC; + //pScreen->PaintWindowBackground = g_rdpScreen.PaintWindowBackground; + //pScreen->PaintWindowBorder = g_rdpScreen.PaintWindowBorder; + pScreen->CopyWindow = g_rdpScreen.CopyWindow; + pScreen->ClearToBackground = g_rdpScreen.ClearToBackground; + pScreen->RestoreAreas = g_rdpScreen.RestoreAreas; + return 1; } /******************************************************************************/ int -draw_item_add(rdpPixmapRec* priv, struct rdp_draw_item* di) +draw_item_add(rdpPixmapRec *priv, struct rdp_draw_item *di) { - if (priv->draw_item_tail == 0) - { - priv->draw_item_tail = di; - priv->draw_item_head = di; - } - else - { - di->prev = priv->draw_item_tail; - priv->draw_item_tail->next = di; - priv->draw_item_tail = di; - } - return 0; -} - -/******************************************************************************/ -int -draw_item_remove(rdpPixmapRec* priv, struct rdp_draw_item* di) -{ - if (di->prev != 0) - { - di->prev->next = di->next; - } - if (di->next != 0) - { - di->next->prev = di->prev; - } - if (priv->draw_item_head == di) - { - priv->draw_item_head = di->next; - } - if (priv->draw_item_tail == di) - { - priv->draw_item_tail = di->prev; - } - if (di->type == RDI_LINE) - { - if (di->u.line.segs != 0) + if (priv->draw_item_tail == 0) { - g_free(di->u.line.segs); - } - } - RegionDestroy(di->reg); - g_free(di); - return 0; -} - -/******************************************************************************/ -int -draw_item_remove_all(rdpPixmapRec* priv) -{ - struct rdp_draw_item* di; - - di = priv->draw_item_head; - while (di != 0) - { - draw_item_remove(priv, di); - di = priv->draw_item_head; - } - return 0; -} - -/******************************************************************************/ -int -draw_item_pack(rdpPixmapRec* priv) -{ - struct rdp_draw_item* di; - struct rdp_draw_item* di_prev; - -#if 1 - /* look for repeating draw types */ - if (priv->draw_item_head != 0) - { - if (priv->draw_item_head->next != 0) - { - di_prev = priv->draw_item_head; - di = priv->draw_item_head->next; - while (di != 0) - { - if ((di_prev->type == RDI_IMGLL) && (di->type == RDI_IMGLL)) - { - LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL")); - RegionUnion(di_prev->reg, di_prev->reg, di->reg); - draw_item_remove(priv, di); - di = di_prev->next; - } - else if ((di_prev->type == RDI_IMGLY) && (di->type == RDI_IMGLY)) - { - LLOGLN(10, ("draw_item_pack: packing RDI_IMGLY")); - RegionUnion(di_prev->reg, di_prev->reg, di->reg); - draw_item_remove(priv, di); - di = di_prev->next; - } - else - { - di_prev = di; - di = di_prev->next; - } - } - } - } -#endif -#if 1 - /* subtract regions */ - if (priv->draw_item_tail != 0) - { - if (priv->draw_item_tail->prev != 0) - { - di = priv->draw_item_tail; - while (di->prev != 0) - { - /* skip subtract flag - * draw items like line can't be used to clear(subtract) previous - * draw items since they are not opaque - * eg they can not be the 'S' in 'D = M - S' - * the region for line draw items is the clip region */ - if ((di->flags & 1) == 0) - { - di_prev = di->prev; - while (di_prev != 0) - { - /* D = M - S */ - RegionSubtract(di_prev->reg, di_prev->reg, di->reg); - di_prev = di_prev->prev; - } - } - di = di->prev; - } - } - } -#endif -#if 1 - /* remove draw items with empty regions */ - di = priv->draw_item_head; - di_prev = 0; - while (di != 0) - { - if (!RegionNotEmpty(di->reg)) - { - LLOGLN(10, ("draw_item_pack: removing empty item type %d", di->type)); - draw_item_remove(priv, di); - di = di_prev == 0 ? priv->draw_item_head : di_prev->next; + priv->draw_item_tail = di; + priv->draw_item_head = di; } else { - di_prev = di; - di = di->next; + di->prev = priv->draw_item_tail; + priv->draw_item_tail->next = di; + priv->draw_item_tail = di; } - } -#endif - return 0; + + return 0; } /******************************************************************************/ int -draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int opcode, +draw_item_remove(rdpPixmapRec *priv, struct rdp_draw_item *di) +{ + if (di->prev != 0) + { + di->prev->next = di->next; + } + + if (di->next != 0) + { + di->next->prev = di->prev; + } + + if (priv->draw_item_head == di) + { + priv->draw_item_head = di->next; + } + + if (priv->draw_item_tail == di) + { + priv->draw_item_tail = di->prev; + } + + if (di->type == RDI_LINE) + { + if (di->u.line.segs != 0) + { + g_free(di->u.line.segs); + } + } + + RegionDestroy(di->reg); + g_free(di); + return 0; +} + +/******************************************************************************/ +int +draw_item_remove_all(rdpPixmapRec *priv) +{ + struct rdp_draw_item *di; + + di = priv->draw_item_head; + + while (di != 0) + { + draw_item_remove(priv, di); + di = priv->draw_item_head; + } + + return 0; +} + +/******************************************************************************/ +int +draw_item_pack(rdpPixmapRec *priv) +{ + struct rdp_draw_item *di; + struct rdp_draw_item *di_prev; + +#if 1 + + /* look for repeating draw types */ + if (priv->draw_item_head != 0) + { + if (priv->draw_item_head->next != 0) + { + di_prev = priv->draw_item_head; + di = priv->draw_item_head->next; + + while (di != 0) + { + if ((di_prev->type == RDI_IMGLL) && (di->type == RDI_IMGLL)) + { + LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL")); + RegionUnion(di_prev->reg, di_prev->reg, di->reg); + draw_item_remove(priv, di); + di = di_prev->next; + } + else if ((di_prev->type == RDI_IMGLY) && (di->type == RDI_IMGLY)) + { + LLOGLN(10, ("draw_item_pack: packing RDI_IMGLY")); + RegionUnion(di_prev->reg, di_prev->reg, di->reg); + draw_item_remove(priv, di); + di = di_prev->next; + } + else + { + di_prev = di; + di = di_prev->next; + } + } + } + } + +#endif +#if 1 + + /* subtract regions */ + if (priv->draw_item_tail != 0) + { + if (priv->draw_item_tail->prev != 0) + { + di = priv->draw_item_tail; + + while (di->prev != 0) + { + /* skip subtract flag + * draw items like line can't be used to clear(subtract) previous + * draw items since they are not opaque + * eg they can not be the 'S' in 'D = M - S' + * the region for line draw items is the clip region */ + if ((di->flags & 1) == 0) + { + di_prev = di->prev; + + while (di_prev != 0) + { + /* D = M - S */ + RegionSubtract(di_prev->reg, di_prev->reg, di->reg); + di_prev = di_prev->prev; + } + } + + di = di->prev; + } + } + } + +#endif +#if 1 + /* remove draw items with empty regions */ + di = priv->draw_item_head; + di_prev = 0; + + while (di != 0) + { + if (!RegionNotEmpty(di->reg)) + { + LLOGLN(10, ("draw_item_pack: removing empty item type %d", di->type)); + draw_item_remove(priv, di); + di = di_prev == 0 ? priv->draw_item_head : di_prev->next; + } + else + { + di_prev = di; + di = di->next; + } + } + +#endif + return 0; +} + +/******************************************************************************/ +int +draw_item_add_img_region(rdpPixmapRec *priv, RegionPtr reg, int opcode, int type) { - struct rdp_draw_item* di; + struct rdp_draw_item *di; - di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1); - di->type = type; - di->reg = RegionCreate(NullBox, 0); - RegionCopy(di->reg, reg); - di->u.img.opcode = opcode; - draw_item_add(priv, di); - return 0; + di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); + di->type = type; + di->reg = RegionCreate(NullBox, 0); + RegionCopy(di->reg, reg); + di->u.img.opcode = opcode; + draw_item_add(priv, di); + return 0; } /******************************************************************************/ int -draw_item_add_fill_region(rdpPixmapRec* priv, RegionPtr reg, int color, +draw_item_add_fill_region(rdpPixmapRec *priv, RegionPtr reg, int color, int opcode) { - struct rdp_draw_item* di; + struct rdp_draw_item *di; - di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1); - di->type = RDI_FILL; - di->u.fill.fg_color = color; - di->u.fill.opcode = opcode; - di->reg = RegionCreate(NullBox, 0); - RegionCopy(di->reg, reg); - draw_item_add(priv, di); - return 0; + di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); + di->type = RDI_FILL; + di->u.fill.fg_color = color; + di->u.fill.opcode = opcode; + di->reg = RegionCreate(NullBox, 0); + RegionCopy(di->reg, reg); + draw_item_add(priv, di); + return 0; } /******************************************************************************/ int -draw_item_add_line_region(rdpPixmapRec* priv, RegionPtr reg, int color, - int opcode, int width, xSegment* segs, int nseg, +draw_item_add_line_region(rdpPixmapRec *priv, RegionPtr reg, int color, + int opcode, int width, xSegment *segs, int nseg, int is_segment) { - struct rdp_draw_item* di; + struct rdp_draw_item *di; - LLOGLN(10, ("draw_item_add_line_region:")); - di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1); - di->type = RDI_LINE; - di->u.line.fg_color = color; - di->u.line.opcode = opcode; - di->u.line.width = width; - di->u.line.segs = (xSegment*)g_malloc(sizeof(xSegment) * nseg, 1); - memcpy(di->u.line.segs, segs, sizeof(xSegment) * nseg); - di->u.line.nseg = nseg; - if (is_segment) - { - di->u.line.flags = 1; - } - di->reg = RegionCreate(NullBox, 0); - di->flags |= 1; - RegionCopy(di->reg, reg); - draw_item_add(priv, di); - return 0; + LLOGLN(10, ("draw_item_add_line_region:")); + di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); + di->type = RDI_LINE; + di->u.line.fg_color = color; + di->u.line.opcode = opcode; + di->u.line.width = width; + di->u.line.segs = (xSegment *)g_malloc(sizeof(xSegment) * nseg, 1); + memcpy(di->u.line.segs, segs, sizeof(xSegment) * nseg); + di->u.line.nseg = nseg; + + if (is_segment) + { + di->u.line.flags = 1; + } + + di->reg = RegionCreate(NullBox, 0); + di->flags |= 1; + RegionCopy(di->reg, reg); + draw_item_add(priv, di); + return 0; } /******************************************************************************/ @@ -604,317 +642,342 @@ PixmapPtr rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint) { - PixmapPtr rv; - rdpPixmapRec* priv; - int org_width; + PixmapPtr rv; + rdpPixmapRec *priv; + int org_width; - org_width = width; - /* width must be a multiple of 4 in rdp */ - width = (width + 3) & ~3; - LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d depth %d screen depth %d", - width, org_width, depth, g_rdpScreen.depth)); - pScreen->CreatePixmap = g_rdpScreen.CreatePixmap; - rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint); - priv = GETPIXPRIV(rv); - priv->rdpindex = -1; - if ((rv->drawable.depth >= g_rdpScreen.depth) && - (org_width > 1) && (height > 1)) - { - priv->allocBytes = width * height * g_Bpp; - priv->rdpindex = rdpup_add_os_bitmap(rv, priv); - if (priv->rdpindex >= 0) + org_width = width; + /* width must be a multiple of 4 in rdp */ + width = (width + 3) & ~3; + LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d depth %d screen depth %d", + width, org_width, depth, g_rdpScreen.depth)); + pScreen->CreatePixmap = g_rdpScreen.CreatePixmap; + rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint); + priv = GETPIXPRIV(rv); + priv->rdpindex = -1; + + if ((rv->drawable.depth >= g_rdpScreen.depth) && + (org_width > 1) && (height > 1)) { - priv->status = 1; - rdpup_create_os_surface(priv->rdpindex, width, height); + priv->allocBytes = width * height * g_Bpp; + priv->rdpindex = rdpup_add_os_bitmap(rv, priv); + + if (priv->rdpindex >= 0) + { + priv->status = 1; + rdpup_create_os_surface(priv->rdpindex, width, height); + } } - } - pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0); - pScreen->CreatePixmap = rdpCreatePixmap; - return rv; + + pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0); + pScreen->CreatePixmap = rdpCreatePixmap; + return rv; } -extern struct rdpup_os_bitmap* g_os_bitmaps; +extern struct rdpup_os_bitmap *g_os_bitmaps; /******************************************************************************/ Bool rdpDestroyPixmap(PixmapPtr pPixmap) { - Bool rv; - ScreenPtr pScreen; - rdpPixmapRec* priv; + Bool rv; + ScreenPtr pScreen; + rdpPixmapRec *priv; - LLOGLN(10, ("rdpDestroyPixmap:")); - priv = GETPIXPRIV(pPixmap); - LLOGLN(10, ("status %d refcnt %d", priv->status, pPixmap->refcnt)); - if (pPixmap->refcnt < 2) - { - if (XRDP_IS_OS(priv)) + LLOGLN(10, ("rdpDestroyPixmap:")); + priv = GETPIXPRIV(pPixmap); + LLOGLN(10, ("status %d refcnt %d", priv->status, pPixmap->refcnt)); + + if (pPixmap->refcnt < 2) { - rdpup_remove_os_bitmap(priv->rdpindex); - rdpup_delete_os_surface(priv->rdpindex); - draw_item_remove_all(priv); + if (XRDP_IS_OS(priv)) + { + rdpup_remove_os_bitmap(priv->rdpindex); + rdpup_delete_os_surface(priv->rdpindex); + draw_item_remove_all(priv); + } } - } - pScreen = pPixmap->drawable.pScreen; - pScreen->DestroyPixmap = g_rdpScreen.DestroyPixmap; - rv = pScreen->DestroyPixmap(pPixmap); - pScreen->DestroyPixmap = rdpDestroyPixmap; - return rv; + + pScreen = pPixmap->drawable.pScreen; + pScreen->DestroyPixmap = g_rdpScreen.DestroyPixmap; + rv = pScreen->DestroyPixmap(pPixmap); + pScreen->DestroyPixmap = rdpDestroyPixmap; + return rv; } /******************************************************************************/ Bool rdpCreateWindow(WindowPtr pWindow) { - ScreenPtr pScreen; - rdpWindowRec* priv; - Bool rv; + ScreenPtr pScreen; + rdpWindowRec *priv; + Bool rv; - LLOGLN(10, ("rdpCreateWindow:")); - priv = GETWINPRIV(pWindow); - LLOGLN(10, (" %p status %d", priv, priv->status)); - pScreen = pWindow->drawable.pScreen; - pScreen->CreateWindow = g_rdpScreen.CreateWindow; - rv = pScreen->CreateWindow(pWindow); - pScreen->CreateWindow = rdpCreateWindow; - if (g_use_rail) - { - } - return rv; + LLOGLN(10, ("rdpCreateWindow:")); + priv = GETWINPRIV(pWindow); + LLOGLN(10, (" %p status %d", priv, priv->status)); + pScreen = pWindow->drawable.pScreen; + pScreen->CreateWindow = g_rdpScreen.CreateWindow; + rv = pScreen->CreateWindow(pWindow); + pScreen->CreateWindow = rdpCreateWindow; + + if (g_use_rail) + { + } + + return rv; } /******************************************************************************/ Bool rdpDestroyWindow(WindowPtr pWindow) { - ScreenPtr pScreen; - rdpWindowRec* priv; - Bool rv; + ScreenPtr pScreen; + rdpWindowRec *priv; + Bool rv; - LLOGLN(10, ("rdpDestroyWindow:")); - priv = GETWINPRIV(pWindow); - pScreen = pWindow->drawable.pScreen; - pScreen->DestroyWindow = g_rdpScreen.DestroyWindow; - rv = pScreen->DestroyWindow(pWindow); - pScreen->DestroyWindow = rdpDestroyWindow; - if (g_use_rail) - { - } - return rv; + LLOGLN(10, ("rdpDestroyWindow:")); + priv = GETWINPRIV(pWindow); + pScreen = pWindow->drawable.pScreen; + pScreen->DestroyWindow = g_rdpScreen.DestroyWindow; + rv = pScreen->DestroyWindow(pWindow); + pScreen->DestroyWindow = rdpDestroyWindow; + + if (g_use_rail) + { + } + + return rv; } /******************************************************************************/ Bool rdpPositionWindow(WindowPtr pWindow, int x, int y) { - ScreenPtr pScreen; - rdpWindowRec* priv; - Bool rv; + ScreenPtr pScreen; + rdpWindowRec *priv; + Bool rv; - LLOGLN(10, ("rdpPositionWindow:")); - priv = GETWINPRIV(pWindow); - pScreen = pWindow->drawable.pScreen; - pScreen->PositionWindow = g_rdpScreen.PositionWindow; - rv = pScreen->PositionWindow(pWindow, x, y); - pScreen->PositionWindow = rdpPositionWindow; - if (g_use_rail) - { - if (priv->status == 1) + LLOGLN(10, ("rdpPositionWindow:")); + priv = GETWINPRIV(pWindow); + pScreen = pWindow->drawable.pScreen; + pScreen->PositionWindow = g_rdpScreen.PositionWindow; + rv = pScreen->PositionWindow(pWindow, x, y); + pScreen->PositionWindow = rdpPositionWindow; + + if (g_use_rail) { - LLOGLN(10, ("rdpPositionWindow:")); - LLOGLN(10, (" x %d y %d", x, y)); + if (priv->status == 1) + { + LLOGLN(10, ("rdpPositionWindow:")); + LLOGLN(10, (" x %d y %d", x, y)); + } } - } - return rv; + + return rv; } /******************************************************************************/ Bool rdpRealizeWindow(WindowPtr pWindow) { - ScreenPtr pScreen; - rdpWindowRec* priv; - Bool rv; + ScreenPtr pScreen; + rdpWindowRec *priv; + Bool rv; - LLOGLN(10, ("rdpRealizeWindow:")); - priv = GETWINPRIV(pWindow); - pScreen = pWindow->drawable.pScreen; - pScreen->RealizeWindow = g_rdpScreen.RealizeWindow; - rv = pScreen->RealizeWindow(pWindow); - pScreen->RealizeWindow = rdpRealizeWindow; - if (g_use_rail) - { - if ((pWindow != g_invalidate_window) && (pWindow->parent != 0)) + LLOGLN(10, ("rdpRealizeWindow:")); + priv = GETWINPRIV(pWindow); + pScreen = pWindow->drawable.pScreen; + pScreen->RealizeWindow = g_rdpScreen.RealizeWindow; + rv = pScreen->RealizeWindow(pWindow); + pScreen->RealizeWindow = rdpRealizeWindow; + + if (g_use_rail) { - if (XR_IS_ROOT(pWindow->parent)) - { - LLOGLN(10, ("rdpRealizeWindow:")); - LLOGLN(10, (" pWindow %p id 0x%x pWindow->parent %p id 0x%x x %d " - "y %d width %d height %d", - pWindow, pWindow->drawable.id, - pWindow->parent, pWindow->parent->drawable.id, - pWindow->drawable.x, pWindow->drawable.y, - pWindow->drawable.width, pWindow->drawable.height)); - priv->status = 1; - rdpup_create_window(pWindow, priv); - } + if ((pWindow != g_invalidate_window) && (pWindow->parent != 0)) + { + if (XR_IS_ROOT(pWindow->parent)) + { + LLOGLN(10, ("rdpRealizeWindow:")); + LLOGLN(10, (" pWindow %p id 0x%x pWindow->parent %p id 0x%x x %d " + "y %d width %d height %d", + pWindow, pWindow->drawable.id, + pWindow->parent, pWindow->parent->drawable.id, + pWindow->drawable.x, pWindow->drawable.y, + pWindow->drawable.width, pWindow->drawable.height)); + priv->status = 1; + rdpup_create_window(pWindow, priv); + } + } } - } - return rv; + + return rv; } /******************************************************************************/ Bool rdpUnrealizeWindow(WindowPtr pWindow) { - ScreenPtr pScreen; - rdpWindowRec* priv; - Bool rv; + ScreenPtr pScreen; + rdpWindowRec *priv; + Bool rv; - LLOGLN(10, ("rdpUnrealizeWindow:")); - priv = GETWINPRIV(pWindow); - pScreen = pWindow->drawable.pScreen; - pScreen->UnrealizeWindow = g_rdpScreen.UnrealizeWindow; - rv = pScreen->UnrealizeWindow(pWindow); - pScreen->UnrealizeWindow = rdpUnrealizeWindow; - if (g_use_rail) - { - if (priv->status == 1) + LLOGLN(10, ("rdpUnrealizeWindow:")); + priv = GETWINPRIV(pWindow); + pScreen = pWindow->drawable.pScreen; + pScreen->UnrealizeWindow = g_rdpScreen.UnrealizeWindow; + rv = pScreen->UnrealizeWindow(pWindow); + pScreen->UnrealizeWindow = rdpUnrealizeWindow; + + if (g_use_rail) { - LLOGLN(10, ("rdpUnrealizeWindow:")); - priv->status = 0; - rdpup_delete_window(pWindow, priv); + if (priv->status == 1) + { + LLOGLN(10, ("rdpUnrealizeWindow:")); + priv->status = 0; + rdpup_delete_window(pWindow, priv); + } } - } - return rv; + + return rv; } /******************************************************************************/ Bool rdpChangeWindowAttributes(WindowPtr pWindow, unsigned long mask) { - ScreenPtr pScreen; - rdpWindowRec* priv; - Bool rv; + ScreenPtr pScreen; + rdpWindowRec *priv; + Bool rv; - LLOGLN(10, ("rdpChangeWindowAttributes:")); - priv = GETWINPRIV(pWindow); - pScreen = pWindow->drawable.pScreen; - pScreen->ChangeWindowAttributes = g_rdpScreen.ChangeWindowAttributes; - rv = pScreen->ChangeWindowAttributes(pWindow, mask); - pScreen->ChangeWindowAttributes = rdpChangeWindowAttributes; - if (g_use_rail) - { - } - return rv; + LLOGLN(10, ("rdpChangeWindowAttributes:")); + priv = GETWINPRIV(pWindow); + pScreen = pWindow->drawable.pScreen; + pScreen->ChangeWindowAttributes = g_rdpScreen.ChangeWindowAttributes; + rv = pScreen->ChangeWindowAttributes(pWindow, mask); + pScreen->ChangeWindowAttributes = rdpChangeWindowAttributes; + + if (g_use_rail) + { + } + + return rv; } /******************************************************************************/ void rdpWindowExposures(WindowPtr pWindow, RegionPtr pRegion, RegionPtr pBSRegion) { - ScreenPtr pScreen; - rdpWindowRec* priv; + ScreenPtr pScreen; + rdpWindowRec *priv; - LLOGLN(10, ("rdpWindowExposures:")); - priv = GETWINPRIV(pWindow); - pScreen = pWindow->drawable.pScreen; - pScreen->WindowExposures = g_rdpScreen.WindowExposures; - pScreen->WindowExposures(pWindow, pRegion, pBSRegion); - if (g_use_rail) - { - } - pScreen->WindowExposures = rdpWindowExposures; + LLOGLN(10, ("rdpWindowExposures:")); + priv = GETWINPRIV(pWindow); + pScreen = pWindow->drawable.pScreen; + pScreen->WindowExposures = g_rdpScreen.WindowExposures; + pScreen->WindowExposures(pWindow, pRegion, pBSRegion); + + if (g_use_rail) + { + } + + pScreen->WindowExposures = rdpWindowExposures; } /******************************************************************************/ Bool rdpCreateGC(GCPtr pGC) { - rdpGCRec* priv; - Bool rv; + rdpGCRec *priv; + Bool rv; - LLOGLN(10, ("in rdpCreateGC\n")); - priv = GETGCPRIV(pGC); - g_pScreen->CreateGC = g_rdpScreen.CreateGC; - rv = g_pScreen->CreateGC(pGC); - if (rv) - { - priv->funcs = pGC->funcs; - priv->ops = 0; - pGC->funcs = &g_rdpGCFuncs; - } - else - { - rdpLog("error in rdpCreateGC, CreateGC failed\n"); - } - g_pScreen->CreateGC = rdpCreateGC; - return rv; + LLOGLN(10, ("in rdpCreateGC\n")); + priv = GETGCPRIV(pGC); + g_pScreen->CreateGC = g_rdpScreen.CreateGC; + rv = g_pScreen->CreateGC(pGC); + + if (rv) + { + priv->funcs = pGC->funcs; + priv->ops = 0; + pGC->funcs = &g_rdpGCFuncs; + } + else + { + rdpLog("error in rdpCreateGC, CreateGC failed\n"); + } + + g_pScreen->CreateGC = rdpCreateGC; + return rv; } /******************************************************************************/ void rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) { - RegionRec reg; - RegionRec clip; - int dx; - int dy; - int i; - int j; - int num_clip_rects; - int num_reg_rects; - BoxRec box1; - BoxRec box2; + RegionRec reg; + RegionRec clip; + int dx; + int dy; + int i; + int j; + int num_clip_rects; + int num_reg_rects; + BoxRec box1; + BoxRec box2; - LLOGLN(10, ("in rdpCopyWindow")); - RegionInit(®, NullBox, 0); - RegionCopy(®, pOldRegion); - g_pScreen->CopyWindow = g_rdpScreen.CopyWindow; - g_pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion); - RegionInit(&clip, NullBox, 0); - RegionCopy(&clip, &pWin->borderClip); - dx = pWin->drawable.x - ptOldOrg.x; - dy = pWin->drawable.y - ptOldOrg.y; - rdpup_begin_update(); - num_clip_rects = REGION_NUM_RECTS(&clip); - num_reg_rects = REGION_NUM_RECTS(®); - /* should maybe sort the rects instead of checking dy < 0 */ - /* If we can depend on the rects going from top to bottom, left - to right we are ok */ - if (dy < 0 || (dy == 0 && dx < 0)) - { - for (j = 0; j < num_clip_rects; j++) + LLOGLN(10, ("in rdpCopyWindow")); + RegionInit(®, NullBox, 0); + RegionCopy(®, pOldRegion); + g_pScreen->CopyWindow = g_rdpScreen.CopyWindow; + g_pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion); + RegionInit(&clip, NullBox, 0); + RegionCopy(&clip, &pWin->borderClip); + dx = pWin->drawable.x - ptOldOrg.x; + dy = pWin->drawable.y - ptOldOrg.y; + rdpup_begin_update(); + num_clip_rects = REGION_NUM_RECTS(&clip); + num_reg_rects = REGION_NUM_RECTS(®); + + /* should maybe sort the rects instead of checking dy < 0 */ + /* If we can depend on the rects going from top to bottom, left + to right we are ok */ + if (dy < 0 || (dy == 0 && dx < 0)) { - box1 = REGION_RECTS(&clip)[j]; - rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1); - for (i = 0; i < num_reg_rects; i++) - { - box2 = REGION_RECTS(®)[i]; - rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1, - box2.y2 - box2.y1, box2.x1, box2.y1); - } + for (j = 0; j < num_clip_rects; j++) + { + box1 = REGION_RECTS(&clip)[j]; + rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1); + + for (i = 0; i < num_reg_rects; i++) + { + box2 = REGION_RECTS(®)[i]; + rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1, + box2.y2 - box2.y1, box2.x1, box2.y1); + } + } } - } - else - { - for (j = num_clip_rects - 1; j >= 0; j--) + else { - box1 = REGION_RECTS(&clip)[j]; - rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1); - for (i = num_reg_rects - 1; i >= 0; i--) - { - box2 = REGION_RECTS(®)[i]; - rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1, - box2.y2 - box2.y1, box2.x1, box2.y1); - } + for (j = num_clip_rects - 1; j >= 0; j--) + { + box1 = REGION_RECTS(&clip)[j]; + rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1); + + for (i = num_reg_rects - 1; i >= 0; i--) + { + box2 = REGION_RECTS(®)[i]; + rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1, + box2.y2 - box2.y1, box2.x1, box2.y1); + } + } } - } - rdpup_reset_clip(); - rdpup_end_update(); - RegionUninit(®); - RegionUninit(&clip); - g_pScreen->CopyWindow = rdpCopyWindow; + + rdpup_reset_clip(); + rdpup_end_update(); + RegionUninit(®); + RegionUninit(&clip); + g_pScreen->CopyWindow = rdpCopyWindow; } /******************************************************************************/ @@ -922,119 +985,130 @@ void rdpClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures) { - int j; - BoxRec box; - RegionRec reg; + int j; + BoxRec box; + RegionRec reg; - LLOGLN(10, ("in rdpClearToBackground")); - g_pScreen->ClearToBackground = g_rdpScreen.ClearToBackground; - g_pScreen->ClearToBackground(pWin, x, y, w, h, generateExposures); - if (!generateExposures) - { - if (w > 0 && h > 0) + LLOGLN(10, ("in rdpClearToBackground")); + g_pScreen->ClearToBackground = g_rdpScreen.ClearToBackground; + g_pScreen->ClearToBackground(pWin, x, y, w, h, generateExposures); + + if (!generateExposures) { - box.x1 = x; - box.y1 = y; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; + if (w > 0 && h > 0) + { + box.x1 = x; + box.y1 = y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + } + else + { + box.x1 = pWin->drawable.x; + box.y1 = pWin->drawable.y; + box.x2 = box.x1 + pWin->drawable.width; + box.y2 = box.y1 + pWin->drawable.height; + } + + RegionInit(®, &box, 0); + RegionIntersect(®, ®, &pWin->clipList); + rdpup_begin_update(); + + for (j = REGION_NUM_RECTS(®) - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_end_update(); + RegionUninit(®); } - else - { - box.x1 = pWin->drawable.x; - box.y1 = pWin->drawable.y; - box.x2 = box.x1 + pWin->drawable.width; - box.y2 = box.y1 + pWin->drawable.height; - } - RegionInit(®, &box, 0); - RegionIntersect(®, ®, &pWin->clipList); - rdpup_begin_update(); - for (j = REGION_NUM_RECTS(®) - 1; j >= 0; j--) - { - box = REGION_RECTS(®)[j]; - rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } - rdpup_end_update(); - RegionUninit(®); - } - g_pScreen->ClearToBackground = rdpClearToBackground; + + g_pScreen->ClearToBackground = rdpClearToBackground; } /******************************************************************************/ RegionPtr rdpRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed) { - RegionRec reg; - RegionPtr rv; - int j; - BoxRec box; + RegionRec reg; + RegionPtr rv; + int j; + BoxRec box; - LLOGLN(10, ("in rdpRestoreAreas")); - RegionInit(®, NullBox, 0); - RegionCopy(®, prgnExposed); - g_pScreen->RestoreAreas = g_rdpScreen.RestoreAreas; - rv = g_pScreen->RestoreAreas(pWin, prgnExposed); - rdpup_begin_update(); - for (j = REGION_NUM_RECTS(®) - 1; j >= 0; j--) - { - box = REGION_RECTS(®)[j]; - rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } - rdpup_end_update(); - RegionUninit(®); - g_pScreen->RestoreAreas = rdpRestoreAreas; - return rv; + LLOGLN(10, ("in rdpRestoreAreas")); + RegionInit(®, NullBox, 0); + RegionCopy(®, prgnExposed); + g_pScreen->RestoreAreas = g_rdpScreen.RestoreAreas; + rv = g_pScreen->RestoreAreas(pWin, prgnExposed); + rdpup_begin_update(); + + for (j = REGION_NUM_RECTS(®) - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_end_update(); + RegionUninit(®); + g_pScreen->RestoreAreas = rdpRestoreAreas; + return rv; } /******************************************************************************/ void rdpInstallColormap(ColormapPtr pmap) { - ColormapPtr oldpmap; + ColormapPtr oldpmap; - oldpmap = g_rdpInstalledColormap; - if (pmap != oldpmap) - { - if (oldpmap != (ColormapPtr)None) + oldpmap = g_rdpInstalledColormap; + + if (pmap != oldpmap) { - WalkTree(pmap->pScreen, TellLostMap, (char*)&oldpmap->mid); + if (oldpmap != (ColormapPtr)None) + { + WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid); + } + + /* Install pmap */ + g_rdpInstalledColormap = pmap; + WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid); + /*rfbSetClientColourMaps(0, 0);*/ } - /* Install pmap */ - g_rdpInstalledColormap = pmap; - WalkTree(pmap->pScreen, TellGainedMap, (char*)&pmap->mid); - /*rfbSetClientColourMaps(0, 0);*/ - } - /*g_rdpScreen.InstallColormap(pmap);*/ + + /*g_rdpScreen.InstallColormap(pmap);*/ } /******************************************************************************/ void rdpUninstallColormap(ColormapPtr pmap) { - ColormapPtr curpmap; + ColormapPtr curpmap; - curpmap = g_rdpInstalledColormap; - if (pmap == curpmap) - { - if (pmap->mid != pmap->pScreen->defColormap) + curpmap = g_rdpInstalledColormap; + + if (pmap == curpmap) { - //curpmap = (ColormapPtr)LookupIDByType(pmap->pScreen->defColormap, - // RT_COLORMAP); - //pmap->pScreen->InstallColormap(curpmap); + if (pmap->mid != pmap->pScreen->defColormap) + { + //curpmap = (ColormapPtr)LookupIDByType(pmap->pScreen->defColormap, + // RT_COLORMAP); + //pmap->pScreen->InstallColormap(curpmap); + } } - } } /******************************************************************************/ int -rdpListInstalledColormaps(ScreenPtr pScreen, Colormap* pmaps) +rdpListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps) { - *pmaps = g_rdpInstalledColormap->mid; - return 1; + *pmaps = g_rdpInstalledColormap->mid; + return 1; } /******************************************************************************/ void -rdpStoreColors(ColormapPtr pmap, int ndef, xColorItem* pdefs) +rdpStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs) { } @@ -1042,7 +1116,7 @@ rdpStoreColors(ColormapPtr pmap, int ndef, xColorItem* pdefs) Bool rdpSaveScreen(ScreenPtr pScreen, int on) { - return 1; + return 1; } /******************************************************************************/ @@ -1052,140 +1126,152 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { - BoxRec box; - PictureScreenPtr ps; - RegionRec reg1; - RegionRec reg2; - DrawablePtr p; - int dirty_type; - int j; - int num_clips; - int post_process; - int reset_surface; - int got_id; - int lx; - int ly; - WindowPtr pDstWnd; - PixmapPtr pDstPixmap; - rdpPixmapRec* pDstPriv; - rdpPixmapRec* pDirtyPriv; - struct image_data id; + BoxRec box; + PictureScreenPtr ps; + RegionRec reg1; + RegionRec reg2; + DrawablePtr p; + int dirty_type; + int j; + int num_clips; + int post_process; + int reset_surface; + int got_id; + int lx; + int ly; + WindowPtr pDstWnd; + PixmapPtr pDstPixmap; + rdpPixmapRec *pDstPriv; + rdpPixmapRec *pDirtyPriv; + struct image_data id; - LLOGLN(10, ("rdpComposite:")); - ps = GetPictureScreen(g_pScreen); - ps->Composite = g_rdpScreen.Composite; - ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc, - xMask, yMask, xDst, yDst, width, height); - ps->Composite = rdpComposite; + LLOGLN(10, ("rdpComposite:")); + ps = GetPictureScreen(g_pScreen); + ps->Composite = g_rdpScreen.Composite; + ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc, + xMask, yMask, xDst, yDst, width, height); + ps->Composite = rdpComposite; - p = pDst->pDrawable; + p = pDst->pDrawable; - dirty_type = 0; - pDirtyPriv = 0; - post_process = 0; - reset_surface = 0; - got_id = 0; - if (p->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)p; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; + got_id = 0; + + if (p->type == DRAWABLE_PIXMAP) { - post_process = 1; - if (g_do_dirty_os) - { - LLOGLN(10, ("rdpComposite: gettig dirty")); - pDstPriv->is_dirty = 1; - dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY; - pDirtyPriv = pDstPriv; + pDstPixmap = (PixmapPtr)p; + pDstPriv = GETPIXPRIV(pDstPixmap); - } - else - { - rdpup_switch_os_surface(pDstPriv->rdpindex); - reset_surface = 1; - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; - LLOGLN(10, ("rdpComposite: offscreen")); - } - } - } - else - { - if (p->type == DRAWABLE_WINDOW) - { - pDstWnd = (WindowPtr)p; - if (pDstWnd->viewable) - { - post_process = 1; - rdpup_get_screen_image_rect(&id); - got_id = 1; - LLOGLN(10, ("rdpComposite: screen")); - } - } - } - if (!post_process) - { - return; - } - - if (pDst->clientClipType == CT_REGION) - { - box.x1 = p->x + xDst; - box.y1 = p->y + yDst; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - RegionInit(®1, &box, 0); - RegionInit(®2, NullBox, 0); - RegionCopy(®2, pDst->clientClip); - lx = p->x + pDst->clipOrigin.x; - ly = p->y + pDst->clipOrigin.y; - RegionTranslate(®2, lx, ly); - RegionIntersect(®1, ®1, ®2); - if (dirty_type != 0) - { - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - } - else if (got_id) - { - num_clips = REGION_NUM_RECTS(®1); - if (num_clips > 0) - { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + if (XRDP_IS_OS(pDstPriv)) { - box = REGION_RECTS(®1)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + post_process = 1; + + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpComposite: gettig dirty")); + pDstPriv->is_dirty = 1; + dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY; + pDirtyPriv = pDstPriv; + + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + LLOGLN(10, ("rdpComposite: offscreen")); + } } - rdpup_end_update(); - } } - RegionUninit(®1); - RegionUninit(®2); - } - else - { - box.x1 = p->x + xDst; - box.y1 = p->y + yDst; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - if (dirty_type != 0) + else { - RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); - RegionUninit(®1); + if (p->type == DRAWABLE_WINDOW) + { + pDstWnd = (WindowPtr)p; + + if (pDstWnd->viewable) + { + post_process = 1; + rdpup_get_screen_image_rect(&id); + got_id = 1; + LLOGLN(10, ("rdpComposite: screen")); + } + } } - else if (got_id) + + if (!post_process) { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); + return; + } + + if (pDst->clientClipType == CT_REGION) + { + box.x1 = p->x + xDst; + box.y1 = p->y + yDst; + box.x2 = box.x1 + width; + box.y2 = box.y1 + height; + RegionInit(®1, &box, 0); + RegionInit(®2, NullBox, 0); + RegionCopy(®2, pDst->clientClip); + lx = p->x + pDst->clipOrigin.x; + ly = p->y + pDst->clipOrigin.y; + RegionTranslate(®2, lx, ly); + RegionIntersect(®1, ®1, ®2); + + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + } + else if (got_id) + { + num_clips = REGION_NUM_RECTS(®1); + + if (num_clips > 0) + { + rdpup_begin_update(); + + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®1)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_end_update(); + } + } + + RegionUninit(®1); + RegionUninit(®2); + } + else + { + box.x1 = p->x + xDst; + box.y1 = p->y + yDst; + box.x2 = box.x1 + width; + box.y2 = box.y1 + height; + + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } + } + + if (reset_surface) + { + rdpup_switch_os_surface(-1); } - } - if (reset_surface) - { - rdpup_switch_os_surface(-1); - } } /******************************************************************************/ @@ -1193,27 +1279,29 @@ void rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlists, GlyphListPtr lists, - GlyphPtr* glyphs) + GlyphPtr *glyphs) { - PictureScreenPtr ps; - int index; + PictureScreenPtr ps; + int index; - LLOGLN(10, ("rdpGlyphs:")); - LLOGLN(10, ("rdpGlyphs: nlists %d len %d", nlists, lists->len)); - rdpup_set_hints(1, 1); - g_doing_font = 1; - for (index = 0; index < lists->len; index++) - { - LLOGLN(10, (" index %d size %d refcnt %d width %d height %d", - index, (int)(glyphs[index]->size), (int)(glyphs[index]->refcnt), - glyphs[index]->info.width, glyphs[index]->info.height)); - } - ps = GetPictureScreen(g_pScreen); - ps->Glyphs = g_rdpScreen.Glyphs; - ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, - nlists, lists, glyphs); - ps->Glyphs = rdpGlyphs; - rdpup_set_hints(0, 1); - g_doing_font = 0; - LLOGLN(10, ("rdpGlyphs: out")); + LLOGLN(10, ("rdpGlyphs:")); + LLOGLN(10, ("rdpGlyphs: nlists %d len %d", nlists, lists->len)); + rdpup_set_hints(1, 1); + g_doing_font = 1; + + for (index = 0; index < lists->len; index++) + { + LLOGLN(10, (" index %d size %d refcnt %d width %d height %d", + index, (int)(glyphs[index]->size), (int)(glyphs[index]->refcnt), + glyphs[index]->info.width, glyphs[index]->info.height)); + } + + ps = GetPictureScreen(g_pScreen); + ps->Glyphs = g_rdpScreen.Glyphs; + ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, + nlists, lists, glyphs); + ps->Glyphs = rdpGlyphs; + rdpup_set_hints(0, 1); + g_doing_font = 0; + LLOGLN(10, ("rdpGlyphs: out")); } diff --git a/xorg/X11R7.6/rdp/rdpinput.c b/xorg/X11R7.6/rdp/rdpinput.c index 1256d0e0..b8e1746a 100644 --- a/xorg/X11R7.6/rdp/rdpinput.c +++ b/xorg/X11R7.6/rdp/rdpinput.c @@ -80,161 +80,161 @@ static int g_scroll_lock_down = 0; #define NUM_LOCK_KEY_CODE 77 #define N_PREDEFINED_KEYS \ - (sizeof(g_kbdMap) / (sizeof(KeySym) * GLYPHS_PER_KEY)) + (sizeof(g_kbdMap) / (sizeof(KeySym) * GLYPHS_PER_KEY)) /* Copied from Xvnc/lib/font/util/utilbitmap.c */ static unsigned char g_reverse_byte[0x100] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff }; static KeySym g_kbdMap[] = { - NoSymbol, NoSymbol, /* 8 */ - XK_Escape, NoSymbol, /* 9 */ - XK_1, XK_exclam, /* 10 */ - XK_2, XK_at, - XK_3, XK_numbersign, - XK_4, XK_dollar, - XK_5, XK_percent, - XK_6, XK_asciicircum, - XK_7, XK_ampersand, - XK_8, XK_asterisk, - XK_9, XK_parenleft, - XK_0, XK_parenright, - XK_minus, XK_underscore, /* 20 */ - XK_equal, XK_plus, - XK_BackSpace, NoSymbol, - XK_Tab, XK_ISO_Left_Tab, - XK_Q, NoSymbol, - XK_W, NoSymbol, - XK_E, NoSymbol, - XK_R, NoSymbol, - XK_T, NoSymbol, - XK_Y, NoSymbol, - XK_U, NoSymbol, /* 30 */ - XK_I, NoSymbol, - XK_O, NoSymbol, - XK_P, NoSymbol, - XK_bracketleft, XK_braceleft, - XK_bracketright, XK_braceright, - XK_Return, NoSymbol, - XK_Control_L, NoSymbol, - XK_A, NoSymbol, - XK_S, NoSymbol, - XK_D, NoSymbol, /* 40 */ - XK_F, NoSymbol, - XK_G, NoSymbol, - XK_H, NoSymbol, - XK_J, NoSymbol, - XK_K, NoSymbol, - XK_L, NoSymbol, - XK_semicolon, XK_colon, - XK_apostrophe, XK_quotedbl, - XK_grave, XK_asciitilde, - XK_Shift_L, NoSymbol, /* 50 */ - XK_backslash, XK_bar, - XK_Z, NoSymbol, - XK_X, NoSymbol, - XK_C, NoSymbol, - XK_V, NoSymbol, - XK_B, NoSymbol, - XK_N, NoSymbol, - XK_M, NoSymbol, - XK_comma, XK_less, - XK_period, XK_greater, /* 60 */ - XK_slash, XK_question, - XK_Shift_R, NoSymbol, - XK_KP_Multiply, NoSymbol, - XK_Alt_L, NoSymbol, - XK_space, NoSymbol, - XK_Caps_Lock, NoSymbol, - XK_F1, NoSymbol, - XK_F2, NoSymbol, - XK_F3, NoSymbol, - XK_F4, NoSymbol, /* 70 */ - XK_F5, NoSymbol, - XK_F6, NoSymbol, - XK_F7, NoSymbol, - XK_F8, NoSymbol, - XK_F9, NoSymbol, - XK_F10, NoSymbol, - XK_Num_Lock, NoSymbol, - XK_Scroll_Lock, NoSymbol, - XK_KP_Home, XK_KP_7, - XK_KP_Up, XK_KP_8, /* 80 */ - XK_KP_Prior, XK_KP_9, - XK_KP_Subtract, NoSymbol, - XK_KP_Left, XK_KP_4, - XK_KP_Begin, XK_KP_5, - XK_KP_Right, XK_KP_6, - XK_KP_Add, NoSymbol, - XK_KP_End, XK_KP_1, - XK_KP_Down, XK_KP_2, - XK_KP_Next, XK_KP_3, - XK_KP_Insert, XK_KP_0, /* 90 */ - XK_KP_Delete, XK_KP_Decimal, - NoSymbol, NoSymbol, - NoSymbol, NoSymbol, - NoSymbol, NoSymbol, - XK_F11, NoSymbol, - XK_F12, NoSymbol, - XK_Home, NoSymbol, - XK_Up, NoSymbol, - XK_Prior, NoSymbol, - XK_Left, NoSymbol, /* 100 */ - XK_Print, NoSymbol, - XK_Right, NoSymbol, - XK_End, NoSymbol, - XK_Down, NoSymbol, - XK_Next, NoSymbol, - XK_Insert, NoSymbol, - XK_Delete, NoSymbol, - XK_KP_Enter, NoSymbol, - XK_Control_R, NoSymbol, - XK_Pause, NoSymbol, /* 110 */ - XK_Print, NoSymbol, - XK_KP_Divide, NoSymbol, - XK_Alt_R, NoSymbol, - NoSymbol, NoSymbol, - XK_Super_L, NoSymbol, - XK_Super_R, NoSymbol, - XK_Menu, NoSymbol, - NoSymbol, NoSymbol, - NoSymbol, NoSymbol, - NoSymbol, NoSymbol, /* 120 */ - NoSymbol, NoSymbol + NoSymbol, NoSymbol, /* 8 */ + XK_Escape, NoSymbol, /* 9 */ + XK_1, XK_exclam, /* 10 */ + XK_2, XK_at, + XK_3, XK_numbersign, + XK_4, XK_dollar, + XK_5, XK_percent, + XK_6, XK_asciicircum, + XK_7, XK_ampersand, + XK_8, XK_asterisk, + XK_9, XK_parenleft, + XK_0, XK_parenright, + XK_minus, XK_underscore, /* 20 */ + XK_equal, XK_plus, + XK_BackSpace, NoSymbol, + XK_Tab, XK_ISO_Left_Tab, + XK_Q, NoSymbol, + XK_W, NoSymbol, + XK_E, NoSymbol, + XK_R, NoSymbol, + XK_T, NoSymbol, + XK_Y, NoSymbol, + XK_U, NoSymbol, /* 30 */ + XK_I, NoSymbol, + XK_O, NoSymbol, + XK_P, NoSymbol, + XK_bracketleft, XK_braceleft, + XK_bracketright, XK_braceright, + XK_Return, NoSymbol, + XK_Control_L, NoSymbol, + XK_A, NoSymbol, + XK_S, NoSymbol, + XK_D, NoSymbol, /* 40 */ + XK_F, NoSymbol, + XK_G, NoSymbol, + XK_H, NoSymbol, + XK_J, NoSymbol, + XK_K, NoSymbol, + XK_L, NoSymbol, + XK_semicolon, XK_colon, + XK_apostrophe, XK_quotedbl, + XK_grave, XK_asciitilde, + XK_Shift_L, NoSymbol, /* 50 */ + XK_backslash, XK_bar, + XK_Z, NoSymbol, + XK_X, NoSymbol, + XK_C, NoSymbol, + XK_V, NoSymbol, + XK_B, NoSymbol, + XK_N, NoSymbol, + XK_M, NoSymbol, + XK_comma, XK_less, + XK_period, XK_greater, /* 60 */ + XK_slash, XK_question, + XK_Shift_R, NoSymbol, + XK_KP_Multiply, NoSymbol, + XK_Alt_L, NoSymbol, + XK_space, NoSymbol, + XK_Caps_Lock, NoSymbol, + XK_F1, NoSymbol, + XK_F2, NoSymbol, + XK_F3, NoSymbol, + XK_F4, NoSymbol, /* 70 */ + XK_F5, NoSymbol, + XK_F6, NoSymbol, + XK_F7, NoSymbol, + XK_F8, NoSymbol, + XK_F9, NoSymbol, + XK_F10, NoSymbol, + XK_Num_Lock, NoSymbol, + XK_Scroll_Lock, NoSymbol, + XK_KP_Home, XK_KP_7, + XK_KP_Up, XK_KP_8, /* 80 */ + XK_KP_Prior, XK_KP_9, + XK_KP_Subtract, NoSymbol, + XK_KP_Left, XK_KP_4, + XK_KP_Begin, XK_KP_5, + XK_KP_Right, XK_KP_6, + XK_KP_Add, NoSymbol, + XK_KP_End, XK_KP_1, + XK_KP_Down, XK_KP_2, + XK_KP_Next, XK_KP_3, + XK_KP_Insert, XK_KP_0, /* 90 */ + XK_KP_Delete, XK_KP_Decimal, + NoSymbol, NoSymbol, + NoSymbol, NoSymbol, + NoSymbol, NoSymbol, + XK_F11, NoSymbol, + XK_F12, NoSymbol, + XK_Home, NoSymbol, + XK_Up, NoSymbol, + XK_Prior, NoSymbol, + XK_Left, NoSymbol, /* 100 */ + XK_Print, NoSymbol, + XK_Right, NoSymbol, + XK_End, NoSymbol, + XK_Down, NoSymbol, + XK_Next, NoSymbol, + XK_Insert, NoSymbol, + XK_Delete, NoSymbol, + XK_KP_Enter, NoSymbol, + XK_Control_R, NoSymbol, + XK_Pause, NoSymbol, /* 110 */ + XK_Print, NoSymbol, + XK_KP_Divide, NoSymbol, + XK_Alt_R, NoSymbol, + NoSymbol, NoSymbol, + XK_Super_L, NoSymbol, + XK_Super_R, NoSymbol, + XK_Menu, NoSymbol, + NoSymbol, NoSymbol, + NoSymbol, NoSymbol, + NoSymbol, NoSymbol, /* 120 */ + NoSymbol, NoSymbol }; #if 0 @@ -242,346 +242,369 @@ static KeySym g_kbdMap[] = static void rdpSendBell(void) { - DEBUG_OUT_INPUT(("rdpSendBell\n")); + DEBUG_OUT_INPUT(("rdpSendBell\n")); } #endif /******************************************************************************/ void -KbdDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8* pModMap) +KbdDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8 *pModMap) { - int i; + int i; - DEBUG_OUT_INPUT(("KbdDeviceInit\n")); - for (i = 0; i < MAP_LENGTH; i++) - { - pModMap[i] = NoSymbol; - } - pModMap[SHIFT_L_KEY_CODE] = ShiftMask; - pModMap[SHIFT_R_KEY_CODE] = ShiftMask; - pModMap[CAPS_LOCK_KEY_CODE] = LockMask; - pModMap[CONTROL_L_KEY_CODE] = ControlMask; - pModMap[CONTROL_R_KEY_CODE] = ControlMask; - pModMap[ALT_L_KEY_CODE] = Mod1Mask; - pModMap[ALT_R_KEY_CODE] = Mod1Mask; - pModMap[NUM_LOCK_KEY_CODE] = Mod2Mask; - pModMap[SUPER_L_KEY_CODE] = Mod4Mask; - pModMap[SUPER_R_KEY_CODE] = Mod4Mask; - pKeySyms->minKeyCode = MIN_KEY_CODE; - pKeySyms->maxKeyCode = MAX_KEY_CODE; - pKeySyms->mapWidth = GLYPHS_PER_KEY; - i = sizeof(KeySym) * MAP_LENGTH * GLYPHS_PER_KEY; - pKeySyms->map = (KeySym*)g_malloc(i, 1); - if (pKeySyms->map == 0) - { - rdpLog("KbdDeviceInit g_malloc failed\n"); - exit(1); - } - for (i = 0; i < MAP_LENGTH * GLYPHS_PER_KEY; i++) - { - pKeySyms->map[i] = NoSymbol; - } - for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++) - { - pKeySyms->map[i] = g_kbdMap[i]; - } + DEBUG_OUT_INPUT(("KbdDeviceInit\n")); + + for (i = 0; i < MAP_LENGTH; i++) + { + pModMap[i] = NoSymbol; + } + + pModMap[SHIFT_L_KEY_CODE] = ShiftMask; + pModMap[SHIFT_R_KEY_CODE] = ShiftMask; + pModMap[CAPS_LOCK_KEY_CODE] = LockMask; + pModMap[CONTROL_L_KEY_CODE] = ControlMask; + pModMap[CONTROL_R_KEY_CODE] = ControlMask; + pModMap[ALT_L_KEY_CODE] = Mod1Mask; + pModMap[ALT_R_KEY_CODE] = Mod1Mask; + pModMap[NUM_LOCK_KEY_CODE] = Mod2Mask; + pModMap[SUPER_L_KEY_CODE] = Mod4Mask; + pModMap[SUPER_R_KEY_CODE] = Mod4Mask; + pKeySyms->minKeyCode = MIN_KEY_CODE; + pKeySyms->maxKeyCode = MAX_KEY_CODE; + pKeySyms->mapWidth = GLYPHS_PER_KEY; + i = sizeof(KeySym) * MAP_LENGTH * GLYPHS_PER_KEY; + pKeySyms->map = (KeySym *)g_malloc(i, 1); + + if (pKeySyms->map == 0) + { + rdpLog("KbdDeviceInit g_malloc failed\n"); + exit(1); + } + + for (i = 0; i < MAP_LENGTH * GLYPHS_PER_KEY; i++) + { + pKeySyms->map[i] = NoSymbol; + } + + for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++) + { + pKeySyms->map[i] = g_kbdMap[i]; + } } /******************************************************************************/ void KbdDeviceOn(void) { - DEBUG_OUT_INPUT(("KbdDeviceOn\n")); + DEBUG_OUT_INPUT(("KbdDeviceOn\n")); } /******************************************************************************/ void KbdDeviceOff(void) { - DEBUG_OUT_INPUT(("KbdDeviceOff\n")); + DEBUG_OUT_INPUT(("KbdDeviceOff\n")); } /******************************************************************************/ void rdpBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls) { - ErrorF("rdpBell:\n"); + ErrorF("rdpBell:\n"); } /******************************************************************************/ void -rdpChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl* ctrl) +rdpChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl) { - ErrorF("rdpChangeKeyboardControl:\n"); + ErrorF("rdpChangeKeyboardControl:\n"); } /******************************************************************************/ int rdpKeybdProc(DeviceIntPtr pDevice, int onoff) { - KeySymsRec keySyms; - CARD8 modMap[MAP_LENGTH]; - DevicePtr pDev; - XkbRMLVOSet set; + KeySymsRec keySyms; + CARD8 modMap[MAP_LENGTH]; + DevicePtr pDev; + XkbRMLVOSet set; - DEBUG_OUT_INPUT(("rdpKeybdProc\n")); - pDev = (DevicePtr)pDevice; - switch (onoff) - { - case DEVICE_INIT: - KbdDeviceInit(pDevice, &keySyms, modMap); - memset(&set, 0, sizeof(set)); - set.rules = "base"; - set.model = "pc104"; - set.layout = "us"; - set.variant = ""; - set.options = ""; - InitKeyboardDeviceStruct(pDevice, &set, rdpBell, - rdpChangeKeyboardControl); - //XkbDDXChangeControls(pDevice, 0, 0); - break; - case DEVICE_ON: - pDev->on = 1; - KbdDeviceOn(); - break; - case DEVICE_OFF: - pDev->on = 0; - KbdDeviceOff(); - break; - case DEVICE_CLOSE: - if (pDev->on) - { - KbdDeviceOff(); - } - break; - } - return Success; + DEBUG_OUT_INPUT(("rdpKeybdProc\n")); + pDev = (DevicePtr)pDevice; + + switch (onoff) + { + case DEVICE_INIT: + KbdDeviceInit(pDevice, &keySyms, modMap); + memset(&set, 0, sizeof(set)); + set.rules = "base"; + set.model = "pc104"; + set.layout = "us"; + set.variant = ""; + set.options = ""; + InitKeyboardDeviceStruct(pDevice, &set, rdpBell, + rdpChangeKeyboardControl); + //XkbDDXChangeControls(pDevice, 0, 0); + break; + case DEVICE_ON: + pDev->on = 1; + KbdDeviceOn(); + break; + case DEVICE_OFF: + pDev->on = 0; + KbdDeviceOff(); + break; + case DEVICE_CLOSE: + + if (pDev->on) + { + KbdDeviceOff(); + } + + break; + } + + return Success; } /******************************************************************************/ void -PtrDeviceControl(DeviceIntPtr dev, PtrCtrl* ctrl) +PtrDeviceControl(DeviceIntPtr dev, PtrCtrl *ctrl) { - DEBUG_OUT_INPUT(("PtrDeviceControl\n")); + DEBUG_OUT_INPUT(("PtrDeviceControl\n")); } /******************************************************************************/ void PtrDeviceInit(void) { - DEBUG_OUT_INPUT(("PtrDeviceInit\n")); + DEBUG_OUT_INPUT(("PtrDeviceInit\n")); } /******************************************************************************/ void PtrDeviceOn(DeviceIntPtr pDev) { - DEBUG_OUT_INPUT(("PtrDeviceOn\n")); + DEBUG_OUT_INPUT(("PtrDeviceOn\n")); } /******************************************************************************/ void PtrDeviceOff(void) { - DEBUG_OUT_INPUT(("PtrDeviceOff\n")); + DEBUG_OUT_INPUT(("PtrDeviceOff\n")); } /******************************************************************************/ static void -rdpMouseCtrl(DeviceIntPtr pDevice, PtrCtrl* pCtrl) +rdpMouseCtrl(DeviceIntPtr pDevice, PtrCtrl *pCtrl) { - ErrorF("rdpMouseCtrl:\n"); + ErrorF("rdpMouseCtrl:\n"); } /******************************************************************************/ int rdpMouseProc(DeviceIntPtr pDevice, int onoff) { - BYTE map[6]; - DevicePtr pDev; - Atom btn_labels[6]; - Atom axes_labels[2]; + BYTE map[6]; + DevicePtr pDev; + Atom btn_labels[6]; + Atom axes_labels[2]; - DEBUG_OUT_INPUT(("rdpMouseProc\n")); - pDev = (DevicePtr)pDevice; - switch (onoff) - { - case DEVICE_INIT: - PtrDeviceInit(); - map[0] = 0; - map[1] = 1; - map[2] = 2; - map[3] = 3; - map[4] = 4; - map[5] = 5; + DEBUG_OUT_INPUT(("rdpMouseProc\n")); + pDev = (DevicePtr)pDevice; - btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); - btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); - btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); - btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); - btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); + switch (onoff) + { + case DEVICE_INIT: + PtrDeviceInit(); + map[0] = 0; + map[1] = 1; + map[2] = 2; + map[3] = 3; + map[4] = 4; + map[5] = 5; - axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); - axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); - InitPointerDeviceStruct(pDev, map, 5, btn_labels, rdpMouseCtrl, - GetMotionHistorySize(), 2, axes_labels); + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); - break; - case DEVICE_ON: - pDev->on = 1; - PtrDeviceOn(pDevice); - break; - case DEVICE_OFF: - pDev->on = 0; - PtrDeviceOff(); - break; - case DEVICE_CLOSE: - if (pDev->on) - { - PtrDeviceOff(); - } - break; - } - return Success; + InitPointerDeviceStruct(pDev, map, 5, btn_labels, rdpMouseCtrl, + GetMotionHistorySize(), 2, axes_labels); + + break; + case DEVICE_ON: + pDev->on = 1; + PtrDeviceOn(pDevice); + break; + case DEVICE_OFF: + pDev->on = 0; + PtrDeviceOff(); + break; + case DEVICE_CLOSE: + + if (pDev->on) + { + PtrDeviceOff(); + } + + break; + } + + return Success; } /******************************************************************************/ Bool -rdpCursorOffScreen(ScreenPtr* ppScreen, int* x, int* y) +rdpCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) { - DEBUG_OUT_INPUT(("rdpCursorOffScreen\n")); - return 0; + DEBUG_OUT_INPUT(("rdpCursorOffScreen\n")); + return 0; } /******************************************************************************/ void rdpCrossScreen(ScreenPtr pScreen, Bool entering) { - DEBUG_OUT_INPUT(("rdpCrossScreen\n")); + DEBUG_OUT_INPUT(("rdpCrossScreen\n")); } /******************************************************************************/ void rdpPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y) { - ErrorF("rdpPointerWarpCursor:\n"); - miPointerWarpCursor(pDev, pScr, x, y); + ErrorF("rdpPointerWarpCursor:\n"); + miPointerWarpCursor(pDev, pScr, x, y); } /******************************************************************************/ void -rdpPointerEnqueueEvent(DeviceIntPtr pDev, InternalEvent* event) +rdpPointerEnqueueEvent(DeviceIntPtr pDev, InternalEvent *event) { - ErrorF("rdpPointerEnqueueEvent:\n"); + ErrorF("rdpPointerEnqueueEvent:\n"); } /******************************************************************************/ void rdpPointerNewEventScreen(DeviceIntPtr pDev, ScreenPtr pScr, Bool fromDIX) { - ErrorF("rdpPointerNewEventScreen:\n"); + ErrorF("rdpPointerNewEventScreen:\n"); } /******************************************************************************/ Bool rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs) { - DEBUG_OUT_INPUT(("rdpSpriteRealizeCursor\n")); - return 1; + DEBUG_OUT_INPUT(("rdpSpriteRealizeCursor\n")); + return 1; } /******************************************************************************/ Bool rdpSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs) { - DEBUG_OUT_INPUT(("hi rdpSpriteUnrealizeCursor\n")); - return 1; + DEBUG_OUT_INPUT(("hi rdpSpriteUnrealizeCursor\n")); + return 1; } /******************************************************************************/ int -get_pixel_safe(char* data, int x, int y, int width, int height, int bpp) +get_pixel_safe(char *data, int x, int y, int width, int height, int bpp) { - int start; - int shift; - int c; + int start; + int shift; + int c; - if (x < 0) - { - return 0; - } - if (y < 0) - { - return 0; - } - if (x >= width) - { - return 0; - } - if (y >= height) - { - return 0; - } - if (bpp == 1) - { - width = (width + 7) / 8; - start = (y * width) + x / 8; - shift = x % 8; - c = (unsigned char)(data[start]); + if (x < 0) + { + return 0; + } + + if (y < 0) + { + return 0; + } + + if (x >= width) + { + return 0; + } + + if (y >= height) + { + return 0; + } + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + c = (unsigned char)(data[start]); #if (X_BYTE_ORDER == X_LITTLE_ENDIAN) - return (g_reverse_byte[c] & (0x80 >> shift)) != 0; + return (g_reverse_byte[c] & (0x80 >> shift)) != 0; #else - return (c & (0x80 >> shift)) != 0; + return (c & (0x80 >> shift)) != 0; #endif - } - return 0; + } + + return 0; } /******************************************************************************/ void -set_pixel_safe(char* data, int x, int y, int width, int height, int bpp, +set_pixel_safe(char *data, int x, int y, int width, int height, int bpp, int pixel) { - int start; - int shift; + int start; + int shift; - if (x < 0) - { - return; - } - if (y < 0) - { - return; - } - if (x >= width) - { - return; - } - if (y >= height) - { - return; - } - if (bpp == 1) - { - width = (width + 7) / 8; - start = (y * width) + x / 8; - shift = x % 8; - if (pixel & 1) + if (x < 0) { - data[start] = data[start] | (0x80 >> shift); + return; } - else + + if (y < 0) { - data[start] = data[start] & ~(0x80 >> shift); + return; + } + + if (x >= width) + { + return; + } + + if (y >= height) + { + return; + } + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + + if (pixel & 1) + { + data[start] = data[start] | (0x80 >> shift); + } + else + { + data[start] = data[start] & ~(0x80 >> shift); + } + } + else if (bpp == 24) + { + *(data + (3 * (y * width + x)) + 0) = pixel >> 0; + *(data + (3 * (y * width + x)) + 1) = pixel >> 8; + *(data + (3 * (y * width + x)) + 2) = pixel >> 16; } - } - else if (bpp == 24) - { - *(data + (3 * (y * width + x)) + 0) = pixel >> 0; - *(data + (3 * (y * width + x)) + 1) = pixel >> 8; - *(data + (3 * (y * width + x)) + 2) = pixel >> 16; - } } /******************************************************************************/ @@ -589,217 +612,231 @@ void rdpSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs, int x, int y) { - char cur_data[32 * (32 * 3)]; - char cur_mask[32 * (32 / 8)]; - char* mask; - char* data; - int i; - int j; - int w; - int h; - int p; - int xhot; - int yhot; - int paddedRowBytes; - int fgcolor; - int bgcolor; + char cur_data[32 * (32 * 3)]; + char cur_mask[32 * (32 / 8)]; + char *mask; + char *data; + int i; + int j; + int w; + int h; + int p; + int xhot; + int yhot; + int paddedRowBytes; + int fgcolor; + int bgcolor; - if (pCurs == 0) - { - return; - } - if (pCurs->bits == 0) - { - return; - } - w = pCurs->bits->width; - h = pCurs->bits->height; - paddedRowBytes = PixmapBytePad(w, 1); - xhot = pCurs->bits->xhot; - yhot = pCurs->bits->yhot; - /* ErrorF("xhot %d yhot %d\n", xhot, yhot); */ - data = (char*)(pCurs->bits->source); - mask = (char*)(pCurs->bits->mask); - fgcolor = (((pCurs->foreRed >> 8) & 0xff) << 16) | - (((pCurs->foreGreen >> 8) & 0xff) << 8) | - ((pCurs->foreBlue >> 8) & 0xff); - bgcolor = (((pCurs->backRed >> 8) & 0xff) << 16) | - (((pCurs->backGreen >> 8) & 0xff) << 8) | - ((pCurs->backBlue >> 8) & 0xff); - memset(cur_data, 0, sizeof(cur_data)); - memset(cur_mask, 0, sizeof(cur_mask)); - for (j = 0; j < 32; j++) - { - for (i = 0; i < 32; i++) + if (pCurs == 0) { - p = get_pixel_safe(mask, i, j, paddedRowBytes * 8, h, 1); - set_pixel_safe(cur_mask, i, 31 - j, 32, 32, 1, !p); - if (p != 0) - { - p = get_pixel_safe(data, i, j, paddedRowBytes * 8, h, 1); - p = p ? fgcolor : bgcolor; - set_pixel_safe(cur_data, i, 31 - j, 32, 32, 24, p); - } + return; } - } - rdpup_begin_update(); - rdpup_set_cursor(xhot, yhot, cur_data, cur_mask); - rdpup_end_update(); + + if (pCurs->bits == 0) + { + return; + } + + w = pCurs->bits->width; + h = pCurs->bits->height; + paddedRowBytes = PixmapBytePad(w, 1); + xhot = pCurs->bits->xhot; + yhot = pCurs->bits->yhot; + /* ErrorF("xhot %d yhot %d\n", xhot, yhot); */ + data = (char *)(pCurs->bits->source); + mask = (char *)(pCurs->bits->mask); + fgcolor = (((pCurs->foreRed >> 8) & 0xff) << 16) | + (((pCurs->foreGreen >> 8) & 0xff) << 8) | + ((pCurs->foreBlue >> 8) & 0xff); + bgcolor = (((pCurs->backRed >> 8) & 0xff) << 16) | + (((pCurs->backGreen >> 8) & 0xff) << 8) | + ((pCurs->backBlue >> 8) & 0xff); + memset(cur_data, 0, sizeof(cur_data)); + memset(cur_mask, 0, sizeof(cur_mask)); + + for (j = 0; j < 32; j++) + { + for (i = 0; i < 32; i++) + { + p = get_pixel_safe(mask, i, j, paddedRowBytes * 8, h, 1); + set_pixel_safe(cur_mask, i, 31 - j, 32, 32, 1, !p); + + if (p != 0) + { + p = get_pixel_safe(data, i, j, paddedRowBytes * 8, h, 1); + p = p ? fgcolor : bgcolor; + set_pixel_safe(cur_data, i, 31 - j, 32, 32, 24, p); + } + } + } + + rdpup_begin_update(); + rdpup_set_cursor(xhot, yhot, cur_data, cur_mask); + rdpup_end_update(); } /******************************************************************************/ void rdpSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y) { - DEBUG_OUT_INPUT(("hi rdpSpriteMoveCursor\n")); + DEBUG_OUT_INPUT(("hi rdpSpriteMoveCursor\n")); } /******************************************************************************/ Bool rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr) { - ErrorF("rdpSpriteDeviceCursorInitialize:\n"); - return 1; + ErrorF("rdpSpriteDeviceCursorInitialize:\n"); + return 1; } /******************************************************************************/ void rdpSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr) { - ErrorF("rdpSpriteDeviceCursorCleanup:\n"); + ErrorF("rdpSpriteDeviceCursorCleanup:\n"); } /******************************************************************************/ static void rdpEnqueueMotion(int x, int y) { - int i; - int n; - int valuators[2]; - EventListPtr rdp_events; - xEvent* pev; + int i; + int n; + int valuators[2]; + EventListPtr rdp_events; + xEvent *pev; # if 0 - if (x < 128) - { - rdpup_begin_update(); - rdpup_send_area(0, 0, 1024, 768); - rdpup_end_update(); - } -#endif - miPointerSetPosition(g_pointer, &x, &y); - valuators[0] = x; - valuators[1] = y; - GetEventList(&rdp_events); - n = GetPointerEvents(rdp_events, g_pointer, MotionNotify, 0, - POINTER_ABSOLUTE | POINTER_SCREEN, - 0, 2, valuators); - for (i = 0; i < n; i++) - { - pev = (rdp_events + i)->event; - mieqEnqueue(g_pointer, (InternalEvent*)pev); - } + if (x < 128) + { + rdpup_begin_update(); + rdpup_send_area(0, 0, 1024, 768); + rdpup_end_update(); + } + +#endif + miPointerSetPosition(g_pointer, &x, &y); + valuators[0] = x; + valuators[1] = y; + + GetEventList(&rdp_events); + n = GetPointerEvents(rdp_events, g_pointer, MotionNotify, 0, + POINTER_ABSOLUTE | POINTER_SCREEN, + 0, 2, valuators); + + for (i = 0; i < n; i++) + { + pev = (rdp_events + i)->event; + mieqEnqueue(g_pointer, (InternalEvent *)pev); + } } /******************************************************************************/ static void rdpEnqueueButton(int type, int buttons) { - int i; - int n; - EventListPtr rdp_events; - xEvent* pev; + int i; + int n; + EventListPtr rdp_events; + xEvent *pev; - i = GetEventList(&rdp_events); - n = GetPointerEvents(rdp_events, g_pointer, type, buttons, 0, 0, 0, 0); - for (i = 0; i < n; i++) - { - pev = (rdp_events + i)->event; - mieqEnqueue(g_pointer, (InternalEvent*)pev); - } + i = GetEventList(&rdp_events); + n = GetPointerEvents(rdp_events, g_pointer, type, buttons, 0, 0, 0, 0); + + for (i = 0; i < n; i++) + { + pev = (rdp_events + i)->event; + mieqEnqueue(g_pointer, (InternalEvent *)pev); + } } /******************************************************************************/ static void rdpEnqueueKey(int type, int scancode) { - int i; - int n; - EventListPtr rdp_events; - xEvent* pev; + int i; + int n; + EventListPtr rdp_events; + xEvent *pev; - i = GetEventList(&rdp_events); - n = GetKeyboardEvents(rdp_events, g_keyboard, type, scancode); - for (i = 0; i < n; i++) - { - pev = (rdp_events + i)->event; - mieqEnqueue(g_keyboard, (InternalEvent*)pev); - } + i = GetEventList(&rdp_events); + n = GetKeyboardEvents(rdp_events, g_keyboard, type, scancode); + + for (i = 0; i < n; i++) + { + pev = (rdp_events + i)->event; + mieqEnqueue(g_keyboard, (InternalEvent *)pev); + } } /******************************************************************************/ void PtrAddEvent(int buttonMask, int x, int y) { - int i; - int type; - int buttons; + int i; + int type; + int buttons; - rdpEnqueueMotion(x, y); - for (i = 0; i < 5; i++) - { - if ((buttonMask ^ g_old_button_mask) & (1 << i)) + rdpEnqueueMotion(x, y); + + for (i = 0; i < 5; i++) { - if (buttonMask & (1 << i)) - { - type = ButtonPress; - buttons = i + 1; - rdpEnqueueButton(type, buttons); - } - else - { - type = ButtonRelease; - buttons = i + 1; - rdpEnqueueButton(type, buttons); - } + if ((buttonMask ^ g_old_button_mask) & (1 << i)) + { + if (buttonMask & (1 << i)) + { + type = ButtonPress; + buttons = i + 1; + rdpEnqueueButton(type, buttons); + } + else + { + type = ButtonRelease; + buttons = i + 1; + rdpEnqueueButton(type, buttons); + } + } } - } - g_old_button_mask = buttonMask; + + g_old_button_mask = buttonMask; } /******************************************************************************/ void check_keysa(void) { - if (g_ctrl_down != 0) - { - rdpEnqueueKey(KeyRelease, g_ctrl_down); - g_ctrl_down = 0; - } - if (g_alt_down != 0) - { - rdpEnqueueKey(KeyRelease, g_alt_down); - g_alt_down = 0; - } - if (g_shift_down != 0) - { - rdpEnqueueKey(KeyRelease, g_shift_down); - g_shift_down = 0; - } + if (g_ctrl_down != 0) + { + rdpEnqueueKey(KeyRelease, g_ctrl_down); + g_ctrl_down = 0; + } + + if (g_alt_down != 0) + { + rdpEnqueueKey(KeyRelease, g_alt_down); + g_alt_down = 0; + } + + if (g_shift_down != 0) + { + rdpEnqueueKey(KeyRelease, g_shift_down); + g_shift_down = 0; + } } /******************************************************************************/ void sendDownUpKeyEvent(int type, int x_scancode) { - /* if type is keydown, send keydown + keyup */ - /* this allows us to ignore keyup events */ - if (type == KeyPress) - { - rdpEnqueueKey(KeyPress, x_scancode); - rdpEnqueueKey(KeyRelease, x_scancode); - } + /* if type is keydown, send keydown + keyup */ + /* this allows us to ignore keyup events */ + if (type == KeyPress) + { + rdpEnqueueKey(KeyPress, x_scancode); + rdpEnqueueKey(KeyRelease, x_scancode); + } } /** @@ -812,182 +849,192 @@ sendDownUpKeyEvent(int type, int x_scancode) void KbdAddEvent(int down, int param1, int param2, int param3, int param4) { - int rdp_scancode; - int x_scancode; - int is_ext; - int is_spe; - int type; + int rdp_scancode; + int x_scancode; + int is_ext; + int is_spe; + int type; #if 0 - fprintf(stderr, "down=0x%x param1=0x%x param2=0x%x param3=0x%x " - "param4=0x%x\n", down, param1, param2, param3, param4); + fprintf(stderr, "down=0x%x param1=0x%x param2=0x%x param3=0x%x " + "param4=0x%x\n", down, param1, param2, param3, param4); #endif - type = down ? KeyPress : KeyRelease; - rdp_scancode = param3; - is_ext = param4 & 256; /* 0x100 */ - is_spe = param4 & 512; /* 0x200 */ - x_scancode = 0; + type = down ? KeyPress : KeyRelease; + rdp_scancode = param3; + is_ext = param4 & 256; /* 0x100 */ + is_spe = param4 & 512; /* 0x200 */ + x_scancode = 0; - switch (rdp_scancode) - { - case 58: /* caps lock */ - case 42: /* left shift */ - case 54: /* right shift */ - case 70: /* scroll lock */ - x_scancode = rdp_scancode + MIN_KEY_CODE; - if (x_scancode > 0) - { - rdpEnqueueKey(type, x_scancode); - } + switch (rdp_scancode) + { + case 58: /* caps lock */ + case 42: /* left shift */ + case 54: /* right shift */ + case 70: /* scroll lock */ + x_scancode = rdp_scancode + MIN_KEY_CODE; - break; + if (x_scancode > 0) + { + rdpEnqueueKey(type, x_scancode); + } - case 56: /* left - right alt button */ - if (is_ext) - { - x_scancode = 113; /* right alt button */ - } - else - { - x_scancode = 64; /* left alt button */ - } + break; - rdpEnqueueKey(type, x_scancode); - break; + case 56: /* left - right alt button */ - case 15: /* tab */ - if (!down && !g_tab_down) - { - check_keysa(); /* leave x_scancode 0 here, we don't want the tab key up */ - } - else - { - sendDownUpKeyEvent(type, 23); - } + if (is_ext) + { + x_scancode = 113; /* right alt button */ + } + else + { + x_scancode = 64; /* left alt button */ + } - g_tab_down = down; - break; + rdpEnqueueKey(type, x_scancode); + break; - case 29: /* left or right ctrl */ - /* this is to handle special case with pause key sending control first */ - if (is_spe) - { - if (down) - { - g_pause_spe = 1; - /* leave x_scancode 0 here, we don't want the control key down */ - } - } - else - { - x_scancode = is_ext ? 109 : 37; - g_ctrl_down = down ? x_scancode : 0; - rdpEnqueueKey(type, x_scancode); - } - break; + case 15: /* tab */ - case 69: /* Pause or Num Lock */ - if (g_pause_spe) - { - x_scancode = 110; - if (!down) - { - g_pause_spe = 0; - } - } - else - { - x_scancode = g_ctrl_down ? 110 : 77; - } - sendDownUpKeyEvent(type, x_scancode); - break; + if (!down && !g_tab_down) + { + check_keysa(); /* leave x_scancode 0 here, we don't want the tab key up */ + } + else + { + sendDownUpKeyEvent(type, 23); + } - case 28: /* Enter or Return */ - x_scancode = is_ext ? 108 : 36; - sendDownUpKeyEvent(type, x_scancode); - break; + g_tab_down = down; + break; - case 53: /* / */ - x_scancode = is_ext ? 112 : 61; - sendDownUpKeyEvent(type, x_scancode); - break; + case 29: /* left or right ctrl */ - case 55: /* * on KP or Print Screen */ - x_scancode = is_ext ? 111 : 63; - sendDownUpKeyEvent(type, x_scancode); - break; + /* this is to handle special case with pause key sending control first */ + if (is_spe) + { + if (down) + { + g_pause_spe = 1; + /* leave x_scancode 0 here, we don't want the control key down */ + } + } + else + { + x_scancode = is_ext ? 109 : 37; + g_ctrl_down = down ? x_scancode : 0; + rdpEnqueueKey(type, x_scancode); + } - case 71: /* 7 or Home */ - x_scancode = is_ext ? 97 : 79; - sendDownUpKeyEvent(type, x_scancode); - break; + break; - case 72: /* 8 or Up */ - x_scancode = is_ext ? 98 : 80; - sendDownUpKeyEvent(type, x_scancode); - break; + case 69: /* Pause or Num Lock */ - case 73: /* 9 or PgUp */ - x_scancode = is_ext ? 99 : 81; - sendDownUpKeyEvent(type, x_scancode); - break; + if (g_pause_spe) + { + x_scancode = 110; - case 75: /* 4 or Left */ - x_scancode = is_ext ? 100 : 83; - sendDownUpKeyEvent(type, x_scancode); - break; + if (!down) + { + g_pause_spe = 0; + } + } + else + { + x_scancode = g_ctrl_down ? 110 : 77; + } - case 77: /* 6 or Right */ - x_scancode = is_ext ? 102 : 85; - sendDownUpKeyEvent(type, x_scancode); - break; + sendDownUpKeyEvent(type, x_scancode); + break; - case 79: /* 1 or End */ - x_scancode = is_ext ? 103 : 87; - sendDownUpKeyEvent(type, x_scancode); - break; + case 28: /* Enter or Return */ + x_scancode = is_ext ? 108 : 36; + sendDownUpKeyEvent(type, x_scancode); + break; - case 80: /* 2 or Down */ - x_scancode = is_ext ? 104 : 88; - sendDownUpKeyEvent(type, x_scancode); - break; + case 53: /* / */ + x_scancode = is_ext ? 112 : 61; + sendDownUpKeyEvent(type, x_scancode); + break; - case 81: /* 3 or PgDn */ - x_scancode = is_ext ? 105 : 89; - sendDownUpKeyEvent(type, x_scancode); - break; + case 55: /* * on KP or Print Screen */ + x_scancode = is_ext ? 111 : 63; + sendDownUpKeyEvent(type, x_scancode); + break; - case 82: /* 0 or Insert */ - x_scancode = is_ext ? 106 : 90; - sendDownUpKeyEvent(type, x_scancode); - break; + case 71: /* 7 or Home */ + x_scancode = is_ext ? 97 : 79; + sendDownUpKeyEvent(type, x_scancode); + break; - case 83: /* . or Delete */ - x_scancode = is_ext ? 107 : 91; - sendDownUpKeyEvent(type, x_scancode); - break; + case 72: /* 8 or Up */ + x_scancode = is_ext ? 98 : 80; + sendDownUpKeyEvent(type, x_scancode); + break; - case 91: /* left win key */ - rdpEnqueueKey(type, 115); - break; + case 73: /* 9 or PgUp */ + x_scancode = is_ext ? 99 : 81; + sendDownUpKeyEvent(type, x_scancode); + break; - case 92: /* right win key */ - rdpEnqueueKey(type, 116); - break; + case 75: /* 4 or Left */ + x_scancode = is_ext ? 100 : 83; + sendDownUpKeyEvent(type, x_scancode); + break; - case 93: /* menu key */ - rdpEnqueueKey(type, 117); - break; + case 77: /* 6 or Right */ + x_scancode = is_ext ? 102 : 85; + sendDownUpKeyEvent(type, x_scancode); + break; - default: - x_scancode = rdp_scancode + MIN_KEY_CODE; - if (x_scancode > 0) - { - sendDownUpKeyEvent(type, x_scancode); - } - break; - } + case 79: /* 1 or End */ + x_scancode = is_ext ? 103 : 87; + sendDownUpKeyEvent(type, x_scancode); + break; + + case 80: /* 2 or Down */ + x_scancode = is_ext ? 104 : 88; + sendDownUpKeyEvent(type, x_scancode); + break; + + case 81: /* 3 or PgDn */ + x_scancode = is_ext ? 105 : 89; + sendDownUpKeyEvent(type, x_scancode); + break; + + case 82: /* 0 or Insert */ + x_scancode = is_ext ? 106 : 90; + sendDownUpKeyEvent(type, x_scancode); + break; + + case 83: /* . or Delete */ + x_scancode = is_ext ? 107 : 91; + sendDownUpKeyEvent(type, x_scancode); + break; + + case 91: /* left win key */ + rdpEnqueueKey(type, 115); + break; + + case 92: /* right win key */ + rdpEnqueueKey(type, 116); + break; + + case 93: /* menu key */ + rdpEnqueueKey(type, 117); + break; + + default: + x_scancode = rdp_scancode + MIN_KEY_CODE; + + if (x_scancode > 0) + { + sendDownUpKeyEvent(type, x_scancode); + } + + break; + } } /******************************************************************************/ @@ -997,26 +1044,28 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4) void KbdSync(int param1) { - int xkb_state; + int xkb_state; - xkb_state = XkbStateFieldFromRec(&(g_keyboard->key->xkbInfo->state)); - if ((!(xkb_state & 0x02)) != (!(param1 & 4))) /* caps lock */ - { - ErrorF("KbdSync: toggling caps lock\n"); - KbdAddEvent(1, 58, 0, 58, 0); - KbdAddEvent(0, 58, 49152, 58, 49152); - } + xkb_state = XkbStateFieldFromRec(&(g_keyboard->key->xkbInfo->state)); - if ((!(xkb_state & 0x10)) != (!(param1 & 2))) /* num lock */ - { - ErrorF("KbdSync: toggling num lock\n"); - KbdAddEvent(1, 69, 0, 69, 0); - KbdAddEvent(0, 69, 49152, 69, 49152); - } - if ((!(g_scroll_lock_down)) != (!(param1 & 1))) /* scroll lock */ - { - ErrorF("KbdSync: toggling scroll lock\n"); - KbdAddEvent(1, 70, 0, 70, 0); - KbdAddEvent(0, 70, 49152, 70, 49152); - } + if ((!(xkb_state & 0x02)) != (!(param1 & 4))) /* caps lock */ + { + ErrorF("KbdSync: toggling caps lock\n"); + KbdAddEvent(1, 58, 0, 58, 0); + KbdAddEvent(0, 58, 49152, 58, 49152); + } + + if ((!(xkb_state & 0x10)) != (!(param1 & 2))) /* num lock */ + { + ErrorF("KbdSync: toggling num lock\n"); + KbdAddEvent(1, 69, 0, 69, 0); + KbdAddEvent(0, 69, 49152, 69, 49152); + } + + if ((!(g_scroll_lock_down)) != (!(param1 & 1))) /* scroll lock */ + { + ErrorF("KbdSync: toggling scroll lock\n"); + KbdAddEvent(1, 70, 0, 70, 0); + KbdAddEvent(0, 70, 49152, 70, 49152); + } } diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c index 48f5a2e9..6a88b0e0 100644 --- a/xorg/X11R7.6/rdp/rdpmain.c +++ b/xorg/X11R7.6/rdp/rdpmain.c @@ -69,33 +69,33 @@ static int g_initOutputCalled = 0; /* Common pixmap formats */ static PixmapFormatRec g_formats[MAXFORMATS] = { - { 1, 1, BITMAP_SCANLINE_PAD }, - { 4, 8, BITMAP_SCANLINE_PAD }, - { 8, 8, BITMAP_SCANLINE_PAD }, - { 15, 16, BITMAP_SCANLINE_PAD }, - { 16, 16, BITMAP_SCANLINE_PAD }, - { 24, 32, BITMAP_SCANLINE_PAD }, - { 32, 32, BITMAP_SCANLINE_PAD }, + { 1, 1, BITMAP_SCANLINE_PAD }, + { 4, 8, BITMAP_SCANLINE_PAD }, + { 8, 8, BITMAP_SCANLINE_PAD }, + { 15, 16, BITMAP_SCANLINE_PAD }, + { 16, 16, BITMAP_SCANLINE_PAD }, + { 24, 32, BITMAP_SCANLINE_PAD }, + { 32, 32, BITMAP_SCANLINE_PAD }, }; static int g_numFormats = 7; static miPointerSpriteFuncRec g_rdpSpritePointerFuncs = { - /* these are in rdpinput.c */ - rdpSpriteRealizeCursor, - rdpSpriteUnrealizeCursor, - rdpSpriteSetCursor, - rdpSpriteMoveCursor, - rdpSpriteDeviceCursorInitialize, - rdpSpriteDeviceCursorCleanup + /* these are in rdpinput.c */ + rdpSpriteRealizeCursor, + rdpSpriteUnrealizeCursor, + rdpSpriteSetCursor, + rdpSpriteMoveCursor, + rdpSpriteDeviceCursorInitialize, + rdpSpriteDeviceCursorCleanup }; static miPointerScreenFuncRec g_rdpPointerCursorFuncs = { - /* these are in rdpinput.c */ - rdpCursorOffScreen, - rdpCrossScreen, - rdpPointerWarpCursor, - rdpPointerEnqueueEvent, - rdpPointerNewEventScreen + /* these are in rdpinput.c */ + rdpCursorOffScreen, + rdpCrossScreen, + rdpPointerWarpCursor, + rdpPointerEnqueueEvent, + rdpPointerNewEventScreen }; /******************************************************************************/ @@ -103,55 +103,57 @@ static miPointerScreenFuncRec g_rdpPointerCursorFuncs = static int set_bpp(int bpp) { - int rv; + int rv; - rv = 0; - g_bpp = bpp; - if (g_bpp == 8) - { - g_Bpp = 1; - g_Bpp_mask = 0xff; - g_redBits = 3; - g_greenBits = 3; - g_blueBits = 2; - } - else if (g_bpp == 15) - { - g_Bpp = 2; - g_Bpp_mask = 0x7fff; - g_redBits = 5; - g_greenBits = 5; - g_blueBits = 5; - } - else if (g_bpp == 16) - { - g_Bpp = 2; - g_Bpp_mask = 0xffff; - g_redBits = 5; - g_greenBits = 6; - g_blueBits = 5; - } - else if (g_bpp == 24) - { - g_Bpp = 4; - g_Bpp_mask = 0xffffff; - g_redBits = 8; - g_greenBits = 8; - g_blueBits = 8; - } - else if (g_bpp == 32) - { - g_Bpp = 4; - g_Bpp_mask = 0xffffff; - g_redBits = 8; - g_greenBits = 8; - g_blueBits = 8; - } - else - { - rv = 1; - } - return rv; + rv = 0; + g_bpp = bpp; + + if (g_bpp == 8) + { + g_Bpp = 1; + g_Bpp_mask = 0xff; + g_redBits = 3; + g_greenBits = 3; + g_blueBits = 2; + } + else if (g_bpp == 15) + { + g_Bpp = 2; + g_Bpp_mask = 0x7fff; + g_redBits = 5; + g_greenBits = 5; + g_blueBits = 5; + } + else if (g_bpp == 16) + { + g_Bpp = 2; + g_Bpp_mask = 0xffff; + g_redBits = 5; + g_greenBits = 6; + g_blueBits = 5; + } + else if (g_bpp == 24) + { + g_Bpp = 4; + g_Bpp_mask = 0xffffff; + g_redBits = 8; + g_greenBits = 8; + g_blueBits = 8; + } + else if (g_bpp == 32) + { + g_Bpp = 4; + g_Bpp_mask = 0xffffff; + g_redBits = 8; + g_greenBits = 8; + g_blueBits = 8; + } + else + { + rv = 1; + } + + return rv; } /******************************************************************************/ @@ -159,9 +161,9 @@ static void rdpWakeupHandler(int i, pointer blockData, unsigned long err, pointer pReadmask) { - g_pScreen->WakeupHandler = g_rdpScreen.WakeupHandler; - g_pScreen->WakeupHandler(i, blockData, err, pReadmask); - g_pScreen->WakeupHandler = rdpWakeupHandler; + g_pScreen->WakeupHandler = g_rdpScreen.WakeupHandler; + g_pScreen->WakeupHandler(i, blockData, err, pReadmask); + g_pScreen->WakeupHandler = rdpWakeupHandler; } /******************************************************************************/ @@ -174,7 +176,7 @@ rdpBlockHandler1(pointer blockData, OSTimePtr pTimeout, pointer pReadmask) static void rdpWakeupHandler1(pointer blockData, int result, pointer pReadmask) { - rdpup_check(); + rdpup_check(); } #if 0 @@ -182,15 +184,15 @@ rdpWakeupHandler1(pointer blockData, int result, pointer pReadmask) static Bool rdpDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) { - ErrorF("rdpDeviceCursorInitializeProcPtr:\n"); - return 1; + ErrorF("rdpDeviceCursorInitializeProcPtr:\n"); + return 1; } /******************************************************************************/ static void rdpDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) { - ErrorF("rdpDeviceCursorCleanupProcPtr:\n"); + ErrorF("rdpDeviceCursorCleanupProcPtr:\n"); } #endif @@ -199,301 +201,327 @@ rdpDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) Bool rdpCreateColormap(ColormapPtr pCmap) { - ErrorF("rdpCreateColormap:\n"); - return 1; + ErrorF("rdpCreateColormap:\n"); + return 1; } /******************************************************************************/ static void rdpDestroyColormap(ColormapPtr pColormap) { - ErrorF("rdpDestroyColormap:\n"); + ErrorF("rdpDestroyColormap:\n"); } #endif /******************************************************************************/ /* returns boolean, true if everything is ok */ static Bool -rdpScreenInit(int index, ScreenPtr pScreen, int argc, char** argv) +rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) { - int dpix; - int dpiy; - int ret; - Bool vis_found; - VisualPtr vis; - PictureScreenPtr ps; - rrScrPrivPtr pRRScrPriv; + int dpix; + int dpiy; + int ret; + Bool vis_found; + VisualPtr vis; + PictureScreenPtr ps; + rrScrPrivPtr pRRScrPriv; - g_pScreen = pScreen; + g_pScreen = pScreen; - /*dpix = 75; - dpiy = 75;*/ - dpix = PixelDPI; - dpiy = PixelDPI; - if (monitorResolution != 0) - { - dpix = monitorResolution; - dpiy = monitorResolution; - } - g_rdpScreen.paddedWidthInBytes = PixmapBytePad(g_rdpScreen.width, - g_rdpScreen.depth); - g_rdpScreen.bitsPerPixel = rdpBitsPerPixel(g_rdpScreen.depth); - ErrorF("\n"); - ErrorF("X11rdp, an X server for xrdp\n"); - ErrorF("Version %s\n", X11RDPVER); - ErrorF("Copyright (C) 2005-2012 Jay Sorg\n"); - ErrorF("See http://xrdp.sf.net for information on xrdp.\n"); + /*dpix = 75; + dpiy = 75;*/ + dpix = PixelDPI; + dpiy = PixelDPI; + + if (monitorResolution != 0) + { + dpix = monitorResolution; + dpiy = monitorResolution; + } + + g_rdpScreen.paddedWidthInBytes = PixmapBytePad(g_rdpScreen.width, + g_rdpScreen.depth); + g_rdpScreen.bitsPerPixel = rdpBitsPerPixel(g_rdpScreen.depth); + ErrorF("\n"); + ErrorF("X11rdp, an X server for xrdp\n"); + ErrorF("Version %s\n", X11RDPVER); + ErrorF("Copyright (C) 2005-2012 Jay Sorg\n"); + ErrorF("See http://xrdp.sf.net for information on xrdp.\n"); #if defined(XORG_VERSION_CURRENT) && defined (XVENDORNAME) - ErrorF("Underlying X server release %d, %s\n", - XORG_VERSION_CURRENT, XVENDORNAME); + ErrorF("Underlying X server release %d, %s\n", + XORG_VERSION_CURRENT, XVENDORNAME); #endif #if defined(XORG_RELEASE) - ErrorF("Xorg %s\n", XORG_RELEASE); + ErrorF("Xorg %s\n", XORG_RELEASE); #endif - ErrorF("Screen width %d height %d depth %d bpp %d\n", g_rdpScreen.width, - g_rdpScreen.height, g_rdpScreen.depth, g_rdpScreen.bitsPerPixel); - ErrorF("dpix %d dpiy %d\n", dpix, dpiy); - if (g_rdpScreen.pfbMemory == 0) - { - g_rdpScreen.sizeInBytes = - (g_rdpScreen.paddedWidthInBytes * g_rdpScreen.height); - ErrorF("buffer size %d\n", g_rdpScreen.sizeInBytes); - g_rdpScreen.pfbMemory = (char*)g_malloc(2048 * 2048 * 4, 1); - } - if (g_rdpScreen.pfbMemory == 0) - { - rdpLog("rdpScreenInit g_malloc failed\n"); - return 0; - } - miClearVisualTypes(); - if (defaultColorVisualClass == -1) - { - defaultColorVisualClass = TrueColor; - } - if (!miSetVisualTypes(g_rdpScreen.depth, - miGetDefaultVisualMask(g_rdpScreen.depth), - 8, defaultColorVisualClass)) - { - rdpLog("rdpScreenInit miSetVisualTypes failed\n"); - return 0; - } - miSetPixmapDepths(); - switch (g_rdpScreen.bitsPerPixel) - { - case 8: - ret = fbScreenInit(pScreen, g_rdpScreen.pfbMemory, - g_rdpScreen.width, g_rdpScreen.height, - dpix, dpiy, g_rdpScreen.paddedWidthInBytes, 8); - break; - case 16: - ret = fbScreenInit(pScreen, g_rdpScreen.pfbMemory, - g_rdpScreen.width, g_rdpScreen.height, - dpix, dpiy, g_rdpScreen.paddedWidthInBytes / 2, 16); - break; - case 32: - ret = fbScreenInit(pScreen, g_rdpScreen.pfbMemory, - g_rdpScreen.width, g_rdpScreen.height, - dpix, dpiy, g_rdpScreen.paddedWidthInBytes / 4, 32); - break; - default: - ErrorF("rdpScreenInit: error\n"); - return 0; - } - if (!ret) - { - ErrorF("rdpScreenInit: error\n"); - return 0; - } + ErrorF("Screen width %d height %d depth %d bpp %d\n", g_rdpScreen.width, + g_rdpScreen.height, g_rdpScreen.depth, g_rdpScreen.bitsPerPixel); + ErrorF("dpix %d dpiy %d\n", dpix, dpiy); - miInitializeBackingStore(pScreen); - - /* this is for rgb, not bgr, just doing rgb for now */ - vis = g_pScreen->visuals + (g_pScreen->numVisuals - 1); - while (vis >= pScreen->visuals) - { - if ((vis->class | DynamicClass) == DirectColor) + if (g_rdpScreen.pfbMemory == 0) { - vis->offsetBlue = 0; - vis->blueMask = (1 << g_blueBits) - 1; - vis->offsetGreen = g_blueBits; - vis->greenMask = ((1 << g_greenBits) - 1) << vis->offsetGreen; - vis->offsetRed = g_blueBits + g_greenBits; - vis->redMask = ((1 << g_redBits) - 1) << vis->offsetRed; + g_rdpScreen.sizeInBytes = + (g_rdpScreen.paddedWidthInBytes * g_rdpScreen.height); + ErrorF("buffer size %d\n", g_rdpScreen.sizeInBytes); + g_rdpScreen.pfbMemory = (char *)g_malloc(2048 * 2048 * 4, 1); } - vis--; - } - if (g_rdpScreen.bitsPerPixel > 4) - { - fbPictureInit(pScreen, 0, 0); - } + if (g_rdpScreen.pfbMemory == 0) + { + rdpLog("rdpScreenInit g_malloc failed\n"); + return 0; + } - if (!dixRegisterPrivateKey(&g_rdpGCIndex, PRIVATE_GC, sizeof(rdpGCRec))) - { - FatalError("rdpScreenInit: dixRegisterPrivateKey PRIVATE_GC failed\n"); - } + miClearVisualTypes(); - if (!dixRegisterPrivateKey(&g_rdpWindowIndex, PRIVATE_WINDOW, sizeof(rdpWindowRec))) - { - FatalError("rdpScreenInit: dixRegisterPrivateKey PRIVATE_WINDOW failed\n"); - } + if (defaultColorVisualClass == -1) + { + defaultColorVisualClass = TrueColor; + } - if (!dixRegisterPrivateKey(&g_rdpPixmapIndex, PRIVATE_PIXMAP, sizeof(rdpPixmapRec))) - { - FatalError("rdpScreenInit: dixRegisterPrivateKey PRIVATE_PIXMAP failed\n"); - } + if (!miSetVisualTypes(g_rdpScreen.depth, + miGetDefaultVisualMask(g_rdpScreen.depth), + 8, defaultColorVisualClass)) + { + rdpLog("rdpScreenInit miSetVisualTypes failed\n"); + return 0; + } - /* Random screen procedures */ - g_rdpScreen.CloseScreen = pScreen->CloseScreen; - /* GC procedures */ - g_rdpScreen.CreateGC = pScreen->CreateGC; - /* Pixmap procudures */ - g_rdpScreen.CreatePixmap = pScreen->CreatePixmap; - g_rdpScreen.DestroyPixmap = pScreen->DestroyPixmap; + miSetPixmapDepths(); - /* Window Procedures */ - g_rdpScreen.CreateWindow = pScreen->CreateWindow; - g_rdpScreen.DestroyWindow = pScreen->DestroyWindow; - g_rdpScreen.ChangeWindowAttributes = pScreen->ChangeWindowAttributes; - g_rdpScreen.RealizeWindow = pScreen->RealizeWindow; - g_rdpScreen.UnrealizeWindow = pScreen->UnrealizeWindow; - g_rdpScreen.PositionWindow = pScreen->PositionWindow; - g_rdpScreen.WindowExposures = pScreen->WindowExposures; - g_rdpScreen.CopyWindow = pScreen->CopyWindow; - g_rdpScreen.ClearToBackground = pScreen->ClearToBackground; + switch (g_rdpScreen.bitsPerPixel) + { + case 8: + ret = fbScreenInit(pScreen, g_rdpScreen.pfbMemory, + g_rdpScreen.width, g_rdpScreen.height, + dpix, dpiy, g_rdpScreen.paddedWidthInBytes, 8); + break; + case 16: + ret = fbScreenInit(pScreen, g_rdpScreen.pfbMemory, + g_rdpScreen.width, g_rdpScreen.height, + dpix, dpiy, g_rdpScreen.paddedWidthInBytes / 2, 16); + break; + case 32: + ret = fbScreenInit(pScreen, g_rdpScreen.pfbMemory, + g_rdpScreen.width, g_rdpScreen.height, + dpix, dpiy, g_rdpScreen.paddedWidthInBytes / 4, 32); + break; + default: + ErrorF("rdpScreenInit: error\n"); + return 0; + } - /* Backing store procedures */ - g_rdpScreen.RestoreAreas = pScreen->RestoreAreas; - g_rdpScreen.WakeupHandler = pScreen->WakeupHandler; + if (!ret) + { + ErrorF("rdpScreenInit: error\n"); + return 0; + } - g_rdpScreen.CreateColormap = pScreen->CreateColormap; - g_rdpScreen.DestroyColormap = pScreen->DestroyColormap; + miInitializeBackingStore(pScreen); - ps = GetPictureScreenIfSet(pScreen); - if (ps) - { - g_rdpScreen.Composite = ps->Composite; - g_rdpScreen.Glyphs = ps->Glyphs; + /* this is for rgb, not bgr, just doing rgb for now */ + vis = g_pScreen->visuals + (g_pScreen->numVisuals - 1); - } - pScreen->blackPixel = g_rdpScreen.blackPixel; - pScreen->whitePixel = g_rdpScreen.whitePixel; - /* Random screen procedures */ - pScreen->CloseScreen = rdpCloseScreen; - pScreen->WakeupHandler = rdpWakeupHandler; - if (ps) - { - ps->Composite = rdpComposite; - ps->Glyphs = rdpGlyphs; - } - pScreen->SaveScreen = rdpSaveScreen; - /* GC procedures */ - pScreen->CreateGC = rdpCreateGC; + while (vis >= pScreen->visuals) + { + if ((vis->class | DynamicClass) == DirectColor) + { + vis->offsetBlue = 0; + vis->blueMask = (1 << g_blueBits) - 1; + vis->offsetGreen = g_blueBits; + vis->greenMask = ((1 << g_greenBits) - 1) << vis->offsetGreen; + vis->offsetRed = g_blueBits + g_greenBits; + vis->redMask = ((1 << g_redBits) - 1) << vis->offsetRed; + } - if (g_wrapPixmap) - { - /* Pixmap procedures */ - pScreen->CreatePixmap = rdpCreatePixmap; - pScreen->DestroyPixmap = rdpDestroyPixmap; - } + vis--; + } + + if (g_rdpScreen.bitsPerPixel > 4) + { + fbPictureInit(pScreen, 0, 0); + } + + if (!dixRegisterPrivateKey(&g_rdpGCIndex, PRIVATE_GC, sizeof(rdpGCRec))) + { + FatalError("rdpScreenInit: dixRegisterPrivateKey PRIVATE_GC failed\n"); + } + + if (!dixRegisterPrivateKey(&g_rdpWindowIndex, PRIVATE_WINDOW, sizeof(rdpWindowRec))) + { + FatalError("rdpScreenInit: dixRegisterPrivateKey PRIVATE_WINDOW failed\n"); + } + + if (!dixRegisterPrivateKey(&g_rdpPixmapIndex, PRIVATE_PIXMAP, sizeof(rdpPixmapRec))) + { + FatalError("rdpScreenInit: dixRegisterPrivateKey PRIVATE_PIXMAP failed\n"); + } + + /* Random screen procedures */ + g_rdpScreen.CloseScreen = pScreen->CloseScreen; + /* GC procedures */ + g_rdpScreen.CreateGC = pScreen->CreateGC; + /* Pixmap procudures */ + g_rdpScreen.CreatePixmap = pScreen->CreatePixmap; + g_rdpScreen.DestroyPixmap = pScreen->DestroyPixmap; - if (g_wrapWindow) - { /* Window Procedures */ - pScreen->CreateWindow = rdpCreateWindow; - pScreen->DestroyWindow = rdpDestroyWindow; - pScreen->ChangeWindowAttributes = rdpChangeWindowAttributes; - pScreen->RealizeWindow = rdpRealizeWindow; - pScreen->UnrealizeWindow = rdpUnrealizeWindow; - pScreen->PositionWindow = rdpPositionWindow; - pScreen->WindowExposures = rdpWindowExposures; - } + g_rdpScreen.CreateWindow = pScreen->CreateWindow; + g_rdpScreen.DestroyWindow = pScreen->DestroyWindow; + g_rdpScreen.ChangeWindowAttributes = pScreen->ChangeWindowAttributes; + g_rdpScreen.RealizeWindow = pScreen->RealizeWindow; + g_rdpScreen.UnrealizeWindow = pScreen->UnrealizeWindow; + g_rdpScreen.PositionWindow = pScreen->PositionWindow; + g_rdpScreen.WindowExposures = pScreen->WindowExposures; + g_rdpScreen.CopyWindow = pScreen->CopyWindow; + g_rdpScreen.ClearToBackground = pScreen->ClearToBackground; - pScreen->CopyWindow = rdpCopyWindow; - pScreen->ClearToBackground = rdpClearToBackground; + /* Backing store procedures */ + g_rdpScreen.RestoreAreas = pScreen->RestoreAreas; + g_rdpScreen.WakeupHandler = pScreen->WakeupHandler; - /* Backing store procedures */ - pScreen->RestoreAreas = rdpRestoreAreas; + g_rdpScreen.CreateColormap = pScreen->CreateColormap; + g_rdpScreen.DestroyColormap = pScreen->DestroyColormap; + + ps = GetPictureScreenIfSet(pScreen); + + if (ps) + { + g_rdpScreen.Composite = ps->Composite; + g_rdpScreen.Glyphs = ps->Glyphs; + + } + + pScreen->blackPixel = g_rdpScreen.blackPixel; + pScreen->whitePixel = g_rdpScreen.whitePixel; + /* Random screen procedures */ + pScreen->CloseScreen = rdpCloseScreen; + pScreen->WakeupHandler = rdpWakeupHandler; + + if (ps) + { + ps->Composite = rdpComposite; + ps->Glyphs = rdpGlyphs; + } + + pScreen->SaveScreen = rdpSaveScreen; + /* GC procedures */ + pScreen->CreateGC = rdpCreateGC; + + if (g_wrapPixmap) + { + /* Pixmap procedures */ + pScreen->CreatePixmap = rdpCreatePixmap; + pScreen->DestroyPixmap = rdpDestroyPixmap; + } + + if (g_wrapWindow) + { + /* Window Procedures */ + pScreen->CreateWindow = rdpCreateWindow; + pScreen->DestroyWindow = rdpDestroyWindow; + pScreen->ChangeWindowAttributes = rdpChangeWindowAttributes; + pScreen->RealizeWindow = rdpRealizeWindow; + pScreen->UnrealizeWindow = rdpUnrealizeWindow; + pScreen->PositionWindow = rdpPositionWindow; + pScreen->WindowExposures = rdpWindowExposures; + } + + pScreen->CopyWindow = rdpCopyWindow; + pScreen->ClearToBackground = rdpClearToBackground; + + /* Backing store procedures */ + pScreen->RestoreAreas = rdpRestoreAreas; #if 0 - pScreen->CreateColormap = rdpCreateColormap; - pScreen->DestroyColormap = rdpDestroyColormap; + pScreen->CreateColormap = rdpCreateColormap; + pScreen->DestroyColormap = rdpDestroyColormap; #endif - miPointerInitialize(pScreen, &g_rdpSpritePointerFuncs, - &g_rdpPointerCursorFuncs, 1); + miPointerInitialize(pScreen, &g_rdpSpritePointerFuncs, + &g_rdpPointerCursorFuncs, 1); #if 0 - pScreen->DeviceCursorInitialize = rdpDeviceCursorInitialize; - pScreen->DeviceCursorCleanup = rdpDeviceCursorCleanup; + pScreen->DeviceCursorInitialize = rdpDeviceCursorInitialize; + pScreen->DeviceCursorCleanup = rdpDeviceCursorCleanup; #endif - vis_found = 0; - vis = g_pScreen->visuals + (g_pScreen->numVisuals - 1); - while (vis >= pScreen->visuals) - { - if (vis->vid == pScreen->rootVisual) + vis_found = 0; + vis = g_pScreen->visuals + (g_pScreen->numVisuals - 1); + + while (vis >= pScreen->visuals) { - vis_found = 1; + if (vis->vid == pScreen->rootVisual) + { + vis_found = 1; + } + + vis--; } - vis--; - } - if (!vis_found) - { - rdpLog("rdpScreenInit: couldn't find root visual\n"); - exit(1); - } - ret = 1; - if (ret) - { - ret = fbCreateDefColormap(pScreen); - if (!ret) + + if (!vis_found) { - ErrorF("rdpScreenInit: fbCreateDefColormap failed\n"); + rdpLog("rdpScreenInit: couldn't find root visual\n"); + exit(1); } - } - if (ret) - { - ret = rdpup_init(); - if (!ret) + + ret = 1; + + if (ret) { - ErrorF("rdpScreenInit: rdpup_init failed\n"); + ret = fbCreateDefColormap(pScreen); + + if (!ret) + { + ErrorF("rdpScreenInit: fbCreateDefColormap failed\n"); + } } - } - if (ret) - { - RegisterBlockAndWakeupHandlers(rdpBlockHandler1, rdpWakeupHandler1, NULL); - } - if (!RRScreenInit(pScreen)) - { - ErrorF("rdpmain.c: RRScreenInit: screen init failed\n"); - } - else - { - pRRScrPriv = rrGetScrPriv(pScreen); - ErrorF("pRRScrPriv %p\n", pRRScrPriv); - pRRScrPriv->rrSetConfig = rdpRRSetConfig; + if (ret) + { + ret = rdpup_init(); - pRRScrPriv->rrGetInfo = rdpRRGetInfo; + if (!ret) + { + ErrorF("rdpScreenInit: rdpup_init failed\n"); + } + } - pRRScrPriv->rrScreenSetSize = rdpRRScreenSetSize; - pRRScrPriv->rrCrtcSet = rdpRRCrtcSet; - pRRScrPriv->rrCrtcGetGamma = rdpRRCrtcGetGamma; - pRRScrPriv->rrCrtcSetGamma = rdpRRCrtcSetGamma; - pRRScrPriv->rrOutputSetProperty = rdpRROutputSetProperty; - pRRScrPriv->rrOutputValidateMode = rdpRROutputValidateMode; - pRRScrPriv->rrModeDestroy = rdpRRModeDestroy; + if (ret) + { + RegisterBlockAndWakeupHandlers(rdpBlockHandler1, rdpWakeupHandler1, NULL); + } - pRRScrPriv->rrOutputGetProperty = rdpRROutputGetProperty; - pRRScrPriv->rrGetPanning = rdpRRGetPanning; - pRRScrPriv->rrSetPanning = rdpRRSetPanning; + if (!RRScreenInit(pScreen)) + { + ErrorF("rdpmain.c: RRScreenInit: screen init failed\n"); + } + else + { + pRRScrPriv = rrGetScrPriv(pScreen); + ErrorF("pRRScrPriv %p\n", pRRScrPriv); - } + pRRScrPriv->rrSetConfig = rdpRRSetConfig; - ErrorF("rdpScreenInit: ret %d\n", ret); + pRRScrPriv->rrGetInfo = rdpRRGetInfo; - return ret; + pRRScrPriv->rrScreenSetSize = rdpRRScreenSetSize; + pRRScrPriv->rrCrtcSet = rdpRRCrtcSet; + pRRScrPriv->rrCrtcGetGamma = rdpRRCrtcGetGamma; + pRRScrPriv->rrCrtcSetGamma = rdpRRCrtcSetGamma; + pRRScrPriv->rrOutputSetProperty = rdpRROutputSetProperty; + pRRScrPriv->rrOutputValidateMode = rdpRROutputValidateMode; + pRRScrPriv->rrModeDestroy = rdpRRModeDestroy; + + pRRScrPriv->rrOutputGetProperty = rdpRROutputGetProperty; + pRRScrPriv->rrGetPanning = rdpRRGetPanning; + pRRScrPriv->rrSetPanning = rdpRRSetPanning; + + } + + ErrorF("rdpScreenInit: ret %d\n", ret); + + return ret; } /******************************************************************************/ @@ -501,52 +529,61 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char** argv) returns the number or parameters processed if it dosen't apply to the rdp part, return 0 */ int -ddxProcessArgument(int argc, char** argv, int i) +ddxProcessArgument(int argc, char **argv, int i) { - if (g_firstTime) - { - memset(&g_rdpScreen, 0, sizeof(g_rdpScreen)); - g_rdpScreen.width = 1024; - g_rdpScreen.height = 768; - g_rdpScreen.depth = 24; - set_bpp(24); - g_rdpScreen.blackPixel = 1; - g_firstTime = 0; - RRExtensionInit(); - } - if (strcmp(argv[i], "-geometry") == 0) - { - if (i + 1 >= argc) + if (g_firstTime) { - UseMsg(); + memset(&g_rdpScreen, 0, sizeof(g_rdpScreen)); + g_rdpScreen.width = 1024; + g_rdpScreen.height = 768; + g_rdpScreen.depth = 24; + set_bpp(24); + g_rdpScreen.blackPixel = 1; + g_firstTime = 0; + RRExtensionInit(); } - if (sscanf(argv[i + 1], "%dx%d", &g_rdpScreen.width, - &g_rdpScreen.height) != 2) + + if (strcmp(argv[i], "-geometry") == 0) { - ErrorF("Invalid geometry %s\n", argv[i + 1]); - UseMsg(); + if (i + 1 >= argc) + { + UseMsg(); + } + + if (sscanf(argv[i + 1], "%dx%d", &g_rdpScreen.width, + &g_rdpScreen.height) != 2) + { + ErrorF("Invalid geometry %s\n", argv[i + 1]); + UseMsg(); + } + + return 2; } - return 2; - } - if (strcmp(argv[i], "-depth") == 0) - { - if (i + 1 >= argc) + + if (strcmp(argv[i], "-depth") == 0) { - UseMsg(); + if (i + 1 >= argc) + { + UseMsg(); + } + + g_rdpScreen.depth = atoi(argv[i + 1]); + + if (set_bpp(g_rdpScreen.depth) != 0) + { + UseMsg(); + } + + return 2; } - g_rdpScreen.depth = atoi(argv[i + 1]); - if (set_bpp(g_rdpScreen.depth) != 0) + + if (strcmp(argv[i], "-uds") == 0) { - UseMsg(); + g_use_uds = 1; + return 1; } - return 2; - } - if (strcmp(argv[i], "-uds") == 0) - { - g_use_uds = 1; - return 1; - } - return 0; + + return 0; } /******************************************************************************/ @@ -564,27 +601,27 @@ ddxInitGlobals(void) /******************************************************************************/ int -XkbDDXSwitchScreen(DeviceIntPtr dev, KeyCode key, XkbAction* act) +XkbDDXSwitchScreen(DeviceIntPtr dev, KeyCode key, XkbAction *act) { - ErrorF("XkbDDXSwitchScreen:\n"); - return 1; + ErrorF("XkbDDXSwitchScreen:\n"); + return 1; } /******************************************************************************/ int -XkbDDXPrivate(DeviceIntPtr dev, KeyCode key, XkbAction* act) +XkbDDXPrivate(DeviceIntPtr dev, KeyCode key, XkbAction *act) { - ErrorF("XkbDDXPrivate:\n"); - return 0; + ErrorF("XkbDDXPrivate:\n"); + return 0; } /******************************************************************************/ int -XkbDDXTerminateServer(DeviceIntPtr dev, KeyCode key, XkbAction* act) +XkbDDXTerminateServer(DeviceIntPtr dev, KeyCode key, XkbAction *act) { - ErrorF("XkbDDXTerminateServer:\n"); - GiveUp(1); - return 0; + ErrorF("XkbDDXTerminateServer:\n"); + GiveUp(1); + return 0; } /******************************************************************************/ @@ -592,50 +629,55 @@ XkbDDXTerminateServer(DeviceIntPtr dev, KeyCode key, XkbAction* act) AddScreen for each screen (but we only ever have one), and in turn this will call rdpScreenInit. */ void -InitOutput(ScreenInfo* screenInfo, int argc, char** argv) +InitOutput(ScreenInfo *screenInfo, int argc, char **argv) { - int i; + int i; - ErrorF("InitOutput:\n"); - g_initOutputCalled = 1; - /* initialize pixmap formats */ - screenInfo->imageByteOrder = IMAGE_BYTE_ORDER; - screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; - screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; - screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; - screenInfo->numPixmapFormats = g_numFormats; - for (i = 0; i < g_numFormats; i++) - { - screenInfo->formats[i] = g_formats[i]; - } - if (!AddCallback(&ClientStateCallback, rdpClientStateChange, NULL)) - { - rdpLog("InitOutput: AddCallback failed\n"); - return; - } - /* initialize screen */ - if (AddScreen(rdpScreenInit, argc, argv) == -1) - { - FatalError("Couldn't add screen\n"); - } - ErrorF("InitOutput: out\n"); + ErrorF("InitOutput:\n"); + g_initOutputCalled = 1; + /* initialize pixmap formats */ + screenInfo->imageByteOrder = IMAGE_BYTE_ORDER; + screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; + screenInfo->numPixmapFormats = g_numFormats; + + for (i = 0; i < g_numFormats; i++) + { + screenInfo->formats[i] = g_formats[i]; + } + + if (!AddCallback(&ClientStateCallback, rdpClientStateChange, NULL)) + { + rdpLog("InitOutput: AddCallback failed\n"); + return; + } + + /* initialize screen */ + if (AddScreen(rdpScreenInit, argc, argv) == -1) + { + FatalError("Couldn't add screen\n"); + } + + ErrorF("InitOutput: out\n"); } /******************************************************************************/ void -InitInput(int argc, char** argv) +InitInput(int argc, char **argv) { - int rc; + int rc; - ErrorF("InitInput:\n"); - rc = AllocDevicePair(serverClient, "X11rdp", &g_pointer, &g_keyboard, - rdpMouseProc, rdpKeybdProc, 0); - if (rc != Success) - { - FatalError("Failed to init X11rdp default devices.\n"); - } + ErrorF("InitInput:\n"); + rc = AllocDevicePair(serverClient, "X11rdp", &g_pointer, &g_keyboard, + rdpMouseProc, rdpKeybdProc, 0); - mieqInit(); + if (rc != Success) + { + FatalError("Failed to init X11rdp default devices.\n"); + } + + mieqInit(); } @@ -643,35 +685,37 @@ InitInput(int argc, char** argv) void ddxGiveUp(void) { - char unixSocketName[128]; + char unixSocketName[128]; - ErrorF("ddxGiveUp:\n"); - g_free(g_rdpScreen.pfbMemory); - if (g_initOutputCalled) - { - sprintf(unixSocketName, "/tmp/.X11-unix/X%s", display); - unlink(unixSocketName); - sprintf(unixSocketName, "/tmp/.xrdp/xrdp_disconnect_display_%s", display); - unlink(unixSocketName); - if(g_uds_data[0] != 0) + ErrorF("ddxGiveUp:\n"); + g_free(g_rdpScreen.pfbMemory); + + if (g_initOutputCalled) { - unlink(g_uds_data); + sprintf(unixSocketName, "/tmp/.X11-unix/X%s", display); + unlink(unixSocketName); + sprintf(unixSocketName, "/tmp/.xrdp/xrdp_disconnect_display_%s", display); + unlink(unixSocketName); + + if (g_uds_data[0] != 0) + { + unlink(g_uds_data); + } } - } } /******************************************************************************/ Bool LegalModifier(unsigned int key, DeviceIntPtr pDev) { - return 1; /* true */ + return 1; /* true */ } /******************************************************************************/ void ProcessInputEvents(void) { - mieqProcessInputEvents(); + mieqProcessInputEvents(); } /******************************************************************************/ @@ -686,7 +730,7 @@ rfbRootPropertyChange(PropertyPtr pProp) void AbortDDX(void) { - ddxGiveUp(); + ddxGiveUp(); } /******************************************************************************/ @@ -700,13 +744,13 @@ OsVendorFatalError(void) void ddxUseMsg(void) { - ErrorF("\n"); - ErrorF("X11rdp specific options\n"); - ErrorF("-geometry WxH set framebuffer width & height\n"); - ErrorF("-depth D set framebuffer depth\n"); - ErrorF("-uds create and listen on /tmp/.xrdp/xrdp_display_x\n"); - ErrorF("\n"); - exit(1); + ErrorF("\n"); + ErrorF("X11rdp specific options\n"); + ErrorF("-geometry WxH set framebuffer width & height\n"); + ErrorF("-depth D set framebuffer depth\n"); + ErrorF("-uds create and listen on /tmp/.xrdp/xrdp_display_x\n"); + ErrorF("\n"); + exit(1); } /******************************************************************************/ @@ -719,19 +763,19 @@ OsVendorPreInit(void) void CloseInput(void) { - ErrorF("CloseInput\n"); + ErrorF("CloseInput\n"); } /******************************************************************************/ void DDXRingBell(int volume, int pitch, int duration) { - ErrorF("DDXRingBell\n"); + ErrorF("DDXRingBell\n"); } /******************************************************************************/ void DeleteInputDeviceRequest(DeviceIntPtr dev) { - ErrorF("DeleteInputDeviceRequest\n"); + ErrorF("DeleteInputDeviceRequest\n"); } diff --git a/xorg/X11R7.6/rdp/rdpmisc.c b/xorg/X11R7.6/rdp/rdpmisc.c index d3defe27..c221dd15 100644 --- a/xorg/X11R7.6/rdp/rdpmisc.c +++ b/xorg/X11R7.6/rdp/rdpmisc.c @@ -32,60 +32,60 @@ Bool noFontCacheExtension = 1; void rdpLog(char *format, ...) { - va_list args; - char buf[256]; - time_t clock; + va_list args; + char buf[256]; + time_t clock; - va_start(args, format); - time(&clock); - strftime(buf, 255, "%d/%m/%y %T ", localtime(&clock)); - fprintf(stderr, "%s", buf); - vfprintf(stderr, format, args); - fflush(stderr); - va_end(args); + va_start(args, format); + time(&clock); + strftime(buf, 255, "%d/%m/%y %T ", localtime(&clock)); + fprintf(stderr, "%s", buf); + vfprintf(stderr, format, args); + fflush(stderr); + va_end(args); } /******************************************************************************/ int rdpBitsPerPixel(int depth) { - if (depth == 1) - { - return 1; - } - else if (depth <= 8) - { - return 8; - } - else if (depth <= 16) - { - return 16; - } - else - { - return 32; - } + if (depth == 1) + { + return 1; + } + else if (depth <= 8) + { + return 8; + } + else if (depth <= 16) + { + return 16; + } + else + { + return 32; + } } /******************************************************************************/ void -rdpClientStateChange(CallbackListPtr* cbl, pointer myData, pointer clt) +rdpClientStateChange(CallbackListPtr *cbl, pointer myData, pointer clt) { - dispatchException &= ~DE_RESET; /* hack - force server not to reset */ + dispatchException &= ~DE_RESET; /* hack - force server not to reset */ } /******************************************************************************/ int DPMSSupported(void) { - return 0; + return 0; } /******************************************************************************/ int -DPSMGet(int* level) +DPSMGet(int *level) { - return -1; + return -1; } /******************************************************************************/ @@ -102,38 +102,38 @@ AddOtherInputDevices(void) /******************************************************************************/ void -OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int* status) +OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int *status) { } /******************************************************************************/ int SetDeviceValuators(register ClientPtr client, DeviceIntPtr dev, - int* valuators, int first_valuator, int num_valuators) + int *valuators, int first_valuator, int num_valuators) { - return BadMatch; + return BadMatch; } /******************************************************************************/ int SetDeviceMode(register ClientPtr client, DeviceIntPtr dev, int mode) { - return BadMatch; + return BadMatch; } /******************************************************************************/ int ChangeKeyboardDevice(DeviceIntPtr old_dev, DeviceIntPtr new_dev) { - return BadMatch; + return BadMatch; } /******************************************************************************/ int ChangeDeviceControl(register ClientPtr client, DeviceIntPtr dev, - void* control) + void *control) { - return BadMatch; + return BadMatch; } /******************************************************************************/ @@ -141,7 +141,7 @@ int ChangePointerDevice(DeviceIntPtr old_dev, DeviceIntPtr new_dev, unsigned char x, unsigned char y) { - return BadMatch; + return BadMatch; } /******************************************************************************/ @@ -154,332 +154,357 @@ CloseInputDevice(DeviceIntPtr d, ClientPtr client) /*****************************************************************************/ int -g_tcp_recv(int sck, void* ptr, int len, int flags) +g_tcp_recv(int sck, void *ptr, int len, int flags) { - return recv(sck, ptr, len, flags); + return recv(sck, ptr, len, flags); } /*****************************************************************************/ void g_tcp_close(int sck) { - if (sck == 0) - { - return; - } - shutdown(sck, 2); - close(sck); + if (sck == 0) + { + return; + } + + shutdown(sck, 2); + close(sck); } /*****************************************************************************/ int g_tcp_last_error_would_block(int sck) { - return (errno == EWOULDBLOCK) || (errno == EINPROGRESS); + return (errno == EWOULDBLOCK) || (errno == EINPROGRESS); } /*****************************************************************************/ void g_sleep(int msecs) { - usleep(msecs * 1000); + usleep(msecs * 1000); } /*****************************************************************************/ int -g_tcp_send(int sck, void* ptr, int len, int flags) +g_tcp_send(int sck, void *ptr, int len, int flags) { - return send(sck, ptr, len, flags); + return send(sck, ptr, len, flags); } /*****************************************************************************/ -void* +void * g_malloc(int size, int zero) { - char* rv; + char *rv; -//#ifdef _XSERVER64 + //#ifdef _XSERVER64 #if 1 - /* I thought xalloc whould work here but I guess not, why, todo */ - rv = (char*)malloc(size); + /* I thought xalloc whould work here but I guess not, why, todo */ + rv = (char *)malloc(size); #else - rv = (char*)Xalloc(size); + rv = (char *)Xalloc(size); #endif - if (zero) - { - if (rv != 0) + + if (zero) { - memset(rv, 0, size); + if (rv != 0) + { + memset(rv, 0, size); + } } - } - return rv; + + return rv; } /*****************************************************************************/ void -g_free(void* ptr) +g_free(void *ptr) { - if (ptr != 0) - { -//#ifdef _XSERVER64 + if (ptr != 0) + { + //#ifdef _XSERVER64 #if 1 - /* I thought xfree whould work here but I guess not, why, todo */ - free(ptr); + /* I thought xfree whould work here but I guess not, why, todo */ + free(ptr); #else - Xfree(ptr); + Xfree(ptr); #endif - } + } } /*****************************************************************************/ void -g_sprintf(char* dest, char* format, ...) +g_sprintf(char *dest, char *format, ...) { - va_list ap; + va_list ap; - va_start(ap, format); - vsprintf(dest, format, ap); - va_end(ap); + va_start(ap, format); + vsprintf(dest, format, ap); + va_end(ap); } /*****************************************************************************/ int g_tcp_socket(void) { - int rv; - int i; + int rv; + int i; - i = 1; - rv = socket(PF_INET, SOCK_STREAM, 0); - setsockopt(rv, IPPROTO_TCP, TCP_NODELAY, (void*)&i, sizeof(i)); - setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (void*)&i, sizeof(i)); - return rv; + i = 1; + rv = socket(PF_INET, SOCK_STREAM, 0); + setsockopt(rv, IPPROTO_TCP, TCP_NODELAY, (void *)&i, sizeof(i)); + setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(i)); + return rv; } /*****************************************************************************/ int g_tcp_local_socket_dgram(void) { - return socket(AF_UNIX, SOCK_DGRAM, 0); + return socket(AF_UNIX, SOCK_DGRAM, 0); } /*****************************************************************************/ int g_tcp_local_socket_stream(void) { - return socket(AF_UNIX, SOCK_STREAM, 0); + return socket(AF_UNIX, SOCK_STREAM, 0); } /*****************************************************************************/ void -g_memcpy(void* d_ptr, const void* s_ptr, int size) +g_memcpy(void *d_ptr, const void *s_ptr, int size) { - memcpy(d_ptr, s_ptr, size); + memcpy(d_ptr, s_ptr, size); } /*****************************************************************************/ int g_tcp_set_no_delay(int sck) { - int i; + int i; - i = 1; - setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (void*)&i, sizeof(i)); - return 0; + i = 1; + setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (void *)&i, sizeof(i)); + return 0; } /*****************************************************************************/ int g_tcp_set_non_blocking(int sck) { - unsigned long i; + unsigned long i; - i = fcntl(sck, F_GETFL); - i = i | O_NONBLOCK; - fcntl(sck, F_SETFL, i); - return 0; + i = fcntl(sck, F_GETFL); + i = i | O_NONBLOCK; + fcntl(sck, F_SETFL, i); + return 0; } /*****************************************************************************/ int g_tcp_accept(int sck) { - struct sockaddr_in s; - unsigned int i; + struct sockaddr_in s; + unsigned int i; - i = sizeof(struct sockaddr_in); - memset(&s, 0, i); - return accept(sck, (struct sockaddr*)&s, &i); + i = sizeof(struct sockaddr_in); + memset(&s, 0, i); + return accept(sck, (struct sockaddr *)&s, &i); } /*****************************************************************************/ int g_tcp_select(int sck1, int sck2, int sck3) { - fd_set rfds; - struct timeval time; - int max; - int rv; + fd_set rfds; + struct timeval time; + int max; + int rv; - time.tv_sec = 0; - time.tv_usec = 0; - FD_ZERO(&rfds); - if (sck1 > 0) - { - FD_SET(((unsigned int)sck1), &rfds); - } - if (sck2 > 0) - { - FD_SET(((unsigned int)sck2), &rfds); - } - if (sck3 > 0) - { - FD_SET(((unsigned int)sck3), &rfds); - } - max = sck1; - if (sck2 > max) - { - max = sck2; - } - if (sck3 > max) - { - max = sck3; - } - rv = select(max + 1, &rfds, 0, 0, &time); - if (rv > 0) - { - rv = 0; - if (FD_ISSET(((unsigned int)sck1), &rfds)) + time.tv_sec = 0; + time.tv_usec = 0; + FD_ZERO(&rfds); + + if (sck1 > 0) { - rv = rv | 1; + FD_SET(((unsigned int)sck1), &rfds); } - if (FD_ISSET(((unsigned int)sck2), &rfds)) + + if (sck2 > 0) { - rv = rv | 2; + FD_SET(((unsigned int)sck2), &rfds); } - if (FD_ISSET(((unsigned int)sck3), &rfds)) + + if (sck3 > 0) { - rv = rv | 4; + FD_SET(((unsigned int)sck3), &rfds); } - } - else - { - rv = 0; - } - return rv; + + max = sck1; + + if (sck2 > max) + { + max = sck2; + } + + if (sck3 > max) + { + max = sck3; + } + + rv = select(max + 1, &rfds, 0, 0, &time); + + if (rv > 0) + { + rv = 0; + + if (FD_ISSET(((unsigned int)sck1), &rfds)) + { + rv = rv | 1; + } + + if (FD_ISSET(((unsigned int)sck2), &rfds)) + { + rv = rv | 2; + } + + if (FD_ISSET(((unsigned int)sck3), &rfds)) + { + rv = rv | 4; + } + } + else + { + rv = 0; + } + + return rv; } /*****************************************************************************/ int -g_tcp_bind(int sck, char* port) +g_tcp_bind(int sck, char *port) { - struct sockaddr_in s; + struct sockaddr_in s; - memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons(atoi(port)); - s.sin_addr.s_addr = INADDR_ANY; - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); + memset(&s, 0, sizeof(struct sockaddr_in)); + s.sin_family = AF_INET; + s.sin_port = htons(atoi(port)); + s.sin_addr.s_addr = INADDR_ANY; + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_in)); } /*****************************************************************************/ int -g_tcp_local_bind(int sck, char* port) +g_tcp_local_bind(int sck, char *port) { - struct sockaddr_un s; + struct sockaddr_un s; - memset(&s, 0, sizeof(struct sockaddr_un)); - s.sun_family = AF_UNIX; - strcpy(s.sun_path, port); - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_un)); + memset(&s, 0, sizeof(struct sockaddr_un)); + s.sun_family = AF_UNIX; + strcpy(s.sun_path, port); + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_un)); } /*****************************************************************************/ int g_tcp_listen(int sck) { - return listen(sck, 2); + return listen(sck, 2); } /*****************************************************************************/ /* returns boolean */ int -g_create_dir(const char* dirname) +g_create_dir(const char *dirname) { - return mkdir(dirname, (mode_t)-1) == 0; + return mkdir(dirname, (mode_t) - 1) == 0; } /*****************************************************************************/ /* returns boolean, non zero if the directory exists */ int -g_directory_exist(const char* dirname) +g_directory_exist(const char *dirname) { - struct stat st; + struct stat st; - if (stat(dirname, &st) == 0) - { - return S_ISDIR(st.st_mode); - } - else - { - return 0; - } + if (stat(dirname, &st) == 0) + { + return S_ISDIR(st.st_mode); + } + else + { + return 0; + } } /*****************************************************************************/ /* returns error */ int -g_chmod_hex(const char* filename, int flags) +g_chmod_hex(const char *filename, int flags) { - int fl; + int fl; - fl = 0; - fl |= (flags & 0x4000) ? S_ISUID : 0; - fl |= (flags & 0x2000) ? S_ISGID : 0; - fl |= (flags & 0x1000) ? S_ISVTX : 0; - fl |= (flags & 0x0400) ? S_IRUSR : 0; - fl |= (flags & 0x0200) ? S_IWUSR : 0; - fl |= (flags & 0x0100) ? S_IXUSR : 0; - fl |= (flags & 0x0040) ? S_IRGRP : 0; - fl |= (flags & 0x0020) ? S_IWGRP : 0; - fl |= (flags & 0x0010) ? S_IXGRP : 0; - fl |= (flags & 0x0004) ? S_IROTH : 0; - fl |= (flags & 0x0002) ? S_IWOTH : 0; - fl |= (flags & 0x0001) ? S_IXOTH : 0; - return chmod(filename, fl); + fl = 0; + fl |= (flags & 0x4000) ? S_ISUID : 0; + fl |= (flags & 0x2000) ? S_ISGID : 0; + fl |= (flags & 0x1000) ? S_ISVTX : 0; + fl |= (flags & 0x0400) ? S_IRUSR : 0; + fl |= (flags & 0x0200) ? S_IWUSR : 0; + fl |= (flags & 0x0100) ? S_IXUSR : 0; + fl |= (flags & 0x0040) ? S_IRGRP : 0; + fl |= (flags & 0x0020) ? S_IWGRP : 0; + fl |= (flags & 0x0010) ? S_IXGRP : 0; + fl |= (flags & 0x0004) ? S_IROTH : 0; + fl |= (flags & 0x0002) ? S_IWOTH : 0; + fl |= (flags & 0x0001) ? S_IXOTH : 0; + return chmod(filename, fl); } /* produce a hex dump */ void -hexdump(unsigned char* p, unsigned int len) +hexdump(unsigned char *p, unsigned int len) { - unsigned char* line; - int i; - int thisline; - int offset; + unsigned char *line; + int i; + int thisline; + int offset; - offset = 0; - line = p; - while (offset < len) - { - ErrorF("%04x ", offset); - thisline = len - offset; - if (thisline > 16) - thisline = 16; + offset = 0; + line = p; - for (i = 0; i < thisline; i++) - ErrorF("%02x ", line[i]); + while (offset < len) + { + ErrorF("%04x ", offset); + thisline = len - offset; - for (; i < 16; i++) - ErrorF(" "); + if (thisline > 16) + { + thisline = 16; + } - for (i = 0; i < thisline; i++) - ErrorF("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); + for (i = 0; i < thisline; i++) + { + ErrorF("%02x ", line[i]); + } - ErrorF("\n"); - offset += thisline; - line += thisline; - } + for (; i < 16; i++) + { + ErrorF(" "); + } + + for (i = 0; i < thisline; i++) + { + ErrorF("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); + } + + ErrorF("\n"); + offset += thisline; + line += thisline; + } } /* @@ -490,26 +515,26 @@ hexdump(unsigned char* p, unsigned int len) Bool XpClientIsBitmapClient(ClientPtr client) { - return 1; + return 1; } /*****************************************************************************/ Bool XpClientIsPrintClient(ClientPtr client, FontPathElementPtr fpe) { - return 0; + return 0; } /*****************************************************************************/ int -PrinterOptions(int argc, char** argv, int i) +PrinterOptions(int argc, char **argv, int i) { - return i; + return i; } /*****************************************************************************/ void -PrinterInitOutput(ScreenInfo* pScreenInfo, int argc, char** argv) +PrinterInitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) { } @@ -533,40 +558,44 @@ FontCacheExtensionInit(INITARGS) /******************************************************************************/ void -RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg) +RegionAroundSegs(RegionPtr reg, xSegment *segs, int nseg) { - int index; - BoxRec box; - RegionRec treg; + int index; + BoxRec box; + RegionRec treg; - index = 0; - while (index < nseg) - { - if (segs[index].x1 < segs[index].x2) + index = 0; + + while (index < nseg) { - box.x1 = segs[index].x1; - box.x2 = segs[index].x2; + if (segs[index].x1 < segs[index].x2) + { + box.x1 = segs[index].x1; + box.x2 = segs[index].x2; + } + else + { + box.x1 = segs[index].x2; + box.x2 = segs[index].x1; + } + + box.x2++; + + if (segs[index].y1 < segs[index].y2) + { + box.y1 = segs[index].y1; + box.y2 = segs[index].y2; + } + else + { + box.y1 = segs[index].y2; + box.y2 = segs[index].y1; + } + + box.y2++; + RegionInit(&treg, &box, 0); + RegionUnion(reg, reg, &treg); + RegionUninit(&treg); + index++; } - else - { - box.x1 = segs[index].x2; - box.x2 = segs[index].x1; - } - box.x2++; - if (segs[index].y1 < segs[index].y2) - { - box.y1 = segs[index].y1; - box.y2 = segs[index].y2; - } - else - { - box.y1 = segs[index].y2; - box.y2 = segs[index].y1; - } - box.y2++; - RegionInit(&treg, &box, 0); - RegionUnion(reg, reg, &treg); - RegionUninit(&treg); - index++; - } } diff --git a/xorg/X11R7.6/rdp/rdprandr.c b/xorg/X11R7.6/rdp/rdprandr.c index ec011e8f..832d86d4 100644 --- a/xorg/X11R7.6/rdp/rdprandr.c +++ b/xorg/X11R7.6/rdp/rdprandr.c @@ -42,17 +42,17 @@ static XID g_wid = 0; Bool rdpRRRegisterSize(ScreenPtr pScreen, int width, int height) { - int mmwidth; - int mmheight; - RRScreenSizePtr pSize; + int mmwidth; + int mmheight; + RRScreenSizePtr pSize; - ErrorF("rdpRRRegisterSize: width %d height %d\n", width, height); - mmwidth = PixelToMM(width); - mmheight = PixelToMM(height); - pSize = RRRegisterSize(pScreen, width, height, mmwidth, mmheight); - /* Tell RandR what the current config is */ - RRSetCurrentConfig(pScreen, RR_Rotate_0, 0, pSize); - return TRUE; + ErrorF("rdpRRRegisterSize: width %d height %d\n", width, height); + mmwidth = PixelToMM(width); + mmheight = PixelToMM(height); + pSize = RRRegisterSize(pScreen, width, height, mmwidth, mmheight); + /* Tell RandR what the current config is */ + RRSetCurrentConfig(pScreen, RR_Rotate_0, 0, pSize); + return TRUE; } /******************************************************************************/ @@ -60,24 +60,24 @@ Bool rdpRRSetConfig(ScreenPtr pScreen, Rotation rotateKind, int rate, RRScreenSizePtr pSize) { - ErrorF("rdpRRSetConfig:\n"); - return TRUE; + ErrorF("rdpRRSetConfig:\n"); + return TRUE; } /******************************************************************************/ Bool -rdpRRGetInfo(ScreenPtr pScreen, Rotation* pRotations) +rdpRRGetInfo(ScreenPtr pScreen, Rotation *pRotations) { - int width; - int height; + int width; + int height; - ErrorF("rdpRRGetInfo:\n"); - *pRotations = RR_Rotate_0; + ErrorF("rdpRRGetInfo:\n"); + *pRotations = RR_Rotate_0; - width = g_rdpScreen.width; - height = g_rdpScreen.height; - rdpRRRegisterSize(pScreen, width, height); - return TRUE; + width = g_rdpScreen.width; + height = g_rdpScreen.height; + rdpRRRegisterSize(pScreen, width, height); + return TRUE; } /******************************************************************************/ @@ -86,35 +86,39 @@ rdpRRGetInfo(ScreenPtr pScreen, Rotation* pRotations) static int rdpInvalidateArea(ScreenPtr pScreen, int x, int y, int cx, int cy) { - WindowPtr pWin; - int result; - int attri; - XID attributes[4]; - Mask mask; + WindowPtr pWin; + int result; + int attri; + XID attributes[4]; + Mask mask; - DEBUG_OUT(("rdpInvalidateArea:\n")); - mask = 0; - attri = 0; - attributes[attri++] = pScreen->blackPixel; - mask |= CWBackPixel; - attributes[attri++] = xTrue; - mask |= CWOverrideRedirect; - if (g_wid == 0) - { - g_wid = FakeClientID(0); - } - pWin = CreateWindow(g_wid, pScreen->root, - x, y, cx, cy, 0, InputOutput, mask, - attributes, 0, serverClient, - wVisual(pScreen->root), &result); - if (result == 0) - { - g_invalidate_window = pWin; - MapWindow(pWin, serverClient); - DeleteWindow(pWin, None); - g_invalidate_window = pWin; - } - return 0; + DEBUG_OUT(("rdpInvalidateArea:\n")); + mask = 0; + attri = 0; + attributes[attri++] = pScreen->blackPixel; + mask |= CWBackPixel; + attributes[attri++] = xTrue; + mask |= CWOverrideRedirect; + + if (g_wid == 0) + { + g_wid = FakeClientID(0); + } + + pWin = CreateWindow(g_wid, pScreen->root, + x, y, cx, cy, 0, InputOutput, mask, + attributes, 0, serverClient, + wVisual(pScreen->root), &result); + + if (result == 0) + { + g_invalidate_window = pWin; + MapWindow(pWin, serverClient); + DeleteWindow(pWin, None); + g_invalidate_window = pWin; + } + + return 0; } /******************************************************************************/ @@ -122,84 +126,87 @@ Bool rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height, CARD32 mmWidth, CARD32 mmHeight) { - PixmapPtr screenPixmap; - BoxRec box; + PixmapPtr screenPixmap; + BoxRec box; - ErrorF("rdpRRScreenSetSize: width %d height %d mmWidth %d mmHeight %d\n", - width, height, (int)mmWidth, (int)mmHeight); + ErrorF("rdpRRScreenSetSize: width %d height %d mmWidth %d mmHeight %d\n", + width, height, (int)mmWidth, (int)mmHeight); - if ((width < 1) || (height < 1)) - { - ErrorF(" error width %d height %d\n", width, height); - return FALSE; - } - g_rdpScreen.width = width; - g_rdpScreen.height = height; - g_rdpScreen.paddedWidthInBytes = - PixmapBytePad(g_rdpScreen.width, g_rdpScreen.depth); - g_rdpScreen.sizeInBytes = - g_rdpScreen.paddedWidthInBytes * g_rdpScreen.height; - pScreen->width = width; - pScreen->height = height; - pScreen->mmWidth = mmWidth; - pScreen->mmHeight = mmHeight; + if ((width < 1) || (height < 1)) + { + ErrorF(" error width %d height %d\n", width, height); + return FALSE; + } - screenPixmap = pScreen->GetScreenPixmap(pScreen); - if (screenPixmap != 0) - { - ErrorF(" resizing screenPixmap [%p] to %dx%d, currently at %dx%d\n", - (void*)screenPixmap, width, height, - screenPixmap->drawable.width, screenPixmap->drawable.height); - pScreen->ModifyPixmapHeader(screenPixmap, width, height, - g_rdpScreen.depth, g_rdpScreen.bitsPerPixel, - g_rdpScreen.paddedWidthInBytes, - g_rdpScreen.pfbMemory); - ErrorF(" pixmap resized to %dx%d\n", - screenPixmap->drawable.width, screenPixmap->drawable.height); - } - DEBUG_OUT((" root window %p\n", (void*)pScreen->root)); - box.x1 = 0; - box.y1 = 0; - box.x2 = width; - box.y2 = height; - RegionInit(&pScreen->root->winSize, &box, 1); - RegionInit(&pScreen->root->borderSize, &box, 1); - RegionReset(&pScreen->root->borderClip, &box); - RegionBreak(&pScreen->root->clipList); - pScreen->root->drawable.width = width; - pScreen->root->drawable.height = height; - ResizeChildrenWinSize(pScreen->root, 0, 0, 0, 0); - RRScreenSizeNotify(pScreen); - rdpInvalidateArea(g_pScreen, 0, 0, g_rdpScreen.width, g_rdpScreen.height); - ErrorF(" screen resized to %dx%d\n", - pScreen->width, pScreen->height); - return TRUE; + g_rdpScreen.width = width; + g_rdpScreen.height = height; + g_rdpScreen.paddedWidthInBytes = + PixmapBytePad(g_rdpScreen.width, g_rdpScreen.depth); + g_rdpScreen.sizeInBytes = + g_rdpScreen.paddedWidthInBytes * g_rdpScreen.height; + pScreen->width = width; + pScreen->height = height; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; + + screenPixmap = pScreen->GetScreenPixmap(pScreen); + + if (screenPixmap != 0) + { + ErrorF(" resizing screenPixmap [%p] to %dx%d, currently at %dx%d\n", + (void *)screenPixmap, width, height, + screenPixmap->drawable.width, screenPixmap->drawable.height); + pScreen->ModifyPixmapHeader(screenPixmap, width, height, + g_rdpScreen.depth, g_rdpScreen.bitsPerPixel, + g_rdpScreen.paddedWidthInBytes, + g_rdpScreen.pfbMemory); + ErrorF(" pixmap resized to %dx%d\n", + screenPixmap->drawable.width, screenPixmap->drawable.height); + } + + DEBUG_OUT((" root window %p\n", (void *)pScreen->root)); + box.x1 = 0; + box.y1 = 0; + box.x2 = width; + box.y2 = height; + RegionInit(&pScreen->root->winSize, &box, 1); + RegionInit(&pScreen->root->borderSize, &box, 1); + RegionReset(&pScreen->root->borderClip, &box); + RegionBreak(&pScreen->root->clipList); + pScreen->root->drawable.width = width; + pScreen->root->drawable.height = height; + ResizeChildrenWinSize(pScreen->root, 0, 0, 0, 0); + RRScreenSizeNotify(pScreen); + rdpInvalidateArea(g_pScreen, 0, 0, g_rdpScreen.width, g_rdpScreen.height); + ErrorF(" screen resized to %dx%d\n", + pScreen->width, pScreen->height); + return TRUE; } /******************************************************************************/ Bool rdpRRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode, int x, int y, Rotation rotation, int numOutputs, - RROutputPtr* outputs) + RROutputPtr *outputs) { - ErrorF("rdpRRCrtcSet:\n"); - return TRUE; + ErrorF("rdpRRCrtcSet:\n"); + return TRUE; } /******************************************************************************/ Bool rdpRRCrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr crtc) { - ErrorF("rdpRRCrtcSetGamma:\n"); - return TRUE; + ErrorF("rdpRRCrtcSetGamma:\n"); + return TRUE; } /******************************************************************************/ Bool rdpRRCrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr crtc) { - ErrorF("rdpRRCrtcGetGamma:\n"); - return TRUE; + ErrorF("rdpRRCrtcGetGamma:\n"); + return TRUE; } /******************************************************************************/ @@ -207,8 +214,8 @@ Bool rdpRROutputSetProperty(ScreenPtr pScreen, RROutputPtr output, Atom property, RRPropertyValuePtr value) { - ErrorF("rdpRROutputSetProperty:\n"); - return TRUE; + ErrorF("rdpRROutputSetProperty:\n"); + return TRUE; } /******************************************************************************/ @@ -216,60 +223,64 @@ Bool rdpRROutputValidateMode(ScreenPtr pScreen, RROutputPtr output, RRModePtr mode) { - ErrorF("rdpRROutputValidateMode:\n"); - return TRUE; + ErrorF("rdpRROutputValidateMode:\n"); + return TRUE; } /******************************************************************************/ void rdpRRModeDestroy(ScreenPtr pScreen, RRModePtr mode) { - ErrorF("rdpRRModeDestroy:\n"); + ErrorF("rdpRRModeDestroy:\n"); } /******************************************************************************/ Bool rdpRROutputGetProperty(ScreenPtr pScreen, RROutputPtr output, Atom property) { - ErrorF("rdpRROutputGetProperty:\n"); - return TRUE; + ErrorF("rdpRROutputGetProperty:\n"); + return TRUE; } /******************************************************************************/ Bool rdpRRGetPanning(ScreenPtr pScrn, RRCrtcPtr crtc, BoxPtr totalArea, - BoxPtr trackingArea, INT16* border) + BoxPtr trackingArea, INT16 *border) { - ErrorF("rdpRRGetPanning:\n"); - if (totalArea != 0) - { - totalArea->x1 = 0; - totalArea->y1 = 0; - totalArea->x2 = g_rdpScreen.width; - totalArea->y2 = g_rdpScreen.height; - } - if (trackingArea != 0) - { - trackingArea->x1 = 0; - trackingArea->y1 = 0; - trackingArea->x2 = g_rdpScreen.width; - trackingArea->y2 = g_rdpScreen.height; - } - if (border != 0) - { - border[0] = 0; - border[1] = 0; - border[2] = 0; - border[3] = 0; - } - return TRUE; + ErrorF("rdpRRGetPanning:\n"); + + if (totalArea != 0) + { + totalArea->x1 = 0; + totalArea->y1 = 0; + totalArea->x2 = g_rdpScreen.width; + totalArea->y2 = g_rdpScreen.height; + } + + if (trackingArea != 0) + { + trackingArea->x1 = 0; + trackingArea->y1 = 0; + trackingArea->x2 = g_rdpScreen.width; + trackingArea->y2 = g_rdpScreen.height; + } + + if (border != 0) + { + border[0] = 0; + border[1] = 0; + border[2] = 0; + border[3] = 0; + } + + return TRUE; } /******************************************************************************/ Bool rdpRRSetPanning(ScreenPtr pScrn, RRCrtcPtr crtc, BoxPtr totalArea, - BoxPtr trackingArea, INT16* border) + BoxPtr trackingArea, INT16 *border) { - ErrorF("rdpRRSetPanning:\n"); - return TRUE; + ErrorF("rdpRRSetPanning:\n"); + return TRUE; } diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c index 81165a3a..ac46060e 100644 --- a/xorg/X11R7.6/rdp/rdpup.c +++ b/xorg/X11R7.6/rdp/rdpup.c @@ -24,9 +24,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) int g_con_number = 0; /* increments for each connection */ @@ -40,8 +40,8 @@ static int g_dis_listen_sck = 0; //static int g_dis_connected = 0; static int g_begin = 0; -static struct stream* g_out_s = 0; -static struct stream* g_in_s = 0; +static struct stream *g_out_s = 0; +static struct stream *g_in_s = 0; static int g_button_mask = 0; static int g_cursor_x = 0; static int g_cursor_y = 0; @@ -62,13 +62,13 @@ extern char g_uds_data[]; /* in rdpmain.c */ struct rdpup_os_bitmap { - int used; - PixmapPtr pixmap; - rdpPixmapPtr priv; - int stamp; + int used; + PixmapPtr pixmap; + rdpPixmapPtr priv; + int stamp; }; -static struct rdpup_os_bitmap* g_os_bitmaps = 0; +static struct rdpup_os_bitmap *g_os_bitmaps = 0; static int g_max_os_bitmaps = 0; static int g_os_bitmap_stamp = 0; @@ -96,320 +96,353 @@ f GXset 1 static int g_rdp_opcodes[16] = { - 0x00, /* GXclear 0x0 0 */ - 0x88, /* GXand 0x1 src AND dst */ - 0x44, /* GXandReverse 0x2 src AND NOT dst */ - 0xcc, /* GXcopy 0x3 src */ - 0x22, /* GXandInverted 0x4 NOT src AND dst */ - 0xaa, /* GXnoop 0x5 dst */ - 0x66, /* GXxor 0x6 src XOR dst */ - 0xee, /* GXor 0x7 src OR dst */ - 0x11, /* GXnor 0x8 NOT src AND NOT dst */ - 0x99, /* GXequiv 0x9 NOT src XOR dst */ - 0x55, /* GXinvert 0xa NOT dst */ - 0xdd, /* GXorReverse 0xb src OR NOT dst */ - 0x33, /* GXcopyInverted 0xc NOT src */ - 0xbb, /* GXorInverted 0xd NOT src OR dst */ - 0x77, /* GXnand 0xe NOT src OR NOT dst */ - 0xff /* GXset 0xf 1 */ + 0x00, /* GXclear 0x0 0 */ + 0x88, /* GXand 0x1 src AND dst */ + 0x44, /* GXandReverse 0x2 src AND NOT dst */ + 0xcc, /* GXcopy 0x3 src */ + 0x22, /* GXandInverted 0x4 NOT src AND dst */ + 0xaa, /* GXnoop 0x5 dst */ + 0x66, /* GXxor 0x6 src XOR dst */ + 0xee, /* GXor 0x7 src OR dst */ + 0x11, /* GXnor 0x8 NOT src AND NOT dst */ + 0x99, /* GXequiv 0x9 NOT src XOR dst */ + 0x55, /* GXinvert 0xa NOT dst */ + 0xdd, /* GXorReverse 0xb src OR NOT dst */ + 0x33, /* GXcopyInverted 0xc NOT src */ + 0xbb, /* GXorInverted 0xd NOT src OR dst */ + 0x77, /* GXnand 0xe NOT src OR NOT dst */ + 0xff /* GXset 0xf 1 */ }; /*****************************************************************************/ static int rdpup_disconnect(void) { - int index; + int index; - RemoveEnabledDevice(g_sck); - g_connected = 0; - g_tcp_close(g_sck); - g_sck = 0; - g_sck_closed = 1; - g_pixmap_byte_total = 0; - g_pixmap_num_used = 0; - if (g_max_os_bitmaps > 0) - { - for (index = 0; index < g_max_os_bitmaps; index++) + RemoveEnabledDevice(g_sck); + g_connected = 0; + g_tcp_close(g_sck); + g_sck = 0; + g_sck_closed = 1; + g_pixmap_byte_total = 0; + g_pixmap_num_used = 0; + + if (g_max_os_bitmaps > 0) { - if (g_os_bitmaps[index].used) - { - if (g_os_bitmaps[index].priv != 0) + for (index = 0; index < g_max_os_bitmaps; index++) { - g_os_bitmaps[index].priv->status = 0; + if (g_os_bitmaps[index].used) + { + if (g_os_bitmaps[index].priv != 0) + { + g_os_bitmaps[index].priv->status = 0; + } + } } - } } - } - g_max_os_bitmaps = 0; - g_free(g_os_bitmaps); - g_os_bitmaps = 0; - g_use_rail = 0; - return 0; + + g_max_os_bitmaps = 0; + g_free(g_os_bitmaps); + g_os_bitmaps = 0; + g_use_rail = 0; + return 0; } /*****************************************************************************/ int rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv) { - int index; - int rv; - int oldest; - int oldest_index; + int index; + int rv; + int oldest; + int oldest_index; - if (!g_connected) - { - return -1; - } - if (g_os_bitmaps == 0) - { - return -1; - } - rv = -1; - index = 0; - while (index < g_max_os_bitmaps) - { - if (g_os_bitmaps[index].used == 0) + if (!g_connected) { - g_os_bitmaps[index].used = 1; - g_os_bitmaps[index].pixmap = pixmap; - g_os_bitmaps[index].priv = priv; - g_os_bitmaps[index].stamp = g_os_bitmap_stamp; - g_os_bitmap_stamp++; - g_pixmap_num_used++; - rv = index; - break; + return -1; } - index++; - } - if (rv == -1) - { - /* find oldest */ - oldest = 0x7fffffff; - oldest_index = 0; + + if (g_os_bitmaps == 0) + { + return -1; + } + + rv = -1; index = 0; + while (index < g_max_os_bitmaps) { - if (g_os_bitmaps[index].stamp < oldest) - { - oldest = g_os_bitmaps[index].stamp; - oldest_index = index; - } - index++; + if (g_os_bitmaps[index].used == 0) + { + g_os_bitmaps[index].used = 1; + g_os_bitmaps[index].pixmap = pixmap; + g_os_bitmaps[index].priv = priv; + g_os_bitmaps[index].stamp = g_os_bitmap_stamp; + g_os_bitmap_stamp++; + g_pixmap_num_used++; + rv = index; + break; + } + + index++; } - LLOGLN(10, ("rdpup_add_os_bitmap: evicting old, oldest_index %d", oldest_index)); - /* evict old */ - g_os_bitmaps[oldest_index].priv->status = 0; - /* set new */ - g_os_bitmaps[oldest_index].pixmap = pixmap; - g_os_bitmaps[oldest_index].priv = priv; - g_os_bitmaps[oldest_index].stamp = g_os_bitmap_stamp; - g_os_bitmap_stamp++; - rv = oldest_index; - } - LLOGLN(10, ("rdpup_add_os_bitmap: new bitmap index %d", rv)); - LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used)); - return rv; + + if (rv == -1) + { + /* find oldest */ + oldest = 0x7fffffff; + oldest_index = 0; + index = 0; + + while (index < g_max_os_bitmaps) + { + if (g_os_bitmaps[index].stamp < oldest) + { + oldest = g_os_bitmaps[index].stamp; + oldest_index = index; + } + + index++; + } + + LLOGLN(10, ("rdpup_add_os_bitmap: evicting old, oldest_index %d", oldest_index)); + /* evict old */ + g_os_bitmaps[oldest_index].priv->status = 0; + /* set new */ + g_os_bitmaps[oldest_index].pixmap = pixmap; + g_os_bitmaps[oldest_index].priv = priv; + g_os_bitmaps[oldest_index].stamp = g_os_bitmap_stamp; + g_os_bitmap_stamp++; + rv = oldest_index; + } + + LLOGLN(10, ("rdpup_add_os_bitmap: new bitmap index %d", rv)); + LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used)); + return rv; } /*****************************************************************************/ int rdpup_remove_os_bitmap(int rdpindex) { - LLOGLN(10, ("rdpup_remove_os_bitmap: index %d stamp %d", - rdpindex, g_os_bitmaps[rdpindex].stamp)); - if (g_os_bitmaps == 0) - { - return 1; - } - if ((rdpindex < 0) && (rdpindex >= g_max_os_bitmaps)) - { - return 1; - } - if (g_os_bitmaps[rdpindex].used) - { - g_os_bitmaps[rdpindex].used = 0; - g_os_bitmaps[rdpindex].pixmap = 0; - g_os_bitmaps[rdpindex].priv = 0; - g_pixmap_num_used--; - } - LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used)); - return 0; + LLOGLN(10, ("rdpup_remove_os_bitmap: index %d stamp %d", + rdpindex, g_os_bitmaps[rdpindex].stamp)); + + if (g_os_bitmaps == 0) + { + return 1; + } + + if ((rdpindex < 0) && (rdpindex >= g_max_os_bitmaps)) + { + return 1; + } + + if (g_os_bitmaps[rdpindex].used) + { + g_os_bitmaps[rdpindex].used = 0; + g_os_bitmaps[rdpindex].pixmap = 0; + g_os_bitmaps[rdpindex].priv = 0; + g_pixmap_num_used--; + } + + LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used)); + return 0; } /*****************************************************************************/ /* returns error */ static int -rdpup_send(char* data, int len) +rdpup_send(char *data, int len) { - int sent; + int sent; - LLOGLN(10, ("rdpup_send - sending %d bytes", len)); - if (g_sck_closed) - { - return 1; - } - while (len > 0) - { - sent = g_tcp_send(g_sck, data, len, 0); - if (sent == -1) + LLOGLN(10, ("rdpup_send - sending %d bytes", len)); + + if (g_sck_closed) { - if (g_tcp_last_error_would_block(g_sck)) - { - g_sleep(1); - } - else - { - rdpup_disconnect(); return 1; - } } - else if (sent == 0) + + while (len > 0) { - rdpup_disconnect(); - return 1; + sent = g_tcp_send(g_sck, data, len, 0); + + if (sent == -1) + { + if (g_tcp_last_error_would_block(g_sck)) + { + g_sleep(1); + } + else + { + rdpup_disconnect(); + return 1; + } + } + else if (sent == 0) + { + rdpup_disconnect(); + return 1; + } + else + { + data += sent; + len -= sent; + } } - else - { - data += sent; - len -= sent; - } - } - return 0; + + return 0; } /******************************************************************************/ static int -rdpup_send_msg(struct stream* s) +rdpup_send_msg(struct stream *s) { - int len; - int rv; + int len; + int rv; - rv = 1; - if (s != 0) - { - len = (int)(s->end - s->data); - if (len > s->size) + rv = 1; + + if (s != 0) { - rdpLog("overrun error len %d count %d\n", len, g_count); + len = (int)(s->end - s->data); + + if (len > s->size) + { + rdpLog("overrun error len %d count %d\n", len, g_count); + } + + s_pop_layer(s, iso_hdr); + out_uint16_le(s, 3); + out_uint16_le(s, g_count); + out_uint32_le(s, len - 8); + rv = rdpup_send(s->data, len); } - s_pop_layer(s, iso_hdr); - out_uint16_le(s, 3); - out_uint16_le(s, g_count); - out_uint32_le(s, len - 8); - rv = rdpup_send(s->data, len); - } - if (rv != 0) - { - rdpLog("error in rdpup_send_msg\n"); - } - return rv; + + if (rv != 0) + { + rdpLog("error in rdpup_send_msg\n"); + } + + return rv; } /******************************************************************************/ static int rdpup_send_pending(void) { - if (g_connected && g_begin) - { - LLOGLN(10, ("end %d", g_count)); - out_uint16_le(g_out_s, 2); - out_uint16_le(g_out_s, 4); - g_count++; - s_mark_end(g_out_s); - rdpup_send_msg(g_out_s); - } - g_count = 0; - g_begin = 0; - return 0; + if (g_connected && g_begin) + { + LLOGLN(10, ("end %d", g_count)); + out_uint16_le(g_out_s, 2); + out_uint16_le(g_out_s, 4); + g_count++; + s_mark_end(g_out_s); + rdpup_send_msg(g_out_s); + } + + g_count = 0; + g_begin = 0; + return 0; } /******************************************************************************/ static CARD32 rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg) { - rdpup_send_pending(); - g_scheduled = 0; - return 0; + rdpup_send_pending(); + g_scheduled = 0; + return 0; } /******************************************************************************/ static void rdpScheduleDeferredUpdate(void) { - if (!g_scheduled) - { - g_scheduled = 1; - g_timer = TimerSet(g_timer, 0, 40, rdpDeferredUpdateCallback, 0); - } + if (!g_scheduled) + { + g_scheduled = 1; + g_timer = TimerSet(g_timer, 0, 40, rdpDeferredUpdateCallback, 0); + } } /******************************************************************************/ /* returns error */ static int -rdpup_recv(char* data, int len) +rdpup_recv(char *data, int len) { - int rcvd; + int rcvd; - if (g_sck_closed) - { - return 1; - } - while (len > 0) - { - rcvd = g_tcp_recv(g_sck, data, len, 0); - if (rcvd == -1) + if (g_sck_closed) { - if (g_tcp_last_error_would_block(g_sck)) - { - g_sleep(1); - } - else - { - rdpup_disconnect(); return 1; - } } - else if (rcvd == 0) + + while (len > 0) { - rdpup_disconnect(); - return 1; + rcvd = g_tcp_recv(g_sck, data, len, 0); + + if (rcvd == -1) + { + if (g_tcp_last_error_would_block(g_sck)) + { + g_sleep(1); + } + else + { + rdpup_disconnect(); + return 1; + } + } + else if (rcvd == 0) + { + rdpup_disconnect(); + return 1; + } + else + { + data += rcvd; + len -= rcvd; + } } - else - { - data += rcvd; - len -= rcvd; - } - } - return 0; + + return 0; } /******************************************************************************/ static int -rdpup_recv_msg(struct stream* s) +rdpup_recv_msg(struct stream *s) { - int len; - int rv; + int len; + int rv; - rv = 1; - if (s != 0) - { - init_stream(s, 4); - rv = rdpup_recv(s->data, 4); - if (rv == 0) + rv = 1; + + if (s != 0) { - in_uint32_le(s, len); - if (len > 3) - { - init_stream(s, len); - rv = rdpup_recv(s->data, len - 4); - } + init_stream(s, 4); + rv = rdpup_recv(s->data, 4); + + if (rv == 0) + { + in_uint32_le(s, len); + + if (len > 3) + { + init_stream(s, len); + rv = rdpup_recv(s->data, len - 4); + } + } } - } - if (rv != 0) - { - rdpLog("error in rdpup_recv_msg\n"); - } - return rv; + + if (rv != 0) + { + rdpLog("error in rdpup_recv_msg\n"); + } + + return rv; } /******************************************************************************/ @@ -421,1022 +454,1120 @@ rdpup_recv_msg(struct stream* s) static int process_screen_size_msg(int width, int height, int bpp) { - RRScreenSizePtr pSize; - int mmwidth; - int mmheight; - Bool ok; + RRScreenSizePtr pSize; + int mmwidth; + int mmheight; + Bool ok; - LLOGLN(0, ("process_screen_size_msg: set width %d height %d bpp %d", - width, height, bpp)); - g_rdpScreen.rdp_width = width; - g_rdpScreen.rdp_height = height; - g_rdpScreen.rdp_bpp = bpp; - if (bpp < 15) - { - g_rdpScreen.rdp_Bpp = 1; - g_rdpScreen.rdp_Bpp_mask = 0xff; - } - else if (bpp == 15) - { - g_rdpScreen.rdp_Bpp = 2; - g_rdpScreen.rdp_Bpp_mask = 0x7fff; - } - else if (bpp == 16) - { - g_rdpScreen.rdp_Bpp = 2; - g_rdpScreen.rdp_Bpp_mask = 0xffff; - } - else if (bpp > 16) - { - g_rdpScreen.rdp_Bpp = 4; - g_rdpScreen.rdp_Bpp_mask = 0xffffff; - } - mmwidth = PixelToMM(width); - mmheight = PixelToMM(height); + LLOGLN(0, ("process_screen_size_msg: set width %d height %d bpp %d", + width, height, bpp)); + g_rdpScreen.rdp_width = width; + g_rdpScreen.rdp_height = height; + g_rdpScreen.rdp_bpp = bpp; - pSize = RRRegisterSize(g_pScreen, width, height, mmwidth, mmheight); - RRSetCurrentConfig(g_pScreen, RR_Rotate_0, 0, pSize); - if ((g_rdpScreen.width != width) || (g_rdpScreen.height != height)) - { - LLOGLN(0, (" calling RRScreenSizeSet")); - ok = RRScreenSizeSet(g_pScreen, width, height, mmwidth, mmheight); - LLOGLN(0, (" RRScreenSizeSet ok=[%d]", ok)); - } - return 0; + if (bpp < 15) + { + g_rdpScreen.rdp_Bpp = 1; + g_rdpScreen.rdp_Bpp_mask = 0xff; + } + else if (bpp == 15) + { + g_rdpScreen.rdp_Bpp = 2; + g_rdpScreen.rdp_Bpp_mask = 0x7fff; + } + else if (bpp == 16) + { + g_rdpScreen.rdp_Bpp = 2; + g_rdpScreen.rdp_Bpp_mask = 0xffff; + } + else if (bpp > 16) + { + g_rdpScreen.rdp_Bpp = 4; + g_rdpScreen.rdp_Bpp_mask = 0xffffff; + } + + mmwidth = PixelToMM(width); + mmheight = PixelToMM(height); + + pSize = RRRegisterSize(g_pScreen, width, height, mmwidth, mmheight); + RRSetCurrentConfig(g_pScreen, RR_Rotate_0, 0, pSize); + + if ((g_rdpScreen.width != width) || (g_rdpScreen.height != height)) + { + LLOGLN(0, (" calling RRScreenSizeSet")); + ok = RRScreenSizeSet(g_pScreen, width, height, mmwidth, mmheight); + LLOGLN(0, (" RRScreenSizeSet ok=[%d]", ok)); + } + + return 0; } /******************************************************************************/ static int l_bound_by(int val, int low, int high) { - if (val > high) - { - val = high; - } - if (val < low) - { - val = low; - } - return val; + if (val > high) + { + val = high; + } + + if (val < low) + { + val = low; + } + + return val; } /******************************************************************************/ static int rdpup_send_caps(void) { - struct stream* ls; - int len; - int rv; - int cap_count; - int cap_bytes; + struct stream *ls; + int len; + int rv; + int cap_count; + int cap_bytes; - make_stream(ls); - init_stream(ls, 8192); - s_push_layer(ls, iso_hdr, 8); + make_stream(ls); + init_stream(ls, 8192); + s_push_layer(ls, iso_hdr, 8); - cap_count = 0; - cap_bytes = 0; + cap_count = 0; + cap_bytes = 0; #if 0 - out_uint16_le(ls, 0); - out_uint16_le(ls, 4); - cap_count++; - cap_bytes += 4; + out_uint16_le(ls, 0); + out_uint16_le(ls, 4); + cap_count++; + cap_bytes += 4; - out_uint16_le(ls, 1); - out_uint16_le(ls, 4); - cap_count++; - cap_bytes += 4; + out_uint16_le(ls, 1); + out_uint16_le(ls, 4); + cap_count++; + cap_bytes += 4; #endif - s_mark_end(ls); - len = (int)(ls->end - ls->data); - s_pop_layer(ls, iso_hdr); - out_uint16_le(ls, 2); /* caps */ - out_uint16_le(ls, cap_count); /* num caps */ - out_uint32_le(ls, cap_bytes); /* caps len after header */ + s_mark_end(ls); + len = (int)(ls->end - ls->data); + s_pop_layer(ls, iso_hdr); + out_uint16_le(ls, 2); /* caps */ + out_uint16_le(ls, cap_count); /* num caps */ + out_uint32_le(ls, cap_bytes); /* caps len after header */ - rv = rdpup_send(ls->data, len); - if (rv != 0) - { - LLOGLN(0, ("rdpup_send_caps: rdpup_send failed")); - } - free_stream(ls); - return rv; + rv = rdpup_send(ls->data, len); + + if (rv != 0) + { + LLOGLN(0, ("rdpup_send_caps: rdpup_send failed")); + } + + free_stream(ls); + return rv; } /******************************************************************************/ static int process_version_msg(int param1, int param2, int param3, int param4) { - LLOGLN(0, ("process_version_msg: version %d %d %d %d", param1, param2, - param3, param4)); - if ((param1 > 0) || (param2 > 0) || (param3 > 0) || (param4 > 0)) - { - rdpup_send_caps(); - } - return 0; + LLOGLN(0, ("process_version_msg: version %d %d %d %d", param1, param2, + param3, param4)); + + if ((param1 > 0) || (param2 > 0) || (param3 > 0) || (param4 > 0)) + { + rdpup_send_caps(); + } + + return 0; } /******************************************************************************/ static int -rdpup_process_msg(struct stream* s) +rdpup_process_msg(struct stream *s) { - int msg_type; - int msg; - int param1; - int param2; - int param3; - int param4; - int bytes; - int i1; + int msg_type; + int msg; + int param1; + int param2; + int param3; + int param4; + int bytes; + int i1; - in_uint16_le(s, msg_type); - if (msg_type == 103) - { - in_uint32_le(s, msg); - in_uint32_le(s, param1); - in_uint32_le(s, param2); - in_uint32_le(s, param3); - in_uint32_le(s, param4); - LLOGLN(10, ("rdpup_process_msg - msg %d param1 %d param2 %d param3 %d " - "param4 %d", msg, param1, param2, param3, param4)); - switch (msg) + in_uint16_le(s, msg_type); + + if (msg_type == 103) { - case 15: /* key down */ - case 16: /* key up */ - KbdAddEvent(msg == 15, param1, param2, param3, param4); - break; - case 17: /* from RDP_INPUT_SYNCHRONIZE */ - KbdSync(param1); - break; - case 100: - /* without the minus 2, strange things happen when dragging - past the width or height */ - g_cursor_x = l_bound_by(param1, 0, g_rdpScreen.width - 2); - g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2); - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 101: - g_button_mask = g_button_mask & (~1); - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 102: - g_button_mask = g_button_mask | 1; - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 103: - g_button_mask = g_button_mask & (~4); - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 104: - g_button_mask = g_button_mask | 4; - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 105: - g_button_mask = g_button_mask & (~2); - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 106: - g_button_mask = g_button_mask | 2; - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 107: - g_button_mask = g_button_mask & (~8); - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 108: - g_button_mask = g_button_mask | 8; - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 109: - g_button_mask = g_button_mask & (~16); - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 110: - g_button_mask = g_button_mask | 16; - PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); - break; - case 200: - rdpup_begin_update(); - rdpup_send_area(0, (param1 >> 16) & 0xffff, param1 & 0xffff, - (param2 >> 16) & 0xffff, param2 & 0xffff); - rdpup_end_update(); - break; - case 300: - process_screen_size_msg(param1, param2, param3); - break; - case 301: - process_version_msg(param1, param2, param3, param4); - break; + in_uint32_le(s, msg); + in_uint32_le(s, param1); + in_uint32_le(s, param2); + in_uint32_le(s, param3); + in_uint32_le(s, param4); + LLOGLN(10, ("rdpup_process_msg - msg %d param1 %d param2 %d param3 %d " + "param4 %d", msg, param1, param2, param3, param4)); + + switch (msg) + { + case 15: /* key down */ + case 16: /* key up */ + KbdAddEvent(msg == 15, param1, param2, param3, param4); + break; + case 17: /* from RDP_INPUT_SYNCHRONIZE */ + KbdSync(param1); + break; + case 100: + /* without the minus 2, strange things happen when dragging + past the width or height */ + g_cursor_x = l_bound_by(param1, 0, g_rdpScreen.width - 2); + g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2); + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 101: + g_button_mask = g_button_mask & (~1); + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 102: + g_button_mask = g_button_mask | 1; + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 103: + g_button_mask = g_button_mask & (~4); + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 104: + g_button_mask = g_button_mask | 4; + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 105: + g_button_mask = g_button_mask & (~2); + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 106: + g_button_mask = g_button_mask | 2; + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 107: + g_button_mask = g_button_mask & (~8); + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 108: + g_button_mask = g_button_mask | 8; + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 109: + g_button_mask = g_button_mask & (~16); + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 110: + g_button_mask = g_button_mask | 16; + PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); + break; + case 200: + rdpup_begin_update(); + rdpup_send_area(0, (param1 >> 16) & 0xffff, param1 & 0xffff, + (param2 >> 16) & 0xffff, param2 & 0xffff); + rdpup_end_update(); + break; + case 300: + process_screen_size_msg(param1, param2, param3); + break; + case 301: + process_version_msg(param1, param2, param3, param4); + break; + } } - } - else if (msg_type == 104) - { - in_uint32_le(s, bytes); - if (bytes > sizeof(g_rdpScreen.client_info)) + else if (msg_type == 104) { - bytes = sizeof(g_rdpScreen.client_info); + in_uint32_le(s, bytes); + + if (bytes > sizeof(g_rdpScreen.client_info)) + { + bytes = sizeof(g_rdpScreen.client_info); + } + + memcpy(&(g_rdpScreen.client_info), s->p - 4, bytes); + g_rdpScreen.client_info.size = bytes; + LLOGLN(0, ("rdpup_process_msg: got client info bytes %d", bytes)); + LLOGLN(0, (" jpeg support %d", g_rdpScreen.client_info.jpeg)); + i1 = g_rdpScreen.client_info.offscreen_support_level; + LLOGLN(0, (" offscreen support %d", i1)); + i1 = g_rdpScreen.client_info.offscreen_cache_size; + LLOGLN(0, (" offscreen size %d", i1)); + i1 = g_rdpScreen.client_info.offscreen_cache_entries; + LLOGLN(0, (" offscreen entries %d", i1)); + + if (g_rdpScreen.client_info.offscreen_support_level > 0) + { + if (g_rdpScreen.client_info.offscreen_cache_entries > 0) + { + g_max_os_bitmaps = g_rdpScreen.client_info.offscreen_cache_entries; + g_free(g_os_bitmaps); + g_os_bitmaps = (struct rdpup_os_bitmap *) + g_malloc(sizeof(struct rdpup_os_bitmap) * g_max_os_bitmaps, 1); + } + } + + if (g_rdpScreen.client_info.rail_support_level > 0) + { + g_use_rail = 1; + } } - memcpy(&(g_rdpScreen.client_info), s->p - 4, bytes); - g_rdpScreen.client_info.size = bytes; - LLOGLN(0, ("rdpup_process_msg: got client info bytes %d", bytes)); - LLOGLN(0, (" jpeg support %d", g_rdpScreen.client_info.jpeg)); - i1 = g_rdpScreen.client_info.offscreen_support_level; - LLOGLN(0, (" offscreen support %d", i1)); - i1 = g_rdpScreen.client_info.offscreen_cache_size; - LLOGLN(0, (" offscreen size %d", i1)); - i1 = g_rdpScreen.client_info.offscreen_cache_entries; - LLOGLN(0, (" offscreen entries %d", i1)); - if (g_rdpScreen.client_info.offscreen_support_level > 0) + else { - if (g_rdpScreen.client_info.offscreen_cache_entries > 0) - { - g_max_os_bitmaps = g_rdpScreen.client_info.offscreen_cache_entries; - g_free(g_os_bitmaps); - g_os_bitmaps = (struct rdpup_os_bitmap*) - g_malloc(sizeof(struct rdpup_os_bitmap) * g_max_os_bitmaps, 1); - } + rdpLog("unknown message type in rdpup_process_msg %d\n", msg_type); } - if (g_rdpScreen.client_info.rail_support_level > 0) - { - g_use_rail = 1; - } - } - else - { - rdpLog("unknown message type in rdpup_process_msg %d\n", msg_type); - } - return 0; + + return 0; } /******************************************************************************/ void -rdpup_get_screen_image_rect(struct image_data* id) +rdpup_get_screen_image_rect(struct image_data *id) { - id->width = g_rdpScreen.width; - id->height = g_rdpScreen.height; - id->bpp = g_rdpScreen.rdp_bpp; - id->Bpp = g_rdpScreen.rdp_Bpp; - id->lineBytes = g_rdpScreen.paddedWidthInBytes; - id->pixels = g_rdpScreen.pfbMemory; + id->width = g_rdpScreen.width; + id->height = g_rdpScreen.height; + id->bpp = g_rdpScreen.rdp_bpp; + id->Bpp = g_rdpScreen.rdp_Bpp; + id->lineBytes = g_rdpScreen.paddedWidthInBytes; + id->pixels = g_rdpScreen.pfbMemory; } /******************************************************************************/ void -rdpup_get_pixmap_image_rect(PixmapPtr pPixmap, struct image_data* id) +rdpup_get_pixmap_image_rect(PixmapPtr pPixmap, struct image_data *id) { - id->width = pPixmap->drawable.width; - id->height = pPixmap->drawable.height; - id->bpp = g_rdpScreen.rdp_bpp; - id->Bpp = g_rdpScreen.rdp_Bpp; - id->lineBytes = pPixmap->devKind; - id->pixels = (char*)(pPixmap->devPrivate.ptr); + id->width = pPixmap->drawable.width; + id->height = pPixmap->drawable.height; + id->bpp = g_rdpScreen.rdp_bpp; + id->Bpp = g_rdpScreen.rdp_Bpp; + id->lineBytes = pPixmap->devKind; + id->pixels = (char *)(pPixmap->devPrivate.ptr); } /******************************************************************************/ int rdpup_init(void) { - char text[256]; - int i; + char text[256]; + int i; - if (!g_directory_exist("/tmp/.xrdp")) - { - if (!g_create_dir("/tmp/.xrdp")) + if (!g_directory_exist("/tmp/.xrdp")) { - LLOGLN(0, ("rdpup_init: g_create_dir failed")); - return 0; + if (!g_create_dir("/tmp/.xrdp")) + { + LLOGLN(0, ("rdpup_init: g_create_dir failed")); + return 0; + } + + g_chmod_hex("/tmp/.xrdp", 0x1777); } - g_chmod_hex("/tmp/.xrdp", 0x1777); - } - i = atoi(display); - if (i < 1) - { - return 0; - } - if (g_in_s == 0) - { - make_stream(g_in_s); - init_stream(g_in_s, 8192); - } - if (g_out_s == 0) - { - make_stream(g_out_s); - init_stream(g_out_s, 8192 * g_Bpp + 100); - } - if (g_use_uds) - { - g_sprintf(g_uds_data, "/tmp/.xrdp/xrdp_display_%s", display); - if (g_listen_sck == 0) + + i = atoi(display); + + if (i < 1) { - g_listen_sck = g_tcp_local_socket_stream(); - if (g_tcp_local_bind(g_listen_sck, g_uds_data) != 0) - { - LLOGLN(0, ("rdpup_init: g_tcp_local_bind failed")); return 0; - } - g_tcp_listen(g_listen_sck); - AddEnabledDevice(g_listen_sck); } - } - else - { - g_sprintf(text, "62%2.2d", i); - if (g_listen_sck == 0) + + if (g_in_s == 0) { - g_listen_sck = g_tcp_socket(); - if (g_tcp_bind(g_listen_sck, text) != 0) - { - return 0; - } - g_tcp_listen(g_listen_sck); - AddEnabledDevice(g_listen_sck); + make_stream(g_in_s); + init_stream(g_in_s, 8192); } - } - g_dis_listen_sck = g_tcp_local_socket_dgram(); - if (g_dis_listen_sck != 0) - { - g_sprintf(text, "/tmp/.xrdp/xrdp_disconnect_display_%s", display); - if (g_tcp_local_bind(g_dis_listen_sck, text) == 0) + + if (g_out_s == 0) { - AddEnabledDevice(g_dis_listen_sck); + make_stream(g_out_s); + init_stream(g_out_s, 8192 * g_Bpp + 100); + } + + if (g_use_uds) + { + g_sprintf(g_uds_data, "/tmp/.xrdp/xrdp_display_%s", display); + + if (g_listen_sck == 0) + { + g_listen_sck = g_tcp_local_socket_stream(); + + if (g_tcp_local_bind(g_listen_sck, g_uds_data) != 0) + { + LLOGLN(0, ("rdpup_init: g_tcp_local_bind failed")); + return 0; + } + + g_tcp_listen(g_listen_sck); + AddEnabledDevice(g_listen_sck); + } } else { - rdpLog("g_tcp_local_bind failed [%s]\n", text); + g_sprintf(text, "62%2.2d", i); + + if (g_listen_sck == 0) + { + g_listen_sck = g_tcp_socket(); + + if (g_tcp_bind(g_listen_sck, text) != 0) + { + return 0; + } + + g_tcp_listen(g_listen_sck); + AddEnabledDevice(g_listen_sck); + } } - } - return 1; + + g_dis_listen_sck = g_tcp_local_socket_dgram(); + + if (g_dis_listen_sck != 0) + { + g_sprintf(text, "/tmp/.xrdp/xrdp_disconnect_display_%s", display); + + if (g_tcp_local_bind(g_dis_listen_sck, text) == 0) + { + AddEnabledDevice(g_dis_listen_sck); + } + else + { + rdpLog("g_tcp_local_bind failed [%s]\n", text); + } + } + + return 1; } /******************************************************************************/ int rdpup_check(void) { - int sel; - int new_sck; - char buf[8]; + int sel; + int new_sck; + char buf[8]; - sel = g_tcp_select(g_listen_sck, g_sck, g_dis_listen_sck); - if (sel & 1) - { - new_sck = g_tcp_accept(g_listen_sck); - if (new_sck == -1) + sel = g_tcp_select(g_listen_sck, g_sck, g_dis_listen_sck); + + if (sel & 1) { + new_sck = g_tcp_accept(g_listen_sck); + + if (new_sck == -1) + { + } + else + { + if (g_sck != 0) + { + /* should maybe ask is user wants to allow here with timeout */ + rdpLog("replacing connection, already got a connection\n"); + rdpup_disconnect(); + } + + rdpLog("got a connection\n"); + g_sck = new_sck; + g_tcp_set_non_blocking(g_sck); + g_tcp_set_no_delay(g_sck); + g_connected = 1; + g_sck_closed = 0; + g_begin = 0; + g_con_number++; + AddEnabledDevice(g_sck); + } } - else + + if (sel & 2) { - if (g_sck != 0) - { - /* should maybe ask is user wants to allow here with timeout */ - rdpLog("replacing connection, already got a connection\n"); - rdpup_disconnect(); - } - rdpLog("got a connection\n"); - g_sck = new_sck; - g_tcp_set_non_blocking(g_sck); - g_tcp_set_no_delay(g_sck); - g_connected = 1; - g_sck_closed = 0; - g_begin = 0; - g_con_number++; - AddEnabledDevice(g_sck); + if (rdpup_recv_msg(g_in_s) == 0) + { + rdpup_process_msg(g_in_s); + } } - } - if (sel & 2) - { - if (rdpup_recv_msg(g_in_s) == 0) + + if (sel & 4) { - rdpup_process_msg(g_in_s); + if (g_tcp_recv(g_dis_listen_sck, buf, 4, 0) > 0) + { + if (g_sck != 0) + { + rdpLog("disconnecting session via user request\n"); + rdpup_disconnect(); + } + } } - } - if (sel & 4) - { - if (g_tcp_recv(g_dis_listen_sck, buf, 4, 0) > 0) - { - if (g_sck != 0) - { - rdpLog("disconnecting session via user request\n"); - rdpup_disconnect(); - } - } - } - return 0; + + return 0; } /******************************************************************************/ int rdpup_begin_update(void) { - if (g_connected) - { - if (g_begin) + if (g_connected) { - return 0; + if (g_begin) + { + return 0; + } + + init_stream(g_out_s, 0); + s_push_layer(g_out_s, iso_hdr, 8); + out_uint16_le(g_out_s, 1); /* begin update */ + out_uint16_le(g_out_s, 4); /* size */ + LLOGLN(10, ("begin %d", g_count)); + g_begin = 1; + g_count = 1; } - init_stream(g_out_s, 0); - s_push_layer(g_out_s, iso_hdr, 8); - out_uint16_le(g_out_s, 1); /* begin update */ - out_uint16_le(g_out_s, 4); /* size */ - LLOGLN(10, ("begin %d", g_count)); - g_begin = 1; - g_count = 1; - } - return 0; + + return 0; } /******************************************************************************/ int rdpup_end_update(void) { - if (g_connected && g_begin) - { - rdpScheduleDeferredUpdate(); - } - return 0; + if (g_connected && g_begin) + { + rdpScheduleDeferredUpdate(); + } + + return 0; } /******************************************************************************/ int rdpup_pre_check(int in_size) { - if (!g_begin) - { - rdpup_begin_update(); - } - if ((g_out_s->p - g_out_s->data) > (g_out_s->size - (in_size + 20))) - { - s_mark_end(g_out_s); - rdpup_send_msg(g_out_s); - g_count = 0; - init_stream(g_out_s, 0); - s_push_layer(g_out_s, iso_hdr, 8); - } - return 0; + if (!g_begin) + { + rdpup_begin_update(); + } + + if ((g_out_s->p - g_out_s->data) > (g_out_s->size - (in_size + 20))) + { + s_mark_end(g_out_s); + rdpup_send_msg(g_out_s); + g_count = 0; + init_stream(g_out_s, 0); + s_push_layer(g_out_s, iso_hdr, 8); + } + + return 0; } /******************************************************************************/ int rdpup_fill_rect(short x, short y, int cx, int cy) { - if (g_connected) - { - LLOGLN(10, (" rdpup_fill_rect")); - rdpup_pre_check(12); - out_uint16_le(g_out_s, 3); /* fill rect */ - out_uint16_le(g_out_s, 12); /* size */ - g_count++; - out_uint16_le(g_out_s, x); - out_uint16_le(g_out_s, y); - out_uint16_le(g_out_s, cx); - out_uint16_le(g_out_s, cy); - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_fill_rect")); + rdpup_pre_check(12); + out_uint16_le(g_out_s, 3); /* fill rect */ + out_uint16_le(g_out_s, 12); /* size */ + g_count++; + out_uint16_le(g_out_s, x); + out_uint16_le(g_out_s, y); + out_uint16_le(g_out_s, cx); + out_uint16_le(g_out_s, cy); + } + + return 0; } /******************************************************************************/ int rdpup_screen_blt(short x, short y, int cx, int cy, short srcx, short srcy) { - if (g_connected) - { - LLOGLN(10, (" rdpup_screen_blt")); - rdpup_pre_check(16); - out_uint16_le(g_out_s, 4); /* screen blt */ - out_uint16_le(g_out_s, 16); /* size */ - g_count++; - out_uint16_le(g_out_s, x); - out_uint16_le(g_out_s, y); - out_uint16_le(g_out_s, cx); - out_uint16_le(g_out_s, cy); - out_uint16_le(g_out_s, srcx); - out_uint16_le(g_out_s, srcy); - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_screen_blt")); + rdpup_pre_check(16); + out_uint16_le(g_out_s, 4); /* screen blt */ + out_uint16_le(g_out_s, 16); /* size */ + g_count++; + out_uint16_le(g_out_s, x); + out_uint16_le(g_out_s, y); + out_uint16_le(g_out_s, cx); + out_uint16_le(g_out_s, cy); + out_uint16_le(g_out_s, srcx); + out_uint16_le(g_out_s, srcy); + } + + return 0; } /******************************************************************************/ int rdpup_set_clip(short x, short y, int cx, int cy) { - if (g_connected) - { - LLOGLN(10, (" rdpup_set_clip")); - rdpup_pre_check(12); - out_uint16_le(g_out_s, 10); /* set clip */ - out_uint16_le(g_out_s, 12); /* size */ - g_count++; - out_uint16_le(g_out_s, x); - out_uint16_le(g_out_s, y); - out_uint16_le(g_out_s, cx); - out_uint16_le(g_out_s, cy); - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_set_clip")); + rdpup_pre_check(12); + out_uint16_le(g_out_s, 10); /* set clip */ + out_uint16_le(g_out_s, 12); /* size */ + g_count++; + out_uint16_le(g_out_s, x); + out_uint16_le(g_out_s, y); + out_uint16_le(g_out_s, cx); + out_uint16_le(g_out_s, cy); + } + + return 0; } /******************************************************************************/ int rdpup_reset_clip(void) { - if (g_connected) - { - LLOGLN(10, (" rdpup_reset_clip")); - rdpup_pre_check(4); - out_uint16_le(g_out_s, 11); /* reset clip */ - out_uint16_le(g_out_s, 4); /* size */ - g_count++; - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_reset_clip")); + rdpup_pre_check(4); + out_uint16_le(g_out_s, 11); /* reset clip */ + out_uint16_le(g_out_s, 4); /* size */ + g_count++; + } + + return 0; } #define COLOR8(r, g, b) \ - ((((r) >> 5) << 0) | (((g) >> 5) << 3) | (((b) >> 6) << 6)) + ((((r) >> 5) << 0) | (((g) >> 5) << 3) | (((b) >> 6) << 6)) #define COLOR15(r, g, b) \ - ((((r) >> 3) << 10) | (((g) >> 3) << 5) | (((b) >> 3) << 0)) + ((((r) >> 3) << 10) | (((g) >> 3) << 5) | (((b) >> 3) << 0)) #define COLOR16(r, g, b) \ - ((((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0)) + ((((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0)) #define COLOR24(r, g, b) \ - ((((r) >> 0) << 0) | (((g) >> 0) << 8) | (((b) >> 0) << 16)) + ((((r) >> 0) << 0) | (((g) >> 0) << 8) | (((b) >> 0) << 16)) #define SPLITCOLOR32(r, g, b, c) \ -{ \ - r = ((c) >> 16) & 0xff; \ - g = ((c) >> 8) & 0xff; \ - b = (c) & 0xff; \ -} + { \ + r = ((c) >> 16) & 0xff; \ + g = ((c) >> 8) & 0xff; \ + b = (c) & 0xff; \ + } int convert_pixel(int in_pixel) { - int red; - int green; - int blue; - int rv; + int red; + int green; + int blue; + int rv; - rv = 0; - if (g_rdpScreen.depth == 24) - { - if (g_rdpScreen.rdp_bpp == 24) + rv = 0; + + if (g_rdpScreen.depth == 24) { - rv = in_pixel; - SPLITCOLOR32(red, green, blue, rv); - rv = COLOR24(red, green, blue); + if (g_rdpScreen.rdp_bpp == 24) + { + rv = in_pixel; + SPLITCOLOR32(red, green, blue, rv); + rv = COLOR24(red, green, blue); + } + else if (g_rdpScreen.rdp_bpp == 16) + { + rv = in_pixel; + SPLITCOLOR32(red, green, blue, rv); + rv = COLOR16(red, green, blue); + } + else if (g_rdpScreen.rdp_bpp == 15) + { + rv = in_pixel; + SPLITCOLOR32(red, green, blue, rv); + rv = COLOR15(red, green, blue); + } + else if (g_rdpScreen.rdp_bpp == 8) + { + rv = in_pixel; + SPLITCOLOR32(red, green, blue, rv); + rv = COLOR8(red, green, blue); + } } - else if (g_rdpScreen.rdp_bpp == 16) + else if (g_rdpScreen.depth == g_rdpScreen.rdp_bpp) { - rv = in_pixel; - SPLITCOLOR32(red, green, blue, rv); - rv = COLOR16(red, green, blue); + return in_pixel; } - else if (g_rdpScreen.rdp_bpp == 15) - { - rv = in_pixel; - SPLITCOLOR32(red, green, blue, rv); - rv = COLOR15(red, green, blue); - } - else if (g_rdpScreen.rdp_bpp == 8) - { - rv = in_pixel; - SPLITCOLOR32(red, green, blue, rv); - rv = COLOR8(red, green, blue); - } - } - else if (g_rdpScreen.depth == g_rdpScreen.rdp_bpp) - { - return in_pixel; - } - return rv; + + return rv; } int -convert_pixels(void* src, void* dst, int num_pixels) +convert_pixels(void *src, void *dst, int num_pixels) { - unsigned int pixel; - unsigned int red; - unsigned int green; - unsigned int blue; - unsigned int* src32; - unsigned int* dst32; - unsigned short* dst16; - unsigned char* dst8; - int index; + unsigned int pixel; + unsigned int red; + unsigned int green; + unsigned int blue; + unsigned int *src32; + unsigned int *dst32; + unsigned short *dst16; + unsigned char *dst8; + int index; + + if (g_rdpScreen.depth == g_rdpScreen.rdp_bpp) + { + memcpy(dst, src, num_pixels * g_Bpp); + return 0; + } + + if (g_rdpScreen.depth == 24) + { + src32 = (unsigned int *)src; + + if (g_rdpScreen.rdp_bpp == 24) + { + dst32 = (unsigned int *)dst; + + for (index = 0; index < num_pixels; index++) + { + pixel = *src32; + *dst32 = pixel; + dst32++; + src32++; + } + } + else if (g_rdpScreen.rdp_bpp == 16) + { + dst16 = (unsigned short *)dst; + + for (index = 0; index < num_pixels; index++) + { + pixel = *src32; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + *dst16 = pixel; + dst16++; + src32++; + } + } + else if (g_rdpScreen.rdp_bpp == 15) + { + dst16 = (unsigned short *)dst; + + for (index = 0; index < num_pixels; index++) + { + pixel = *src32; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR15(red, green, blue); + *dst16 = pixel; + dst16++; + src32++; + } + } + else if (g_rdpScreen.rdp_bpp == 8) + { + dst8 = (unsigned char *)dst; + + for (index = 0; index < num_pixels; index++) + { + pixel = *src32; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + *dst8 = pixel; + dst8++; + src32++; + } + } + } - if (g_rdpScreen.depth == g_rdpScreen.rdp_bpp) - { - memcpy(dst, src, num_pixels * g_Bpp); return 0; - } - if (g_rdpScreen.depth == 24) - { - src32 = (unsigned int*)src; - if (g_rdpScreen.rdp_bpp == 24) - { - dst32 = (unsigned int*)dst; - for (index = 0; index < num_pixels; index++) - { - pixel = *src32; - *dst32 = pixel; - dst32++; - src32++; - } - } - else if (g_rdpScreen.rdp_bpp == 16) - { - dst16 = (unsigned short*)dst; - for (index = 0; index < num_pixels; index++) - { - pixel = *src32; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR16(red, green, blue); - *dst16 = pixel; - dst16++; - src32++; - } - } - else if (g_rdpScreen.rdp_bpp == 15) - { - dst16 = (unsigned short*)dst; - for (index = 0; index < num_pixels; index++) - { - pixel = *src32; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR15(red, green, blue); - *dst16 = pixel; - dst16++; - src32++; - } - } - else if (g_rdpScreen.rdp_bpp == 8) - { - dst8 = (unsigned char*)dst; - for (index = 0; index < num_pixels; index++) - { - pixel = *src32; - SPLITCOLOR32(red, green, blue, pixel); - pixel = COLOR8(red, green, blue); - *dst8 = pixel; - dst8++; - src32++; - } - } - } - return 0; } /******************************************************************************/ int rdpup_set_fgcolor(int fgcolor) { - if (g_connected) - { - LLOGLN(10, (" rdpup_set_fgcolor")); - rdpup_pre_check(8); - out_uint16_le(g_out_s, 12); /* set fgcolor */ - out_uint16_le(g_out_s, 8); /* size */ - g_count++; - fgcolor = fgcolor & g_Bpp_mask; - fgcolor = convert_pixel(fgcolor) & g_rdpScreen.rdp_Bpp_mask; - out_uint32_le(g_out_s, fgcolor); - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_set_fgcolor")); + rdpup_pre_check(8); + out_uint16_le(g_out_s, 12); /* set fgcolor */ + out_uint16_le(g_out_s, 8); /* size */ + g_count++; + fgcolor = fgcolor & g_Bpp_mask; + fgcolor = convert_pixel(fgcolor) & g_rdpScreen.rdp_Bpp_mask; + out_uint32_le(g_out_s, fgcolor); + } + + return 0; } /******************************************************************************/ int rdpup_set_bgcolor(int bgcolor) { - if (g_connected) - { - LLOGLN(10, (" rdpup_set_bgcolor")); - rdpup_pre_check(8); - out_uint16_le(g_out_s, 13); /* set bg color */ - out_uint16_le(g_out_s, 8); /* size */ - g_count++; - bgcolor = bgcolor & g_Bpp_mask; - bgcolor = convert_pixel(bgcolor) & g_rdpScreen.rdp_Bpp_mask; - out_uint32_le(g_out_s, bgcolor); - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_set_bgcolor")); + rdpup_pre_check(8); + out_uint16_le(g_out_s, 13); /* set bg color */ + out_uint16_le(g_out_s, 8); /* size */ + g_count++; + bgcolor = bgcolor & g_Bpp_mask; + bgcolor = convert_pixel(bgcolor) & g_rdpScreen.rdp_Bpp_mask; + out_uint32_le(g_out_s, bgcolor); + } + + return 0; } /******************************************************************************/ int rdpup_set_opcode(int opcode) { - if (g_connected) - { - LLOGLN(10, (" rdpup_set_opcode")); - rdpup_pre_check(6); - out_uint16_le(g_out_s, 14); /* set opcode */ - out_uint16_le(g_out_s, 6); /* size */ - g_count++; - out_uint16_le(g_out_s, g_rdp_opcodes[opcode & 0xf]); - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_set_opcode")); + rdpup_pre_check(6); + out_uint16_le(g_out_s, 14); /* set opcode */ + out_uint16_le(g_out_s, 6); /* size */ + g_count++; + out_uint16_le(g_out_s, g_rdp_opcodes[opcode & 0xf]); + } + + return 0; } /******************************************************************************/ int rdpup_set_pen(int style, int width) { - if (g_connected) - { - LLOGLN(10, (" rdpup_set_pen")); - rdpup_pre_check(8); - out_uint16_le(g_out_s, 17); /* set pen */ - out_uint16_le(g_out_s, 8); /* size */ - g_count++; - out_uint16_le(g_out_s, style); - out_uint16_le(g_out_s, width); - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_set_pen")); + rdpup_pre_check(8); + out_uint16_le(g_out_s, 17); /* set pen */ + out_uint16_le(g_out_s, 8); /* size */ + g_count++; + out_uint16_le(g_out_s, style); + out_uint16_le(g_out_s, width); + } + + return 0; } /******************************************************************************/ int rdpup_draw_line(short x1, short y1, short x2, short y2) { - if (g_connected) - { - LLOGLN(10, (" rdpup_draw_line")); - rdpup_pre_check(12); - out_uint16_le(g_out_s, 18); /* draw line */ - out_uint16_le(g_out_s, 12); /* size */ - g_count++; - out_uint16_le(g_out_s, x1); - out_uint16_le(g_out_s, y1); - out_uint16_le(g_out_s, x2); - out_uint16_le(g_out_s, y2); - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_draw_line")); + rdpup_pre_check(12); + out_uint16_le(g_out_s, 18); /* draw line */ + out_uint16_le(g_out_s, 12); /* size */ + g_count++; + out_uint16_le(g_out_s, x1); + out_uint16_le(g_out_s, y1); + out_uint16_le(g_out_s, x2); + out_uint16_le(g_out_s, y2); + } + + return 0; } /******************************************************************************/ int -rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask) +rdpup_set_cursor(short x, short y, char *cur_data, char *cur_mask) { - int size; + int size; - if (g_connected) - { - LLOGLN(10, (" rdpup_set_cursor")); - size = 8 + 32 * (32 * 3) + 32 * (32 / 8); - rdpup_pre_check(size); - out_uint16_le(g_out_s, 19); /* set cursor */ - out_uint16_le(g_out_s, size); /* size */ - g_count++; - x = MAX(0, x); - x = MIN(31, x); - y = MAX(0, y); - y = MIN(31, y); - out_uint16_le(g_out_s, x); - out_uint16_le(g_out_s, y); - out_uint8a(g_out_s, cur_data, 32 * (32 * 3)); - out_uint8a(g_out_s, cur_mask, 32 * (32 / 8)); - } - return 0; + if (g_connected) + { + LLOGLN(10, (" rdpup_set_cursor")); + size = 8 + 32 * (32 * 3) + 32 * (32 / 8); + rdpup_pre_check(size); + out_uint16_le(g_out_s, 19); /* set cursor */ + out_uint16_le(g_out_s, size); /* size */ + g_count++; + x = MAX(0, x); + x = MIN(31, x); + y = MAX(0, y); + y = MIN(31, y); + out_uint16_le(g_out_s, x); + out_uint16_le(g_out_s, y); + out_uint8a(g_out_s, cur_data, 32 * (32 * 3)); + out_uint8a(g_out_s, cur_mask, 32 * (32 / 8)); + } + + return 0; } /******************************************************************************/ int rdpup_create_os_surface(int rdpindex, int width, int height) { - LLOGLN(10, ("rdpup_create_os_surface:")); - if (g_connected) - { - LLOGLN(10, (" rdpup_create_os_surface width %d height %d", width, height)); - rdpup_pre_check(12); - out_uint16_le(g_out_s, 20); - out_uint16_le(g_out_s, 12); - g_count++; - out_uint32_le(g_out_s, rdpindex); - out_uint16_le(g_out_s, width); - out_uint16_le(g_out_s, height); - } - return 0; + LLOGLN(10, ("rdpup_create_os_surface:")); + + if (g_connected) + { + LLOGLN(10, (" rdpup_create_os_surface width %d height %d", width, height)); + rdpup_pre_check(12); + out_uint16_le(g_out_s, 20); + out_uint16_le(g_out_s, 12); + g_count++; + out_uint32_le(g_out_s, rdpindex); + out_uint16_le(g_out_s, width); + out_uint16_le(g_out_s, height); + } + + return 0; } /******************************************************************************/ int rdpup_switch_os_surface(int rdpindex) { - LLOGLN(10, ("rdpup_switch_os_surface:")); - if (g_connected) - { - if (g_rdpindex == rdpindex) + LLOGLN(10, ("rdpup_switch_os_surface:")); + + if (g_connected) { - return 0; + if (g_rdpindex == rdpindex) + { + return 0; + } + + g_rdpindex = rdpindex; + LLOGLN(10, ("rdpup_switch_os_surface: rdpindex %d", rdpindex)); + /* switch surface */ + rdpup_pre_check(8); + out_uint16_le(g_out_s, 21); + out_uint16_le(g_out_s, 8); + out_uint32_le(g_out_s, rdpindex); + g_count++; } - g_rdpindex = rdpindex; - LLOGLN(10, ("rdpup_switch_os_surface: rdpindex %d", rdpindex)); - /* switch surface */ - rdpup_pre_check(8); - out_uint16_le(g_out_s, 21); - out_uint16_le(g_out_s, 8); - out_uint32_le(g_out_s, rdpindex); - g_count++; - } - return 0; + + return 0; } /******************************************************************************/ int rdpup_delete_os_surface(int rdpindex) { - LLOGLN(10, ("rdpup_delete_os_surface: rdpindex %d", rdpindex)); - if (g_connected) - { LLOGLN(10, ("rdpup_delete_os_surface: rdpindex %d", rdpindex)); - rdpup_pre_check(8); - out_uint16_le(g_out_s, 22); - out_uint16_le(g_out_s, 8); - g_count++; - out_uint32_le(g_out_s, rdpindex); - } - return 0; + + if (g_connected) + { + LLOGLN(10, ("rdpup_delete_os_surface: rdpindex %d", rdpindex)); + rdpup_pre_check(8); + out_uint16_le(g_out_s, 22); + out_uint16_le(g_out_s, 8); + g_count++; + out_uint32_le(g_out_s, rdpindex); + } + + return 0; } /******************************************************************************/ static int -get_single_color(struct image_data* id, int x, int y, int w, int h) +get_single_color(struct image_data *id, int x, int y, int w, int h) { - int rv; - int i; - int j; - int p; - unsigned char* i8; - unsigned short* i16; - unsigned int* i32; + int rv; + int i; + int j; + int p; + unsigned char *i8; + unsigned short *i16; + unsigned int *i32; - p = 0; - rv = -1; - if (g_Bpp == 1) - { - for (i = 0; i < h; i++) + p = 0; + rv = -1; + + if (g_Bpp == 1) { - i8 = (unsigned char*)(id->pixels + - ((y + i) * id->lineBytes) + (x * g_Bpp)); - if (i == 0) - { - p = *i8; - } - for (j = 0; j < w; j++) - { - if (i8[j] != p) + for (i = 0; i < h; i++) { - return -1; + i8 = (unsigned char *)(id->pixels + + ((y + i) * id->lineBytes) + (x * g_Bpp)); + + if (i == 0) + { + p = *i8; + } + + for (j = 0; j < w; j++) + { + if (i8[j] != p) + { + return -1; + } + } } - } + + rv = p; } - rv = p; - } - else if (g_Bpp == 2) - { - for (i = 0; i < h; i++) + else if (g_Bpp == 2) { - i16 = (unsigned short*)(id->pixels + - ((y + i) * id->lineBytes) + (x * g_Bpp)); - if (i == 0) - { - p = *i16; - } - for (j = 0; j < w; j++) - { - if (i16[j] != p) + for (i = 0; i < h; i++) { - return -1; + i16 = (unsigned short *)(id->pixels + + ((y + i) * id->lineBytes) + (x * g_Bpp)); + + if (i == 0) + { + p = *i16; + } + + for (j = 0; j < w; j++) + { + if (i16[j] != p) + { + return -1; + } + } } - } + + rv = p; } - rv = p; - } - else if (g_Bpp == 4) - { - for (i = 0; i < h; i++) + else if (g_Bpp == 4) { - i32 = (unsigned int*)(id->pixels + - ((y + i) * id->lineBytes) + (x * g_Bpp)); - if (i == 0) - { - p = *i32; - } - for (j = 0; j < w; j++) - { - if (i32[j] != p) + for (i = 0; i < h; i++) { - return -1; + i32 = (unsigned int *)(id->pixels + + ((y + i) * id->lineBytes) + (x * g_Bpp)); + + if (i == 0) + { + p = *i32; + } + + for (j = 0; j < w; j++) + { + if (i32[j] != p) + { + return -1; + } + } } - } + + rv = p; } - rv = p; - } - return rv; + + return rv; } /******************************************************************************/ /* split the bitmap up into 64 x 64 pixel areas */ void -rdpup_send_area(struct image_data* id, int x, int y, int w, int h) +rdpup_send_area(struct image_data *id, int x, int y, int w, int h) { - char* s; - int i; - int single_color; - int lx; - int ly; - int lh; - int lw; - int size; - struct image_data lid; + char *s; + int i; + int single_color; + int lx; + int ly; + int lh; + int lw; + int size; + struct image_data lid; - LLOGLN(10, ("rdpup_send_area: id %p x %d y %d w %d h %d", id, x, y, w, h)); - if (id == 0) - { - rdpup_get_screen_image_rect(&lid); - id = &lid; - } + LLOGLN(10, ("rdpup_send_area: id %p x %d y %d w %d h %d", id, x, y, w, h)); - if (x >= id->width) - { - return; - } - if (y >= id->height) - { - return; - } - if (x < 0) - { - w += x; - x = 0; - } - if (y < 0) - { - h += y; - y = 0; - } - if (w <= 0) - { - return; - } - if (h <= 0) - { - return; - } - if (x + w > id->width) - { - w = id->width - x; - } - if (y + h > id->height) - { - h = id->height - y; - } - LLOGLN(10, ("%d", w * h)); - if (g_connected && g_begin) - { - LLOGLN(10, (" rdpup_send_area")); - ly = y; - while (ly < y + h) + if (id == 0) { - lx = x; - while (lx < x + w) - { - lw = MIN(64, (x + w) - lx); - lh = MIN(64, (y + h) - ly); - single_color = get_single_color(id, lx, ly, lw, lh); - if (single_color != -1) - { - LLOGLN(10, ("%d sending single color", g_count)); - rdpup_set_fgcolor(single_color); - rdpup_fill_rect(lx, ly, lw, lh); - } - else - { - size = lw * lh * id->Bpp + 24; - rdpup_pre_check(size); - out_uint16_le(g_out_s, 5); - out_uint16_le(g_out_s, size); - g_count++; - out_uint16_le(g_out_s, lx); - out_uint16_le(g_out_s, ly); - out_uint16_le(g_out_s, lw); - out_uint16_le(g_out_s, lh); - out_uint32_le(g_out_s, lw * lh * id->Bpp); - for (i = 0; i < lh; i++) - { - s = (id->pixels + - ((ly + i) * id->lineBytes) + (lx * g_Bpp)); - convert_pixels(s, g_out_s->p, lw); - g_out_s->p += lw * id->Bpp; - } - out_uint16_le(g_out_s, lw); - out_uint16_le(g_out_s, lh); - out_uint16_le(g_out_s, 0); - out_uint16_le(g_out_s, 0); - } - lx += 64; - } - ly += 64; + rdpup_get_screen_image_rect(&lid); + id = &lid; + } + + if (x >= id->width) + { + return; + } + + if (y >= id->height) + { + return; + } + + if (x < 0) + { + w += x; + x = 0; + } + + if (y < 0) + { + h += y; + y = 0; + } + + if (w <= 0) + { + return; + } + + if (h <= 0) + { + return; + } + + if (x + w > id->width) + { + w = id->width - x; + } + + if (y + h > id->height) + { + h = id->height - y; + } + + LLOGLN(10, ("%d", w * h)); + + if (g_connected && g_begin) + { + LLOGLN(10, (" rdpup_send_area")); + ly = y; + + while (ly < y + h) + { + lx = x; + + while (lx < x + w) + { + lw = MIN(64, (x + w) - lx); + lh = MIN(64, (y + h) - ly); + single_color = get_single_color(id, lx, ly, lw, lh); + + if (single_color != -1) + { + LLOGLN(10, ("%d sending single color", g_count)); + rdpup_set_fgcolor(single_color); + rdpup_fill_rect(lx, ly, lw, lh); + } + else + { + size = lw * lh * id->Bpp + 24; + rdpup_pre_check(size); + out_uint16_le(g_out_s, 5); + out_uint16_le(g_out_s, size); + g_count++; + out_uint16_le(g_out_s, lx); + out_uint16_le(g_out_s, ly); + out_uint16_le(g_out_s, lw); + out_uint16_le(g_out_s, lh); + out_uint32_le(g_out_s, lw * lh * id->Bpp); + + for (i = 0; i < lh; i++) + { + s = (id->pixels + + ((ly + i) * id->lineBytes) + (lx * g_Bpp)); + convert_pixels(s, g_out_s->p, lw); + g_out_s->p += lw * id->Bpp; + } + + out_uint16_le(g_out_s, lw); + out_uint16_le(g_out_s, lh); + out_uint16_le(g_out_s, 0); + out_uint16_le(g_out_s, 0); + } + + lx += 64; + } + + ly += 64; + } } - } } /******************************************************************************/ @@ -1444,262 +1575,283 @@ void rdpup_paint_rect_os(int x, int y, int cx, int cy, int rdpindex, int srcx, int srcy) { - if (g_connected) - { - rdpup_pre_check(20); - out_uint16_le(g_out_s, 23); - out_uint16_le(g_out_s, 20); - g_count++; - out_uint16_le(g_out_s, x); - out_uint16_le(g_out_s, y); - out_uint16_le(g_out_s, cx); - out_uint16_le(g_out_s, cy); - out_uint32_le(g_out_s, rdpindex); - out_uint16_le(g_out_s, srcx); - out_uint16_le(g_out_s, srcy); - } + if (g_connected) + { + rdpup_pre_check(20); + out_uint16_le(g_out_s, 23); + out_uint16_le(g_out_s, 20); + g_count++; + out_uint16_le(g_out_s, x); + out_uint16_le(g_out_s, y); + out_uint16_le(g_out_s, cx); + out_uint16_le(g_out_s, cy); + out_uint32_le(g_out_s, rdpindex); + out_uint16_le(g_out_s, srcx); + out_uint16_le(g_out_s, srcy); + } } /******************************************************************************/ void rdpup_set_hints(int hints, int mask) { - if (g_connected) - { - rdpup_pre_check(12); - out_uint16_le(g_out_s, 24); - out_uint16_le(g_out_s, 12); - g_count++; - out_uint32_le(g_out_s, hints); - out_uint32_le(g_out_s, mask); - } + if (g_connected) + { + rdpup_pre_check(12); + out_uint16_le(g_out_s, 24); + out_uint16_le(g_out_s, 12); + g_count++; + out_uint32_le(g_out_s, hints); + out_uint32_le(g_out_s, mask); + } } /******************************************************************************/ void -rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv) +rdpup_create_window(WindowPtr pWindow, rdpWindowRec *priv) { - int bytes; - int index; - int flags; - int num_window_rects; - int num_visibility_rects; - int title_bytes; - int style; - int ext_style; - int root_id; - char title[256]; + int bytes; + int index; + int flags; + int num_window_rects; + int num_visibility_rects; + int title_bytes; + int style; + int ext_style; + int root_id; + char title[256]; - LLOGLN(10, ("rdpup_create_window: id 0x%8.8x", pWindow->drawable.id)); - if (g_connected) - { - root_id = pWindow->drawable.pScreen->root->drawable.id; + LLOGLN(10, ("rdpup_create_window: id 0x%8.8x", pWindow->drawable.id)); - if (pWindow->overrideRedirect) + if (g_connected) { - style = XR_STYLE_TOOLTIP; - ext_style = XR_EXT_STYLE_TOOLTIP; + root_id = pWindow->drawable.pScreen->root->drawable.id; + + if (pWindow->overrideRedirect) + { + style = XR_STYLE_TOOLTIP; + ext_style = XR_EXT_STYLE_TOOLTIP; + } + else + { + style = XR_STYLE_NORMAL; + ext_style = XR_EXT_STYLE_NORMAL; + } + + flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_NEW; + strcpy(title, "title"); + title_bytes = strlen(title); + + num_window_rects = 1; + num_visibility_rects = 1; + + /* calculate bytes */ + bytes = (2 + 2) + (5 * 4) + (2 + title_bytes) + (12 * 4) + + (2 + num_window_rects * 8) + (4 + 4) + + (2 + num_visibility_rects * 8) + 4; + + rdpup_pre_check(bytes); + out_uint16_le(g_out_s, 25); + out_uint16_le(g_out_s, bytes); + g_count++; + out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */ + out_uint32_le(g_out_s, pWindow->parent->drawable.id); /* owner_window_id */ + flags |= WINDOW_ORDER_FIELD_OWNER; + out_uint32_le(g_out_s, style); /* style */ + out_uint32_le(g_out_s, ext_style); /* extended_style */ + flags |= WINDOW_ORDER_FIELD_STYLE; + out_uint32_le(g_out_s, 0); /* show_state */ + flags |= WINDOW_ORDER_FIELD_SHOW; + out_uint16_le(g_out_s, title_bytes); /* title_info */ + out_uint8a(g_out_s, title, title_bytes); + flags |= WINDOW_ORDER_FIELD_TITLE; + out_uint32_le(g_out_s, 0); /* client_offset_x */ + out_uint32_le(g_out_s, 0); /* client_offset_y */ + flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET; + out_uint32_le(g_out_s, pWindow->drawable.width); /* client_area_width */ + out_uint32_le(g_out_s, pWindow->drawable.height); /* client_area_height */ + flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE; + out_uint32_le(g_out_s, 0); /* rp_content */ + out_uint32_le(g_out_s, root_id); /* root_parent_handle */ + flags |= WINDOW_ORDER_FIELD_ROOT_PARENT; + out_uint32_le(g_out_s, pWindow->drawable.x); /* window_offset_x */ + out_uint32_le(g_out_s, pWindow->drawable.y); /* window_offset_y */ + flags |= WINDOW_ORDER_FIELD_WND_OFFSET; + out_uint32_le(g_out_s, 0); /* window_client_delta_x */ + out_uint32_le(g_out_s, 0); /* window_client_delta_y */ + flags |= WINDOW_ORDER_FIELD_WND_CLIENT_DELTA; + out_uint32_le(g_out_s, pWindow->drawable.width); /* window_width */ + out_uint32_le(g_out_s, pWindow->drawable.height); /* window_height */ + flags |= WINDOW_ORDER_FIELD_WND_SIZE; + out_uint16_le(g_out_s, num_window_rects); /* num_window_rects */ + + for (index = 0; index < num_window_rects; index++) + { + out_uint16_le(g_out_s, 0); /* left */ + out_uint16_le(g_out_s, 0); /* top */ + out_uint16_le(g_out_s, pWindow->drawable.width); /* right */ + out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */ + } + + flags |= WINDOW_ORDER_FIELD_WND_RECTS; + out_uint32_le(g_out_s, 0); /* visible_offset_x */ + out_uint32_le(g_out_s, 0); /* visible_offset_y */ + flags |= WINDOW_ORDER_FIELD_VIS_OFFSET; + out_uint16_le(g_out_s, num_visibility_rects); /* num_visibility_rects */ + + for (index = 0; index < num_visibility_rects; index++) + { + out_uint16_le(g_out_s, 0); /* left */ + out_uint16_le(g_out_s, 0); /* top */ + out_uint16_le(g_out_s, pWindow->drawable.width); /* right */ + out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */ + } + + flags |= WINDOW_ORDER_FIELD_VISIBILITY; + + out_uint32_le(g_out_s, flags); /* flags */ } - else - { - style = XR_STYLE_NORMAL; - ext_style = XR_EXT_STYLE_NORMAL; - } - - flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_NEW; - strcpy(title, "title"); - title_bytes = strlen(title); - - num_window_rects = 1; - num_visibility_rects = 1; - - /* calculate bytes */ - bytes = (2 + 2) + (5 * 4) + (2 + title_bytes) + (12 * 4) + - (2 + num_window_rects * 8) + (4 + 4) + - (2 + num_visibility_rects * 8) + 4; - - rdpup_pre_check(bytes); - out_uint16_le(g_out_s, 25); - out_uint16_le(g_out_s, bytes); - g_count++; - out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */ - out_uint32_le(g_out_s, pWindow->parent->drawable.id); /* owner_window_id */ - flags |= WINDOW_ORDER_FIELD_OWNER; - out_uint32_le(g_out_s, style); /* style */ - out_uint32_le(g_out_s, ext_style); /* extended_style */ - flags |= WINDOW_ORDER_FIELD_STYLE; - out_uint32_le(g_out_s, 0); /* show_state */ - flags |= WINDOW_ORDER_FIELD_SHOW; - out_uint16_le(g_out_s, title_bytes); /* title_info */ - out_uint8a(g_out_s, title, title_bytes); - flags |= WINDOW_ORDER_FIELD_TITLE; - out_uint32_le(g_out_s, 0); /* client_offset_x */ - out_uint32_le(g_out_s, 0); /* client_offset_y */ - flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET; - out_uint32_le(g_out_s, pWindow->drawable.width); /* client_area_width */ - out_uint32_le(g_out_s, pWindow->drawable.height); /* client_area_height */ - flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE; - out_uint32_le(g_out_s, 0); /* rp_content */ - out_uint32_le(g_out_s, root_id); /* root_parent_handle */ - flags |= WINDOW_ORDER_FIELD_ROOT_PARENT; - out_uint32_le(g_out_s, pWindow->drawable.x); /* window_offset_x */ - out_uint32_le(g_out_s, pWindow->drawable.y); /* window_offset_y */ - flags |= WINDOW_ORDER_FIELD_WND_OFFSET; - out_uint32_le(g_out_s, 0); /* window_client_delta_x */ - out_uint32_le(g_out_s, 0); /* window_client_delta_y */ - flags |= WINDOW_ORDER_FIELD_WND_CLIENT_DELTA; - out_uint32_le(g_out_s, pWindow->drawable.width); /* window_width */ - out_uint32_le(g_out_s, pWindow->drawable.height); /* window_height */ - flags |= WINDOW_ORDER_FIELD_WND_SIZE; - out_uint16_le(g_out_s, num_window_rects); /* num_window_rects */ - for (index = 0; index < num_window_rects; index++) - { - out_uint16_le(g_out_s, 0); /* left */ - out_uint16_le(g_out_s, 0); /* top */ - out_uint16_le(g_out_s, pWindow->drawable.width); /* right */ - out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */ - } - flags |= WINDOW_ORDER_FIELD_WND_RECTS; - out_uint32_le(g_out_s, 0); /* visible_offset_x */ - out_uint32_le(g_out_s, 0); /* visible_offset_y */ - flags |= WINDOW_ORDER_FIELD_VIS_OFFSET; - out_uint16_le(g_out_s, num_visibility_rects); /* num_visibility_rects */ - for (index = 0; index < num_visibility_rects; index++) - { - out_uint16_le(g_out_s, 0); /* left */ - out_uint16_le(g_out_s, 0); /* top */ - out_uint16_le(g_out_s, pWindow->drawable.width); /* right */ - out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */ - } - flags |= WINDOW_ORDER_FIELD_VISIBILITY; - - out_uint32_le(g_out_s, flags); /* flags */ - } } /******************************************************************************/ void -rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv) +rdpup_delete_window(WindowPtr pWindow, rdpWindowRec *priv) { - LLOGLN(10, ("rdpup_delete_window: id 0x%8.8x", pWindow->drawable.id)); - if (g_connected) - { - rdpup_pre_check(8); - out_uint16_le(g_out_s, 26); - out_uint16_le(g_out_s, 8); - g_count++; - out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */ - } + LLOGLN(10, ("rdpup_delete_window: id 0x%8.8x", pWindow->drawable.id)); + + if (g_connected) + { + rdpup_pre_check(8); + out_uint16_le(g_out_s, 26); + out_uint16_le(g_out_s, 8); + g_count++; + out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */ + } } /******************************************************************************/ int -rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv) +rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec *pDirtyPriv) { - int index; - int clip_index; - int count; - int num_clips; - BoxRec box; - xSegment* seg; - struct image_data id; - struct rdp_draw_item* di; + int index; + int clip_index; + int count; + int num_clips; + BoxRec box; + xSegment *seg; + struct image_data id; + struct rdp_draw_item *di; - if (pDirtyPriv == 0) - { - return 0; - } - if (pDirtyPriv->is_dirty == 0) - { - return 0; - } - - /* update use time / count */ - g_os_bitmaps[pDirtyPriv->rdpindex].stamp = g_os_bitmap_stamp; - g_os_bitmap_stamp++; - - LLOGLN(10, ("-----------------got dirty")); - rdpup_switch_os_surface(pDirtyPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDirtyPixmap, &id); - rdpup_begin_update(); - draw_item_pack(pDirtyPriv); - di = pDirtyPriv->draw_item_head; - while (di != 0) - { - LLOGLN(10, ("rdpup_check_dirty: type %d", di->type)); - switch (di->type) + if (pDirtyPriv == 0) { - case RDI_FILL: - rdpup_set_fgcolor(di->u.fill.fg_color); - rdpup_set_opcode(di->u.fill.opcode); - count = REGION_NUM_RECTS(di->reg); - for (index = 0; index < count; index++) - { - box = REGION_RECTS(di->reg)[index]; - LLOGLN(10, (" RDI_FILL %d %d %d %d", box.x1, box.y1, - box.x2, box.y2)); - rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } - rdpup_set_opcode(GXcopy); - break; - case RDI_IMGLL: - rdpup_set_hints(1, 1); - rdpup_set_opcode(di->u.img.opcode); - count = REGION_NUM_RECTS(di->reg); - for (index = 0; index < count; index++) - { - box = REGION_RECTS(di->reg)[index]; - LLOGLN(10, (" RDI_IMGLL %d %d %d %d", box.x1, box.y1, - box.x2, box.y2)); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); - } - rdpup_set_opcode(GXcopy); - rdpup_set_hints(0, 1); - break; - case RDI_IMGLY: - rdpup_set_opcode(di->u.img.opcode); - count = REGION_NUM_RECTS(di->reg); - for (index = 0; index < count; index++) - { - box = REGION_RECTS(di->reg)[index]; - LLOGLN(10, (" RDI_IMGLY %d %d %d %d", box.x1, box.y1, - box.x2, box.y2)); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); - } - rdpup_set_opcode(GXcopy); - break; - case RDI_LINE: - LLOGLN(10, (" RDI_LINE")); - num_clips = REGION_NUM_RECTS(di->reg); - if (num_clips > 0) - { - rdpup_set_fgcolor(di->u.line.fg_color); - rdpup_set_opcode(di->u.line.opcode); - rdpup_set_pen(0, di->u.line.width); - for (clip_index = num_clips - 1; clip_index >= 0; clip_index--) - { - box = REGION_RECTS(di->reg)[clip_index]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - for (index = 0; index < di->u.line.nseg; index++) - { - seg = di->u.line.segs + index; - LLOGLN(10, (" RDI_LINE %d %d %d %d", seg->x1, seg->y1, - seg->x2, seg->y2)); - rdpup_draw_line(seg->x1, seg->y1, seg->x2, seg->y2); - } - } - } - rdpup_reset_clip(); - rdpup_set_opcode(GXcopy); - break; + return 0; } - di = di->next; - } - draw_item_remove_all(pDirtyPriv); - rdpup_end_update(); - pDirtyPriv->is_dirty = 0; - rdpup_switch_os_surface(-1); - return 0; + + if (pDirtyPriv->is_dirty == 0) + { + return 0; + } + + /* update use time / count */ + g_os_bitmaps[pDirtyPriv->rdpindex].stamp = g_os_bitmap_stamp; + g_os_bitmap_stamp++; + + LLOGLN(10, ("-----------------got dirty")); + rdpup_switch_os_surface(pDirtyPriv->rdpindex); + rdpup_get_pixmap_image_rect(pDirtyPixmap, &id); + rdpup_begin_update(); + draw_item_pack(pDirtyPriv); + di = pDirtyPriv->draw_item_head; + + while (di != 0) + { + LLOGLN(10, ("rdpup_check_dirty: type %d", di->type)); + + switch (di->type) + { + case RDI_FILL: + rdpup_set_fgcolor(di->u.fill.fg_color); + rdpup_set_opcode(di->u.fill.opcode); + count = REGION_NUM_RECTS(di->reg); + + for (index = 0; index < count; index++) + { + box = REGION_RECTS(di->reg)[index]; + LLOGLN(10, (" RDI_FILL %d %d %d %d", box.x1, box.y1, + box.x2, box.y2)); + rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + + rdpup_set_opcode(GXcopy); + break; + case RDI_IMGLL: + rdpup_set_hints(1, 1); + rdpup_set_opcode(di->u.img.opcode); + count = REGION_NUM_RECTS(di->reg); + + for (index = 0; index < count; index++) + { + box = REGION_RECTS(di->reg)[index]; + LLOGLN(10, (" RDI_IMGLL %d %d %d %d", box.x1, box.y1, + box.x2, box.y2)); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + + rdpup_set_opcode(GXcopy); + rdpup_set_hints(0, 1); + break; + case RDI_IMGLY: + rdpup_set_opcode(di->u.img.opcode); + count = REGION_NUM_RECTS(di->reg); + + for (index = 0; index < count; index++) + { + box = REGION_RECTS(di->reg)[index]; + LLOGLN(10, (" RDI_IMGLY %d %d %d %d", box.x1, box.y1, + box.x2, box.y2)); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + + rdpup_set_opcode(GXcopy); + break; + case RDI_LINE: + LLOGLN(10, (" RDI_LINE")); + num_clips = REGION_NUM_RECTS(di->reg); + + if (num_clips > 0) + { + rdpup_set_fgcolor(di->u.line.fg_color); + rdpup_set_opcode(di->u.line.opcode); + rdpup_set_pen(0, di->u.line.width); + + for (clip_index = num_clips - 1; clip_index >= 0; clip_index--) + { + box = REGION_RECTS(di->reg)[clip_index]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + + for (index = 0; index < di->u.line.nseg; index++) + { + seg = di->u.line.segs + index; + LLOGLN(10, (" RDI_LINE %d %d %d %d", seg->x1, seg->y1, + seg->x2, seg->y2)); + rdpup_draw_line(seg->x1, seg->y1, seg->x2, seg->y2); + } + } + } + + rdpup_reset_clip(); + rdpup_set_opcode(GXcopy); + break; + } + + di = di->next; + } + + draw_item_remove_all(pDirtyPriv); + rdpup_end_update(); + pDirtyPriv->is_dirty = 0; + rdpup_switch_os_surface(-1); + return 0; } diff --git a/xorg/tests/client.sh b/xorg/tests/nx/client.sh similarity index 100% rename from xorg/tests/client.sh rename to xorg/tests/nx/client.sh diff --git a/xorg/tests/server.sh b/xorg/tests/nx/server.sh similarity index 100% rename from xorg/tests/server.sh rename to xorg/tests/nx/server.sh diff --git a/xorg/tests/tcp_proxy/Makefile b/xorg/tests/tcp_proxy/Makefile deleted file mode 100644 index eeb33711..00000000 --- a/xorg/tests/tcp_proxy/Makefile +++ /dev/null @@ -1,15 +0,0 @@ - -XRDP_INSTALL_BASE=/home/jay/xrdpinst - -OBJS = main.o -CFLAGS = -O2 -Wall -I../../../common -LDFLAGS = -Wl,-rpath,$(XRDP_INSTALL_BASE)/lib/xrdp -LIBS = -L$(XRDP_INSTALL_BASE)/lib/xrdp -ldl -lcommon - -all: tcp_proxy - -tcp_proxy: $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -o tcp_proxy $(OBJS) $(LIBS) - -clean: - rm -f $(OBJS) tcp_proxy diff --git a/xorg/tests/tcp_proxy/main.c b/xorg/tests/tcp_proxy/main.c deleted file mode 100644 index 0e6f4fe3..00000000 --- a/xorg/tests/tcp_proxy/main.c +++ /dev/null @@ -1,265 +0,0 @@ - -#include "os_calls.h" - -int g_loc_io_count = 0; // bytes read from local port -int g_rem_io_count = 0; // bytes read from remote port - -static int g_terminated = 0; -static char g_buf[1024 * 32]; - -/*****************************************************************************/ -static int -main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump) -{ - int lis_sck; - int acc_sck; - int con_sck; - int sel; - int count; - int sent; - int error; - int i; - int acc_to_con; - int con_to_acc; - - acc_to_con = 0; - con_to_acc = 0; - acc_sck = 0; - - /* create the listening socket and setup options */ - lis_sck = g_tcp_socket(); - g_tcp_set_non_blocking(lis_sck); - error = g_tcp_bind(lis_sck, local_port); - if (error != 0) - { - g_writeln("bind failed"); - } - - /* listen for an incomming connection */ - if (error == 0) - { - error = g_tcp_listen(lis_sck); - if (error == 0) - { - g_writeln("listening for connection"); - } - } - - /* accept an incomming connection */ - if (error == 0) - { - while ((!g_terminated) && (error == 0)) - { - acc_sck = g_tcp_accept(lis_sck); - if ((acc_sck == -1) && g_tcp_last_error_would_block(lis_sck)) - { - g_sleep(100); - } - else if (acc_sck == -1) - { - error = 1; - } - else - { - break; - } - } - if (error == 0) - { - error = g_terminated; - } - - /* stop listening */ - g_tcp_close(lis_sck); - lis_sck = 0; - if (error == 0) - { - g_writeln("got connection"); - } - } - - /* connect outgoing socket */ - con_sck = 0; - if (error == 0) - { - con_sck = g_tcp_socket(); - g_tcp_set_non_blocking(con_sck); - error = g_tcp_connect(con_sck, remote_ip, remote_port); - if ((error == -1) && g_tcp_last_error_would_block(con_sck)) - { - error = 0; - i = 0; - while ((!g_tcp_can_send(con_sck, 100)) && (!g_terminated) && (i < 100)) - { - g_sleep(100); - i++; - } - if (i > 99) - { - g_writeln("timout connecting"); - error = 1; - } - if (g_terminated) - { - error = 1; - } - } - if ((error != 0) && (!g_terminated)) - { - g_writeln("error connecting to remote\r\n"); - } - } - while ((!g_terminated) && (error == 0)) - { - sel = g_tcp_select(con_sck, acc_sck); - if (sel == 0) - { - g_sleep(10); - continue; - } - if (sel & 1) - { - // can read from con_sck w/o blocking - count = g_tcp_recv(con_sck, g_buf, 1024 * 16, 0); - error = count < 1; - if (error == 0) - { - g_loc_io_count += count; - con_to_acc += count; - if (hexdump) - { - g_writeln("from remove, the socket from connect"); - g_hexdump(g_buf, count); - } -#if 0 - g_writeln("local_io_count: %d\tremote_io_count: %d", - g_loc_io_count, g_rem_io_count); -#endif - sent = 0; - while ((sent < count) && (error == 0) && (!g_terminated)) - { - i = g_tcp_send(acc_sck, g_buf + sent, count - sent, 0); - if ((i == -1) && g_tcp_last_error_would_block(acc_sck)) - { - g_tcp_can_send(acc_sck, 1000); - } - else if (i < 1) - { - error = 1; - } - else - { - sent += i; - } - } - } - } - if (sel & 2) - { - // can read from acc_sck w/o blocking - count = g_tcp_recv(acc_sck, g_buf, 1024 * 16, 0); - error = count < 1; - if (error == 0) - { - g_rem_io_count += count; - acc_to_con += count; - if (hexdump) - { - g_writeln("from accepted, the socket from accept"); - g_hexdump(g_buf, count); - } -#if 0 - g_writeln("local_io_count: %d\tremote_io_count: %d", - g_loc_io_count, g_rem_io_count); -#endif - sent = 0; - while ((sent < count) && (error == 0) && (!g_terminated)) - { - i = g_tcp_send(con_sck, g_buf + sent, count - sent, 0); - if ((i == -1) && g_tcp_last_error_would_block(con_sck)) - { - g_tcp_can_send(con_sck, 1000); - } - else if (i < 1) - { - error = 1; - } - else - { - sent += i; - } - } - } - } - } - g_tcp_close(lis_sck); - g_tcp_close(con_sck); - g_tcp_close(acc_sck); - g_writeln("acc_to_con %d", acc_to_con); - g_writeln("con_to_acc %d", con_to_acc); - return 0; -} - - -/*****************************************************************************/ -static int -usage(void) -{ - g_writeln("tcp_proxy [dump]"); - return 0; -} - - -/*****************************************************************************/ -void -proxy_shutdown(int sig) -{ - g_writeln("shutting down"); - g_terminated = 1; -} - -void -clear_counters(int sig) -{ - g_writeln("cleared counters at: local_io_count: %d remote_io_count: %d", - g_loc_io_count, g_rem_io_count); - g_loc_io_count = 0; - g_rem_io_count = 0; -} - -/*****************************************************************************/ -int -main(int argc, char** argv) -{ - int dump; - - if (argc < 4) - { - usage(); - return 0; - } - g_init("tcp_proxy"); - g_signal_user_interrupt(proxy_shutdown); /* SIGINT */ - g_signal_kill(proxy_shutdown); /* SIGKILL */ - g_signal_usr1(clear_counters); /* SIGUSR1*/ - g_signal_terminate(proxy_shutdown); /* SIGTERM */ - if (argc < 5) - { - while (!g_terminated) - { - g_loc_io_count = 0; - g_rem_io_count = 0; - main_loop(argv[1], argv[2], argv[3], 0); - } - } - else - { - dump = g_strcasecmp(argv[4], "dump") == 0; - while (!g_terminated) - { - main_loop(argv[1], argv[2], argv[3], dump); - } - } - g_deinit(); - return 0; -} diff --git a/xorg/tests/xdemo/README.txt b/xorg/tests/xdemo/README.txt index 52bda08c..2bb59358 100644 --- a/xorg/tests/xdemo/README.txt +++ b/xorg/tests/xdemo/README.txt @@ -1,3 +1,3 @@ -this is a project to develope a program to test xwindows +this is a program to test xwindows diff --git a/xorg/tests/xdemo/bmp_parser.c b/xorg/tests/xdemo/bmp_parser.c index 9d3e43c8..66c050d8 100644 --- a/xorg/tests/xdemo/bmp_parser.c +++ b/xorg/tests/xdemo/bmp_parser.c @@ -1,3 +1,21 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Laxmikant Rashinkar 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include #include #include @@ -50,13 +68,15 @@ int parse_bmp(char *filename, struct pic_info *pic_info) struct bmp_hdr bmp_hdr; struct dib_hdr dib_hdr; - if ((fd = open(filename, O_RDONLY)) < 0) { + if ((fd = open(filename, O_RDONLY)) < 0) + { printf("error opeing %s\n", filename); return -1; } // read BMP magic... - if ((rval = read(fd, magic.magic, 2)) != 2) { + if ((rval = read(fd, magic.magic, 2)) != 2) + { fprintf(stderr, "error reading BMP signature from file %s\n", filename); return -1; } @@ -64,44 +84,53 @@ int parse_bmp(char *filename, struct pic_info *pic_info) got_magic = 0; // ...and confirm that this is indeed a BMP file - if ((magic.magic[0] == 'B') && (magic.magic[1] == 'M')) { + if ((magic.magic[0] == 'B') && (magic.magic[1] == 'M')) + { // BM – Windows 3.1x, 95, NT, ... etc got_magic = 1; } - else if ((magic.magic[0] == 'B') && (magic.magic[1] == 'A')) { + else if ((magic.magic[0] == 'B') && (magic.magic[1] == 'A')) + { // BA – OS/2 struct Bitmap Array got_magic = 1; } - else if ((magic.magic[0] == 'C') && (magic.magic[1] == 'I')) { + else if ((magic.magic[0] == 'C') && (magic.magic[1] == 'I')) + { // CI – OS/2 struct Color Icon got_magic = 1; } - else if ((magic.magic[0] == 'C') && (magic.magic[1] == 'P')) { + else if ((magic.magic[0] == 'C') && (magic.magic[1] == 'P')) + { // CP – OS/2 const Color Pointer got_magic = 1; } - else if ((magic.magic[0] == 'I') && (magic.magic[1] == 'C')) { + else if ((magic.magic[0] == 'I') && (magic.magic[1] == 'C')) + { // IC – OS/2 struct Icon got_magic = 1; } - else if ((magic.magic[0] == 'P') && (magic.magic[1] == 'T')) { + else if ((magic.magic[0] == 'P') && (magic.magic[1] == 'T')) + { // PT – OS/2 Pointer got_magic = 1; } - if (!got_magic) { + if (!got_magic) + { fprintf(stderr, "%s is not a valid BMP file\n", filename); return -1; } // read BMP header - if ((rval = read(fd, &bmp_hdr, sizeof(bmp_hdr))) < sizeof(bmp_hdr)) { + if ((rval = read(fd, &bmp_hdr, sizeof(bmp_hdr))) < sizeof(bmp_hdr)) + { fprintf(stderr, "error BMP header from file %s\n", filename); return -1; } // read DIB header - if ((rval = read(fd, &dib_hdr, sizeof(dib_hdr))) < sizeof(dib_hdr)) { + if ((rval = read(fd, &dib_hdr, sizeof(dib_hdr))) < sizeof(dib_hdr)) + { fprintf(stderr, "error reading DIB header from file %s\n", filename); return -1; } @@ -120,7 +149,8 @@ int parse_bmp(char *filename, struct pic_info *pic_info) printf("nimpcolors: %d\n", dib_hdr.nimpcolors); #endif - if (dib_hdr.compress_type) { + if (dib_hdr.compress_type) + { printf("TODO: compressed images not yet supported\n"); return -1; } @@ -128,9 +158,11 @@ int parse_bmp(char *filename, struct pic_info *pic_info) pic_info->width = dib_hdr.width; pic_info->height = dib_hdr.height; - if (dib_hdr.bpp == 24) { + if (dib_hdr.bpp == 24) + { rval = parse_bmp_24(&bmp_hdr, &dib_hdr, fd, pic_info); } + close(fd); return rval; } @@ -189,6 +221,7 @@ int parse_bmp_24( for (i = 0; i < h; i ++) { cptr = ptr_file_data; + for (j = 0; j < w; j++) { *ptr_mem_data++ = *cptr++; // blue value @@ -196,6 +229,7 @@ int parse_bmp_24( *ptr_mem_data++ = *cptr++; // red value *ptr_mem_data++ = 0; // alpha channel } + ptr_file_data -= bpl; } diff --git a/xorg/tests/xdemo/common.h b/xorg/tests/xdemo/common.h index 2ce75bba..8ed4ee65 100644 --- a/xorg/tests/xdemo/common.h +++ b/xorg/tests/xdemo/common.h @@ -1,3 +1,21 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Laxmikant Rashinkar 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef __XDEMO_H #define __XDEMO_H diff --git a/xorg/tests/xdemo/xdemo.c b/xorg/tests/xdemo/xdemo.c index 01bd248e..f7e6b0ef 100644 --- a/xorg/tests/xdemo/xdemo.c +++ b/xorg/tests/xdemo/xdemo.c @@ -1,3 +1,21 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Laxmikant Rashinkar 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include #include #include @@ -78,7 +96,8 @@ int drawLines(int count) int i; int index; - if (count <= 0) { + if (count <= 0) + { return 0; // nothing to do } @@ -92,14 +111,18 @@ int drawLines(int count) x2 = random() % g_winWidth; y2 = random() % g_winHeight; XSetForeground(g_disp, g_gc, g_colors[index++].pixel); - if (index == MAX_COLORS) { + + if (index == MAX_COLORS) + { index = 0; } + // from-to XDrawLine(g_disp, g_win, g_gc, x1, y1, x2, y2); XFlush(g_disp); usleep(g_delay_dur); } + return 0; } @@ -114,7 +137,8 @@ int drawRectangles(int count) int i; int index; - if (count <= 0) { + if (count <= 0) + { return 0; // nothing to do } @@ -128,14 +152,18 @@ int drawRectangles(int count) w = 160; h = 140; XSetForeground(g_disp, g_gc, g_colors[index++].pixel); - if (index == MAX_COLORS) { + + if (index == MAX_COLORS) + { index = 0; } + //XDrawRectangle(g_disp, g_win, g_gc, x1, y1, w, h); XFillRectangle(g_disp, g_win, g_gc, x1, y1, w, h); XFlush(g_disp); usleep(g_delay_dur); } + return 0; } @@ -153,7 +181,8 @@ int drawFont(int count, char *msg) char **font_list; #endif - if (count <= 0) { + if (count <= 0) + { return 0; // nothing to do } @@ -162,17 +191,23 @@ int drawFont(int count, char *msg) #ifdef CHANGE_FONT_SIZE font_list = XListFonts(g_disp, "−*−courier−*−*−*−*−0−0−*−*−*−0−*−*", 2000, &actual_count); - if (!font_list) { + + if (!font_list) + { printf("actual_count=%d\n", actual_count); + for (i = 0; i < actual_count; i++) { printf("%s\n", font_list[i]); } + XFreeFontNames(font_list); } - else { + else + { printf("XListFonts() reted NULL\n"); } + #endif srandom(time(NULL)); @@ -182,13 +217,17 @@ int drawFont(int count, char *msg) x1 = random() % g_winWidth; y1 = random() % g_winHeight; XSetForeground(g_disp, g_gc, g_colors[index++].pixel); - if (index == MAX_COLORS) { + + if (index == MAX_COLORS) + { index = 0; } + XDrawString(g_disp, g_win, g_gc, x1, y1, msg, strlen(msg)); XFlush(g_disp); usleep(g_delay_dur); } + return 0; // nothing to do } @@ -244,7 +283,7 @@ usage(void) } int -main(int argc, char** argv) +main(int argc, char **argv) { XEvent evt; Colormap colormap; @@ -286,160 +325,190 @@ main(int argc, char** argv) // process cmd line args opterr = 0; + while ((opt = getopt(argc, argv, "lrsjg:c:f:i:d:o:z:")) != -1) { switch (opt) { - - case 'j': - draw_lines = 0; - draw_rects = 0; - draw_stipples = 0; - draw_fonts = 0; - draw_image = 0; - draw_offscreen = 1; - break; - - case 'g': - if (sscanf(optarg, "%dx%d", &g_winWidth, &g_winHeight) != 2) { - fprintf(stderr, "\nerror: invalid geometry specified\n\n"); + + case 'j': + draw_lines = 0; + draw_rects = 0; + draw_stipples = 0; + draw_fonts = 0; + draw_image = 0; + draw_offscreen = 1; + break; + + case 'g': + + if (sscanf(optarg, "%dx%d", &g_winWidth, &g_winHeight) != 2) + { + fprintf(stderr, "\nerror: invalid geometry specified\n\n"); + usage(); + return -1; + } + + break; + + case 'c': + + if (sscanf(optarg, "%d", &iters) != 1) + { + fprintf(stderr, "\nerror: invalid count specified\n\n"); + usage(); + return -1; + } + + break; + + case 'l': + draw_lines = 1; + draw_rects = 0; + draw_stipples = 0; + draw_fonts = 0; + draw_image = 0; + draw_offscreen = 0; + break; + + case 'r': + draw_rects = 1; + draw_lines = 0; + draw_stipples = 0; + draw_fonts = 0; + draw_image = 0; + draw_offscreen = 0; + break; + + case 's': + draw_stipples = 1; + draw_lines = 0; + draw_rects = 0; + draw_fonts = 0; + draw_image = 0; + draw_offscreen = 0; + break; + + case 'f': + + if (strlen(optarg) <= 0) + { + fprintf(stderr, "\nerror: -f option requires an argument\n\n"); + usage(); + return -1; + } + + draw_fonts = 1; + strncpy(msg, optarg, 4096); + draw_lines = 0; + draw_rects = 0; + draw_stipples = 0; + draw_image = 0; + draw_offscreen = 0; + break; + + case 'i': + + if (strlen(optarg) <= 0) + { + fprintf(stderr, "\nerror: -i option requires an argument\n\n"); + usage(); + return -1; + } + + draw_image = 1; + strncpy(image_file, optarg, 255); + draw_lines = 0; + draw_rects = 0; + draw_stipples = 0; + draw_fonts = 0; + draw_offscreen = 0; + break; + + case 'h': + usage(); + return 0; + break; + + case 'v': + printf("xdemo Ver 1.0\n"); + return 0; + break; + + case 'd': + + if (sscanf(optarg, "%d", &g_delay_dur) != 1) + { + fprintf(stderr, "\nerror: -d option requires an argument\n\n"); + usage(); + return -1; + } + + break; + + case 'z': + + if (strlen(optarg) <= 0) + { + fprintf(stderr, "\nerror: invalid proxy application specified\n\n"); + usage(); + return -1; + } + + strcpy(proxy_app, optarg); + printf("##### LK_TODO: proxy_app=%s\n", proxy_app); + zero_counters = 1; + break; + + case 'o': + + if (strcmp(optarg, "jump") == 0) + { + scroll_type = SCROLL_JUMP; + } + else if (strcmp(optarg, "smooth1") == 0) + { + scroll_type = SCROLL_SMOOTH1; + } + else if (strcmp(optarg, "smooth2") == 0) + { + scroll_type = SCROLL_SMOOTH2; + } + else if (strcmp(optarg, "smooth3") == 0) + { + scroll_type = SCROLL_SMOOTH3; + } + else if (strcmp(optarg, "smooth4") == 0) + { + scroll_type = SCROLL_SMOOTH4; + } + else + { + fprintf(stderr, "\ninvalid scroll type specified\n\n"); + usage(); + return -1; + } + + break; + + default: usage(); return -1; - } - break; - - case 'c': - if (sscanf(optarg, "%d", &iters) != 1) { - fprintf(stderr, "\nerror: invalid count specified\n\n"); - usage(); - return -1; - } - break; - - case 'l': - draw_lines = 1; - draw_rects = 0; - draw_stipples = 0; - draw_fonts = 0; - draw_image = 0; - draw_offscreen = 0; - break; - - case 'r': - draw_rects = 1; - draw_lines = 0; - draw_stipples = 0; - draw_fonts = 0; - draw_image = 0; - draw_offscreen = 0; - break; - - case 's': - draw_stipples = 1; - draw_lines = 0; - draw_rects = 0; - draw_fonts = 0; - draw_image = 0; - draw_offscreen = 0; - break; - - case 'f': - if (strlen(optarg) <= 0) { - fprintf(stderr, "\nerror: -f option requires an argument\n\n"); - usage(); - return -1; - } - draw_fonts = 1; - strncpy(msg, optarg, 4096); - draw_lines = 0; - draw_rects = 0; - draw_stipples = 0; - draw_image = 0; - draw_offscreen = 0; - break; - - case 'i': - if (strlen(optarg) <= 0) { - fprintf(stderr, "\nerror: -i option requires an argument\n\n"); - usage(); - return -1; - } - draw_image = 1; - strncpy(image_file, optarg, 255); - draw_lines = 0; - draw_rects = 0; - draw_stipples = 0; - draw_fonts = 0; - draw_offscreen= 0; - break; - - case 'h': - usage(); - return 0; - break; - - case 'v': - printf("xdemo Ver 1.0\n"); - return 0; - break; - - case 'd': - if (sscanf(optarg, "%d", &g_delay_dur) != 1) { - fprintf(stderr, "\nerror: -d option requires an argument\n\n"); - usage(); - return -1; - } - break; - - case 'z': - if (strlen(optarg) <= 0) { - fprintf(stderr, "\nerror: invalid proxy application specified\n\n"); - usage(); - return -1; - } - strcpy(proxy_app, optarg); - printf("##### LK_TODO: proxy_app=%s\n", proxy_app); - zero_counters = 1; - break; - - case 'o': - if (strcmp(optarg, "jump") == 0) { - scroll_type = SCROLL_JUMP; - } - else if (strcmp(optarg, "smooth1") == 0) { - scroll_type = SCROLL_SMOOTH1; - } - else if (strcmp(optarg, "smooth2") == 0) { - scroll_type = SCROLL_SMOOTH2; - } - else if (strcmp(optarg, "smooth3") == 0) { - scroll_type = SCROLL_SMOOTH3; - } - else if (strcmp(optarg, "smooth4") == 0) { - scroll_type = SCROLL_SMOOTH4; - } - else { - fprintf(stderr, "\ninvalid scroll type specified\n\n"); - usage(); - return -1; - } - break; - - default: - usage(); - return -1; } } // must have at least one operation if ((!draw_lines) && (!draw_rects) && (!draw_stipples) && - (!draw_fonts) && (!draw_image) && (!draw_offscreen)) { + (!draw_fonts) && (!draw_image) && (!draw_offscreen)) + { usage(); return -1; } g_disp = XOpenDisplay(NULL); - if (!g_disp) { + + if (!g_disp) + { dprint("error opening X display\n"); exit(-1); } @@ -461,88 +530,114 @@ main(int argc, char** argv) XSelectInput(g_disp, g_win, eventMask); g_gc = XCreateGC(g_disp, g_win, - 0, // mask of values - NULL ); // array of values - #if 0 + 0, // mask of values + NULL ); // array of values +#if 0 + do { dprint("about to call XNextEvent(...)\n"); XNextEvent(g_disp, &evt);// calls XFlush dprint("returned from XNextEvent(...)\n"); } + //while(evt.type != MapNotify); - while(evt.type != VisibilityNotify); - #endif + while (evt.type != VisibilityNotify) + { + ; + } + +#endif // get access to the screen's color map colormap = DefaultColormap(g_disp, screenNumber); // alloc red color rc = XAllocNamedColor(g_disp, colormap, "red", &g_colors[0], &g_colors[0]); - if (rc == 0) { + + if (rc == 0) + { printf("XAllocNamedColor - failed to allocated 'red' color.\n"); exit(1); } rc = XAllocNamedColor(g_disp, colormap, "green", &g_colors[1], &g_colors[1]); - if (rc == 0) { + + if (rc == 0) + { printf("XAllocNamedColor - failed to allocated 'green' color.\n"); exit(1); } rc = XAllocNamedColor(g_disp, colormap, "blue", &g_colors[2], &g_colors[2]); - if (rc == 0) { + + if (rc == 0) + { printf("XAllocNamedColor - failed to allocated 'blue' color.\n"); exit(1); } + rc = XAllocNamedColor(g_disp, colormap, "yellow", &g_colors[3], &g_colors[3]); - if (rc == 0) { + + if (rc == 0) + { printf("XAllocNamedColor - failed to allocated 'yellow' color.\n"); exit(1); } + rc = XAllocNamedColor(g_disp, colormap, "orange", &g_colors[4], &g_colors[4]); - if (rc == 0) { + + if (rc == 0) + { printf("XAllocNamedColor - failed to allocated 'orange' color.\n"); exit(1); } - if (zero_counters) { + if (zero_counters) + { signal_tcp_proxy(proxy_app); } - if (draw_lines) { + if (draw_lines) + { start_timer(&tv); drawLines(iters); printf("drew %d lines in %d ms\n", iters, time_elapsed_ms(tv)); } - if (draw_rects) { + if (draw_rects) + { start_timer(&tv); drawRectangles(iters); printf("drew %d rects in %d ms\n", iters, time_elapsed_ms(tv)); } - if (draw_stipples) { + if (draw_stipples) + { start_timer(&tv); // LK_TODO } - if (draw_fonts) { + if (draw_fonts) + { start_timer(&tv); - drawFont(iters, msg); + drawFont(iters, msg); printf("drew %d strings in %d ms\n", iters, time_elapsed_ms(tv)); } - if (draw_image) { + if (draw_image) + { start_timer(&tv); drawBMP(image_file, scroll_type); printf("drew BMP in %d ms\n", time_elapsed_ms(tv)); } - - if (draw_offscreen) { + + if (draw_offscreen) + { } - if (zero_counters) { + if (zero_counters) + { signal_tcp_proxy(proxy_app); } @@ -553,12 +648,15 @@ main(int argc, char** argv) do { XNextEvent(g_disp, &evt); // calls XFlush() - if (evt.type == KeyPress) { - if (draw_offscreen) { + + if (evt.type == KeyPress) + { + if (draw_offscreen) + { drawoffscreen(); } } - + } while (evt.type != ButtonRelease); @@ -578,9 +676,11 @@ int drawBMP(char *filename, int scroll_type) int i; int j; - if (parse_bmp(filename, &pic_info) < 0) { + if (parse_bmp(filename, &pic_info) < 0) + { exit(-1); } + XClearArea(g_disp, g_win, 0, 0, g_winWidth, g_winHeight, 0); depth = DefaultDepth(g_disp, DefaultScreen(g_disp)); @@ -593,7 +693,8 @@ int drawBMP(char *filename, int scroll_type) image = XCreateImage(g_disp, visual, depth, ZPixmap, 0, pic_info.pixel_data, pic_info.width, pic_info.height, 32, 0); - if (pic_info.height <= g_winHeight) { + if (pic_info.height <= g_winHeight) + { // image is too small to scroll XFlush(g_disp); XPutImage(g_disp, g_win, g_gc, image, 0, 0, 0, 0, pic_info.width, pic_info.height); @@ -604,9 +705,11 @@ int drawBMP(char *filename, int scroll_type) // copy image to pixelmap XPutImage(g_disp, pixmap, g_gc, image, 0, 0, 0, 0, pic_info.width, pic_info.height); - if (scroll_type == SCROLL_JUMP) { + if (scroll_type == SCROLL_JUMP) + { - if (pic_info.height <= g_winHeight) { + if (pic_info.height <= g_winHeight) + { // image too small - no scrolling required XFlush(g_disp); XCopyArea(g_disp, // connection to X server @@ -622,11 +725,15 @@ int drawBMP(char *filename, int scroll_type) } j = pic_info.height / g_winHeight; - if (pic_info.height % g_winHeight != 0) { + + if (pic_info.height % g_winHeight != 0) + { // need to include the last part of the image j++; } + XFlush(g_disp); + for (i = 0; i < j; i++) { XCopyArea(g_disp, // connection to X server @@ -649,25 +756,30 @@ int drawBMP(char *filename, int scroll_type) // number of lines to be scrolled j = pic_info.height - g_winHeight; - if (scroll_type == SCROLL_SMOOTH1) { + if (scroll_type == SCROLL_SMOOTH1) + { printf("running SCROLL_SMOOTH1\n"); XFlush(g_disp); XPutImage(g_disp, g_win, g_gc, image, 0, 0, 0, 0, pic_info.width, pic_info.height); XFlush(g_disp); usleep(10000); + for (i = 0; i < j; i++) { XCopyArea(g_disp, g_win, g_win, g_gc, 0, 1, g_winWidth, g_winHeight - 1, 0, 0); - XPutImage(g_disp, g_win, g_gc, image, 0, g_winHeight + i, 0, g_winHeight -1 , pic_info.width, 1); + XPutImage(g_disp, g_win, g_gc, image, 0, g_winHeight + i, 0, g_winHeight - 1 , pic_info.width, 1); XFlush(g_disp); usleep(10000); } + return 0; } - if (scroll_type == SCROLL_SMOOTH2) { + if (scroll_type == SCROLL_SMOOTH2) + { printf("running SCROLL_SMOOTH2\n"); XFlush(g_disp); + for (i = 0; i < j; i++) { XPutImage(g_disp, g_win, g_gc, image, 0, i, 0, 0, pic_info.width, pic_info.height - i); @@ -675,25 +787,31 @@ int drawBMP(char *filename, int scroll_type) usleep(10000); } } - if (scroll_type == SCROLL_SMOOTH3) { + + if (scroll_type == SCROLL_SMOOTH3) + { printf("running SCROLL_SMOOTH3\n"); XFlush(g_disp); XCopyArea(g_disp, pixmap, g_win, g_gc, 0, 0, pic_info.width, pic_info.height, 0, 0); XFlush(g_disp); usleep(10000); + for (i = 0; i < j; i++) { XCopyArea(g_disp, g_win, g_win, g_gc, 0, 1, g_winWidth, g_winHeight - 1, 0, 0); - XCopyArea(g_disp, pixmap, g_win, g_gc, 0, g_winHeight + i, pic_info.width, 1, 0, g_winHeight -1); + XCopyArea(g_disp, pixmap, g_win, g_gc, 0, g_winHeight + i, pic_info.width, 1, 0, g_winHeight - 1); XFlush(g_disp); usleep(10000); } + return 0; } - if (scroll_type == SCROLL_SMOOTH4) { + if (scroll_type == SCROLL_SMOOTH4) + { printf("running SCROLL_SMOOTH4\n"); XFlush(g_disp); + for (i = 0; i < j; i++) { XCopyArea(g_disp, pixmap, g_win, g_gc, 0, i, pic_info.width, pic_info.height - i, 0, 0); @@ -710,19 +828,21 @@ int process_bmp_event() XEvent ev; long event_mask; - event_mask = ExposureMask|ButtonPressMask|ButtonReleaseMask|StructureNotifyMask; + event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask; XSelectInput(g_disp, g_win, event_mask); XNextEvent(g_disp, &ev); - switch(ev.type) - { - case Expose: - printf("got expose event\n"); - break; - default: - printf("did not get expose event\n"); - break; + switch (ev.type) + { + case Expose: + printf("got expose event\n"); + break; + + default: + printf("did not get expose event\n"); + break; } + return 0; } @@ -743,22 +863,29 @@ int signal_tcp_proxy(char *proc_name) int i; sprintf(buf, "pidof %s", proc_name); - if ((fp = popen(buf, "r")) == NULL ) { + + if ((fp = popen(buf, "r")) == NULL ) + { printf("xdemo: popen() failed\n"); return -1; } cptr = fgets(buf, 2047, fp); - if (cptr == NULL) { + + if (cptr == NULL) + { pclose(fp); return -1; } - num_procs = sscanf(buf, "%d %d %d %d %d %d %d %d %d %d", - &pids[0], &pids[1], &pids[2], &pids[3], &pids[4], + num_procs = sscanf(buf, "%d %d %d %d %d %d %d %d %d %d", + &pids[0], &pids[1], &pids[2], &pids[3], &pids[4], &pids[5], &pids[6], &pids[7], &pids[8], &pids[9]); - if (num_procs > 0) { - for (i = 0; i < num_procs; i++) { + + if (num_procs > 0) + { + for (i = 0; i < num_procs; i++) + { kill(pids[i], SIGUSR1); printf("sent SIGUSR1 to process %d\n", pids[i]); } diff --git a/xrdp/funcs.c b/xrdp/funcs.c index d30d5b90..82662fa9 100644 --- a/xrdp/funcs.c +++ b/xrdp/funcs.c @@ -1,240 +1,269 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - simple functions - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * simple functions + */ #include "xrdp.h" /*****************************************************************************/ /* returns boolean */ int APP_CC -rect_contains_pt(struct xrdp_rect* in, int x, int y) +rect_contains_pt(struct xrdp_rect *in, int x, int y) { - if (x < in->left) - { - return 0; - } - if (y < in->top) - { - return 0; - } - if (x >= in->right) - { - return 0; - } - if (y >= in->bottom) - { - return 0; - } - return 1; + if (x < in->left) + { + return 0; + } + + if (y < in->top) + { + return 0; + } + + if (x >= in->right) + { + return 0; + } + + if (y >= in->bottom) + { + return 0; + } + + return 1; } /*****************************************************************************/ int APP_CC -rect_intersect(struct xrdp_rect* in1, struct xrdp_rect* in2, - struct xrdp_rect* out) +rect_intersect(struct xrdp_rect *in1, struct xrdp_rect *in2, + struct xrdp_rect *out) { - int rv; - struct xrdp_rect dumby; + int rv; + struct xrdp_rect dumby; - if (out == 0) - { - out = &dumby; - } - *out = *in1; - if (in2->left > in1->left) - { - out->left = in2->left; - } - if (in2->top > in1->top) - { - out->top = in2->top; - } - if (in2->right < in1->right) - { - out->right = in2->right; - } - if (in2->bottom < in1->bottom) - { - out->bottom = in2->bottom; - } - rv = !ISRECTEMPTY(*out); - if (!rv) - { - g_memset(out, 0, sizeof(struct xrdp_rect)); - } - return rv; + if (out == 0) + { + out = &dumby; + } + + *out = *in1; + + if (in2->left > in1->left) + { + out->left = in2->left; + } + + if (in2->top > in1->top) + { + out->top = in2->top; + } + + if (in2->right < in1->right) + { + out->right = in2->right; + } + + if (in2->bottom < in1->bottom) + { + out->bottom = in2->bottom; + } + + rv = !ISRECTEMPTY(*out); + + if (!rv) + { + g_memset(out, 0, sizeof(struct xrdp_rect)); + } + + return rv; } /*****************************************************************************/ /* returns boolean */ int APP_CC -rect_contained_by(struct xrdp_rect* in1, int left, int top, +rect_contained_by(struct xrdp_rect *in1, int left, int top, int right, int bottom) { - if (left < in1->left || top < in1->top || - right > in1->right || bottom > in1->bottom) - { - return 0; - } - else - { - return 1; - } + if (left < in1->left || top < in1->top || + right > in1->right || bottom > in1->bottom) + { + return 0; + } + else + { + return 1; + } } /*****************************************************************************/ /* adjust the bounds to fit in the bitmap */ /* return false if there is nothing to draw else return true */ int APP_CC -check_bounds(struct xrdp_bitmap* b, int* x, int* y, int* cx, int* cy) +check_bounds(struct xrdp_bitmap *b, int *x, int *y, int *cx, int *cy) { - if (*x >= b->width) - { - return 0; - } - if (*y >= b->height) - { - return 0; - } - if (*x < 0) - { - *cx += *x; - *x = 0; - } - if (*y < 0) - { - *cy += *y; - *y = 0; - } - if (*cx <= 0) - { - return 0; - } - if (*cy <= 0) - { - return 0; - } - if (*x + *cx > b->width) - { - *cx = b->width - *x; - } - if (*y + *cy > b->height) - { - *cy = b->height - *y; - } - return 1; + if (*x >= b->width) + { + return 0; + } + + if (*y >= b->height) + { + return 0; + } + + if (*x < 0) + { + *cx += *x; + *x = 0; + } + + if (*y < 0) + { + *cy += *y; + *y = 0; + } + + if (*cx <= 0) + { + return 0; + } + + if (*cy <= 0) + { + return 0; + } + + if (*x + *cx > b->width) + { + *cx = b->width - *x; + } + + if (*y + *cy > b->height) + { + *cy = b->height - *y; + } + + return 1; } /*****************************************************************************/ /* add a ch at index position in text, index starts at 0 */ /* if index = -1 add it to the end */ int APP_CC -add_char_at(char* text, int text_size, twchar ch, int index) +add_char_at(char *text, int text_size, twchar ch, int index) { - int len; - int i; - twchar* wstr; + int len; + int i; + twchar *wstr; - len = g_mbstowcs(0, text, 0); - wstr = (twchar*)g_malloc((len + 16) * sizeof(twchar), 0); - g_mbstowcs(wstr, text, len + 1); - if ((index >= len) || (index < 0)) - { - wstr[len] = ch; + len = g_mbstowcs(0, text, 0); + wstr = (twchar *)g_malloc((len + 16) * sizeof(twchar), 0); + g_mbstowcs(wstr, text, len + 1); + + if ((index >= len) || (index < 0)) + { + wstr[len] = ch; + wstr[len + 1] = 0; + g_wcstombs(text, wstr, text_size); + g_free(wstr); + return 0; + } + + for (i = (len - 1); i >= index; i--) + { + wstr[i + 1] = wstr[i]; + } + + wstr[i + 1] = ch; wstr[len + 1] = 0; g_wcstombs(text, wstr, text_size); g_free(wstr); return 0; - } - for (i = (len - 1); i >= index; i--) - { - wstr[i + 1] = wstr[i]; - } - wstr[i + 1] = ch; - wstr[len + 1] = 0; - g_wcstombs(text, wstr, text_size); - g_free(wstr); - return 0; } /*****************************************************************************/ /* remove a ch at index position in text, index starts at 0 */ /* if index = -1 remove it from the end */ int APP_CC -remove_char_at(char* text, int text_size, int index) +remove_char_at(char *text, int text_size, int index) { - int len; - int i; - twchar* wstr; + int len; + int i; + twchar *wstr; + + len = g_mbstowcs(0, text, 0); + + if (len <= 0) + { + return 0; + } + + wstr = (twchar *)g_malloc((len + 16) * sizeof(twchar), 0); + g_mbstowcs(wstr, text, len + 1); + + if ((index >= (len - 1)) || (index < 0)) + { + wstr[len - 1] = 0; + g_wcstombs(text, wstr, text_size); + g_free(wstr); + return 0; + } + + for (i = index; i < (len - 1); i++) + { + wstr[i] = wstr[i + 1]; + } - len = g_mbstowcs(0, text, 0); - if (len <= 0) - { - return 0; - } - wstr = (twchar*)g_malloc((len + 16) * sizeof(twchar), 0); - g_mbstowcs(wstr, text, len + 1); - if ((index >= (len - 1)) || (index < 0)) - { wstr[len - 1] = 0; g_wcstombs(text, wstr, text_size); g_free(wstr); return 0; - } - for (i = index; i < (len - 1); i++) - { - wstr[i] = wstr[i + 1]; - } - wstr[len - 1] = 0; - g_wcstombs(text, wstr, text_size); - g_free(wstr); - return 0; } /*****************************************************************************/ int APP_CC -set_string(char** in_str, const char* in) +set_string(char **in_str, const char *in) { - if (in_str == 0) - { - return 0; - } - g_free(*in_str); - *in_str = g_strdup(in); - return 0; -} - -/*****************************************************************************/ -int APP_CC -wchar_repeat(twchar* dest, int dest_size_in_wchars, twchar ch, int repeat) -{ - int index; - - for (index = 0; index < repeat; index++) - { - if (index >= dest_size_in_wchars) + if (in_str == 0) { - break; + return 0; } - dest[index] = ch; - } - return 0; + + g_free(*in_str); + *in_str = g_strdup(in); + return 0; +} + +/*****************************************************************************/ +int APP_CC +wchar_repeat(twchar *dest, int dest_size_in_wchars, twchar ch, int repeat) +{ + int index; + + for (index = 0; index < repeat; index++) + { + if (index >= dest_size_in_wchars) + { + break; + } + + dest[index] = ch; + } + + return 0; } diff --git a/xrdp/lang.c b/xrdp/lang.c index 1c13839f..29031ea2 100644 --- a/xrdp/lang.c +++ b/xrdp/lang.c @@ -1,25 +1,23 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2006-2010 - - keylayout - maximum unicode 19996(0x4e00) - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * keylayout + * maximum unicode 19996(0x4e00) + */ #include "xrdp.h" #include "log.h" @@ -28,223 +26,241 @@ code1 is regular scancode, code2 is extended scancode */ struct codepair { - tui8 code1; - tui8 code2; + tui8 code1; + tui8 code2; }; static struct codepair g_map[] = { - { 0, 0 }, { 9, 0 }, { 10, 0 }, { 11, 0 }, { 12, 0 }, /* 0 - 4 */ - { 13, 0 }, { 14, 0 }, { 15, 0 }, { 16, 0 }, { 17, 0 }, /* 5 - 9 */ - { 18, 0 }, { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, /* 10 - 14 */ - { 23, 0 }, { 24, 0 }, { 25, 0 }, { 26, 0 }, { 27, 0 }, /* 15 - 19 */ - { 28, 0 }, { 29, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, /* 20 - 24 */ - { 33, 0 }, { 34, 0 }, { 35, 0 }, { 36, 108 }, { 37, 109 }, /* 25 - 29 */ - { 38, 0 }, { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, /* 30 - 34 */ - { 43, 0 }, { 44, 0 }, { 45, 0 }, { 46, 0 }, { 47, 0 }, /* 35 - 39 */ - { 48, 0 }, { 49, 0 }, { 50, 0 }, { 51, 0 }, { 52, 0 }, /* 40 - 44 */ - { 53, 0 }, { 54, 0 }, { 55, 0 }, { 56, 0 }, { 57, 0 }, /* 45 - 49 */ - { 58, 0 }, { 59, 0 }, { 60, 0 }, { 61, 112 }, { 62, 0 }, /* 50 - 54 */ - { 63, 111 }, { 64, 113 }, { 65, 0 }, { 66, 0 }, { 67, 0 }, /* 55 - 59 */ - { 68, 0 }, { 69, 0 }, { 70, 0 }, { 71, 0 }, { 72, 0 }, /* 60 - 64 */ - { 73, 0 }, { 74, 0 }, { 75, 0 }, { 76, 0 }, { 77, 0 }, /* 65 - 69 */ - { 78, 0 }, { 79, 97 }, { 80, 98 }, { 81, 99 }, { 82, 0 }, /* 70 - 74 */ - { 83, 100 }, { 84, 0 }, { 85, 102 }, { 86, 0 }, { 87, 103 }, /* 75 - 79 */ - { 88, 104 }, { 89, 105 }, { 90, 106 }, { 91, 107 }, { 92, 0 }, /* 80 - 84 */ - { 93, 0 }, { 94, 0 }, { 95, 0 }, { 96, 0 }, { 97, 0 }, /* 85 - 89 */ - { 98, 0 }, { 0, 115 }, { 0, 116 }, { 0, 117 }, { 102, 0 }, /* 90 - 94 */ - { 103, 0 }, { 104, 0 }, { 105, 0 }, { 106, 0 }, { 107, 0 }, /* 95 - 99 */ - { 108, 0 }, { 109, 0 }, { 110, 0 }, { 111, 0 }, { 112, 0 }, /* 100 - 104 */ - { 113, 0 }, { 114, 0 }, { 115, 0 }, { 116, 0 }, { 117, 0 }, /* 105 - 109 */ - { 118, 0 }, { 119, 0 }, { 120, 0 }, { 121, 0 }, { 122, 0 }, /* 110 - 114 */ - { 123, 0 }, { 124, 0 }, { 125, 0 }, { 126, 0 }, { 127, 0 }, /* 115 - 119 */ - { 128, 0 }, { 129, 0 }, { 130, 0 }, { 131, 0 }, { 132, 0 }, /* 120 - 124 */ - { 133, 0 }, { 134, 0 }, { 135, 0 } /* 125 - 127 */ + { 0, 0 }, { 9, 0 }, { 10, 0 }, { 11, 0 }, { 12, 0 }, /* 0 - 4 */ + { 13, 0 }, { 14, 0 }, { 15, 0 }, { 16, 0 }, { 17, 0 }, /* 5 - 9 */ + { 18, 0 }, { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, /* 10 - 14 */ + { 23, 0 }, { 24, 0 }, { 25, 0 }, { 26, 0 }, { 27, 0 }, /* 15 - 19 */ + { 28, 0 }, { 29, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, /* 20 - 24 */ + { 33, 0 }, { 34, 0 }, { 35, 0 }, { 36, 108 }, { 37, 109 }, /* 25 - 29 */ + { 38, 0 }, { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, /* 30 - 34 */ + { 43, 0 }, { 44, 0 }, { 45, 0 }, { 46, 0 }, { 47, 0 }, /* 35 - 39 */ + { 48, 0 }, { 49, 0 }, { 50, 0 }, { 51, 0 }, { 52, 0 }, /* 40 - 44 */ + { 53, 0 }, { 54, 0 }, { 55, 0 }, { 56, 0 }, { 57, 0 }, /* 45 - 49 */ + { 58, 0 }, { 59, 0 }, { 60, 0 }, { 61, 112 }, { 62, 0 }, /* 50 - 54 */ + { 63, 111 }, { 64, 113 }, { 65, 0 }, { 66, 0 }, { 67, 0 }, /* 55 - 59 */ + { 68, 0 }, { 69, 0 }, { 70, 0 }, { 71, 0 }, { 72, 0 }, /* 60 - 64 */ + { 73, 0 }, { 74, 0 }, { 75, 0 }, { 76, 0 }, { 77, 0 }, /* 65 - 69 */ + { 78, 0 }, { 79, 97 }, { 80, 98 }, { 81, 99 }, { 82, 0 }, /* 70 - 74 */ + { 83, 100 }, { 84, 0 }, { 85, 102 }, { 86, 0 }, { 87, 103 }, /* 75 - 79 */ + { 88, 104 }, { 89, 105 }, { 90, 106 }, { 91, 107 }, { 92, 0 }, /* 80 - 84 */ + { 93, 0 }, { 94, 0 }, { 95, 0 }, { 96, 0 }, { 97, 0 }, /* 85 - 89 */ + { 98, 0 }, { 0, 115 }, { 0, 116 }, { 0, 117 }, { 102, 0 }, /* 90 - 94 */ + { 103, 0 }, { 104, 0 }, { 105, 0 }, { 106, 0 }, { 107, 0 }, /* 95 - 99 */ + { 108, 0 }, { 109, 0 }, { 110, 0 }, { 111, 0 }, { 112, 0 }, /* 100 - 104 */ + { 113, 0 }, { 114, 0 }, { 115, 0 }, { 116, 0 }, { 117, 0 }, /* 105 - 109 */ + { 118, 0 }, { 119, 0 }, { 120, 0 }, { 121, 0 }, { 122, 0 }, /* 110 - 114 */ + { 123, 0 }, { 124, 0 }, { 125, 0 }, { 126, 0 }, { 127, 0 }, /* 115 - 119 */ + { 128, 0 }, { 129, 0 }, { 130, 0 }, { 131, 0 }, { 132, 0 }, /* 120 - 124 */ + { 133, 0 }, { 134, 0 }, { 135, 0 } /* 125 - 127 */ }; /*****************************************************************************/ -struct xrdp_key_info* APP_CC -get_key_info_from_scan_code(int device_flags, int scan_code, int* keys, +struct xrdp_key_info *APP_CC +get_key_info_from_scan_code(int device_flags, int scan_code, int *keys, int caps_lock, int num_lock, int scroll_lock, - struct xrdp_keymap* keymap) + struct xrdp_keymap *keymap) { - struct xrdp_key_info* rv; - int shift; - int altgr; - int ext; - int index; + struct xrdp_key_info *rv; + int shift; + int altgr; + int ext; + int index; - ext = device_flags & KBD_FLAG_EXT; /* 0x0100 */ - shift = keys[42] || keys[54]; - altgr = keys[56] & KBD_FLAG_EXT; /* right alt */ - rv = 0; - scan_code = scan_code & 0x7f; - index = ext ? g_map[scan_code].code2 : g_map[scan_code].code1; - /* keymap file is created with numlock off so we have to do this */ - if ((index >= 79) && (index <= 91)) - { - if (num_lock) + ext = device_flags &KBD_FLAG_EXT; /* 0x0100 */ + shift = keys[42] || keys[54]; + altgr = keys[56] &KBD_FLAG_EXT; /* right alt */ + rv = 0; + scan_code = scan_code & 0x7f; + index = ext ? g_map[scan_code].code2 : g_map[scan_code].code1; + + /* keymap file is created with numlock off so we have to do this */ + if ((index >= 79) && (index <= 91)) { - rv = &(keymap->keys_shift[index]); + if (num_lock) + { + rv = &(keymap->keys_shift[index]); + } + else + { + rv = &(keymap->keys_noshift[index]); + } + } + else if (shift && caps_lock) + { + rv = &(keymap->keys_shiftcapslock[index]); + } + else if (shift) + { + rv = &(keymap->keys_shift[index]); + } + else if (caps_lock) + { + rv = &(keymap->keys_capslock[index]); + } + else if (altgr) + { + rv = &(keymap->keys_altgr[index]); } else { - rv = &(keymap->keys_noshift[index]); + rv = &(keymap->keys_noshift[index]); } - } - else if (shift && caps_lock) - { - rv = &(keymap->keys_shiftcapslock[index]); - } - else if (shift) - { - rv = &(keymap->keys_shift[index]); - } - else if (caps_lock) - { - rv = &(keymap->keys_capslock[index]); - } - else if (altgr) - { - rv = &(keymap->keys_altgr[index]); - } - else - { - rv = &(keymap->keys_noshift[index]); - } - return rv; + + return rv; } /*****************************************************************************/ int APP_CC -get_keysym_from_scan_code(int device_flags, int scan_code, int* keys, +get_keysym_from_scan_code(int device_flags, int scan_code, int *keys, int caps_lock, int num_lock, int scroll_lock, - struct xrdp_keymap* keymap) + struct xrdp_keymap *keymap) { - struct xrdp_key_info* ki; + struct xrdp_key_info *ki; - ki = get_key_info_from_scan_code(device_flags, scan_code, keys, - caps_lock, num_lock, scroll_lock, - keymap); - if (ki == 0) - { - return 0; - } - return ki->sym; + ki = get_key_info_from_scan_code(device_flags, scan_code, keys, + caps_lock, num_lock, scroll_lock, + keymap); + + if (ki == 0) + { + return 0; + } + + return ki->sym; } /*****************************************************************************/ twchar APP_CC -get_char_from_scan_code(int device_flags, int scan_code, int* keys, +get_char_from_scan_code(int device_flags, int scan_code, int *keys, int caps_lock, int num_lock, int scroll_lock, - struct xrdp_keymap* keymap) + struct xrdp_keymap *keymap) { - struct xrdp_key_info* ki; + struct xrdp_key_info *ki; - ki = get_key_info_from_scan_code(device_flags, scan_code, keys, - caps_lock, num_lock, scroll_lock, - keymap); - if (ki == 0) - { - return 0; - } - return (twchar)(ki->chr); + ki = get_key_info_from_scan_code(device_flags, scan_code, keys, + caps_lock, num_lock, scroll_lock, + keymap); + + if (ki == 0) + { + return 0; + } + + return (twchar)(ki->chr); } /*****************************************************************************/ static int APP_CC -km_read_section(int fd, const char* section_name, struct xrdp_key_info* keymap) +km_read_section(int fd, const char *section_name, struct xrdp_key_info *keymap) { - struct list* names; - struct list* values; - int index; - int code; - int pos1; - char* name; - char* value; + struct list *names; + struct list *values; + int index; + int code; + int pos1; + char *name; + char *value; - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - if (file_read_section(fd, section_name, names, values) == 0) - { - for (index = names->count - 1; index >= 0; index--) + names = list_create(); + names->auto_free = 1; + values = list_create(); + values->auto_free = 1; + + if (file_read_section(fd, section_name, names, values) == 0) { - name = (char*)list_get_item(names, index); - value = (char*)list_get_item(values, index); - if ((name != 0) && (value != 0)) - { - if (g_strncasecmp(name, "key", 3) == 0) + for (index = names->count - 1; index >= 0; index--) { - code = g_atoi(name + 3); + name = (char *)list_get_item(names, index); + value = (char *)list_get_item(values, index); + + if ((name != 0) && (value != 0)) + { + if (g_strncasecmp(name, "key", 3) == 0) + { + code = g_atoi(name + 3); + } + else + { + code = g_atoi(name); + } + + if ((code >= 0) && (code < 256)) + { + pos1 = g_pos(value, ":"); + + if (pos1 >= 0) + { + keymap[code].chr = g_atoi(value + pos1 + 1); + } + + keymap[code].sym = g_atoi(value); + } + } } - else - { - code = g_atoi(name); - } - if ((code >= 0) && (code < 256)) - { - pos1 = g_pos(value, ":"); - if (pos1 >= 0) - { - keymap[code].chr = g_atoi(value + pos1 + 1); - } - keymap[code].sym = g_atoi(value); - } - } } - } - list_delete(names); - list_delete(values); - return 0; + + list_delete(names); + list_delete(values); + return 0; } /*****************************************************************************/ int APP_CC -get_keymaps(int keylayout, struct xrdp_keymap* keymap) +get_keymaps(int keylayout, struct xrdp_keymap *keymap) { - int fd; - char* filename; - struct xrdp_keymap* lkeymap; + int fd; + char *filename; + struct xrdp_keymap *lkeymap; - filename = (char*)g_malloc(256, 0); - /* check if there is a keymap file */ - g_snprintf(filename, 255, "%s/km-%4.4x.ini", XRDP_CFG_PATH, keylayout); - /* if the file does not exist, try again with 'en-us' as fallback */ - if (!g_file_exist(filename)) - { - g_snprintf(filename, 255, "%s/km-0409.ini", XRDP_CFG_PATH); - } - if (g_file_exist(filename)) - { - fd = g_file_open(filename); - if (fd > 0) + filename = (char *)g_malloc(256, 0); + /* check if there is a keymap file */ + g_snprintf(filename, 255, "%s/km-%4.4x.ini", XRDP_CFG_PATH, keylayout); + + /* if the file does not exist, try again with 'en-us' as fallback */ + if (!g_file_exist(filename)) { - lkeymap = (struct xrdp_keymap*)g_malloc(sizeof(struct xrdp_keymap), 0); - /* make a copy of the build in kaymap */ - g_memcpy(lkeymap, keymap, sizeof(struct xrdp_keymap)); - /* clear the keymaps */ - g_memset(keymap, 0, sizeof(struct xrdp_keymap)); - /* read the keymaps */ - km_read_section(fd, "noshift", keymap->keys_noshift); - km_read_section(fd, "shift", keymap->keys_shift); - km_read_section(fd, "altgr", keymap->keys_altgr); - km_read_section(fd, "capslock", keymap->keys_capslock); - km_read_section(fd, "shiftcapslock", keymap->keys_shiftcapslock); - if (g_memcmp(lkeymap, keymap, sizeof(struct xrdp_keymap)) != 0) - { - log_message(LOG_LEVEL_WARNING, - "local keymap file for 0x%4.4x found and dosen't match " - "built in keymap, using local keymap file", keylayout); - } - g_free(lkeymap); - g_file_close(fd); + g_snprintf(filename, 255, "%s/km-0409.ini", XRDP_CFG_PATH); } - } - else - { - log_message(LOG_LEVEL_WARNING,"File does not exist: %s",filename); - } - g_free(filename); - return 0; + + if (g_file_exist(filename)) + { + fd = g_file_open(filename); + + if (fd > 0) + { + lkeymap = (struct xrdp_keymap *)g_malloc(sizeof(struct xrdp_keymap), 0); + /* make a copy of the build in kaymap */ + g_memcpy(lkeymap, keymap, sizeof(struct xrdp_keymap)); + /* clear the keymaps */ + g_memset(keymap, 0, sizeof(struct xrdp_keymap)); + /* read the keymaps */ + km_read_section(fd, "noshift", keymap->keys_noshift); + km_read_section(fd, "shift", keymap->keys_shift); + km_read_section(fd, "altgr", keymap->keys_altgr); + km_read_section(fd, "capslock", keymap->keys_capslock); + km_read_section(fd, "shiftcapslock", keymap->keys_shiftcapslock); + + if (g_memcmp(lkeymap, keymap, sizeof(struct xrdp_keymap)) != 0) + { + log_message(LOG_LEVEL_WARNING, + "local keymap file for 0x%4.4x found and dosen't match " + "built in keymap, using local keymap file", keylayout); + } + + g_free(lkeymap); + g_file_close(fd); + } + } + else + { + log_message(LOG_LEVEL_WARNING, "File does not exist: %s", filename); + } + + g_free(filename); + return 0; } diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index 4af8c4d7..0da7a101 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -1,31 +1,29 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2012 - - main program - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * main program + */ #include "xrdp.h" #include "log.h" #define THREAD_WAITING 100 -static struct xrdp_listen* g_listen = 0; +static struct xrdp_listen *g_listen = 0; static long g_threadid = 0; /* main threadid */ static long g_sync_mutex = 0; @@ -47,73 +45,77 @@ long APP_CC g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, long sync_param2) { - long sync_result; - int sync_command; + long sync_result; + int sync_command; - /* If the function is called from the main thread, the function can - * be called directly. g_threadid= main thread ID*/ - if (tc_threadid_equal(tc_get_threadid(), g_threadid)) - { - /* this is the main thread, call the function directly */ - /* in fork mode, this always happens too */ - sync_result = sync_func(sync_param1, sync_param2); - /*g_writeln("g_xrdp_sync processed IN main thread -> continue");*/ - } - else - { - /* All threads have to wait here until the main thread - * process the function. g_process_waiting_function() is called - * from the listening thread. g_process_waiting_function() process the function*/ - tc_mutex_lock(g_sync1_mutex); - tc_mutex_lock(g_sync_mutex); - g_sync_param1 = sync_param1; - g_sync_param2 = sync_param2; - g_sync_func = sync_func; - /* set a value THREAD_WAITING so the g_process_waiting_function function - * know if any function must be processed */ - g_sync_command = THREAD_WAITING; - tc_mutex_unlock(g_sync_mutex); - /* set this event so that the main thread know if - * g_process_waiting_function() must be called */ - g_set_wait_obj(g_sync_event); - do + /* If the function is called from the main thread, the function can + * be called directly. g_threadid= main thread ID*/ + if (tc_threadid_equal(tc_get_threadid(), g_threadid)) { - g_sleep(100); - tc_mutex_lock(g_sync_mutex); - /* load new value from global to see if the g_process_waiting_function() - * function has processed the function */ - sync_command = g_sync_command; - sync_result = g_sync_result; - tc_mutex_unlock(g_sync_mutex); + /* this is the main thread, call the function directly */ + /* in fork mode, this always happens too */ + sync_result = sync_func(sync_param1, sync_param2); + /*g_writeln("g_xrdp_sync processed IN main thread -> continue");*/ } - while (sync_command != 0); /* loop until g_process_waiting_function() + else + { + /* All threads have to wait here until the main thread + * process the function. g_process_waiting_function() is called + * from the listening thread. g_process_waiting_function() process the function*/ + tc_mutex_lock(g_sync1_mutex); + tc_mutex_lock(g_sync_mutex); + g_sync_param1 = sync_param1; + g_sync_param2 = sync_param2; + g_sync_func = sync_func; + /* set a value THREAD_WAITING so the g_process_waiting_function function + * know if any function must be processed */ + g_sync_command = THREAD_WAITING; + tc_mutex_unlock(g_sync_mutex); + /* set this event so that the main thread know if + * g_process_waiting_function() must be called */ + g_set_wait_obj(g_sync_event); + + do + { + g_sleep(100); + tc_mutex_lock(g_sync_mutex); + /* load new value from global to see if the g_process_waiting_function() + * function has processed the function */ + sync_command = g_sync_command; + sync_result = g_sync_result; + tc_mutex_unlock(g_sync_mutex); + } + while (sync_command != 0); /* loop until g_process_waiting_function() + * has processed the request */ - tc_mutex_unlock(g_sync1_mutex); - /*g_writeln("g_xrdp_sync processed BY main thread -> continue");*/ - } - return sync_result; + tc_mutex_unlock(g_sync1_mutex); + /*g_writeln("g_xrdp_sync processed BY main thread -> continue");*/ + } + + return sync_result; } /*****************************************************************************/ void DEFAULT_CC xrdp_shutdown(int sig) { - tbus threadid; + tbus threadid; - threadid = tc_get_threadid(); - g_writeln("shutting down"); - g_writeln("signal %d threadid %p", sig, threadid); - if (!g_is_wait_obj_set(g_term_event)) - { - g_set_wait_obj(g_term_event); - } + threadid = tc_get_threadid(); + g_writeln("shutting down"); + g_writeln("signal %d threadid %p", sig, threadid); + + if (!g_is_wait_obj_set(g_term_event)) + { + g_set_wait_obj(g_term_event); + } } /*****************************************************************************/ void DEFAULT_CC xrdp_child(int sig) { - g_waitchild(); + g_waitchild(); } /*****************************************************************************/ @@ -121,61 +123,61 @@ xrdp_child(int sig) int APP_CC xrdp_child_fork(void) { - int pid; - char text[256]; + int pid; + char text[256]; - /* close, don't delete these */ - g_close_wait_obj(g_term_event); - g_close_wait_obj(g_sync_event); - pid = g_getpid(); - g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); - g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); - g_sync_event = g_create_wait_obj(text); - return 0; + /* close, don't delete these */ + g_close_wait_obj(g_term_event); + g_close_wait_obj(g_sync_event); + pid = g_getpid(); + g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); + g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); + g_sync_event = g_create_wait_obj(text); + return 0; } /*****************************************************************************/ int APP_CC g_is_term(void) { - return g_is_wait_obj_set(g_term_event); + return g_is_wait_obj_set(g_term_event); } /*****************************************************************************/ void APP_CC g_set_term(int in_val) { - if (in_val) - { - g_set_wait_obj(g_term_event); - } - else - { - g_reset_wait_obj(g_term_event); - } + if (in_val) + { + g_set_wait_obj(g_term_event); + } + else + { + g_reset_wait_obj(g_term_event); + } } /*****************************************************************************/ tbus APP_CC g_get_term_event(void) { - return g_term_event; + return g_term_event; } /*****************************************************************************/ tbus APP_CC g_get_sync_event(void) { - return g_sync_event; + return g_sync_event; } /*****************************************************************************/ void DEFAULT_CC pipe_sig(int sig_num) { - /* do nothing */ - g_writeln("got SIGPIPE(%d)", sig_num); + /* do nothing */ + g_writeln("got SIGPIPE(%d)", sig_num); } /*****************************************************************************/ @@ -184,357 +186,400 @@ pipe_sig(int sig_num) void APP_CC g_process_waiting_function(void) { - tc_mutex_lock(g_sync_mutex); - if (g_sync_command != 0) - { - if (g_sync_func != 0) + tc_mutex_lock(g_sync_mutex); + + if (g_sync_command != 0) { - if (g_sync_command == THREAD_WAITING) - { - g_sync_result = g_sync_func(g_sync_param1, g_sync_param2); - } + if (g_sync_func != 0) + { + if (g_sync_command == THREAD_WAITING) + { + g_sync_result = g_sync_func(g_sync_param1, g_sync_param2); + } + } + + g_sync_command = 0; } - g_sync_command = 0; - } - tc_mutex_unlock(g_sync_mutex); + + tc_mutex_unlock(g_sync_mutex); } /*****************************************************************************/ int APP_CC -xrdp_process_params(int argc, char** argv, - struct xrdp_startup_params* startup_params) +xrdp_process_params(int argc, char **argv, + struct xrdp_startup_params *startup_params) { - int index; - char option[128]; - char value[128]; + int index; + char option[128]; + char value[128]; - index = 1; - while (index < argc) - { - g_strncpy(option, argv[index], 127); - if (index + 1 < argc) + index = 1; + + while (index < argc) { - g_strncpy(value, argv[index + 1], 127); + g_strncpy(option, argv[index], 127); + + if (index + 1 < argc) + { + g_strncpy(value, argv[index + 1], 127); + } + else + { + value[0] = 0; + } + + if ((g_strncasecmp(option, "-help", 255)) == 0 || + (g_strncasecmp(option, "--help", 255)) == 0 || + (g_strncasecmp(option, "-h", 255)) == 0) + { + startup_params->help = 1; + } + else if ((g_strncasecmp(option, "-kill", 255) == 0) || + (g_strncasecmp(option, "--kill", 255) == 0) || + (g_strncasecmp(option, "-k", 255) == 0)) + { + startup_params->kill = 1; + } + else if ((g_strncasecmp(option, "-nodaemon", 255) == 0) || + (g_strncasecmp(option, "--nodaemon", 255) == 0) || + (g_strncasecmp(option, "-nd", 255) == 0) || + (g_strncasecmp(option, "--nd", 255) == 0) || + (g_strncasecmp(option, "-ns", 255) == 0) || + (g_strncasecmp(option, "--ns", 255) == 0)) + { + startup_params->no_daemon = 1; + } + else if ((g_strncasecmp(option, "-v", 255) == 0) || + (g_strncasecmp(option, "--version", 255) == 0)) + { + startup_params->version = 1; + } + else if ((g_strncasecmp(option, "-p", 255) == 0) || + (g_strncasecmp(option, "--port", 255) == 0)) + { + index++; + g_strncpy(startup_params->port, value, 127); + + if (g_strlen(startup_params->port) < 1) + { + g_writeln("error processing params, port [%s]", startup_params->port); + return 1; + } + else + { + g_writeln("--port parameter found, ini override [%s]", + startup_params->port); + } + } + else if ((g_strncasecmp(option, "-f", 255) == 0) || + (g_strncasecmp(option, "--fork", 255) == 0)) + { + startup_params->fork = 1; + g_writeln("--fork parameter found, ini override"); + } + else + { + return 1; + } + + index++; } - else - { - value[0] = 0; - } - if ((g_strncasecmp(option, "-help", 255)) == 0 || - (g_strncasecmp(option, "--help", 255)) == 0 || - (g_strncasecmp(option, "-h", 255)) == 0) - { - startup_params->help = 1; - } - else if ((g_strncasecmp(option, "-kill", 255) == 0) || - (g_strncasecmp(option, "--kill", 255) == 0) || - (g_strncasecmp(option, "-k", 255) == 0)) - { - startup_params->kill = 1; - } - else if ((g_strncasecmp(option, "-nodaemon", 255) == 0) || - (g_strncasecmp(option, "--nodaemon", 255) == 0) || - (g_strncasecmp(option, "-nd", 255) == 0) || - (g_strncasecmp(option, "--nd", 255) == 0) || - (g_strncasecmp(option, "-ns", 255) == 0) || - (g_strncasecmp(option, "--ns", 255) == 0)) - { - startup_params->no_daemon = 1; - } - else if ((g_strncasecmp(option, "-v", 255) == 0) || - (g_strncasecmp(option, "--version", 255) == 0)) - { - startup_params->version = 1; - } - else if ((g_strncasecmp(option, "-p", 255) == 0) || - (g_strncasecmp(option, "--port", 255) == 0)) - { - index++; - g_strncpy(startup_params->port, value, 127); - if (g_strlen(startup_params->port) < 1) - { - g_writeln("error processing params, port [%s]", startup_params->port); - return 1; - } - else - { - g_writeln("--port parameter found, ini override [%s]", - startup_params->port); - } - } - else if ((g_strncasecmp(option, "-f", 255) == 0) || - (g_strncasecmp(option, "--fork", 255) == 0)) - { - startup_params->fork = 1; - g_writeln("--fork parameter found, ini override"); - } - else - { - return 1; - } - index++; - } - return 0; + + return 0; } /*****************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - int test; - int host_be; - char cfg_file[256]; - enum logReturns error; - struct xrdp_startup_params* startup_params; - int pid; - int fd; - int no_daemon; - char text[256]; - char pid_file[256]; + int test; + int host_be; + char cfg_file[256]; + enum logReturns error; + struct xrdp_startup_params *startup_params; + int pid; + int fd; + int no_daemon; + char text[256]; + char pid_file[256]; - g_init("xrdp"); - ssl_init(); - /* check compiled endian with actual endian */ - test = 1; - host_be = !((int)(*(unsigned char*)(&test))); + g_init("xrdp"); + ssl_init(); + /* check compiled endian with actual endian */ + test = 1; + host_be = !((int)(*(unsigned char *)(&test))); #if defined(B_ENDIAN) - if (!host_be) + + if (!host_be) #endif #if defined(L_ENDIAN) - if (host_be) + if (host_be) #endif - { - g_writeln("endian wrong, edit arch.h"); - return 0; - } - /* check long, int and void* sizes */ - if (sizeof(int) != 4) - { - g_writeln("unusable int size, must be 4"); - return 0; - } - if (sizeof(long) != sizeof(void*)) - { - g_writeln("long size must match void* size"); - return 0; - } - if (sizeof(long) != 4 && sizeof(long) != 8) - { - g_writeln("unusable long size, must be 4 or 8"); - return 0; - } - if (sizeof(tui64) != 8) - { - g_writeln("unusable tui64 size, must be 8"); - return 0; - } - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + { + g_writeln("endian wrong, edit arch.h"); + return 0; + } - /* starting logging subsystem */ - error = log_start(cfg_file, "XRDP"); - - if (error != LOG_STARTUP_OK) - { - switch (error) + /* check long, int and void* sizes */ + if (sizeof(int) != 4) { - case LOG_ERROR_MALLOC: - g_writeln("error on malloc. cannot start logging. quitting."); - break; - case LOG_ERROR_FILE_OPEN: - g_writeln("error opening log file [%s]. quitting.", - getLogFile(text, 255)); - break; - default: - g_writeln("log_start error"); - break; + g_writeln("unusable int size, must be 4"); + return 0; } - g_deinit(); - g_exit(1); - } - startup_params = (struct xrdp_startup_params*) - g_malloc(sizeof(struct xrdp_startup_params), 1); - if (xrdp_process_params(argc, argv, startup_params) != 0) - { - g_writeln("Unknown Parameter"); - g_writeln("xrdp -h for help"); - g_writeln(""); - g_deinit(); - g_exit(0); - } + if (sizeof(long) != sizeof(void *)) + { + g_writeln("long size must match void* size"); + return 0; + } - g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH); - no_daemon = 0; + if (sizeof(long) != 4 && sizeof(long) != 8) + { + g_writeln("unusable long size, must be 4 or 8"); + return 0; + } + + if (sizeof(tui64) != 8) + { + g_writeln("unusable tui64 size, must be 8"); + return 0; + } + + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + + /* starting logging subsystem */ + error = log_start(cfg_file, "XRDP"); + + if (error != LOG_STARTUP_OK) + { + switch (error) + { + case LOG_ERROR_MALLOC: + g_writeln("error on malloc. cannot start logging. quitting."); + break; + case LOG_ERROR_FILE_OPEN: + g_writeln("error opening log file [%s]. quitting.", + getLogFile(text, 255)); + break; + default: + g_writeln("log_start error"); + break; + } + + g_deinit(); + g_exit(1); + } + + startup_params = (struct xrdp_startup_params *) + g_malloc(sizeof(struct xrdp_startup_params), 1); + + if (xrdp_process_params(argc, argv, startup_params) != 0) + { + g_writeln("Unknown Parameter"); + g_writeln("xrdp -h for help"); + g_writeln(""); + g_deinit(); + g_exit(0); + } + + g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH); + no_daemon = 0; + + if (startup_params->kill) + { + g_writeln("stopping xrdp"); + /* read the xrdp.pid file */ + fd = -1; + + if (g_file_exist(pid_file)) /* xrdp.pid */ + { + fd = g_file_open(pid_file); /* xrdp.pid */ + } + + if (fd == -1) + { + g_writeln("problem opening to xrdp.pid [%s]", pid_file); + g_writeln("maybe its not running"); + } + else + { + g_memset(text, 0, 32); + g_file_read(fd, text, 31); + pid = g_atoi(text); + g_writeln("stopping process id %d", pid); + + if (pid > 0) + { + g_sigterm(pid); + } + + g_file_close(fd); + } + + g_deinit(); + g_exit(0); + } + + if (startup_params->no_daemon) + { + no_daemon = 1; + } + + if (startup_params->help) + { + g_writeln(""); + g_writeln("xrdp: A Remote Desktop Protocol server."); + g_writeln("Copyright (C) Jay Sorg 2004-2011"); + g_writeln("See http://xrdp.sourceforge.net for more information."); + g_writeln(""); + g_writeln("Usage: xrdp [options]"); + g_writeln(" --help: show help"); + g_writeln(" --nodaemon: don't fork into background"); + g_writeln(" --kill: shut down xrdp"); + g_writeln(" --port: tcp listen port"); + g_writeln(" --fork: fork on new connection"); + g_writeln(""); + g_deinit(); + g_exit(0); + } + + if (startup_params->version) + { + g_writeln(""); + g_writeln("xrdp: A Remote Desktop Protocol server."); + g_writeln("Copyright (C) Jay Sorg 2004-2011"); + g_writeln("See http://xrdp.sourceforge.net for more information."); + g_writeln("Version %s", PACKAGE_VERSION); + g_writeln(""); + g_deinit(); + g_exit(0); + } - if (startup_params->kill) - { - g_writeln("stopping xrdp"); - /* read the xrdp.pid file */ - fd = -1; if (g_file_exist(pid_file)) /* xrdp.pid */ { - fd = g_file_open(pid_file); /* xrdp.pid */ + g_writeln("It looks like xrdp is allready running,"); + g_writeln("if not delete the xrdp.pid file and try again"); + g_deinit(); + g_exit(0); } - if (fd == -1) - { - g_writeln("problem opening to xrdp.pid [%s]", pid_file); - g_writeln("maybe its not running"); - } - else - { - g_memset(text, 0, 32); - g_file_read(fd, text, 31); - pid = g_atoi(text); - g_writeln("stopping process id %d", pid); - if (pid > 0) - { - g_sigterm(pid); - } - g_file_close(fd); - } - g_deinit(); - g_exit(0); - } - if (startup_params->no_daemon) - { - no_daemon = 1; - } - if (startup_params->help) - { - g_writeln(""); - g_writeln("xrdp: A Remote Desktop Protocol server."); - g_writeln("Copyright (C) Jay Sorg 2004-2011"); - g_writeln("See http://xrdp.sourceforge.net for more information."); - g_writeln(""); - g_writeln("Usage: xrdp [options]"); - g_writeln(" --help: show help"); - g_writeln(" --nodaemon: don't fork into background"); - g_writeln(" --kill: shut down xrdp"); - g_writeln(" --port: tcp listen port"); - g_writeln(" --fork: fork on new connection"); - g_writeln(""); - g_deinit(); - g_exit(0); - } - if (startup_params->version) - { - g_writeln(""); - g_writeln("xrdp: A Remote Desktop Protocol server."); - g_writeln("Copyright (C) Jay Sorg 2004-2011"); - g_writeln("See http://xrdp.sourceforge.net for more information."); - g_writeln("Version %s",PACKAGE_VERSION); - g_writeln(""); - g_deinit(); - g_exit(0); - } - if (g_file_exist(pid_file)) /* xrdp.pid */ - { - g_writeln("It looks like xrdp is allready running,"); - g_writeln("if not delete the xrdp.pid file and try again"); - g_deinit(); - g_exit(0); - } - if (!no_daemon) - { - /* make sure containing directory exists */ - g_create_path(pid_file); + if (!no_daemon) + { - /* make sure we can write to pid file */ - fd = g_file_open(pid_file); /* xrdp.pid */ - if (fd == -1) - { - g_writeln("running in daemon mode with no access to pid files, quitting"); - g_deinit(); - g_exit(0); + /* make sure containing directory exists */ + g_create_path(pid_file); + + /* make sure we can write to pid file */ + fd = g_file_open(pid_file); /* xrdp.pid */ + + if (fd == -1) + { + g_writeln("running in daemon mode with no access to pid files, quitting"); + g_deinit(); + g_exit(0); + } + + if (g_file_write(fd, "0", 1) == -1) + { + g_writeln("running in daemon mode with no access to pid files, quitting"); + g_deinit(); + g_exit(0); + } + + g_file_close(fd); + g_file_delete(pid_file); } - if (g_file_write(fd, "0", 1) == -1) + + if (!no_daemon) { - g_writeln("running in daemon mode with no access to pid files, quitting"); - g_deinit(); - g_exit(0); + /* start of daemonizing code */ + pid = g_fork(); + + if (pid == -1) + { + g_writeln("problem forking"); + g_deinit(); + g_exit(1); + } + + if (0 != pid) + { + g_writeln("process %d started ok", pid); + /* exit, this is the main process */ + g_deinit(); + g_exit(0); + } + + g_sleep(1000); + /* write the pid to file */ + pid = g_getpid(); + fd = g_file_open(pid_file); /* xrdp.pid */ + + if (fd == -1) + { + g_writeln("trying to write process id to xrdp.pid"); + g_writeln("problem opening xrdp.pid"); + g_writeln("maybe no rights"); + } + else + { + g_sprintf(text, "%d", pid); + g_file_write(fd, text, g_strlen(text)); + g_file_close(fd); + } + + g_sleep(1000); + g_file_close(0); + g_file_close(1); + g_file_close(2); + g_file_open("/dev/null"); + g_file_open("/dev/null"); + g_file_open("/dev/null"); + /* end of daemonizing code */ } - g_file_close(fd); - g_file_delete(pid_file); - } - if (!no_daemon) - { - /* start of daemonizing code */ - pid = g_fork(); - if (pid == -1) - { - g_writeln("problem forking"); - g_deinit(); - g_exit(1); - } - if (0 != pid) - { - g_writeln("process %d started ok", pid); - /* exit, this is the main process */ - g_deinit(); - g_exit(0); - } - g_sleep(1000); - /* write the pid to file */ + + g_threadid = tc_get_threadid(); + g_listen = xrdp_listen_create(); + g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */ + g_signal_kill(xrdp_shutdown); /* SIGKILL */ + g_signal_pipe(pipe_sig); /* SIGPIPE */ + g_signal_terminate(xrdp_shutdown); /* SIGTERM */ + g_signal_child_stop(xrdp_child); /* SIGCHLD */ + g_sync_mutex = tc_mutex_create(); + g_sync1_mutex = tc_mutex_create(); pid = g_getpid(); - fd = g_file_open(pid_file); /* xrdp.pid */ - if (fd == -1) + g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); + g_term_event = g_create_wait_obj(text); + + if (g_term_event == 0) { - g_writeln("trying to write process id to xrdp.pid"); - g_writeln("problem opening xrdp.pid"); - g_writeln("maybe no rights"); + g_writeln("error creating g_term_event"); } - else + + g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); + g_sync_event = g_create_wait_obj(text); + + if (g_sync_event == 0) { - g_sprintf(text, "%d", pid); - g_file_write(fd, text, g_strlen(text)); - g_file_close(fd); + g_writeln("error creating g_sync_event"); } - g_sleep(1000); - g_file_close(0); - g_file_close(1); - g_file_close(2); - g_file_open("/dev/null"); - g_file_open("/dev/null"); - g_file_open("/dev/null"); - /* end of daemonizing code */ - } - g_threadid = tc_get_threadid(); - g_listen = xrdp_listen_create(); - g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */ - g_signal_kill(xrdp_shutdown); /* SIGKILL */ - g_signal_pipe(pipe_sig); /* SIGPIPE */ - g_signal_terminate(xrdp_shutdown); /* SIGTERM */ - g_signal_child_stop(xrdp_child); /* SIGCHLD */ - g_sync_mutex = tc_mutex_create(); - g_sync1_mutex = tc_mutex_create(); - pid = g_getpid(); - g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); - g_term_event = g_create_wait_obj(text); - if (g_term_event == 0) - { - g_writeln("error creating g_term_event"); - } - g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); - g_sync_event = g_create_wait_obj(text); - if (g_sync_event == 0) - { - g_writeln("error creating g_sync_event"); - } - g_listen->startup_params = startup_params; - xrdp_listen_main_loop(g_listen); - xrdp_listen_delete(g_listen); - tc_mutex_delete(g_sync_mutex); - tc_mutex_delete(g_sync1_mutex); - g_delete_wait_obj(g_term_event); - g_delete_wait_obj(g_sync_event); - /* only main process should delete pid file */ - if ((!no_daemon) && (pid == g_getpid())) - { - /* delete the xrdp.pid file */ - g_file_delete(pid_file); - } - g_free(startup_params); - g_deinit(); - return 0; + + g_listen->startup_params = startup_params; + xrdp_listen_main_loop(g_listen); + xrdp_listen_delete(g_listen); + tc_mutex_delete(g_sync_mutex); + tc_mutex_delete(g_sync1_mutex); + g_delete_wait_obj(g_term_event); + g_delete_wait_obj(g_sync_event); + + /* only main process should delete pid file */ + if ((!no_daemon) && (pid == g_getpid())) + { + /* delete the xrdp.pid file */ + g_file_delete(pid_file); + } + + g_free(startup_params); + g_deinit(); + return 0; } diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 2f4e7eb6..a98acb16 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - main include file - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * main include file + */ /* include other h files */ #if defined(HAVE_CONFIG_H) diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index 828c5139..d60cc920 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -1,27 +1,25 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - bitmap, drawable - this is a object that can be drawn on with a painter - all windows, bitmaps, even the screen are of this type - maybe it should be called xrdp_drawable - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * bitmap, drawable + * this is a object that can be drawn on with a painter + * all windows, bitmaps, even the screen are of this type + * maybe it should be called xrdp_drawable + */ #include "xrdp.h" #include "log.h" @@ -29,303 +27,348 @@ static int g_crc_seed = 0xffffffff; static int g_crc_table[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; #define CRC_START(in_crc) (in_crc) = g_crc_seed #define CRC_PASS(in_pixel, in_crc) \ - (in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8) + (in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8) #define CRC_END(in_crc) (in_crc) = ((in_crc) ^ g_crc_seed) /*****************************************************************************/ -struct xrdp_bitmap* APP_CC +struct xrdp_bitmap *APP_CC xrdp_bitmap_create(int width, int height, int bpp, - int type, struct xrdp_wm* wm) + int type, struct xrdp_wm *wm) { - struct xrdp_bitmap* self = (struct xrdp_bitmap *)NULL; - int Bpp = 0; + struct xrdp_bitmap *self = (struct xrdp_bitmap *)NULL; + int Bpp = 0; - self = (struct xrdp_bitmap*)g_malloc(sizeof(struct xrdp_bitmap), 1); - self->type = type; - self->width = width; - self->height = height; - self->bpp = bpp; - Bpp = 4; - switch (bpp) - { - case 8: Bpp = 1; break; - case 15: Bpp = 2; break; - case 16: Bpp = 2; break; - } - if (self->type == WND_TYPE_BITMAP || self->type == WND_TYPE_IMAGE) - { - self->data = (char*)g_malloc(width * height * Bpp, 0); - } - if (self->type != WND_TYPE_BITMAP) - { - self->child_list = list_create(); - } - self->line_size = width * Bpp; - if (self->type == WND_TYPE_COMBO) - { - self->string_list = list_create(); - self->string_list->auto_free = 1; - self->data_list = list_create(); - self->data_list->auto_free = 1; - } - self->wm = wm; - return self; + self = (struct xrdp_bitmap *)g_malloc(sizeof(struct xrdp_bitmap), 1); + self->type = type; + self->width = width; + self->height = height; + self->bpp = bpp; + Bpp = 4; + + switch (bpp) + { + case 8: + Bpp = 1; + break; + case 15: + Bpp = 2; + break; + case 16: + Bpp = 2; + break; + } + + if (self->type == WND_TYPE_BITMAP || self->type == WND_TYPE_IMAGE) + { + self->data = (char *)g_malloc(width * height * Bpp, 0); + } + + if (self->type != WND_TYPE_BITMAP) + { + self->child_list = list_create(); + } + + self->line_size = width *Bpp; + + if (self->type == WND_TYPE_COMBO) + { + self->string_list = list_create(); + self->string_list->auto_free = 1; + self->data_list = list_create(); + self->data_list->auto_free = 1; + } + + self->wm = wm; + return self; } /*****************************************************************************/ -struct xrdp_bitmap* APP_CC +struct xrdp_bitmap *APP_CC xrdp_bitmap_create_with_data(int width, int height, - int bpp, char* data, - struct xrdp_wm* wm) + int bpp, char *data, + struct xrdp_wm *wm) { - struct xrdp_bitmap* self = (struct xrdp_bitmap *)NULL; + struct xrdp_bitmap *self = (struct xrdp_bitmap *)NULL; - self = (struct xrdp_bitmap*)g_malloc(sizeof(struct xrdp_bitmap), 1); - self->type = WND_TYPE_BITMAP; - self->width = width; - self->height = height; - self->bpp = bpp; - self->data = data; - self->do_not_free_data = 1; - self->wm = wm; - return self; + self = (struct xrdp_bitmap *)g_malloc(sizeof(struct xrdp_bitmap), 1); + self->type = WND_TYPE_BITMAP; + self->width = width; + self->height = height; + self->bpp = bpp; + self->data = data; + self->do_not_free_data = 1; + self->wm = wm; + return self; } /*****************************************************************************/ void APP_CC -xrdp_bitmap_delete(struct xrdp_bitmap* self) +xrdp_bitmap_delete(struct xrdp_bitmap *self) { - int i = 0; - struct xrdp_mod_data* mod_data = (struct xrdp_mod_data *)NULL; + int i = 0; + struct xrdp_mod_data *mod_data = (struct xrdp_mod_data *)NULL; - if (self == 0) - { - return; - } - if (self->wm != 0) - { - if (self->wm->focused_window != 0) + if (self == 0) { - if (self->wm->focused_window->focused_control == self) - { - self->wm->focused_window->focused_control = 0; - } + return; } - if (self->wm->focused_window == self) + + if (self->wm != 0) { - self->wm->focused_window = 0; + if (self->wm->focused_window != 0) + { + if (self->wm->focused_window->focused_control == self) + { + self->wm->focused_window->focused_control = 0; + } + } + + if (self->wm->focused_window == self) + { + self->wm->focused_window = 0; + } + + if (self->wm->dragging_window == self) + { + self->wm->dragging_window = 0; + } + + if (self->wm->button_down == self) + { + self->wm->button_down = 0; + } + + if (self->wm->popup_wnd == self) + { + self->wm->popup_wnd = 0; + } + + if (self->wm->login_window == self) + { + self->wm->login_window = 0; + } + + if (self->wm->log_wnd == self) + { + self->wm->log_wnd = 0; + } } - if (self->wm->dragging_window == self) + + if (self->child_list != 0) { - self->wm->dragging_window = 0; + for (i = self->child_list->count - 1; i >= 0; i--) + { + xrdp_bitmap_delete((struct xrdp_bitmap *)self->child_list->items[i]); + } + + list_delete(self->child_list); } - if (self->wm->button_down == self) + + if (self->parent != 0) { - self->wm->button_down = 0; + i = list_index_of(self->parent->child_list, (long)self); + + if (i >= 0) + { + list_remove_item(self->parent->child_list, i); + } } - if (self->wm->popup_wnd == self) + + if (self->string_list != 0) /* for combo */ { - self->wm->popup_wnd = 0; + list_delete(self->string_list); } - if (self->wm->login_window == self) + + if (self->data_list != 0) /* for combo */ { - self->wm->login_window = 0; + for (i = 0; i < self->data_list->count; i++) + { + mod_data = (struct xrdp_mod_data *)list_get_item(self->data_list, i); + + if (mod_data != 0) + { + list_delete(mod_data->names); + list_delete(mod_data->values); + } + } + + list_delete(self->data_list); } - if (self->wm->log_wnd == self) + + if (!self->do_not_free_data) { - self->wm->log_wnd = 0; + g_free(self->data); } - } - if (self->child_list != 0) - { - for (i = self->child_list->count - 1; i >= 0; i--) - { - xrdp_bitmap_delete((struct xrdp_bitmap*)self->child_list->items[i]); - } - list_delete(self->child_list); - } - if (self->parent != 0) - { - i = list_index_of(self->parent->child_list, (long)self); - if (i >= 0) - { - list_remove_item(self->parent->child_list, i); - } - } - if (self->string_list != 0) /* for combo */ - { - list_delete(self->string_list); - } - if (self->data_list != 0) /* for combo */ - { - for (i = 0; i < self->data_list->count; i++) - { - mod_data = (struct xrdp_mod_data*)list_get_item(self->data_list, i); - if (mod_data != 0) - { - list_delete(mod_data->names); - list_delete(mod_data->values); - } - } - list_delete(self->data_list); - } - if (!self->do_not_free_data) - { - g_free(self->data); - } - g_free(self->caption1); - g_free(self); + + g_free(self->caption1); + g_free(self); } /*****************************************************************************/ -struct xrdp_bitmap* APP_CC -xrdp_bitmap_get_child_by_id(struct xrdp_bitmap* self, int id) +struct xrdp_bitmap *APP_CC +xrdp_bitmap_get_child_by_id(struct xrdp_bitmap *self, int id) { - int i = 0; - struct xrdp_bitmap* b = (struct xrdp_bitmap *)NULL; + int i = 0; + struct xrdp_bitmap *b = (struct xrdp_bitmap *)NULL; - for (i = 0; i < self->child_list->count; i++) - { - b = (struct xrdp_bitmap*)list_get_item(self->child_list, i); - if (b->id == id) + for (i = 0; i < self->child_list->count; i++) { - return b; + b = (struct xrdp_bitmap *)list_get_item(self->child_list, i); + + if (b->id == id) + { + return b; + } } - } - return 0; + + return 0; } /*****************************************************************************/ /* if focused is true focus this window else unfocus it */ /* returns error */ int APP_CC -xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused) +xrdp_bitmap_set_focus(struct xrdp_bitmap *self, int focused) { - struct xrdp_painter* painter = (struct xrdp_painter *)NULL; + struct xrdp_painter *painter = (struct xrdp_painter *)NULL; - if (self == 0) - { + if (self == 0) + { + return 0; + } + + if (self->type != WND_TYPE_WND) /* 1 */ + { + return 0; + } + + painter = xrdp_painter_create(self->wm, self->wm->session); + xrdp_painter_font_needed(painter); + xrdp_painter_begin_update(painter); + + if (focused) + { + /* active title bar */ + painter->fg_color = self->wm->blue; + xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); + painter->fg_color = self->wm->white; + } + else + { + /* inactive title bar */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); + painter->fg_color = self->wm->black; + } + + xrdp_painter_draw_text(painter, self, 4, 4, self->caption1); + xrdp_painter_end_update(painter); + xrdp_painter_delete(painter); return 0; - } - if (self->type != WND_TYPE_WND) /* 1 */ - { - return 0; - } - painter = xrdp_painter_create(self->wm, self->wm->session); - xrdp_painter_font_needed(painter); - xrdp_painter_begin_update(painter); - if (focused) - { - /* active title bar */ - painter->fg_color = self->wm->blue; - xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); - painter->fg_color = self->wm->white; - } - else - { - /* inactive title bar */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); - painter->fg_color = self->wm->black; - } - xrdp_painter_draw_text(painter, self, 4, 4, self->caption1); - xrdp_painter_end_update(painter); - xrdp_painter_delete(painter); - return 0; } /*****************************************************************************/ static int APP_CC -xrdp_bitmap_get_index(struct xrdp_bitmap* self, int* palette, int color) +xrdp_bitmap_get_index(struct xrdp_bitmap *self, int *palette, int color) { - int r = 0; - int g = 0; - int b = 0; + int r = 0; + int g = 0; + int b = 0; - r = (color & 0xff0000) >> 16; - g = (color & 0x00ff00) >> 8; - b = (color & 0x0000ff) >> 0; - r = (r >> 5) << 0; - g = (g >> 5) << 3; - b = (b >> 6) << 6; - return (b | g | r); + r = (color & 0xff0000) >> 16; + g = (color & 0x00ff00) >> 8; + b = (color & 0x0000ff) >> 0; + r = (r >> 5) << 0; + g = (g >> 5) << 3; + b = (b >> 6) << 6; + return (b | g | r); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_bitmap_resize(struct xrdp_bitmap* self, int width, int height) +xrdp_bitmap_resize(struct xrdp_bitmap *self, int width, int height) { - int Bpp = 0; + int Bpp = 0; - if ((width == self->width) && (height == self->height)) - { + if ((width == self->width) && (height == self->height)) + { + return 0; + } + + if (self->do_not_free_data) + { + return 1; + } + + self->width = width; + self->height = height; + Bpp = 4; + + switch (self->bpp) + { + case 8: + Bpp = 1; + break; + case 15: + Bpp = 2; + break; + case 16: + Bpp = 2; + break; + } + + g_free(self->data); + self->data = (char *)g_malloc(width * height * Bpp, 0); + self->line_size = width * Bpp; return 0; - } - if (self->do_not_free_data) - { - return 1; - } - self->width = width; - self->height = height; - Bpp = 4; - switch (self->bpp) - { - case 8: Bpp = 1; break; - case 15: Bpp = 2; break; - case 16: Bpp = 2; break; - } - g_free(self->data); - self->data = (char*)g_malloc(width * height * Bpp, 0); - self->line_size = width * Bpp; - return 0; } /*****************************************************************************/ @@ -333,1428 +376,1569 @@ xrdp_bitmap_resize(struct xrdp_bitmap* self, int width, int height) /* return 0 ok */ /* return 1 error */ int APP_CC -xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette) +xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette) { - int fd = 0; - int i = 0; - int j = 0; - int k = 0; - int color = 0; - int size = 0; - int palette1[256]; - char type1[4]; - struct xrdp_bmp_header header; - struct stream* s = (struct stream *)NULL; + int fd = 0; + int i = 0; + int j = 0; + int k = 0; + int color = 0; + int size = 0; + int palette1[256]; + char type1[4]; + struct xrdp_bmp_header header; + struct stream *s = (struct stream *)NULL; - g_memset(palette1,0,sizeof(int) * 256); - g_memset(type1,0,sizeof(char) * 4); - g_memset(&header,0,sizeof(struct xrdp_bmp_header)); + g_memset(palette1, 0, sizeof(int) * 256); + g_memset(type1, 0, sizeof(char) * 4); + g_memset(&header, 0, sizeof(struct xrdp_bmp_header)); - if (!g_file_exist(filename)) - { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] " - "does not exist", filename); - return 1; - } - s = (struct stream *)NULL; - fd = g_file_open(filename); - if (fd != -1) - { - /* read file type */ - if (g_file_read(fd, type1, 2) != 2) + if (!g_file_exist(filename)) { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] " - "read error", filename); - g_file_close(fd); - return 1; + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] " + "does not exist", filename); + return 1; } - if ((type1[0] != 'B') || (type1[1] != 'M')) + + s = (struct stream *)NULL; + fd = g_file_open(filename); + + if (fd != -1) { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] " - "not BMP file", filename); - g_file_close(fd); - return 1; + /* read file type */ + if (g_file_read(fd, type1, 2) != 2) + { + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] " + "read error", filename); + g_file_close(fd); + return 1; + } + + if ((type1[0] != 'B') || (type1[1] != 'M')) + { + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] " + "not BMP file", filename); + g_file_close(fd); + return 1; + } + + /* read file size */ + make_stream(s); + init_stream(s, 8192); + g_file_read(fd, s->data, 4); + in_uint32_le(s, size); + /* read bmp header */ + g_file_seek(fd, 14); + init_stream(s, 8192); + g_file_read(fd, s->data, 40); /* size better be 40 */ + in_uint32_le(s, header.size); + in_uint32_le(s, header.image_width); + in_uint32_le(s, header.image_height); + in_uint16_le(s, header.planes); + in_uint16_le(s, header.bit_count); + in_uint32_le(s, header.compression); + in_uint32_le(s, header.image_size); + in_uint32_le(s, header.x_pels_per_meter); + in_uint32_le(s, header.y_pels_per_meter); + in_uint32_le(s, header.clr_used); + in_uint32_le(s, header.clr_important); + + if ((header.bit_count != 4) && (header.bit_count != 8) && + (header.bit_count != 24)) + { + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] " + "bad bpp %d", filename, header.bit_count); + free_stream(s); + g_file_close(fd); + return 1; + } + + if (header.bit_count == 24) /* 24 bit bitmap */ + { + g_file_seek(fd, 14 + header.size); + xrdp_bitmap_resize(self, header.image_width, header.image_height); + size = header.image_width * header.image_height * 3; + init_stream(s, size); + + /* read data */ + for (i = header.image_height - 1; i >= 0; i--) + { + size = header.image_width * 3; + k = g_file_read(fd, s->data + i * size, size); + + if (k != size) + { + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap " + "file [%s] read", filename); + } + } + + for (i = 0; i < self->height; i++) + { + for (j = 0; j < self->width; j++) + { + in_uint8(s, k); + color = k; + in_uint8(s, k); + color |= k << 8; + in_uint8(s, k); + color |= k << 16; + + if (self->bpp == 8) + { + color = xrdp_bitmap_get_index(self, palette, color); + } + else if (self->bpp == 15) + { + color = COLOR15((color & 0xff0000) >> 16, + (color & 0x00ff00) >> 8, + (color & 0x0000ff) >> 0); + } + else if (self->bpp == 16) + { + color = COLOR16((color & 0xff0000) >> 16, + (color & 0x00ff00) >> 8, + (color & 0x0000ff) >> 0); + } + + xrdp_bitmap_set_pixel(self, j, i, color); + } + } + } + else if (header.bit_count == 8) /* 8 bit bitmap */ + { + /* read palette */ + g_file_seek(fd, 14 + header.size); + init_stream(s, 8192); + g_file_read(fd, s->data, header.clr_used * sizeof(int)); + + for (i = 0; i < header.clr_used; i++) + { + in_uint32_le(s, palette1[i]); + } + + xrdp_bitmap_resize(self, header.image_width, header.image_height); + size = header.image_width * header.image_height; + init_stream(s, size); + + /* read data */ + for (i = header.image_height - 1; i >= 0; i--) + { + size = header.image_width; + k = g_file_read(fd, s->data + i * size, size); + + if (k != size) + { + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap " + "file [%s] read", filename); + } + } + + for (i = 0; i < self->height; i++) + { + for (j = 0; j < self->width; j++) + { + in_uint8(s, k); + color = palette1[k]; + + if (self->bpp == 8) + { + color = xrdp_bitmap_get_index(self, palette, color); + } + else if (self->bpp == 15) + { + color = COLOR15((color & 0xff0000) >> 16, + (color & 0x00ff00) >> 8, + (color & 0x0000ff) >> 0); + } + else if (self->bpp == 16) + { + color = COLOR16((color & 0xff0000) >> 16, + (color & 0x00ff00) >> 8, + (color & 0x0000ff) >> 0); + } + + xrdp_bitmap_set_pixel(self, j, i, color); + } + } + } + else if (header.bit_count == 4) /* 4 bit bitmap */ + { + /* read palette */ + g_file_seek(fd, 14 + header.size); + init_stream(s, 8192); + g_file_read(fd, s->data, header.clr_used * sizeof(int)); + + for (i = 0; i < header.clr_used; i++) + { + in_uint32_le(s, palette1[i]); + } + + xrdp_bitmap_resize(self, header.image_width, header.image_height); + size = (header.image_width * header.image_height) / 2; + init_stream(s, size); + + /* read data */ + for (i = header.image_height - 1; i >= 0; i--) + { + size = header.image_width / 2; + k = g_file_read(fd, s->data + i * size, size); + + if (k != size) + { + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap " + "file [%s] read", filename); + } + } + + for (i = 0; i < self->height; i++) + { + for (j = 0; j < self->width; j++) + { + if ((j & 1) == 0) + { + in_uint8(s, k); + color = (k >> 4) & 0xf; + } + else + { + color = k & 0xf; + } + + color = palette1[color]; + + if (self->bpp == 8) + { + color = xrdp_bitmap_get_index(self, palette, color); + } + else if (self->bpp == 15) + { + color = COLOR15((color & 0xff0000) >> 16, + (color & 0x00ff00) >> 8, + (color & 0x0000ff) >> 0); + } + else if (self->bpp == 16) + { + color = COLOR16((color & 0xff0000) >> 16, + (color & 0x00ff00) >> 8, + (color & 0x0000ff) >> 0); + } + + xrdp_bitmap_set_pixel(self, j, i, color); + } + } + } + + g_file_close(fd); + free_stream(s); } - /* read file size */ - make_stream(s); - init_stream(s, 8192); - g_file_read(fd, s->data, 4); - in_uint32_le(s, size); - /* read bmp header */ - g_file_seek(fd, 14); - init_stream(s, 8192); - g_file_read(fd, s->data, 40); /* size better be 40 */ - in_uint32_le(s, header.size); - in_uint32_le(s, header.image_width); - in_uint32_le(s, header.image_height); - in_uint16_le(s, header.planes); - in_uint16_le(s, header.bit_count); - in_uint32_le(s, header.compression); - in_uint32_le(s, header.image_size); - in_uint32_le(s, header.x_pels_per_meter); - in_uint32_le(s, header.y_pels_per_meter); - in_uint32_le(s, header.clr_used); - in_uint32_le(s, header.clr_important); - if ((header.bit_count != 4) && (header.bit_count != 8) && - (header.bit_count != 24)) + else { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] " - "bad bpp %d", filename, header.bit_count); - free_stream(s); - g_file_close(fd); - return 1; + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error loading bitmap " + "from file [%s]", filename); + return 1; } - if (header.bit_count == 24) /* 24 bit bitmap */ - { - g_file_seek(fd, 14 + header.size); - xrdp_bitmap_resize(self, header.image_width, header.image_height); - size = header.image_width * header.image_height * 3; - init_stream(s, size); - /* read data */ - for (i = header.image_height - 1; i >= 0; i--) - { - size = header.image_width * 3; - k = g_file_read(fd, s->data + i * size, size); - if (k != size) - { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap " - "file [%s] read", filename); - } - } - for (i = 0; i < self->height; i++) - { - for (j = 0; j < self->width; j++) - { - in_uint8(s, k); - color = k; - in_uint8(s, k); - color |= k << 8; - in_uint8(s, k); - color |= k << 16; - if (self->bpp == 8) - { - color = xrdp_bitmap_get_index(self, palette, color); - } - else if (self->bpp == 15) - { - color = COLOR15((color & 0xff0000) >> 16, - (color & 0x00ff00) >> 8, - (color & 0x0000ff) >> 0); - } - else if (self->bpp == 16) - { - color = COLOR16((color & 0xff0000) >> 16, - (color & 0x00ff00) >> 8, - (color & 0x0000ff) >> 0); - } - xrdp_bitmap_set_pixel(self, j, i, color); - } - } - } - else if (header.bit_count == 8) /* 8 bit bitmap */ - { - /* read palette */ - g_file_seek(fd, 14 + header.size); - init_stream(s, 8192); - g_file_read(fd, s->data, header.clr_used * sizeof(int)); - for (i = 0; i < header.clr_used; i++) - { - in_uint32_le(s, palette1[i]); - } - xrdp_bitmap_resize(self, header.image_width, header.image_height); - size = header.image_width * header.image_height; - init_stream(s, size); - /* read data */ - for (i = header.image_height - 1; i >= 0; i--) - { - size = header.image_width; - k = g_file_read(fd, s->data + i * size, size); - if (k != size) - { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap " - "file [%s] read", filename); - } - } - for (i = 0; i < self->height; i++) - { - for (j = 0; j < self->width; j++) - { - in_uint8(s, k); - color = palette1[k]; - if (self->bpp == 8) - { - color = xrdp_bitmap_get_index(self, palette, color); - } - else if (self->bpp == 15) - { - color = COLOR15((color & 0xff0000) >> 16, - (color & 0x00ff00) >> 8, - (color & 0x0000ff) >> 0); - } - else if (self->bpp == 16) - { - color = COLOR16((color & 0xff0000) >> 16, - (color & 0x00ff00) >> 8, - (color & 0x0000ff) >> 0); - } - xrdp_bitmap_set_pixel(self, j, i, color); - } - } - } - else if (header.bit_count == 4) /* 4 bit bitmap */ - { - /* read palette */ - g_file_seek(fd, 14 + header.size); - init_stream(s, 8192); - g_file_read(fd, s->data, header.clr_used * sizeof(int)); - for (i = 0; i < header.clr_used; i++) - { - in_uint32_le(s, palette1[i]); - } - xrdp_bitmap_resize(self, header.image_width, header.image_height); - size = (header.image_width * header.image_height) / 2; - init_stream(s, size); - /* read data */ - for (i = header.image_height - 1; i >= 0; i--) - { - size = header.image_width / 2; - k = g_file_read(fd, s->data + i * size, size); - if (k != size) - { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap " - "file [%s] read", filename); - } - } - for (i = 0; i < self->height; i++) - { - for (j = 0; j < self->width; j++) - { - if ((j & 1) == 0) - { - in_uint8(s, k); - color = (k >> 4) & 0xf; - } - else - { - color = k & 0xf; - } - color = palette1[color]; - if (self->bpp == 8) - { - color = xrdp_bitmap_get_index(self, palette, color); - } - else if (self->bpp == 15) - { - color = COLOR15((color & 0xff0000) >> 16, - (color & 0x00ff00) >> 8, - (color & 0x0000ff) >> 0); - } - else if (self->bpp == 16) - { - color = COLOR16((color & 0xff0000) >> 16, - (color & 0x00ff00) >> 8, - (color & 0x0000ff) >> 0); - } - xrdp_bitmap_set_pixel(self, j, i, color); - } - } - } - g_file_close(fd); - free_stream(s); - } - else - { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error loading bitmap " - "from file [%s]", filename); - return 1; - } - return 0; + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_bitmap_get_pixel(struct xrdp_bitmap* self, int x, int y) +xrdp_bitmap_get_pixel(struct xrdp_bitmap *self, int x, int y) { - if (self == 0) - { + if (self == 0) + { + return 0; + } + + if (self->data == 0) + { + return 0; + } + + if (x >= 0 && x < self->width && y >= 0 && y < self->height) + { + if (self->bpp == 8) + { + return GETPIXEL8(self->data, x, y, self->width); + } + else if (self->bpp == 15 || self->bpp == 16) + { + return GETPIXEL16(self->data, x, y, self->width); + } + else if (self->bpp == 24) + { + return GETPIXEL32(self->data, x, y, self->width); + } + } + return 0; - } - if (self->data == 0) - { - return 0; - } - if (x >= 0 && x < self->width && y >= 0 && y < self->height) - { - if (self->bpp == 8) - { - return GETPIXEL8(self->data, x, y, self->width); - } - else if (self->bpp == 15 || self->bpp == 16) - { - return GETPIXEL16(self->data, x, y, self->width); - } - else if (self->bpp == 24) - { - return GETPIXEL32(self->data, x, y, self->width); - } - } - return 0; } /*****************************************************************************/ int APP_CC -xrdp_bitmap_set_pixel(struct xrdp_bitmap* self, int x, int y, int pixel) +xrdp_bitmap_set_pixel(struct xrdp_bitmap *self, int x, int y, int pixel) { - if (self == 0) - { + if (self == 0) + { + return 0; + } + + if (self->data == 0) + { + return 0; + } + + if (x >= 0 && x < self->width && y >= 0 && y < self->height) + { + if (self->bpp == 8) + { + SETPIXEL8(self->data, x, y, self->width, pixel); + } + else if (self->bpp == 15 || self->bpp == 16) + { + SETPIXEL16(self->data, x, y, self->width, pixel); + } + else if (self->bpp == 24) + { + SETPIXEL32(self->data, x, y, self->width, pixel); + } + } + return 0; - } - if (self->data == 0) - { - return 0; - } - if (x >= 0 && x < self->width && y >= 0 && y < self->height) - { - if (self->bpp == 8) - { - SETPIXEL8(self->data, x, y, self->width, pixel); - } - else if (self->bpp == 15 || self->bpp == 16) - { - SETPIXEL16(self->data, x, y, self->width, pixel); - } - else if (self->bpp == 24) - { - SETPIXEL32(self->data, x, y, self->width, pixel); - } - } - return 0; } /*****************************************************************************/ /* copy part of self at x, y to 0, 0 in dest */ /* returns error */ int APP_CC -xrdp_bitmap_copy_box(struct xrdp_bitmap* self, - struct xrdp_bitmap* dest, +xrdp_bitmap_copy_box(struct xrdp_bitmap *self, + struct xrdp_bitmap *dest, int x, int y, int cx, int cy) { - int i = 0; - int j = 0; - int destx = 0; - int desty = 0; - int pixel = 0; + int i = 0; + int j = 0; + int destx = 0; + int desty = 0; + int pixel = 0; - if (self == 0) - { - return 1; - } - if (dest == 0) - { - return 1; - } - if (self->type != WND_TYPE_BITMAP && self->type != WND_TYPE_IMAGE) - { - return 1; - } - if (dest->type != WND_TYPE_BITMAP && dest->type != WND_TYPE_IMAGE) - { - return 1; - } - if (self->bpp != dest->bpp) - { - return 1; - } - destx = 0; - desty = 0; - if (!check_bounds(self, &x, &y, &cx, &cy)) - { - return 1; - } - if (!check_bounds(dest, &destx, &desty, &cx, &cy)) - { - return 1; - } - if (self->bpp == 24) - { - for (i = 0; i < cy; i++) + if (self == 0) { - for (j = 0; j < cx; j++) - { - pixel = GETPIXEL32(self->data, j + x, i + y, self->width); - SETPIXEL32(dest->data, j + destx, i + desty, dest->width, pixel); - } + return 1; } - } - else if (self->bpp == 15 || self->bpp == 16) - { - for (i = 0; i < cy; i++) + + if (dest == 0) { - for (j = 0; j < cx; j++) - { - pixel = GETPIXEL16(self->data, j + x, i + y, self->width); - SETPIXEL16(dest->data, j + destx, i + desty, dest->width, pixel); - } + return 1; } - } - else if (self->bpp == 8) - { - for (i = 0; i < cy; i++) + + if (self->type != WND_TYPE_BITMAP && self->type != WND_TYPE_IMAGE) { - for (j = 0; j < cx; j++) - { - pixel = GETPIXEL8(self->data, j + x, i + y, self->width); - SETPIXEL8(dest->data, j + destx, i + desty, dest->width, pixel); - } + return 1; } - } - else - { - return 1; - } - return 0; + + if (dest->type != WND_TYPE_BITMAP && dest->type != WND_TYPE_IMAGE) + { + return 1; + } + + if (self->bpp != dest->bpp) + { + return 1; + } + + destx = 0; + desty = 0; + + if (!check_bounds(self, &x, &y, &cx, &cy)) + { + return 1; + } + + if (!check_bounds(dest, &destx, &desty, &cx, &cy)) + { + return 1; + } + + if (self->bpp == 24) + { + for (i = 0; i < cy; i++) + { + for (j = 0; j < cx; j++) + { + pixel = GETPIXEL32(self->data, j + x, i + y, self->width); + SETPIXEL32(dest->data, j + destx, i + desty, dest->width, pixel); + } + } + } + else if (self->bpp == 15 || self->bpp == 16) + { + for (i = 0; i < cy; i++) + { + for (j = 0; j < cx; j++) + { + pixel = GETPIXEL16(self->data, j + x, i + y, self->width); + SETPIXEL16(dest->data, j + destx, i + desty, dest->width, pixel); + } + } + } + else if (self->bpp == 8) + { + for (i = 0; i < cy; i++) + { + for (j = 0; j < cx; j++) + { + pixel = GETPIXEL8(self->data, j + x, i + y, self->width); + SETPIXEL8(dest->data, j + destx, i + desty, dest->width, pixel); + } + } + } + else + { + return 1; + } + + return 0; } /*****************************************************************************/ /* copy part of self at x, y to 0, 0 in dest */ /* returns error */ int APP_CC -xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap* self, - struct xrdp_bitmap* dest, +xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self, + struct xrdp_bitmap *dest, int x, int y, int cx, int cy) { - int i = 0; - int j = 0; - int destx = 0; - int desty = 0; - int pixel = 0; - int crc = 0; - int incs = 0; - int incd = 0; - unsigned char* s8 = (unsigned char *)NULL; - unsigned char* d8 = (unsigned char *)NULL; - unsigned short* s16 = (unsigned short *)NULL; - unsigned short* d16 = (unsigned short *)NULL; + int i = 0; + int j = 0; + int destx = 0; + int desty = 0; + int pixel = 0; + int crc = 0; + int incs = 0; + int incd = 0; + unsigned char *s8 = (unsigned char *)NULL; + unsigned char *d8 = (unsigned char *)NULL; + unsigned short *s16 = (unsigned short *)NULL; + unsigned short *d16 = (unsigned short *)NULL; - if (self == 0) - { - return 1; - } - if (dest == 0) - { - return 1; - } - if (self->type != WND_TYPE_BITMAP && self->type != WND_TYPE_IMAGE) - { - return 1; - } - if (dest->type != WND_TYPE_BITMAP && dest->type != WND_TYPE_IMAGE) - { - return 1; - } - if (self->bpp != dest->bpp) - { - return 1; - } - destx = 0; - desty = 0; - if (!check_bounds(self, &x, &y, &cx, &cy)) - { - return 1; - } - if (!check_bounds(dest, &destx, &desty, &cx, &cy)) - { - return 1; - } - CRC_START(crc); - if (self->bpp == 24) - { - for (i = 0; i < cy; i++) + if (self == 0) { - for (j = 0; j < cx; j++) - { - pixel = GETPIXEL32(self->data, j + x, i + y, self->width); - CRC_PASS(pixel, crc); - CRC_PASS(pixel >> 8, crc); - CRC_PASS(pixel >> 16, crc); - SETPIXEL32(dest->data, j + destx, i + desty, dest->width, pixel); - } + return 1; } - } - else if (self->bpp == 15 || self->bpp == 16) - { - s16 = ((unsigned short*)(self->data)) + (self->width * y + x); - d16 = ((unsigned short*)(dest->data)) + (dest->width * desty + destx); - incs = self->width - cx; - incd = dest->width - cx; - for (i = 0; i < cy; i++) + + if (dest == 0) { - for (j = 0; j < cx; j++) - { - pixel = *s16; - CRC_PASS(pixel, crc); - CRC_PASS(pixel >> 8, crc); - *d16 = pixel; - s16++; - d16++; - } - s16 += incs; - d16 += incd; + return 1; } - } - else if (self->bpp == 8) - { - s8 = ((unsigned char*)(self->data)) + (self->width * y + x); - d8 = ((unsigned char*)(dest->data)) + (dest->width * desty + destx); - incs = self->width - cx; - incd = dest->width - cx; - for (i = 0; i < cy; i++) + + if (self->type != WND_TYPE_BITMAP && self->type != WND_TYPE_IMAGE) { - for (j = 0; j < cx; j++) - { - pixel = *s8; - CRC_PASS(pixel, crc); - *d8 = pixel; - s8++; - d8++; - } - s8 += incs; - d8 += incd; + return 1; } - } - else - { - return 1; - } - CRC_END(crc); - dest->crc = crc; - return 0; + + if (dest->type != WND_TYPE_BITMAP && dest->type != WND_TYPE_IMAGE) + { + return 1; + } + + if (self->bpp != dest->bpp) + { + return 1; + } + + destx = 0; + desty = 0; + + if (!check_bounds(self, &x, &y, &cx, &cy)) + { + return 1; + } + + if (!check_bounds(dest, &destx, &desty, &cx, &cy)) + { + return 1; + } + + CRC_START(crc); + + if (self->bpp == 24) + { + for (i = 0; i < cy; i++) + { + for (j = 0; j < cx; j++) + { + pixel = GETPIXEL32(self->data, j + x, i + y, self->width); + CRC_PASS(pixel, crc); + CRC_PASS(pixel >> 8, crc); + CRC_PASS(pixel >> 16, crc); + SETPIXEL32(dest->data, j + destx, i + desty, dest->width, pixel); + } + } + } + else if (self->bpp == 15 || self->bpp == 16) + { + s16 = ((unsigned short *)(self->data)) + (self->width * y + x); + d16 = ((unsigned short *)(dest->data)) + (dest->width * desty + destx); + incs = self->width - cx; + incd = dest->width - cx; + + for (i = 0; i < cy; i++) + { + for (j = 0; j < cx; j++) + { + pixel = *s16; + CRC_PASS(pixel, crc); + CRC_PASS(pixel >> 8, crc); + *d16 = pixel; + s16++; + d16++; + } + + s16 += incs; + d16 += incd; + } + } + else if (self->bpp == 8) + { + s8 = ((unsigned char *)(self->data)) + (self->width * y + x); + d8 = ((unsigned char *)(dest->data)) + (dest->width * desty + destx); + incs = self->width - cx; + incd = dest->width - cx; + + for (i = 0; i < cy; i++) + { + for (j = 0; j < cx; j++) + { + pixel = *s8; + CRC_PASS(pixel, crc); + *d8 = pixel; + s8++; + d8++; + } + + s8 += incs; + d8 += incd; + } + } + else + { + return 1; + } + + CRC_END(crc); + dest->crc = crc; + return 0; } /*****************************************************************************/ /* returns true if they are the same, else returns false */ int APP_CC -xrdp_bitmap_compare(struct xrdp_bitmap* self, - struct xrdp_bitmap* b) +xrdp_bitmap_compare(struct xrdp_bitmap *self, + struct xrdp_bitmap *b) { - if (self == 0) - { + if (self == 0) + { + return 0; + } + + if (b == 0) + { + return 0; + } + + if (self->bpp != b->bpp) + { + return 0; + } + + if (self->width != b->width) + { + return 0; + } + + if (self->height != b->height) + { + return 0; + } + + if (g_memcmp(self->data, b->data, b->height * b->line_size) == 0) + { + return 1; + } + return 0; - } - if (b == 0) - { - return 0; - } - if (self->bpp != b->bpp) - { - return 0; - } - if (self->width != b->width) - { - return 0; - } - if (self->height != b->height) - { - return 0; - } - if (g_memcmp(self->data, b->data, b->height * b->line_size) == 0) - { - return 1; - } - return 0; } /*****************************************************************************/ /* returns true if they are the same, else returns false */ int APP_CC -xrdp_bitmap_compare_with_crc(struct xrdp_bitmap* self, - struct xrdp_bitmap* b) +xrdp_bitmap_compare_with_crc(struct xrdp_bitmap *self, + struct xrdp_bitmap *b) { - if (self == 0) - { + if (self == 0) + { + return 0; + } + + if (b == 0) + { + return 0; + } + + if (self->bpp != b->bpp) + { + return 0; + } + + if (self->width != b->width) + { + return 0; + } + + if (self->height != b->height) + { + return 0; + } + + if (self->crc == b->crc) + { + return 1; + } + return 0; - } - if (b == 0) - { - return 0; - } - if (self->bpp != b->bpp) - { - return 0; - } - if (self->width != b->width) - { - return 0; - } - if (self->height != b->height) - { - return 0; - } - if (self->crc == b->crc) - { - return 1; - } - return 0; } /*****************************************************************************/ static int APP_CC -xrdp_bitmap_draw_focus_box(struct xrdp_bitmap* self, - struct xrdp_painter* painter, +xrdp_bitmap_draw_focus_box(struct xrdp_bitmap *self, + struct xrdp_painter *painter, int x, int y, int cx, int cy) { - painter->rop = 0xf0; - xrdp_painter_begin_update(painter); - painter->use_clip = 0; - painter->mix_mode = 1; - painter->brush.pattern[0] = 0xaa; - painter->brush.pattern[1] = 0x55; - painter->brush.pattern[2] = 0xaa; - painter->brush.pattern[3] = 0x55; - painter->brush.pattern[4] = 0xaa; - painter->brush.pattern[5] = 0x55; - painter->brush.pattern[6] = 0xaa; - painter->brush.pattern[7] = 0x55; - painter->brush.x_orgin = x; - painter->brush.x_orgin = x; - painter->brush.style = 3; - painter->fg_color = self->wm->black; - painter->bg_color = self->parent->bg_color; - /* top */ - xrdp_painter_fill_rect(painter, self, x, y, cx, 1); - /* bottom */ - xrdp_painter_fill_rect(painter, self, x, y + (cy - 1), cx, 1); - /* left */ - xrdp_painter_fill_rect(painter, self, x, y + 1, 1, cy - 2); - /* right */ - xrdp_painter_fill_rect(painter, self, x + (cx - 1), y + 1, 1, cy - 2); - xrdp_painter_end_update(painter); - painter->rop = 0xcc; - painter->mix_mode = 0; - return 0; + painter->rop = 0xf0; + xrdp_painter_begin_update(painter); + painter->use_clip = 0; + painter->mix_mode = 1; + painter->brush.pattern[0] = 0xaa; + painter->brush.pattern[1] = 0x55; + painter->brush.pattern[2] = 0xaa; + painter->brush.pattern[3] = 0x55; + painter->brush.pattern[4] = 0xaa; + painter->brush.pattern[5] = 0x55; + painter->brush.pattern[6] = 0xaa; + painter->brush.pattern[7] = 0x55; + painter->brush.x_orgin = x; + painter->brush.x_orgin = x; + painter->brush.style = 3; + painter->fg_color = self->wm->black; + painter->bg_color = self->parent->bg_color; + /* top */ + xrdp_painter_fill_rect(painter, self, x, y, cx, 1); + /* bottom */ + xrdp_painter_fill_rect(painter, self, x, y + (cy - 1), cx, 1); + /* left */ + xrdp_painter_fill_rect(painter, self, x, y + 1, 1, cy - 2); + /* right */ + xrdp_painter_fill_rect(painter, self, x + (cx - 1), y + 1, 1, cy - 2); + xrdp_painter_end_update(painter); + painter->rop = 0xcc; + painter->mix_mode = 0; + return 0; } /*****************************************************************************/ /* x and y are in relation to self for 0, 0 is the top left of the control */ static int APP_CC -xrdp_bitmap_draw_button(struct xrdp_bitmap* self, - struct xrdp_painter* painter, +xrdp_bitmap_draw_button(struct xrdp_bitmap *self, + struct xrdp_painter *painter, int x, int y, int w, int h, int down) { - if (down) - { - /* gray box */ - painter->fg_color = self->wm->grey; - xrdp_painter_fill_rect(painter, self, x, y, w, h); - /* black top line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, x, y, w, 1); - /* black left line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, x, y, 1, h); - /* dark grey top line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, x + 1, y + 1, w - 2, 1); - /* dark grey left line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, x + 1, y + 1, 1, h - 2); - /* dark grey bottom line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, x + 1, y + (h - 2), w - 1, 1); - /* dark grey right line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, x + (w - 2), y + 1, 1, h - 1); - /* black bottom line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, x, y + (h - 1), w, 1); - /* black right line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, x + (w - 1), y, 1, h); - } - else - { - /* gray box */ - painter->fg_color = self->wm->grey; - xrdp_painter_fill_rect(painter, self, x, y, w, h); - /* white top line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, x, y, w, 1); - /* white left line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, x, y, 1, h); - /* dark grey bottom line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, x + 1, y + (h - 2), w - 1, 1); - /* dark grey right line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, (x + w) - 2, y + 1, 1, h - 1); - /* black bottom line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, x, y + (h - 1), w, 1); - /* black right line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, x + (w - 1), y, 1, h); - } - return 0; + if (down) + { + /* gray box */ + painter->fg_color = self->wm->grey; + xrdp_painter_fill_rect(painter, self, x, y, w, h); + /* black top line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x, y, w, 1); + /* black left line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x, y, 1, h); + /* dark grey top line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + 1, y + 1, w - 2, 1); + /* dark grey left line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + 1, y + 1, 1, h - 2); + /* dark grey bottom line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + 1, y + (h - 2), w - 1, 1); + /* dark grey right line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + (w - 2), y + 1, 1, h - 1); + /* black bottom line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x, y + (h - 1), w, 1); + /* black right line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x + (w - 1), y, 1, h); + } + else + { + /* gray box */ + painter->fg_color = self->wm->grey; + xrdp_painter_fill_rect(painter, self, x, y, w, h); + /* white top line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, x, y, w, 1); + /* white left line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, x, y, 1, h); + /* dark grey bottom line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + 1, y + (h - 2), w - 1, 1); + /* dark grey right line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, (x + w) - 2, y + 1, 1, h - 1); + /* black bottom line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x, y + (h - 1), w, 1); + /* black right line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x + (w - 1), y, 1, h); + } + + return 0; } /*****************************************************************************/ /* nil for rect means the whole thing */ /* returns error */ int APP_CC -xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) +xrdp_bitmap_invalidate(struct xrdp_bitmap *self, struct xrdp_rect *rect) { - int i; - int w; - int h; - int x; - int y; - struct xrdp_bitmap* b; - struct xrdp_rect r1; - struct xrdp_rect r2; - struct xrdp_painter* painter; - twchar wtext[256]; - char text[256]; - char* p; + int i; + int w; + int h; + int x; + int y; + struct xrdp_bitmap *b; + struct xrdp_rect r1; + struct xrdp_rect r2; + struct xrdp_painter *painter; + twchar wtext[256]; + char text[256]; + char *p; - if (self == 0) /* if no bitmap */ - { - return 0; - } - if (self->type == WND_TYPE_BITMAP) /* if 0, bitmap, leave */ - { - return 0; - } - painter = xrdp_painter_create(self->wm, self->wm->session); - xrdp_painter_font_needed(painter); - painter->rop = 0xcc; /* copy */ - if (rect == 0) - { - painter->use_clip = 0; - } - else - { - if (ISRECTEMPTY(*rect)) + if (self == 0) /* if no bitmap */ { - xrdp_painter_delete(painter); - return 0; + return 0; } - painter->clip = *rect; - painter->use_clip = &painter->clip; - } - xrdp_painter_begin_update(painter); - if (self->type == WND_TYPE_WND) /* 1 */ - { - /* draw grey background */ - painter->fg_color = self->bg_color; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); - /* top white line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 2, 1); - /* left white line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 2); - /* bottom dark grey line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 1, self->height - 2, - self->width - 2, 1); - /* right dark grey line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, self->width - 2, 1, 1, - self->height - 2); - /* bottom black line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, 0, self->height - 1, - self->width, 1); - /* right black line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, self->width - 1, 0, - 1, self->height); - if (self->wm->focused_window == self) + + if (self->type == WND_TYPE_BITMAP) /* if 0, bitmap, leave */ { - /* active title bar */ - painter->fg_color = self->wm->blue; - xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); - painter->fg_color = self->wm->white; + return 0; } - else - { - /* inactive title bar */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); - painter->fg_color = self->wm->black; - } - xrdp_painter_draw_text(painter, self, 4, 4, self->caption1); - } - else if (self->type == WND_TYPE_SCREEN) /* 2 */ - { - if (self->wm->mm->mod != 0) - { - if (self->wm->mm->mod->mod_event != 0) - { - if (rect != 0) - { - x = rect->left; - y = rect->top; - w = rect->right - rect->left; - h = rect->bottom - rect->top; - if (check_bounds(self->wm->screen, &x, &y, &w, &h)) - { - self->wm->mm->mod->mod_event(self->wm->mm->mod, WM_INVALIDATE, - MAKELONG(y, x), MAKELONG(h, w), - 0, 0); - } - } - else - { - x = 0; - y = 0; - w = self->wm->screen->width; - h = self->wm->screen->height; - self->wm->mm->mod->mod_event(self->wm->mm->mod, WM_INVALIDATE, - MAKELONG(y, x), MAKELONG(h, w), - 0, 0); - } - } - } - else - { - painter->fg_color = self->bg_color; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); - } - } - else if (self->type == WND_TYPE_BUTTON) /* 3 */ - { - if (self->state == BUTTON_STATE_UP) /* 0 */ - { - xrdp_bitmap_draw_button(self, painter, 0, 0, - self->width, self->height, 0); - w = xrdp_painter_text_width(painter, self->caption1); - h = xrdp_painter_text_height(painter, self->caption1); - painter->fg_color = self->wm->black; - xrdp_painter_draw_text(painter, self, self->width / 2 - w / 2, - self->height / 2 - h / 2, self->caption1); - if (self->parent != 0) - { - if (self->wm->focused_window == self->parent) - { - if (self->parent->focused_control == self) - { - xrdp_bitmap_draw_focus_box(self, painter, 4, 4, self->width - 8, - self->height - 8); - } - } - } - } - else if (self->state == BUTTON_STATE_DOWN) /* 1 */ - { - xrdp_bitmap_draw_button(self, painter, 0, 0, - self->width, self->height, 1); - w = xrdp_painter_text_width(painter, self->caption1); - h = xrdp_painter_text_height(painter, self->caption1); - painter->fg_color = self->wm->black; - xrdp_painter_draw_text(painter, self, (self->width / 2 - w / 2) + 1, - (self->height / 2 - h / 2) + 1, self->caption1); - if (self->parent != 0) - if (self->wm->focused_window == self->parent) - if (self->parent->focused_control == self) - xrdp_bitmap_draw_focus_box(self, painter, 4, 4, self->width - 8, - self->height - 8); - } - } - else if (self->type == WND_TYPE_IMAGE) /* 4 */ - { - xrdp_painter_copy(painter, self, self, 0, 0, self->width, - self->height, 0, 0); - } - else if (self->type == WND_TYPE_EDIT) /* 5 */ - { - /* draw gray box */ - painter->fg_color = self->wm->grey; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); - /* main white background */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3, - self->height - 3); - /* dark grey top line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1); - /* dark grey left line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height); - /* white bottom line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, 0, self->height- 1, self->width, 1); - /* white right line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height); - /* black left line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 3); - /* black top line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3, 1); - /* draw text */ - painter->fg_color = self->wm->black; - if (self->password_char != 0) - { - i = g_mbstowcs(0, self->caption1, 0); - g_memset(text, self->password_char, i); - text[i] = 0; - xrdp_painter_draw_text(painter, self, 4, 2, text); - } - else - { - xrdp_painter_draw_text(painter, self, 4, 2, self->caption1); - } - /* draw xor box(cursor) */ - if (self->parent != 0) - { - if (self->parent->focused_control == self) - { - if (self->password_char != 0) - { - wchar_repeat(wtext, 255, self->password_char, self->edit_pos); - wtext[self->edit_pos] = 0; - g_wcstombs(text, wtext, 255); - } - else - { - g_mbstowcs(wtext, self->caption1, 255); - wtext[self->edit_pos] = 0; - g_wcstombs(text, wtext, 255); - } - w = xrdp_painter_text_width(painter, text); - painter->fg_color = self->wm->white; - painter->rop = 0x5a; - xrdp_painter_fill_rect(painter, self, 4 + w, 3, 2, self->height - 6); - } - } - /* reset rop back */ - painter->rop = 0xcc; - } - else if (self->type == WND_TYPE_LABEL) /* 6 */ - { - painter->fg_color = self->wm->black; - xrdp_painter_draw_text(painter, self, 0, 0, self->caption1); - } - else if (self->type == WND_TYPE_COMBO) /* 7 combo box */ - { - /* draw gray box */ - painter->fg_color = self->wm->grey; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); - /* white background */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3, - self->height - 3); - if (self->parent->focused_control == self) - { - painter->fg_color = self->wm->dark_blue; - xrdp_painter_fill_rect(painter, self, 3, 3, (self->width - 6) - 18, - self->height - 5); - } - /* dark grey top line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1); - /* dark grey left line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height); - /* white bottom line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, 0, self->height- 1, self->width, 1); - /* white right line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height); - /* black left line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 3); - /* black top line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3, 1); - /* draw text */ - if (self->parent->focused_control == self) - { - painter->fg_color = self->wm->white; - } - else - { - painter->fg_color = self->wm->black; - } - xrdp_painter_draw_text(painter, self, 4, 2, - (char*)list_get_item(self->string_list, self->item_index)); - /* draw button on right */ - x = self->width - 20; - y = 2; - w = (self->width - x) - 2; - h = self->height - 4; - /* looks better with a background around */ - painter->fg_color = self->wm->grey; - xrdp_painter_fill_rect(painter, self, x, y, w, h); - if (self->state == BUTTON_STATE_UP) /* 0 */ - { - xrdp_bitmap_draw_button(self, painter, x+1, y+1, w-1, h-1, 0); - } - else - { - xrdp_bitmap_draw_button(self, painter, x+1, y+1, w-1, h-1, 1); - } - /* draw the arrow */ - w = w / 2; - x = x + (w / 2) + 1; - h = (h / 2) + 2; - y = y + (h / 2) + 1; - painter->fg_color = self->wm->black; - for (i=w; i>0; i=i-2) - { - xrdp_painter_fill_rect(painter, self, x, y, i, 1); - y++; - x = x + 1; - } - } - else if (self->type == WND_TYPE_SPECIAL) /* 8 special */ - { - if (self->popped_from != 0) - { - /* change height if there are too many items in the list */ - i = xrdp_painter_text_height(painter, "W"); - i = self->popped_from->string_list->count * i; - if (i > self->height) - { - self->height = i; - } - } - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); - /* draw the list items */ - if (self->popped_from != 0) - { - y = 0; - for (i = 0; i < self->popped_from->string_list->count; i++) - { - p = (char*)list_get_item(self->popped_from->string_list, i); - h = xrdp_painter_text_height(painter, p); - self->item_height = h; - if (i == self->item_index) - { - painter->fg_color = self->wm->blue; - xrdp_painter_fill_rect(painter, self, 0, y, self->width, h); - painter->fg_color = self->wm->white; - } - else - { - painter->fg_color = self->wm->black; - } - xrdp_painter_draw_text(painter, self, 2, y, p); - y = y + h; - } - } - } - /* notify */ - if (self->notify != 0) - { - self->notify(self, self, WM_PAINT, (long)painter, 0); /* 3 */ - } - /* draw any child windows in the area */ - for (i = 0; i < self->child_list->count; i++) - { - b = (struct xrdp_bitmap*)list_get_item(self->child_list, i); + + painter = xrdp_painter_create(self->wm, self->wm->session); + xrdp_painter_font_needed(painter); + painter->rop = 0xcc; /* copy */ + if (rect == 0) { - xrdp_bitmap_invalidate(b, 0); + painter->use_clip = 0; } else { - MAKERECT(r1, b->left, b->top, b->width, b->height); - if (rect_intersect(rect, &r1, &r2)) - { - RECTOFFSET(r2, -(b->left), -(b->top)); - xrdp_bitmap_invalidate(b, &r2); - } + if (ISRECTEMPTY(*rect)) + { + xrdp_painter_delete(painter); + return 0; + } + + painter->clip = *rect; + painter->use_clip = &painter->clip; } - } - xrdp_painter_end_update(painter); - xrdp_painter_delete(painter); - return 0; + + xrdp_painter_begin_update(painter); + + if (self->type == WND_TYPE_WND) /* 1 */ + { + /* draw grey background */ + painter->fg_color = self->bg_color; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); + /* top white line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 2, 1); + /* left white line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 2); + /* bottom dark grey line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, 1, self->height - 2, + self->width - 2, 1); + /* right dark grey line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, self->width - 2, 1, 1, + self->height - 2); + /* bottom black line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, 0, self->height - 1, + self->width, 1); + /* right black line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, self->width - 1, 0, + 1, self->height); + + if (self->wm->focused_window == self) + { + /* active title bar */ + painter->fg_color = self->wm->blue; + xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); + painter->fg_color = self->wm->white; + } + else + { + /* inactive title bar */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); + painter->fg_color = self->wm->black; + } + + xrdp_painter_draw_text(painter, self, 4, 4, self->caption1); + } + else if (self->type == WND_TYPE_SCREEN) /* 2 */ + { + if (self->wm->mm->mod != 0) + { + if (self->wm->mm->mod->mod_event != 0) + { + if (rect != 0) + { + x = rect->left; + y = rect->top; + w = rect->right - rect->left; + h = rect->bottom - rect->top; + + if (check_bounds(self->wm->screen, &x, &y, &w, &h)) + { + self->wm->mm->mod->mod_event(self->wm->mm->mod, WM_INVALIDATE, + MAKELONG(y, x), MAKELONG(h, w), + 0, 0); + } + } + else + { + x = 0; + y = 0; + w = self->wm->screen->width; + h = self->wm->screen->height; + self->wm->mm->mod->mod_event(self->wm->mm->mod, WM_INVALIDATE, + MAKELONG(y, x), MAKELONG(h, w), + 0, 0); + } + } + } + else + { + painter->fg_color = self->bg_color; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); + } + } + else if (self->type == WND_TYPE_BUTTON) /* 3 */ + { + if (self->state == BUTTON_STATE_UP) /* 0 */ + { + xrdp_bitmap_draw_button(self, painter, 0, 0, + self->width, self->height, 0); + w = xrdp_painter_text_width(painter, self->caption1); + h = xrdp_painter_text_height(painter, self->caption1); + painter->fg_color = self->wm->black; + xrdp_painter_draw_text(painter, self, self->width / 2 - w / 2, + self->height / 2 - h / 2, self->caption1); + + if (self->parent != 0) + { + if (self->wm->focused_window == self->parent) + { + if (self->parent->focused_control == self) + { + xrdp_bitmap_draw_focus_box(self, painter, 4, 4, self->width - 8, + self->height - 8); + } + } + } + } + else if (self->state == BUTTON_STATE_DOWN) /* 1 */ + { + xrdp_bitmap_draw_button(self, painter, 0, 0, + self->width, self->height, 1); + w = xrdp_painter_text_width(painter, self->caption1); + h = xrdp_painter_text_height(painter, self->caption1); + painter->fg_color = self->wm->black; + xrdp_painter_draw_text(painter, self, (self->width / 2 - w / 2) + 1, + (self->height / 2 - h / 2) + 1, self->caption1); + + if (self->parent != 0) + if (self->wm->focused_window == self->parent) + if (self->parent->focused_control == self) + xrdp_bitmap_draw_focus_box(self, painter, 4, 4, self->width - 8, + self->height - 8); + } + } + else if (self->type == WND_TYPE_IMAGE) /* 4 */ + { + xrdp_painter_copy(painter, self, self, 0, 0, self->width, + self->height, 0, 0); + } + else if (self->type == WND_TYPE_EDIT) /* 5 */ + { + /* draw gray box */ + painter->fg_color = self->wm->grey; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); + /* main white background */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3, + self->height - 3); + /* dark grey top line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1); + /* dark grey left line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height); + /* white bottom line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, 0, self->height - 1, self->width, 1); + /* white right line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height); + /* black left line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 3); + /* black top line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3, 1); + /* draw text */ + painter->fg_color = self->wm->black; + + if (self->password_char != 0) + { + i = g_mbstowcs(0, self->caption1, 0); + g_memset(text, self->password_char, i); + text[i] = 0; + xrdp_painter_draw_text(painter, self, 4, 2, text); + } + else + { + xrdp_painter_draw_text(painter, self, 4, 2, self->caption1); + } + + /* draw xor box(cursor) */ + if (self->parent != 0) + { + if (self->parent->focused_control == self) + { + if (self->password_char != 0) + { + wchar_repeat(wtext, 255, self->password_char, self->edit_pos); + wtext[self->edit_pos] = 0; + g_wcstombs(text, wtext, 255); + } + else + { + g_mbstowcs(wtext, self->caption1, 255); + wtext[self->edit_pos] = 0; + g_wcstombs(text, wtext, 255); + } + + w = xrdp_painter_text_width(painter, text); + painter->fg_color = self->wm->white; + painter->rop = 0x5a; + xrdp_painter_fill_rect(painter, self, 4 + w, 3, 2, self->height - 6); + } + } + + /* reset rop back */ + painter->rop = 0xcc; + } + else if (self->type == WND_TYPE_LABEL) /* 6 */ + { + painter->fg_color = self->wm->black; + xrdp_painter_draw_text(painter, self, 0, 0, self->caption1); + } + else if (self->type == WND_TYPE_COMBO) /* 7 combo box */ + { + /* draw gray box */ + painter->fg_color = self->wm->grey; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); + /* white background */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3, + self->height - 3); + + if (self->parent->focused_control == self) + { + painter->fg_color = self->wm->dark_blue; + xrdp_painter_fill_rect(painter, self, 3, 3, (self->width - 6) - 18, + self->height - 5); + } + + /* dark grey top line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1); + /* dark grey left line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height); + /* white bottom line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, 0, self->height - 1, self->width, 1); + /* white right line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height); + /* black left line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 3); + /* black top line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3, 1); + + /* draw text */ + if (self->parent->focused_control == self) + { + painter->fg_color = self->wm->white; + } + else + { + painter->fg_color = self->wm->black; + } + + xrdp_painter_draw_text(painter, self, 4, 2, + (char *)list_get_item(self->string_list, self->item_index)); + /* draw button on right */ + x = self->width - 20; + y = 2; + w = (self->width - x) - 2; + h = self->height - 4; + /* looks better with a background around */ + painter->fg_color = self->wm->grey; + xrdp_painter_fill_rect(painter, self, x, y, w, h); + + if (self->state == BUTTON_STATE_UP) /* 0 */ + { + xrdp_bitmap_draw_button(self, painter, x + 1, y + 1, w - 1, h - 1, 0); + } + else + { + xrdp_bitmap_draw_button(self, painter, x + 1, y + 1, w - 1, h - 1, 1); + } + + /* draw the arrow */ + w = w / 2; + x = x + (w / 2) + 1; + h = (h / 2) + 2; + y = y + (h / 2) + 1; + painter->fg_color = self->wm->black; + + for (i = w; i > 0; i = i - 2) + { + xrdp_painter_fill_rect(painter, self, x, y, i, 1); + y++; + x = x + 1; + } + } + else if (self->type == WND_TYPE_SPECIAL) /* 8 special */ + { + if (self->popped_from != 0) + { + /* change height if there are too many items in the list */ + i = xrdp_painter_text_height(painter, "W"); + i = self->popped_from->string_list->count * i; + + if (i > self->height) + { + self->height = i; + } + } + + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); + + /* draw the list items */ + if (self->popped_from != 0) + { + y = 0; + + for (i = 0; i < self->popped_from->string_list->count; i++) + { + p = (char *)list_get_item(self->popped_from->string_list, i); + h = xrdp_painter_text_height(painter, p); + self->item_height = h; + + if (i == self->item_index) + { + painter->fg_color = self->wm->blue; + xrdp_painter_fill_rect(painter, self, 0, y, self->width, h); + painter->fg_color = self->wm->white; + } + else + { + painter->fg_color = self->wm->black; + } + + xrdp_painter_draw_text(painter, self, 2, y, p); + y = y + h; + } + } + } + + /* notify */ + if (self->notify != 0) + { + self->notify(self, self, WM_PAINT, (long)painter, 0); /* 3 */ + } + + /* draw any child windows in the area */ + for (i = 0; i < self->child_list->count; i++) + { + b = (struct xrdp_bitmap *)list_get_item(self->child_list, i); + + if (rect == 0) + { + xrdp_bitmap_invalidate(b, 0); + } + else + { + MAKERECT(r1, b->left, b->top, b->width, b->height); + + if (rect_intersect(rect, &r1, &r2)) + { + RECTOFFSET(r2, -(b->left), -(b->top)); + xrdp_bitmap_invalidate(b, &r2); + } + } + } + + xrdp_painter_end_update(painter); + xrdp_painter_delete(painter); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg, +xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg, int param1, int param2) { - twchar c; - int n; - int i; - int shift; - int ext; - int scan_code; - int num_bytes; - int num_chars; - struct xrdp_bitmap* b; - struct xrdp_bitmap* focus_out_control; + twchar c; + int n; + int i; + int shift; + int ext; + int scan_code; + int num_bytes; + int num_chars; + struct xrdp_bitmap *b; + struct xrdp_bitmap *focus_out_control; - if (self == 0) - { - return 0; - } - if (self->wm == 0) - { - return 0; - } - if (self->type == WND_TYPE_WND) - { - if (msg == WM_KEYDOWN) + if (self == 0) { - scan_code = param1 % 128; - if (scan_code == 15) /* tab */ - { - /* move to next tab stop */ - shift = self->wm->keys[42] || self->wm->keys[54]; - i = -1; - if (self->child_list != 0) + return 0; + } + + if (self->wm == 0) + { + return 0; + } + + if (self->type == WND_TYPE_WND) + { + if (msg == WM_KEYDOWN) { - i = list_index_of(self->child_list, (long)self->focused_control); - } - if (shift) - { - i--; - if (i < 0) - { - i = self->child_list->count - 1; - } - } - else - { - i++; - if (i >= self->child_list->count) - { - i = 0; - } - } - n = self->child_list->count; - b = (struct xrdp_bitmap*)list_get_item(self->child_list, i); - while (b != self->focused_control && b != 0 && n > 0) - { - n--; - if (b->tab_stop) - { - focus_out_control = self->focused_control; - self->focused_control = b; - xrdp_bitmap_invalidate(focus_out_control, 0); - xrdp_bitmap_invalidate(b, 0); - break; - } - if (shift) - { - i--; - if (i < 0) + scan_code = param1 % 128; + + if (scan_code == 15) /* tab */ { - i = self->child_list->count - 1; + /* move to next tab stop */ + shift = self->wm->keys[42] || self->wm->keys[54]; + i = -1; + + if (self->child_list != 0) + { + i = list_index_of(self->child_list, (long)self->focused_control); + } + + if (shift) + { + i--; + + if (i < 0) + { + i = self->child_list->count - 1; + } + } + else + { + i++; + + if (i >= self->child_list->count) + { + i = 0; + } + } + + n = self->child_list->count; + b = (struct xrdp_bitmap *)list_get_item(self->child_list, i); + + while (b != self->focused_control && b != 0 && n > 0) + { + n--; + + if (b->tab_stop) + { + focus_out_control = self->focused_control; + self->focused_control = b; + xrdp_bitmap_invalidate(focus_out_control, 0); + xrdp_bitmap_invalidate(b, 0); + break; + } + + if (shift) + { + i--; + + if (i < 0) + { + i = self->child_list->count - 1; + } + } + else + { + i++; + + if (i >= self->child_list->count) + { + i = 0; + } + } + + b = (struct xrdp_bitmap *)list_get_item(self->child_list, i); + } } - } - else - { - i++; - if (i >= self->child_list->count) + else if (scan_code == 28) /* enter */ { - i = 0; + if (self->default_button != 0) + { + if (self->notify != 0) + { + /* I think this should use def_proc */ + self->notify(self, self->default_button, 1, 0, 0); + return 0; + } + } + } + else if (scan_code == 1) /* esc */ + { + if (self->esc_button != 0) + { + if (self->notify != 0) + { + /* I think this should use def_proc */ + self->notify(self, self->esc_button, 1, 0, 0); + return 0; + } + } } - } - b = (struct xrdp_bitmap*)list_get_item(self->child_list, i); } - } - else if (scan_code == 28) /* enter */ - { - if (self->default_button != 0) + + if (self->focused_control != 0) { - if (self->notify != 0) - { - /* I think this should use def_proc */ - self->notify(self, self->default_button, 1, 0, 0); - return 0; - } + xrdp_bitmap_def_proc(self->focused_control, msg, param1, param2); } - } - else if (scan_code == 1) /* esc */ - { - if (self->esc_button != 0) - { - if (self->notify != 0) - { - /* I think this should use def_proc */ - self->notify(self, self->esc_button, 1, 0, 0); - return 0; - } - } - } } - if (self->focused_control != 0) + else if (self->type == WND_TYPE_EDIT) { - xrdp_bitmap_def_proc(self->focused_control, msg, param1, param2); + if (msg == WM_KEYDOWN) + { + scan_code = param1 % 128; + ext = param2 & 0x0100; + + /* left or up arrow */ + if ((scan_code == 75 || scan_code == 72) && + (ext || self->wm->num_lock == 0)) + { + if (self->edit_pos > 0) + { + self->edit_pos--; + xrdp_bitmap_invalidate(self, 0); + } + } + /* right or down arrow */ + else if ((scan_code == 77 || scan_code == 80) && + (ext || self->wm->num_lock == 0)) + { + if (self->edit_pos < g_mbstowcs(0, self->caption1, 0)) + { + self->edit_pos++; + xrdp_bitmap_invalidate(self, 0); + } + } + /* backspace */ + else if (scan_code == 14) + { + n = g_mbstowcs(0, self->caption1, 0); + + if (n > 0) + { + if (self->edit_pos > 0) + { + self->edit_pos--; + remove_char_at(self->caption1, 255, self->edit_pos); + xrdp_bitmap_invalidate(self, 0); + } + } + } + /* delete */ + else if (scan_code == 83 && + (ext || self->wm->num_lock == 0)) + { + n = g_mbstowcs(0, self->caption1, 0); + + if (n > 0) + { + if (self->edit_pos < n) + { + remove_char_at(self->caption1, 255, self->edit_pos); + xrdp_bitmap_invalidate(self, 0); + } + } + } + /* end */ + else if (scan_code == 79 && + (ext || self->wm->num_lock == 0)) + { + n = g_mbstowcs(0, self->caption1, 0); + + if (self->edit_pos < n) + { + self->edit_pos = n; + xrdp_bitmap_invalidate(self, 0); + } + } + /* home */ + else if ((scan_code == 71) && + (ext || (self->wm->num_lock == 0))) + { + if (self->edit_pos > 0) + { + self->edit_pos = 0; + xrdp_bitmap_invalidate(self, 0); + } + } + else + { + c = get_char_from_scan_code + (param2, scan_code, self->wm->keys, self->wm->caps_lock, + self->wm->num_lock, self->wm->scroll_lock, + &(self->wm->keymap)); + num_chars = g_mbstowcs(0, self->caption1, 0); + num_bytes = g_strlen(self->caption1); + + if ((c >= 32) && (num_chars < 127) && (num_bytes < 250)) + { + add_char_at(self->caption1, 255, c, self->edit_pos); + self->edit_pos++; + xrdp_bitmap_invalidate(self, 0); + } + } + } } - } - else if (self->type == WND_TYPE_EDIT) - { - if (msg == WM_KEYDOWN) + else if (self->type == WND_TYPE_COMBO) { - scan_code = param1 % 128; - ext = param2 & 0x0100; - /* left or up arrow */ - if ((scan_code == 75 || scan_code == 72) && - (ext || self->wm->num_lock == 0)) - { - if (self->edit_pos > 0) + if (msg == WM_KEYDOWN) { - self->edit_pos--; - xrdp_bitmap_invalidate(self, 0); + scan_code = param1 % 128; + ext = param2 & 0x0100; + + /* left or up arrow */ + if (((scan_code == 75) || (scan_code == 72)) && + (ext || (self->wm->num_lock == 0))) + { + if (self->item_index > 0) + { + self->item_index--; + xrdp_bitmap_invalidate(self, 0); + + if (self->parent->notify != 0) + { + self->parent->notify(self->parent, self, CB_ITEMCHANGE, 0, 0); + } + } + } + /* right or down arrow */ + else if ((scan_code == 77 || scan_code == 80) && + (ext || self->wm->num_lock == 0)) + { + if ((self->item_index + 1) < self->string_list->count) + { + self->item_index++; + xrdp_bitmap_invalidate(self, 0); + + if (self->parent->notify != 0) + { + self->parent->notify(self->parent, self, CB_ITEMCHANGE, 0, 0); + } + } + } } - } - /* right or down arrow */ - else if ((scan_code == 77 || scan_code == 80) && - (ext || self->wm->num_lock == 0)) - { - if (self->edit_pos < g_mbstowcs(0, self->caption1, 0)) - { - self->edit_pos++; - xrdp_bitmap_invalidate(self, 0); - } - } - /* backspace */ - else if (scan_code == 14) - { - n = g_mbstowcs(0, self->caption1, 0); - if (n > 0) - { - if (self->edit_pos > 0) - { - self->edit_pos--; - remove_char_at(self->caption1, 255, self->edit_pos); - xrdp_bitmap_invalidate(self, 0); - } - } - } - /* delete */ - else if (scan_code == 83 && - (ext || self->wm->num_lock == 0)) - { - n = g_mbstowcs(0, self->caption1, 0); - if (n > 0) - { - if (self->edit_pos < n) - { - remove_char_at(self->caption1, 255, self->edit_pos); - xrdp_bitmap_invalidate(self, 0); - } - } - } - /* end */ - else if (scan_code == 79 && - (ext || self->wm->num_lock == 0)) - { - n = g_mbstowcs(0, self->caption1, 0); - if (self->edit_pos < n) - { - self->edit_pos = n; - xrdp_bitmap_invalidate(self, 0); - } - } - /* home */ - else if ((scan_code == 71) && - (ext || (self->wm->num_lock == 0))) - { - if (self->edit_pos > 0) - { - self->edit_pos = 0; - xrdp_bitmap_invalidate(self, 0); - } - } - else - { - c = get_char_from_scan_code - (param2, scan_code, self->wm->keys, self->wm->caps_lock, - self->wm->num_lock, self->wm->scroll_lock, - &(self->wm->keymap)); - num_chars = g_mbstowcs(0, self->caption1, 0); - num_bytes = g_strlen(self->caption1); - if ((c >= 32) && (num_chars < 127) && (num_bytes < 250)) - { - add_char_at(self->caption1, 255, c, self->edit_pos); - self->edit_pos++; - xrdp_bitmap_invalidate(self, 0); - } - } } - } - else if (self->type == WND_TYPE_COMBO) - { - if (msg == WM_KEYDOWN) + else if (self->type == WND_TYPE_SPECIAL) { - scan_code = param1 % 128; - ext = param2 & 0x0100; - /* left or up arrow */ - if (((scan_code == 75) || (scan_code == 72)) && - (ext || (self->wm->num_lock == 0))) - { - if (self->item_index > 0) + if (msg == WM_MOUSEMOVE) { - self->item_index--; - xrdp_bitmap_invalidate(self, 0); - if (self->parent->notify != 0) - { - self->parent->notify(self->parent, self, CB_ITEMCHANGE, 0, 0); - } + if (self->item_height > 0 && self->popped_from != 0) + { + i = param2; + i = i / self->item_height; + + if (i != self->item_index && + i < self->popped_from->string_list->count) + { + self->item_index = i; + xrdp_bitmap_invalidate(self, 0); + } + } } - } - /* right or down arrow */ - else if ((scan_code == 77 || scan_code == 80) && - (ext || self->wm->num_lock == 0)) - { - if ((self->item_index + 1) < self->string_list->count) + else if (msg == WM_LBUTTONUP) { - self->item_index++; - xrdp_bitmap_invalidate(self, 0); - if (self->parent->notify != 0) - { - self->parent->notify(self->parent, self, CB_ITEMCHANGE, 0, 0); - } + if (self->popped_from != 0) + { + self->popped_from->item_index = self->item_index; + xrdp_bitmap_invalidate(self->popped_from, 0); + + if (self->popped_from->parent->notify != 0) + { + self->popped_from->parent->notify(self->popped_from->parent, + self->popped_from, + CB_ITEMCHANGE, 0, 0); + } + } } - } } - } - else if (self->type == WND_TYPE_SPECIAL) - { - if (msg == WM_MOUSEMOVE) - { - if (self->item_height > 0 && self->popped_from != 0) - { - i = param2; - i = i / self->item_height; - if (i != self->item_index && - i < self->popped_from->string_list->count) - { - self->item_index = i; - xrdp_bitmap_invalidate(self, 0); - } - } - } - else if (msg == WM_LBUTTONUP) - { - if (self->popped_from != 0) - { - self->popped_from->item_index = self->item_index; - xrdp_bitmap_invalidate(self->popped_from, 0); - if (self->popped_from->parent->notify != 0) - { - self->popped_from->parent->notify(self->popped_from->parent, - self->popped_from, - CB_ITEMCHANGE, 0, 0); - } - } - } - } - return 0; + + return 0; } /*****************************************************************************/ /* convert the controls coords to screen coords */ int APP_CC -xrdp_bitmap_to_screenx(struct xrdp_bitmap* self, int x) +xrdp_bitmap_to_screenx(struct xrdp_bitmap *self, int x) { - int i; + int i; - i = x; - while (self != 0) - { - i = i + self->left; - self = self->parent; - } - return i; + i = x; + + while (self != 0) + { + i = i + self->left; + self = self->parent; + } + + return i; } /*****************************************************************************/ /* convert the controls coords to screen coords */ int APP_CC -xrdp_bitmap_to_screeny(struct xrdp_bitmap* self, int y) +xrdp_bitmap_to_screeny(struct xrdp_bitmap *self, int y) { - int i; + int i; - i = y; - while (self != 0) - { - i = i + self->top; - self = self->parent; - } - return i; + i = y; + + while (self != 0) + { + i = i + self->top; + self = self->parent; + } + + return i; } /*****************************************************************************/ /* convert the screen coords to controls coords */ int APP_CC -xrdp_bitmap_from_screenx(struct xrdp_bitmap* self, int x) +xrdp_bitmap_from_screenx(struct xrdp_bitmap *self, int x) { - int i; + int i; - i = x; - while (self != 0) - { - i = i - self->left; - self = self->parent; - } - return i; + i = x; + + while (self != 0) + { + i = i - self->left; + self = self->parent; + } + + return i; } /*****************************************************************************/ /* convert the screen coords to controls coords */ int APP_CC -xrdp_bitmap_from_screeny(struct xrdp_bitmap* self, int y) +xrdp_bitmap_from_screeny(struct xrdp_bitmap *self, int y) { - int i; + int i; - i = y; - while (self != 0) - { - i = i - self->top; - self = self->parent; - } - return i; + i = y; + + while (self != 0) + { + i = i - self->top; + self = self->parent; + } + + return i; } /*****************************************************************************/ int APP_CC -xrdp_bitmap_get_screen_clip(struct xrdp_bitmap* self, - struct xrdp_painter* painter, - struct xrdp_rect* rect, - int* dx, int* dy) +xrdp_bitmap_get_screen_clip(struct xrdp_bitmap *self, + struct xrdp_painter *painter, + struct xrdp_rect *rect, + int *dx, int *dy) { - int ldx; - int ldy; + int ldx; + int ldy; - if (painter->use_clip) - { - *rect = painter->clip; - } - else - { - rect->left = 0; - rect->top = 0; - rect->right = self->width; - rect->bottom = self->height; - } - ldx = xrdp_bitmap_to_screenx(self, 0); - ldy = xrdp_bitmap_to_screeny(self, 0); - rect->left += ldx; - rect->top += ldy; - rect->right += ldx; - rect->bottom += ldy; - if (dx != 0) - { - *dx = ldx; - } - if (dy != 0) - { - *dy = ldy; - } - return 0; + if (painter->use_clip) + { + *rect = painter->clip; + } + else + { + rect->left = 0; + rect->top = 0; + rect->right = self->width; + rect->bottom = self->height; + } + + ldx = xrdp_bitmap_to_screenx(self, 0); + ldy = xrdp_bitmap_to_screeny(self, 0); + rect->left += ldx; + rect->top += ldy; + rect->right += ldx; + rect->bottom += ldy; + + if (dx != 0) + { + *dx = ldx; + } + + if (dy != 0) + { + *dy = ldy; + } + + return 0; } diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c index 17316633..dfc7e60b 100644 --- a/xrdp/xrdp_cache.c +++ b/xrdp/xrdp_cache.c @@ -1,418 +1,451 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - cache - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * cache + */ #include "xrdp.h" /*****************************************************************************/ -struct xrdp_cache* APP_CC -xrdp_cache_create(struct xrdp_wm* owner, - struct xrdp_session* session, - struct xrdp_client_info* client_info) +struct xrdp_cache *APP_CC +xrdp_cache_create(struct xrdp_wm *owner, + struct xrdp_session *session, + struct xrdp_client_info *client_info) { - struct xrdp_cache* self; + struct xrdp_cache *self; - self = (struct xrdp_cache*)g_malloc(sizeof(struct xrdp_cache), 1); - self->wm = owner; - self->session = session; - self->use_bitmap_comp = client_info->use_bitmap_comp; - self->cache1_entries = client_info->cache1_entries; - self->cache1_size = client_info->cache1_size; - self->cache2_entries = client_info->cache2_entries; - self->cache2_size = client_info->cache2_size; - self->cache3_entries = client_info->cache3_entries; - self->cache3_size = client_info->cache3_size; - self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable; - self->bitmap_cache_version = client_info->bitmap_cache_version; - self->pointer_cache_entries = client_info->pointer_cache_entries; - self->xrdp_os_del_list = list_create(); - return self; + self = (struct xrdp_cache *)g_malloc(sizeof(struct xrdp_cache), 1); + self->wm = owner; + self->session = session; + self->use_bitmap_comp = client_info->use_bitmap_comp; + self->cache1_entries = client_info->cache1_entries; + self->cache1_size = client_info->cache1_size; + self->cache2_entries = client_info->cache2_entries; + self->cache2_size = client_info->cache2_size; + self->cache3_entries = client_info->cache3_entries; + self->cache3_size = client_info->cache3_size; + self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable; + self->bitmap_cache_version = client_info->bitmap_cache_version; + self->pointer_cache_entries = client_info->pointer_cache_entries; + self->xrdp_os_del_list = list_create(); + return self; } /*****************************************************************************/ void APP_CC -xrdp_cache_delete(struct xrdp_cache* self) +xrdp_cache_delete(struct xrdp_cache *self) { - int i; - int j; + int i; + int j; - if (self == 0) - { - return; - } - /* free all the cached bitmaps */ - for (i = 0; i < 3; i++) - { - for (j = 0; j < 2000; j++) + if (self == 0) { - xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap); + return; } - } - /* free all the cached font items */ - for (i = 0; i < 12; i++) - { - for (j = 0; j < 256; j++) - { - g_free(self->char_items[i][j].font_item.data); - } - } - /* free all the off screen bitmaps */ - for (i = 0; i < 2000; i++) - { - xrdp_bitmap_delete(self->os_bitmap_items[i].bitmap); - } - list_delete(self->xrdp_os_del_list); - g_free(self); + /* free all the cached bitmaps */ + for (i = 0; i < 3; i++) + { + for (j = 0; j < 2000; j++) + { + xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap); + } + } + + /* free all the cached font items */ + for (i = 0; i < 12; i++) + { + for (j = 0; j < 256; j++) + { + g_free(self->char_items[i][j].font_item.data); + } + } + + /* free all the off screen bitmaps */ + for (i = 0; i < 2000; i++) + { + xrdp_bitmap_delete(self->os_bitmap_items[i].bitmap); + } + + list_delete(self->xrdp_os_del_list); + + g_free(self); } /*****************************************************************************/ int APP_CC -xrdp_cache_reset(struct xrdp_cache* self, - struct xrdp_client_info* client_info) +xrdp_cache_reset(struct xrdp_cache *self, + struct xrdp_client_info *client_info) { - struct xrdp_wm* wm; - struct xrdp_session* session; - int i; - int j; + struct xrdp_wm *wm; + struct xrdp_session *session; + int i; + int j; - /* free all the cached bitmaps */ - for (i = 0; i < 3; i++) - { - for (j = 0; j < 2000; j++) + /* free all the cached bitmaps */ + for (i = 0; i < 3; i++) { - xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap); + for (j = 0; j < 2000; j++) + { + xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap); + } } - } - /* free all the cached font items */ - for (i = 0; i < 12; i++) - { - for (j = 0; j < 256; j++) + + /* free all the cached font items */ + for (i = 0; i < 12; i++) { - g_free(self->char_items[i][j].font_item.data); + for (j = 0; j < 256; j++) + { + g_free(self->char_items[i][j].font_item.data); + } } - } - /* save these */ - wm = self->wm; - session = self->session; - /* set whole struct to zero */ - g_memset(self, 0, sizeof(struct xrdp_cache)); - /* set some stuff back */ - self->wm = wm; - self->session = session; - self->use_bitmap_comp = client_info->use_bitmap_comp; - self->cache1_entries = client_info->cache1_entries; - self->cache1_size = client_info->cache1_size; - self->cache2_entries = client_info->cache2_entries; - self->cache2_size = client_info->cache2_size; - self->cache3_entries = client_info->cache3_entries; - self->cache3_size = client_info->cache3_size; - self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable; - self->bitmap_cache_version = client_info->bitmap_cache_version; - self->pointer_cache_entries = client_info->pointer_cache_entries; - return 0; + + /* save these */ + wm = self->wm; + session = self->session; + /* set whole struct to zero */ + g_memset(self, 0, sizeof(struct xrdp_cache)); + /* set some stuff back */ + self->wm = wm; + self->session = session; + self->use_bitmap_comp = client_info->use_bitmap_comp; + self->cache1_entries = client_info->cache1_entries; + self->cache1_size = client_info->cache1_size; + self->cache2_entries = client_info->cache2_entries; + self->cache2_size = client_info->cache2_size; + self->cache3_entries = client_info->cache3_entries; + self->cache3_size = client_info->cache3_size; + self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable; + self->bitmap_cache_version = client_info->bitmap_cache_version; + self->pointer_cache_entries = client_info->pointer_cache_entries; + return 0; } /*****************************************************************************/ /* returns cache id */ int APP_CC -xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap, +xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap, int hints) { - int i = 0; - int j = 0; - int oldest = 0; - int cache_id = 0; - int cache_idx = 0; - int bmp_size = 0; - int e = 0; - int Bpp = 0; + int i = 0; + int j = 0; + int oldest = 0; + int cache_id = 0; + int cache_idx = 0; + int bmp_size = 0; + int e = 0; + int Bpp = 0; - e = bitmap->width % 4; - if (e != 0) - { - e = 4 - e; - } - Bpp = (bitmap->bpp + 7) / 8; - bmp_size = (bitmap->width + e) * bitmap->height * Bpp; - self->bitmap_stamp++; - /* look for match */ - if (bmp_size <= self->cache1_size) - { - i = 0; - for (j = 0; j < self->cache1_entries; j++) + e = bitmap->width % 4; + + if (e != 0) { + e = 4 - e; + } + + Bpp = (bitmap->bpp + 7) / 8; + bmp_size = (bitmap->width + e) * bitmap->height * Bpp; + self->bitmap_stamp++; + + /* look for match */ + if (bmp_size <= self->cache1_size) + { + i = 0; + + for (j = 0; j < self->cache1_entries; j++) + { #ifdef USE_CRC - if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap)) + + if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap)) #else - if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) + if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) #endif - { - self->bitmap_items[i][j].stamp = self->bitmap_stamp; - DEBUG(("found bitmap at %d %d", i, j)); - xrdp_bitmap_delete(bitmap); - return MAKELONG(j, i); - } + { + self->bitmap_items[i][j].stamp = self->bitmap_stamp; + DEBUG(("found bitmap at %d %d", i, j)); + xrdp_bitmap_delete(bitmap); + return MAKELONG(j, i); + } + } } - } - else if (bmp_size <= self->cache2_size) - { - i = 1; - for (j = 0; j < self->cache2_entries; j++) + else if (bmp_size <= self->cache2_size) { + i = 1; + + for (j = 0; j < self->cache2_entries; j++) + { #ifdef USE_CRC - if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap)) + + if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap)) #else - if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) + if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) #endif - { - self->bitmap_items[i][j].stamp = self->bitmap_stamp; - DEBUG(("found bitmap at %d %d", i, j)); - xrdp_bitmap_delete(bitmap); - return MAKELONG(j, i); - } + { + self->bitmap_items[i][j].stamp = self->bitmap_stamp; + DEBUG(("found bitmap at %d %d", i, j)); + xrdp_bitmap_delete(bitmap); + return MAKELONG(j, i); + } + } } - } - else if (bmp_size <= self->cache3_size) - { - i = 2; - for (j = 0; j < self->cache3_entries; j++) + else if (bmp_size <= self->cache3_size) { + i = 2; + + for (j = 0; j < self->cache3_entries; j++) + { #ifdef USE_CRC - if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap)) + + if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap)) #else - if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) + if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) #endif - { - self->bitmap_items[i][j].stamp = self->bitmap_stamp; - DEBUG(("found bitmap at %d %d", i, j)); - xrdp_bitmap_delete(bitmap); - return MAKELONG(j, i); - } + { + self->bitmap_items[i][j].stamp = self->bitmap_stamp; + DEBUG(("found bitmap at %d %d", i, j)); + xrdp_bitmap_delete(bitmap); + return MAKELONG(j, i); + } + } } - } - else - { - g_writeln("error in xrdp_cache_add_bitmap, too big(%d)", bmp_size); - } - /* look for oldest */ - cache_id = 0; - cache_idx = 0; - oldest = 0x7fffffff; - if (bmp_size <= self->cache1_size) - { - i = 0; - for (j = 0; j < self->cache1_entries; j++) + else { - if (self->bitmap_items[i][j].stamp < oldest) - { - oldest = self->bitmap_items[i][j].stamp; - cache_id = i; - cache_idx = j; - } + g_writeln("error in xrdp_cache_add_bitmap, too big(%d)", bmp_size); } - } - else if (bmp_size <= self->cache2_size) - { - i = 1; - for (j = 0; j < self->cache2_entries; j++) + + /* look for oldest */ + cache_id = 0; + cache_idx = 0; + oldest = 0x7fffffff; + + if (bmp_size <= self->cache1_size) { - if (self->bitmap_items[i][j].stamp < oldest) - { - oldest = self->bitmap_items[i][j].stamp; - cache_id = i; - cache_idx = j; - } + i = 0; + + for (j = 0; j < self->cache1_entries; j++) + { + if (self->bitmap_items[i][j].stamp < oldest) + { + oldest = self->bitmap_items[i][j].stamp; + cache_id = i; + cache_idx = j; + } + } } - } - else if (bmp_size <= self->cache3_size) - { - i = 2; - for (j = 0; j < self->cache3_entries; j++) + else if (bmp_size <= self->cache2_size) { - if (self->bitmap_items[i][j].stamp < oldest) - { - oldest = self->bitmap_items[i][j].stamp; - cache_id = i; - cache_idx = j; - } + i = 1; + + for (j = 0; j < self->cache2_entries; j++) + { + if (self->bitmap_items[i][j].stamp < oldest) + { + oldest = self->bitmap_items[i][j].stamp; + cache_id = i; + cache_idx = j; + } + } } - } - DEBUG(("adding bitmap at %d %d", cache_id, cache_idx)); - /* set, send bitmap and return */ - xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].bitmap); - self->bitmap_items[cache_id][cache_idx].bitmap = bitmap; - self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp; - if (self->use_bitmap_comp) - { - if (self->bitmap_cache_version & 4) + else if (bmp_size <= self->cache3_size) { - if (libxrdp_orders_send_bitmap3(self->session, bitmap->width, - bitmap->height, bitmap->bpp, - bitmap->data, cache_id, cache_idx, - hints) == 0) - { - return MAKELONG(cache_idx, cache_id); - } + i = 2; + + for (j = 0; j < self->cache3_entries; j++) + { + if (self->bitmap_items[i][j].stamp < oldest) + { + oldest = self->bitmap_items[i][j].stamp; + cache_id = i; + cache_idx = j; + } + } } - if (self->bitmap_cache_version & 2) + + DEBUG(("adding bitmap at %d %d", cache_id, cache_idx)); + /* set, send bitmap and return */ + xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].bitmap); + self->bitmap_items[cache_id][cache_idx].bitmap = bitmap; + self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp; + + if (self->use_bitmap_comp) { - libxrdp_orders_send_bitmap2(self->session, bitmap->width, - bitmap->height, bitmap->bpp, - bitmap->data, cache_id, cache_idx, - hints); + if (self->bitmap_cache_version & 4) + { + if (libxrdp_orders_send_bitmap3(self->session, bitmap->width, + bitmap->height, bitmap->bpp, + bitmap->data, cache_id, cache_idx, + hints) == 0) + { + return MAKELONG(cache_idx, cache_id); + } + } + + if (self->bitmap_cache_version & 2) + { + libxrdp_orders_send_bitmap2(self->session, bitmap->width, + bitmap->height, bitmap->bpp, + bitmap->data, cache_id, cache_idx, + hints); + } + else if (self->bitmap_cache_version & 1) + { + libxrdp_orders_send_bitmap(self->session, bitmap->width, + bitmap->height, bitmap->bpp, + bitmap->data, cache_id, cache_idx); + } } - else if (self->bitmap_cache_version & 1) + else { - libxrdp_orders_send_bitmap(self->session, bitmap->width, - bitmap->height, bitmap->bpp, - bitmap->data, cache_id, cache_idx); + if (self->bitmap_cache_version & 2) + { + libxrdp_orders_send_raw_bitmap2(self->session, bitmap->width, + bitmap->height, bitmap->bpp, + bitmap->data, cache_id, cache_idx); + } + else if (self->bitmap_cache_version & 1) + { + libxrdp_orders_send_raw_bitmap(self->session, bitmap->width, + bitmap->height, bitmap->bpp, + bitmap->data, cache_id, cache_idx); + } } - } - else - { - if (self->bitmap_cache_version & 2) - { - libxrdp_orders_send_raw_bitmap2(self->session, bitmap->width, - bitmap->height, bitmap->bpp, - bitmap->data, cache_id, cache_idx); - } - else if (self->bitmap_cache_version & 1) - { - libxrdp_orders_send_raw_bitmap(self->session, bitmap->width, - bitmap->height, bitmap->bpp, - bitmap->data, cache_id, cache_idx); - } - } - return MAKELONG(cache_idx, cache_id); + + return MAKELONG(cache_idx, cache_id); } /*****************************************************************************/ /* not used */ /* not sure how to use a palette in rdp */ int APP_CC -xrdp_cache_add_palette(struct xrdp_cache* self, int* palette) +xrdp_cache_add_palette(struct xrdp_cache *self, int *palette) { - int i; - int oldest; - int index; + int i; + int oldest; + int index; - if (self == 0) - { - return 0; - } - if (palette == 0) - { - return 0; - } - if (self->wm->screen->bpp > 8) - { - return 0; - } - self->palette_stamp++; - /* look for match */ - for (i = 0; i < 6; i++) - { - if (g_memcmp(palette, self->palette_items[i].palette, - 256 * sizeof(int)) == 0) + if (self == 0) { - self->palette_items[i].stamp = self->palette_stamp; - return i; + return 0; } - } - /* look for oldest */ - index = 0; - oldest = 0x7fffffff; - for (i = 0; i < 6; i++) - { - if (self->palette_items[i].stamp < oldest) + + if (palette == 0) { - oldest = self->palette_items[i].stamp; - index = i; + return 0; } - } - /* set, send palette and return */ - g_memcpy(self->palette_items[index].palette, palette, 256 * sizeof(int)); - self->palette_items[index].stamp = self->palette_stamp; - libxrdp_orders_send_palette(self->session, palette, index); - return index; + + if (self->wm->screen->bpp > 8) + { + return 0; + } + + self->palette_stamp++; + + /* look for match */ + for (i = 0; i < 6; i++) + { + if (g_memcmp(palette, self->palette_items[i].palette, + 256 * sizeof(int)) == 0) + { + self->palette_items[i].stamp = self->palette_stamp; + return i; + } + } + + /* look for oldest */ + index = 0; + oldest = 0x7fffffff; + + for (i = 0; i < 6; i++) + { + if (self->palette_items[i].stamp < oldest) + { + oldest = self->palette_items[i].stamp; + index = i; + } + } + + /* set, send palette and return */ + g_memcpy(self->palette_items[index].palette, palette, 256 * sizeof(int)); + self->palette_items[index].stamp = self->palette_stamp; + libxrdp_orders_send_palette(self->session, palette, index); + return index; } /*****************************************************************************/ int APP_CC -xrdp_cache_add_char(struct xrdp_cache* self, - struct xrdp_font_char* font_item) +xrdp_cache_add_char(struct xrdp_cache *self, + struct xrdp_font_char *font_item) { - int i; - int j; - int oldest; - int f; - int c; - int datasize; - struct xrdp_font_char* fi; + int i; + int j; + int oldest; + int f; + int c; + int datasize; + struct xrdp_font_char *fi; - self->char_stamp++; - /* look for match */ - for (i = 7; i < 12; i++) - { - for (j = 0; j < 250; j++) + self->char_stamp++; + + /* look for match */ + for (i = 7; i < 12; i++) { - if (xrdp_font_item_compare(&self->char_items[i][j].font_item, font_item)) - { - self->char_items[i][j].stamp = self->char_stamp; - DEBUG(("found font at %d %d", i, j)); - return MAKELONG(j, i); - } + for (j = 0; j < 250; j++) + { + if (xrdp_font_item_compare(&self->char_items[i][j].font_item, font_item)) + { + self->char_items[i][j].stamp = self->char_stamp; + DEBUG(("found font at %d %d", i, j)); + return MAKELONG(j, i); + } + } } - } - /* look for oldest */ - f = 0; - c = 0; - oldest = 0x7fffffff; - for (i = 7; i < 12; i++) - { - for (j = 0; j < 250; j++) + + /* look for oldest */ + f = 0; + c = 0; + oldest = 0x7fffffff; + + for (i = 7; i < 12; i++) { - if (self->char_items[i][j].stamp < oldest) - { - oldest = self->char_items[i][j].stamp; - f = i; - c = j; - } + for (j = 0; j < 250; j++) + { + if (self->char_items[i][j].stamp < oldest) + { + oldest = self->char_items[i][j].stamp; + f = i; + c = j; + } + } } - } - DEBUG(("adding char at %d %d", f, c)); - /* set, send char and return */ - fi = &self->char_items[f][c].font_item; - g_free(fi->data); - datasize = FONT_DATASIZE(font_item); - fi->data = (char*)g_malloc(datasize, 1); - g_memcpy(fi->data, font_item->data, datasize); - fi->offset = font_item->offset; - fi->baseline = font_item->baseline; - fi->width = font_item->width; - fi->height = font_item->height; - self->char_items[f][c].stamp = self->char_stamp; - libxrdp_orders_send_font(self->session, fi, f, c); - return MAKELONG(c, f); + + DEBUG(("adding char at %d %d", f, c)); + /* set, send char and return */ + fi = &self->char_items[f][c].font_item; + g_free(fi->data); + datasize = FONT_DATASIZE(font_item); + fi->data = (char *)g_malloc(datasize, 1); + g_memcpy(fi->data, font_item->data, datasize); + fi->offset = font_item->offset; + fi->baseline = font_item->baseline; + fi->width = font_item->width; + fi->height = font_item->height; + self->char_items[f][c].stamp = self->char_stamp; + libxrdp_orders_send_font(self->session, fi, f, c); + return MAKELONG(c, f); } /*****************************************************************************/ @@ -421,191 +454,208 @@ xrdp_cache_add_char(struct xrdp_cache* self, returns the index in the cache does not take ownership of pointer_item */ int APP_CC -xrdp_cache_add_pointer(struct xrdp_cache* self, - struct xrdp_pointer_item* pointer_item) +xrdp_cache_add_pointer(struct xrdp_cache *self, + struct xrdp_pointer_item *pointer_item) { - int i; - int oldest; - int index; + int i; + int oldest; + int index; - if (self == 0) - { - return 0; - } - self->pointer_stamp++; - /* look for match */ - for (i = 2; i < self->pointer_cache_entries; i++) - { - if (self->pointer_items[i].x == pointer_item->x && - self->pointer_items[i].y == pointer_item->y && - g_memcmp(self->pointer_items[i].data, - pointer_item->data, 32 * 32 * 3) == 0 && - g_memcmp(self->pointer_items[i].mask, - pointer_item->mask, 32 * 32 / 8) == 0) + if (self == 0) { - self->pointer_items[i].stamp = self->pointer_stamp; - xrdp_wm_set_pointer(self->wm, i); - self->wm->current_pointer = i; - DEBUG(("found pointer at %d", i)); - return i; + return 0; } - } - /* look for oldest */ - index = 2; - oldest = 0x7fffffff; - for (i = 2; i < self->pointer_cache_entries; i++) - { - if (self->pointer_items[i].stamp < oldest) + + self->pointer_stamp++; + + /* look for match */ + for (i = 2; i < self->pointer_cache_entries; i++) { - oldest = self->pointer_items[i].stamp; - index = i; + if (self->pointer_items[i].x == pointer_item->x && + self->pointer_items[i].y == pointer_item->y && + g_memcmp(self->pointer_items[i].data, + pointer_item->data, 32 * 32 * 3) == 0 && + g_memcmp(self->pointer_items[i].mask, + pointer_item->mask, 32 * 32 / 8) == 0) + { + self->pointer_items[i].stamp = self->pointer_stamp; + xrdp_wm_set_pointer(self->wm, i); + self->wm->current_pointer = i; + DEBUG(("found pointer at %d", i)); + return i; + } } - } - self->pointer_items[index].x = pointer_item->x; - self->pointer_items[index].y = pointer_item->y; - g_memcpy(self->pointer_items[index].data, - pointer_item->data, 32 * 32 * 3); - g_memcpy(self->pointer_items[index].mask, - pointer_item->mask, 32 * 32 / 8); - self->pointer_items[index].stamp = self->pointer_stamp; - xrdp_wm_send_pointer(self->wm, index, - self->pointer_items[index].data, - self->pointer_items[index].mask, - self->pointer_items[index].x, - self->pointer_items[index].y); - self->wm->current_pointer = index; - DEBUG(("adding pointer at %d", index)); - return index; + + /* look for oldest */ + index = 2; + oldest = 0x7fffffff; + + for (i = 2; i < self->pointer_cache_entries; i++) + { + if (self->pointer_items[i].stamp < oldest) + { + oldest = self->pointer_items[i].stamp; + index = i; + } + } + + self->pointer_items[index].x = pointer_item->x; + self->pointer_items[index].y = pointer_item->y; + g_memcpy(self->pointer_items[index].data, + pointer_item->data, 32 * 32 * 3); + g_memcpy(self->pointer_items[index].mask, + pointer_item->mask, 32 * 32 / 8); + self->pointer_items[index].stamp = self->pointer_stamp; + xrdp_wm_send_pointer(self->wm, index, + self->pointer_items[index].data, + self->pointer_items[index].mask, + self->pointer_items[index].x, + self->pointer_items[index].y); + self->wm->current_pointer = index; + DEBUG(("adding pointer at %d", index)); + return index; } /*****************************************************************************/ /* this does not take owership of pointer_item, it makes a copy */ int APP_CC -xrdp_cache_add_pointer_static(struct xrdp_cache* self, - struct xrdp_pointer_item* pointer_item, +xrdp_cache_add_pointer_static(struct xrdp_cache *self, + struct xrdp_pointer_item *pointer_item, int index) { - if (self == 0) - { - return 0; - } - self->pointer_items[index].x = pointer_item->x; - self->pointer_items[index].y = pointer_item->y; - g_memcpy(self->pointer_items[index].data, - pointer_item->data, 32 * 32 * 3); - g_memcpy(self->pointer_items[index].mask, - pointer_item->mask, 32 * 32 / 8); - self->pointer_items[index].stamp = self->pointer_stamp; - xrdp_wm_send_pointer(self->wm, index, - self->pointer_items[index].data, - self->pointer_items[index].mask, - self->pointer_items[index].x, - self->pointer_items[index].y); - self->wm->current_pointer = index; - DEBUG(("adding pointer at %d", index)); - return index; + if (self == 0) + { + return 0; + } + + self->pointer_items[index].x = pointer_item->x; + self->pointer_items[index].y = pointer_item->y; + g_memcpy(self->pointer_items[index].data, + pointer_item->data, 32 * 32 * 3); + g_memcpy(self->pointer_items[index].mask, + pointer_item->mask, 32 * 32 / 8); + self->pointer_items[index].stamp = self->pointer_stamp; + xrdp_wm_send_pointer(self->wm, index, + self->pointer_items[index].data, + self->pointer_items[index].mask, + self->pointer_items[index].x, + self->pointer_items[index].y); + self->wm->current_pointer = index; + DEBUG(("adding pointer at %d", index)); + return index; } /*****************************************************************************/ /* this does not take owership of brush_item_data, it makes a copy */ int APP_CC -xrdp_cache_add_brush(struct xrdp_cache* self, - char* brush_item_data) +xrdp_cache_add_brush(struct xrdp_cache *self, + char *brush_item_data) { - int i; - int oldest; - int index; + int i; + int oldest; + int index; - if (self == 0) - { - return 0; - } - self->brush_stamp++; - /* look for match */ - for (i = 0; i < 64; i++) - { - if (g_memcmp(self->brush_items[i].pattern, - brush_item_data, 8) == 0) + if (self == 0) { - self->brush_items[i].stamp = self->brush_stamp; - DEBUG(("found brush at %d", i)); - return i; + return 0; } - } - /* look for oldest */ - index = 0; - oldest = 0x7fffffff; - for (i = 0; i < 64; i++) - { - if (self->brush_items[i].stamp < oldest) + + self->brush_stamp++; + + /* look for match */ + for (i = 0; i < 64; i++) { - oldest = self->brush_items[i].stamp; - index = i; + if (g_memcmp(self->brush_items[i].pattern, + brush_item_data, 8) == 0) + { + self->brush_items[i].stamp = self->brush_stamp; + DEBUG(("found brush at %d", i)); + return i; + } } - } - g_memcpy(self->brush_items[index].pattern, - brush_item_data, 8); - self->brush_items[index].stamp = self->brush_stamp; - libxrdp_orders_send_brush(self->session, 8, 8, 1, 0x81, 8, - self->brush_items[index].pattern, index); - DEBUG(("adding brush at %d", index)); - return index; + + /* look for oldest */ + index = 0; + oldest = 0x7fffffff; + + for (i = 0; i < 64; i++) + { + if (self->brush_items[i].stamp < oldest) + { + oldest = self->brush_items[i].stamp; + index = i; + } + } + + g_memcpy(self->brush_items[index].pattern, + brush_item_data, 8); + self->brush_items[index].stamp = self->brush_stamp; + libxrdp_orders_send_brush(self->session, 8, 8, 1, 0x81, 8, + self->brush_items[index].pattern, index); + DEBUG(("adding brush at %d", index)); + return index; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_cache_add_os_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap, +xrdp_cache_add_os_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap, int rdpindex) { - struct xrdp_os_bitmap_item* bi; + struct xrdp_os_bitmap_item *bi; - if ((rdpindex < 0) || (rdpindex >= 2000)) - { - return 1; - } - bi = self->os_bitmap_items + rdpindex; - bi->bitmap = bitmap; - return 0; + if ((rdpindex < 0) || (rdpindex >= 2000)) + { + return 1; + } + + bi = self->os_bitmap_items + rdpindex; + bi->bitmap = bitmap; + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_cache_remove_os_bitmap(struct xrdp_cache* self, int rdpindex) +xrdp_cache_remove_os_bitmap(struct xrdp_cache *self, int rdpindex) { - struct xrdp_os_bitmap_item* bi; - int index; + struct xrdp_os_bitmap_item *bi; + int index; - if ((rdpindex < 0) || (rdpindex >= 2000)) - { - return 1; - } - bi = self->os_bitmap_items + rdpindex; - if (bi->bitmap->tab_stop) - { - index = list_index_of(self->xrdp_os_del_list, rdpindex); - if (index == -1) + if ((rdpindex < 0) || (rdpindex >= 2000)) { - list_add_item(self->xrdp_os_del_list, rdpindex); + return 1; } - } - xrdp_bitmap_delete(bi->bitmap); - g_memset(bi, 0, sizeof(struct xrdp_os_bitmap_item)); - return 0; + + bi = self->os_bitmap_items + rdpindex; + + if (bi->bitmap->tab_stop) + { + index = list_index_of(self->xrdp_os_del_list, rdpindex); + + if (index == -1) + { + list_add_item(self->xrdp_os_del_list, rdpindex); + } + } + + xrdp_bitmap_delete(bi->bitmap); + g_memset(bi, 0, sizeof(struct xrdp_os_bitmap_item)); + return 0; } /*****************************************************************************/ -struct xrdp_os_bitmap_item* APP_CC -xrdp_cache_get_os_bitmap(struct xrdp_cache* self, int rdpindex) +struct xrdp_os_bitmap_item *APP_CC +xrdp_cache_get_os_bitmap(struct xrdp_cache *self, int rdpindex) { - struct xrdp_os_bitmap_item* bi; + struct xrdp_os_bitmap_item *bi; - if ((rdpindex < 0) || (rdpindex >= 2000)) - { - return 0; - } - bi = self->os_bitmap_items + rdpindex; - return bi; + if ((rdpindex < 0) || (rdpindex >= 2000)) + { + return 0; + } + + bi = self->os_bitmap_items + rdpindex; + return bi; } diff --git a/xrdp/xrdp_font.c b/xrdp/xrdp_font.c index e1c4257b..91734807 100644 --- a/xrdp/xrdp_font.c +++ b/xrdp/xrdp_font.c @@ -1,25 +1,23 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * fonts + */ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - fonts - -*/ /* The fv1 files contain Font File Header (just one) @@ -43,176 +41,197 @@ #if 0 /* not used */ static char w_char[] = { - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x08, 0x20, 0x80, - 0x08, 0x50, 0x80, - 0x04, 0x51, 0x00, - 0x04, 0x51, 0x00, - 0x04, 0x51, 0x00, - 0x02, 0x8a, 0x00, - 0x02, 0x8a, 0x00, - 0x02, 0x8a, 0x00, - 0x01, 0x04, 0x00, - 0x01, 0x04, 0x00, - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x08, 0x20, 0x80, + 0x08, 0x50, 0x80, + 0x04, 0x51, 0x00, + 0x04, 0x51, 0x00, + 0x04, 0x51, 0x00, + 0x02, 0x8a, 0x00, + 0x02, 0x8a, 0x00, + 0x02, 0x8a, 0x00, + 0x01, 0x04, 0x00, + 0x01, 0x04, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, }; #endif /*****************************************************************************/ -struct xrdp_font* APP_CC -xrdp_font_create(struct xrdp_wm* wm) +struct xrdp_font *APP_CC +xrdp_font_create(struct xrdp_wm *wm) { - struct xrdp_font* self; - struct stream* s; - int fd; - int b; - int i; - int index; - int datasize; - int file_size; - struct xrdp_font_char* f; - char file_path[256]; + struct xrdp_font *self; + struct stream *s; + int fd; + int b; + int i; + int index; + int datasize; + int file_size; + struct xrdp_font_char *f; + char file_path[256]; - DEBUG(("in xrdp_font_create")); - g_snprintf(file_path, 255, "%s/%s", XRDP_SHARE_PATH, DEFAULT_FONT_NAME); - if (!g_file_exist(file_path)) - { - g_writeln("xrdp_font_create: error font file [%s] does not exist", - file_path); - return 0; - } - file_size = g_file_get_size(file_path); - if (file_size < 1) - { - g_writeln("xrdp_font_create: error reading font from file [%s]", - file_path); - return 0; - } - self = (struct xrdp_font*)g_malloc(sizeof(struct xrdp_font), 1); - self->wm = wm; - make_stream(s); - init_stream(s, file_size + 1024); - fd = g_file_open(file_path); - if (fd != -1) - { - b = g_file_read(fd, s->data, file_size + 1024); - g_file_close(fd); - if (b > 0) + DEBUG(("in xrdp_font_create")); + g_snprintf(file_path, 255, "%s/%s", XRDP_SHARE_PATH, DEFAULT_FONT_NAME); + + if (!g_file_exist(file_path)) { - s->end = s->data + b; - in_uint8s(s, 4); - in_uint8a(s, self->name, 32); - in_uint16_le(s, self->size); - in_uint16_le(s, self->style); - in_uint8s(s, 8); - index = 32; - while (s_check_rem(s, 16)) - { - f = self->font_items + index; - in_sint16_le(s, i); - f->width = i; - in_sint16_le(s, i); - f->height = i; - in_sint16_le(s, i); - f->baseline = i; - in_sint16_le(s, i); - f->offset = i; - in_sint16_le(s, i); - f->incby = i; - in_uint8s(s, 6); - datasize = FONT_DATASIZE(f); - if (datasize < 0 || datasize > 512) - { - /* shouldn't happen */ - g_writeln("error in xrdp_font_create, datasize wrong"); - g_writeln("width %d height %d datasize %d index %d", - f->width, f->height, datasize, index); - break; - } - if (s_check_rem(s, datasize)) - { - f->data = (char*)g_malloc(datasize, 0); - in_uint8a(s, f->data, datasize); - } - else - { - g_writeln("error in xrdp_font_create"); - } - index++; - } + g_writeln("xrdp_font_create: error font file [%s] does not exist", + file_path); + return 0; } - } - free_stream(s); -/* - self->font_items[0].offset = -4; - self->font_items[0].baseline = -16; - self->font_items[0].width = 24; - self->font_items[0].height = 16; - self->font_items[0].data = g_malloc(3 * 16, 0); - g_memcpy(self->font_items[0].data, w_char, 3 * 16); -*/ - DEBUG(("out xrdp_font_create")); - return self; + + file_size = g_file_get_size(file_path); + + if (file_size < 1) + { + g_writeln("xrdp_font_create: error reading font from file [%s]", + file_path); + return 0; + } + + self = (struct xrdp_font *)g_malloc(sizeof(struct xrdp_font), 1); + self->wm = wm; + make_stream(s); + init_stream(s, file_size + 1024); + fd = g_file_open(file_path); + + if (fd != -1) + { + b = g_file_read(fd, s->data, file_size + 1024); + g_file_close(fd); + + if (b > 0) + { + s->end = s->data + b; + in_uint8s(s, 4); + in_uint8a(s, self->name, 32); + in_uint16_le(s, self->size); + in_uint16_le(s, self->style); + in_uint8s(s, 8); + index = 32; + + while (s_check_rem(s, 16)) + { + f = self->font_items + index; + in_sint16_le(s, i); + f->width = i; + in_sint16_le(s, i); + f->height = i; + in_sint16_le(s, i); + f->baseline = i; + in_sint16_le(s, i); + f->offset = i; + in_sint16_le(s, i); + f->incby = i; + in_uint8s(s, 6); + datasize = FONT_DATASIZE(f); + + if (datasize < 0 || datasize > 512) + { + /* shouldn't happen */ + g_writeln("error in xrdp_font_create, datasize wrong"); + g_writeln("width %d height %d datasize %d index %d", + f->width, f->height, datasize, index); + break; + } + + if (s_check_rem(s, datasize)) + { + f->data = (char *)g_malloc(datasize, 0); + in_uint8a(s, f->data, datasize); + } + else + { + g_writeln("error in xrdp_font_create"); + } + + index++; + } + } + } + + free_stream(s); + /* + self->font_items[0].offset = -4; + self->font_items[0].baseline = -16; + self->font_items[0].width = 24; + self->font_items[0].height = 16; + self->font_items[0].data = g_malloc(3 * 16, 0); + g_memcpy(self->font_items[0].data, w_char, 3 * 16); + */ + DEBUG(("out xrdp_font_create")); + return self; } /*****************************************************************************/ /* free the font and all the items */ void APP_CC -xrdp_font_delete(struct xrdp_font* self) +xrdp_font_delete(struct xrdp_font *self) { - int i; + int i; - if (self == 0) - { - return; - } - for (i = 0; i < NUM_FONTS; i++) - { - g_free(self->font_items[i].data); - } - g_free(self); + if (self == 0) + { + return; + } + + for (i = 0; i < NUM_FONTS; i++) + { + g_free(self->font_items[i].data); + } + + g_free(self); } /*****************************************************************************/ /* compare the two font items returns 1 if they match */ int APP_CC -xrdp_font_item_compare(struct xrdp_font_char* font1, - struct xrdp_font_char* font2) +xrdp_font_item_compare(struct xrdp_font_char *font1, + struct xrdp_font_char *font2) { - int datasize; + int datasize; + + if (font1 == 0) + { + return 0; + } + + if (font2 == 0) + { + return 0; + } + + if (font1->offset != font2->offset) + { + return 0; + } + + if (font1->baseline != font2->baseline) + { + return 0; + } + + if (font1->width != font2->width) + { + return 0; + } + + if (font1->height != font2->height) + { + return 0; + } + + datasize = FONT_DATASIZE(font1); + + if (g_memcmp(font1->data, font2->data, datasize) == 0) + { + return 1; + } - if (font1 == 0) - { return 0; - } - if (font2 == 0) - { - return 0; - } - if (font1->offset != font2->offset) - { - return 0; - } - if (font1->baseline != font2->baseline) - { - return 0; - } - if (font1->width != font2->width) - { - return 0; - } - if (font1->height != font2->height) - { - return 0; - } - datasize = FONT_DATASIZE(font1); - if (g_memcmp(font1->data, font2->data, datasize) == 0) - { - return 1; - } - return 0; } diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 82bade84..5de6f51a 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -1,429 +1,476 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - listen for incoming connection - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * listen for incoming connection + */ #include "xrdp.h" /* 'g_process' is protected by the semaphore 'g_process_sem'. One thread sets g_process and waits for the other to process it */ static tbus g_process_sem = 0; -static struct xrdp_process* g_process = 0; +static struct xrdp_process *g_process = 0; /*****************************************************************************/ static int -xrdp_listen_create_pro_done(struct xrdp_listen* self) +xrdp_listen_create_pro_done(struct xrdp_listen *self) { - int pid; - char text[256]; + int pid; + char text[256]; - pid = g_getpid(); - g_snprintf(text, 255, "xrdp_%8.8x_listen_pro_done_event", pid); - self->pro_done_event = g_create_wait_obj(text); - if(self->pro_done_event == 0) - { - g_writeln("Failure creating pro_done_event"); - } - return 0; + pid = g_getpid(); + g_snprintf(text, 255, "xrdp_%8.8x_listen_pro_done_event", pid); + self->pro_done_event = g_create_wait_obj(text); + + if (self->pro_done_event == 0) + { + g_writeln("Failure creating pro_done_event"); + } + + return 0; } /*****************************************************************************/ -struct xrdp_listen* APP_CC +struct xrdp_listen *APP_CC xrdp_listen_create(void) { - struct xrdp_listen* self; + struct xrdp_listen *self; - self = (struct xrdp_listen*)g_malloc(sizeof(struct xrdp_listen), 1); - xrdp_listen_create_pro_done(self); - self->process_list = list_create(); - if (g_process_sem == 0) - { - g_process_sem = tc_sem_create(0); - } - self->listen_trans = trans_create(TRANS_MODE_TCP, 16, 16); - if (self->listen_trans == 0) - { - g_writeln("xrdp_listen_create: trans_create failed"); - } - return self; + self = (struct xrdp_listen *)g_malloc(sizeof(struct xrdp_listen), 1); + xrdp_listen_create_pro_done(self); + self->process_list = list_create(); + + if (g_process_sem == 0) + { + g_process_sem = tc_sem_create(0); + } + + self->listen_trans = trans_create(TRANS_MODE_TCP, 16, 16); + + if (self->listen_trans == 0) + { + g_writeln("xrdp_listen_create: trans_create failed"); + } + + return self; } /*****************************************************************************/ void APP_CC -xrdp_listen_delete(struct xrdp_listen* self) +xrdp_listen_delete(struct xrdp_listen *self) { - if (self->listen_trans != 0) - { - trans_delete(self->listen_trans); - } - if (g_process_sem != 0) - { - tc_sem_delete(g_process_sem); - g_process_sem = 0; - } - g_delete_wait_obj(self->pro_done_event); - list_delete(self->process_list); - g_free(self); + if (self->listen_trans != 0) + { + trans_delete(self->listen_trans); + } + + if (g_process_sem != 0) + { + tc_sem_delete(g_process_sem); + g_process_sem = 0; + } + + g_delete_wait_obj(self->pro_done_event); + list_delete(self->process_list); + g_free(self); } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_listen_add_pro(struct xrdp_listen* self, struct xrdp_process* process) +xrdp_listen_add_pro(struct xrdp_listen *self, struct xrdp_process *process) { - list_add_item(self->process_list, (tbus)process); - return 0; + list_add_item(self->process_list, (tbus)process); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_listen_delete_done_pro(struct xrdp_listen* self) +xrdp_listen_delete_done_pro(struct xrdp_listen *self) { - int i; - struct xrdp_process* pro; + int i; + struct xrdp_process *pro; - for (i = self->process_list->count - 1; i >= 0; i--) - { - pro = (struct xrdp_process*)list_get_item(self->process_list, i); - if (pro != 0) + for (i = self->process_list->count - 1; i >= 0; i--) { - if (pro->status < 0) - { - xrdp_process_delete(pro); - list_remove_item(self->process_list, i); - } + pro = (struct xrdp_process *)list_get_item(self->process_list, i); + + if (pro != 0) + { + if (pro->status < 0) + { + xrdp_process_delete(pro); + list_remove_item(self->process_list, i); + } + } } - } - return 0; + + return 0; } /*****************************************************************************/ /* i can't get stupid in_val to work, hum using global var for now */ THREAD_RV THREAD_CC -xrdp_process_run(void* in_val) +xrdp_process_run(void *in_val) { - struct xrdp_process* process; + struct xrdp_process *process; - DEBUG(("process started")); - process = g_process; - g_process = 0; - tc_sem_inc(g_process_sem); - xrdp_process_main_loop(process); - DEBUG(("process done")); - return 0; + DEBUG(("process started")); + process = g_process; + g_process = 0; + tc_sem_inc(g_process_sem); + xrdp_process_main_loop(process); + DEBUG(("process done")); + return 0; } /*****************************************************************************/ static int -xrdp_listen_get_port_address(char* port, int port_bytes, - char* address, int address_bytes, +xrdp_listen_get_port_address(char *port, int port_bytes, + char *address, int address_bytes, int *tcp_nodelay, int *tcp_keepalive, - struct xrdp_startup_params* startup_param) + struct xrdp_startup_params *startup_param) { - int fd; - int error; - int index; - char* val; - struct list* names; - struct list* values; - char cfg_file[256]; + int fd; + int error; + int index; + char *val; + struct list *names; + struct list *values; + char cfg_file[256]; - /* default to port 3389 */ - g_strncpy(port, "3389", port_bytes - 1); - /* Default to all */ - g_strncpy(address, "0.0.0.0", address_bytes - 1); - /* see if port or address is in xrdp.ini file */ - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); - *tcp_nodelay = 0 ; - *tcp_keepalive = 0 ; - if (fd > 0) - { - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - if (file_read_section(fd, "globals", names, values) == 0) + /* default to port 3389 */ + g_strncpy(port, "3389", port_bytes - 1); + /* Default to all */ + g_strncpy(address, "0.0.0.0", address_bytes - 1); + /* see if port or address is in xrdp.ini file */ + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + fd = g_file_open(cfg_file); + *tcp_nodelay = 0 ; + *tcp_keepalive = 0 ; + + if (fd > 0) { - for (index = 0; index < names->count; index++) - { - val = (char*)list_get_item(names, index); - if (val != 0) + names = list_create(); + names->auto_free = 1; + values = list_create(); + values->auto_free = 1; + + if (file_read_section(fd, "globals", names, values) == 0) { - if (g_strcasecmp(val, "port") == 0) - { - val = (char*)list_get_item(values, index); - error = g_atoi(val); - if ((error > 0) && (error < 65000)) + for (index = 0; index < names->count; index++) { - g_strncpy(port, val, port_bytes - 1); + val = (char *)list_get_item(names, index); + + if (val != 0) + { + if (g_strcasecmp(val, "port") == 0) + { + val = (char *)list_get_item(values, index); + error = g_atoi(val); + + if ((error > 0) && (error < 65000)) + { + g_strncpy(port, val, port_bytes - 1); + } + } + + if (g_strcasecmp(val, "address") == 0) + { + val = (char *)list_get_item(values, index); + g_strncpy(address, val, address_bytes - 1); + } + + if (g_strcasecmp(val, "fork") == 0) + { + val = (char *)list_get_item(values, index); + + if ((g_strcasecmp(val, "yes") == 0) || + (g_strcasecmp(val, "on") == 0) || + (g_strcasecmp(val, "true") == 0) || + (g_atoi(val) != 0)) + { + startup_param->fork = 1; + } + } + + if (g_strcasecmp(val, "tcp_nodelay") == 0) + { + val = (char *)list_get_item(values, index); + + if ((g_strcasecmp(val, "yes") == 0) || + (g_strcasecmp(val, "on") == 0) || + (g_strcasecmp(val, "true") == 0) || + (g_atoi(val) != 0)) + { + *tcp_nodelay = 1 ; + } + } + + if (g_strcasecmp(val, "tcp_keepalive") == 0) + { + val = (char *)list_get_item(values, index); + + if ((g_strcasecmp(val, "yes") == 0) || + (g_strcasecmp(val, "on") == 0) || + (g_strcasecmp(val, "true") == 0) || + (g_atoi(val) != 0)) + { + *tcp_keepalive = 1 ; + } + } + } } - } - if (g_strcasecmp(val, "address") == 0) - { - val = (char*)list_get_item(values, index); - g_strncpy(address, val, address_bytes - 1); - } - if (g_strcasecmp(val, "fork") == 0) - { - val = (char*)list_get_item(values, index); - if ((g_strcasecmp(val, "yes") == 0) || - (g_strcasecmp(val, "on") == 0) || - (g_strcasecmp(val, "true") == 0) || - (g_atoi(val) != 0)) - { - startup_param->fork = 1; - } - } - if (g_strcasecmp(val, "tcp_nodelay") == 0) - { - val = (char*)list_get_item(values, index); - if ((g_strcasecmp(val, "yes") == 0) || - (g_strcasecmp(val, "on") == 0) || - (g_strcasecmp(val, "true") == 0) || - (g_atoi(val) != 0)) - { - *tcp_nodelay = 1 ; - } - } - if (g_strcasecmp(val, "tcp_keepalive") == 0) - { - val = (char*)list_get_item(values, index); - if ((g_strcasecmp(val, "yes") == 0) || - (g_strcasecmp(val, "on") == 0) || - (g_strcasecmp(val, "true") == 0) || - (g_atoi(val) != 0)) - { - *tcp_keepalive = 1 ; - } - } } - } + + list_delete(names); + list_delete(values); + g_file_close(fd); } - list_delete(names); - list_delete(values); - g_file_close(fd); - } - /* startup_param overrides */ - if (startup_param->port[0] != 0) - { - g_strncpy(port, startup_param->port, port_bytes - 1); - } - return 0; + + /* startup_param overrides */ + if (startup_param->port[0] != 0) + { + g_strncpy(port, startup_param->port, port_bytes - 1); + } + + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_listen_fork(struct xrdp_listen* self, struct trans* server_trans) +xrdp_listen_fork(struct xrdp_listen *self, struct trans *server_trans) { - int pid; - struct xrdp_process* process; + int pid; + struct xrdp_process *process; - pid = g_fork(); - if (pid == 0) - { - /* child */ - /* recreate some main globals */ - xrdp_child_fork(); - /* recreate the process done wait object, not used in fork mode */ - /* close, don't delete this */ - g_close_wait_obj(self->pro_done_event); - xrdp_listen_create_pro_done(self); - /* delete listener, child need not listen */ - trans_delete(self->listen_trans); - self->listen_trans = 0; - /* new connect instance */ - process = xrdp_process_create(self, 0); - process->server_trans = server_trans; - g_process = process; - xrdp_process_run(0); - xrdp_process_delete(process); - /* mark this process to exit */ - g_set_term(1); + pid = g_fork(); + + if (pid == 0) + { + /* child */ + /* recreate some main globals */ + xrdp_child_fork(); + /* recreate the process done wait object, not used in fork mode */ + /* close, don't delete this */ + g_close_wait_obj(self->pro_done_event); + xrdp_listen_create_pro_done(self); + /* delete listener, child need not listen */ + trans_delete(self->listen_trans); + self->listen_trans = 0; + /* new connect instance */ + process = xrdp_process_create(self, 0); + process->server_trans = server_trans; + g_process = process; + xrdp_process_run(0); + xrdp_process_delete(process); + /* mark this process to exit */ + g_set_term(1); + return 0; + } + + /* parent */ + trans_delete(server_trans); return 0; - } - /* parent */ - trans_delete(server_trans); - return 0; } /*****************************************************************************/ /* a new connection is coming in */ int DEFAULT_CC -xrdp_listen_conn_in(struct trans* self, struct trans* new_self) +xrdp_listen_conn_in(struct trans *self, struct trans *new_self) { - struct xrdp_process* process; - struct xrdp_listen* lis; + struct xrdp_process *process; + struct xrdp_listen *lis; - lis = (struct xrdp_listen*)(self->callback_data); - if (lis->startup_params->fork) - { - return xrdp_listen_fork(lis, new_self); - } - process = xrdp_process_create(lis, lis->pro_done_event); - if (xrdp_listen_add_pro(lis, process) == 0) - { - /* start thread */ - process->server_trans = new_self; - g_process = process; - tc_thread_create(xrdp_process_run, 0); - tc_sem_dec(g_process_sem); /* this will wait */ - } - else - { - xrdp_process_delete(process); - } - return 0; + lis = (struct xrdp_listen *)(self->callback_data); + + if (lis->startup_params->fork) + { + return xrdp_listen_fork(lis, new_self); + } + + process = xrdp_process_create(lis, lis->pro_done_event); + + if (xrdp_listen_add_pro(lis, process) == 0) + { + /* start thread */ + process->server_trans = new_self; + g_process = process; + tc_thread_create(xrdp_process_run, 0); + tc_sem_dec(g_process_sem); /* this will wait */ + } + else + { + xrdp_process_delete(process); + } + + return 0; } /*****************************************************************************/ /* wait for incoming connections */ int APP_CC -xrdp_listen_main_loop(struct xrdp_listen* self) +xrdp_listen_main_loop(struct xrdp_listen *self) { - int error; - int robjs_count; - int cont; - int timeout = 0; - char port[128]; - char address[256]; - tbus robjs[8]; - tbus term_obj; - tbus sync_obj; - tbus done_obj; - int tcp_nodelay; - int tcp_keepalive; + int error; + int robjs_count; + int cont; + int timeout = 0; + char port[128]; + char address[256]; + tbus robjs[8]; + tbus term_obj; + tbus sync_obj; + tbus done_obj; + int tcp_nodelay; + int tcp_keepalive; + + self->status = 1; + + if (xrdp_listen_get_port_address(port, sizeof(port), + address, sizeof(address), + &tcp_nodelay, &tcp_keepalive, + self->startup_params) != 0) + { + g_writeln("xrdp_listen_main_loop: xrdp_listen_get_port failed"); + self->status = -1; + return 1; + } + + /*Create socket*/ + error = trans_listen_address(self->listen_trans, port, address); + + if (error == 0) + { + if (tcp_nodelay) + { + if (g_tcp_set_no_delay(self->listen_trans->sck)) + { + g_writeln("Error setting tcp_nodelay"); + } + } + + if (tcp_keepalive) + { + if (g_tcp_set_keepalive(self->listen_trans->sck)) + { + g_writeln("Error setting tcp_keepalive"); + } + } + + self->listen_trans->trans_conn_in = xrdp_listen_conn_in; + self->listen_trans->callback_data = self; + term_obj = g_get_term_event(); /*Global termination event */ + sync_obj = g_get_sync_event(); + done_obj = self->pro_done_event; + cont = 1; + + while (cont) + { + /* build the wait obj list */ + robjs_count = 0; + robjs[robjs_count++] = term_obj; + robjs[robjs_count++] = sync_obj; + robjs[robjs_count++] = done_obj; + timeout = -1; + + if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count) != 0) + { + g_writeln("Listening socket is in wrong state we terminate listener") ; + break; + } + + /* wait - timeout -1 means wait indefinitely*/ + if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0) + { + /* error, should not get here */ + g_sleep(100); + } + + if (g_is_wait_obj_set(term_obj)) /* termination called */ + { + break; + } + + if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */ + { + g_reset_wait_obj(sync_obj); + g_process_waiting_function(); /* run the function */ + } + + if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ + { + g_reset_wait_obj(done_obj); + /* a process has died remove it from lists*/ + xrdp_listen_delete_done_pro(self); + } + + /* Run the callback when accept() returns a new socket*/ + if (trans_check_wait_objs(self->listen_trans) != 0) + { + break; + } + } + + /* stop listening */ + trans_delete(self->listen_trans); + self->listen_trans = 0; + /* second loop to wait for all process threads to close */ + cont = 1; + + while (cont) + { + if (self->process_list->count == 0) + { + break; + } + + timeout = -1; + /* build the wait obj list */ + robjs_count = 0; + robjs[robjs_count++] = sync_obj; + robjs[robjs_count++] = done_obj; + + /* wait - timeout -1 means wait indefinitely*/ + if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0) + { + /* error, should not get here */ + g_sleep(100); + } + + if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */ + { + g_reset_wait_obj(sync_obj); + g_process_waiting_function(); /* run the function that is waiting*/ + } + + if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ + { + g_reset_wait_obj(done_obj); + xrdp_listen_delete_done_pro(self); + } + } + } + else + { + g_writeln("xrdp_listen_main_loop: listen error, possible port " + "already in use"); + } - self->status = 1; - if (xrdp_listen_get_port_address(port, sizeof(port), - address, sizeof(address), - &tcp_nodelay, &tcp_keepalive, - self->startup_params) != 0) - { - g_writeln("xrdp_listen_main_loop: xrdp_listen_get_port failed"); self->status = -1; - return 1; - } - /*Create socket*/ - error = trans_listen_address(self->listen_trans, port, address); - if (error == 0) - { - if(tcp_nodelay) - { - if(g_tcp_set_no_delay(self->listen_trans->sck)) - { - g_writeln("Error setting tcp_nodelay"); - } - } - if(tcp_keepalive) - { - if(g_tcp_set_keepalive(self->listen_trans->sck)) - { - g_writeln("Error setting tcp_keepalive"); - } - } - self->listen_trans->trans_conn_in = xrdp_listen_conn_in; - self->listen_trans->callback_data = self; - term_obj = g_get_term_event(); /*Global termination event */ - sync_obj = g_get_sync_event(); - done_obj = self->pro_done_event; - cont = 1; - while (cont) - { - /* build the wait obj list */ - robjs_count = 0; - robjs[robjs_count++] = term_obj; - robjs[robjs_count++] = sync_obj; - robjs[robjs_count++] = done_obj; - timeout = -1; - if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count) != 0) - { - g_writeln("Listening socket is in wrong state we terminate listener") ; - break; - } - /* wait - timeout -1 means wait indefinitely*/ - if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0) - { - /* error, should not get here */ - g_sleep(100); - } - if (g_is_wait_obj_set(term_obj)) /* termination called */ - { - break; - } - if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */ - { - g_reset_wait_obj(sync_obj); - g_process_waiting_function(); /* run the function */ - } - if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ - { - g_reset_wait_obj(done_obj); - /* a process has died remove it from lists*/ - xrdp_listen_delete_done_pro(self); - } - /* Run the callback when accept() returns a new socket*/ - if (trans_check_wait_objs(self->listen_trans) != 0) - { - break; - } - } - /* stop listening */ - trans_delete(self->listen_trans); - self->listen_trans = 0; - /* second loop to wait for all process threads to close */ - cont = 1; - while (cont) - { - if (self->process_list->count == 0) - { - break; - } - timeout = -1; - /* build the wait obj list */ - robjs_count = 0; - robjs[robjs_count++] = sync_obj; - robjs[robjs_count++] = done_obj; - /* wait - timeout -1 means wait indefinitely*/ - if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0) - { - /* error, should not get here */ - g_sleep(100); - } - if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */ - { - g_reset_wait_obj(sync_obj); - g_process_waiting_function(); /* run the function that is waiting*/ - } - if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ - { - g_reset_wait_obj(done_obj); - xrdp_listen_delete_done_pro(self); - } - } - } - else - { - g_writeln("xrdp_listen_main_loop: listen error, possible port " - "already in use"); - } - self->status = -1; - return 0; + return 0; } diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index 69d3721f..fc4cf125 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - main login window and login help window - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * main login window and login help window + */ #include "xrdp.h" #define ACCESS @@ -27,571 +25,616 @@ /*****************************************************************************/ /* all login help screen events go here */ static int DEFAULT_CC -xrdp_wm_login_help_notify(struct xrdp_bitmap* wnd, - struct xrdp_bitmap* sender, +xrdp_wm_login_help_notify(struct xrdp_bitmap *wnd, + struct xrdp_bitmap *sender, int msg, long param1, long param2) { - struct xrdp_painter* p; + struct xrdp_painter *p; - if (wnd == 0) - { - return 0; - } - if (sender == 0) - { - return 0; - } - if (wnd->owner == 0) - { - return 0; - } - if (msg == 1) /* click */ - { - if (sender->id == 1) /* ok button */ + if (wnd == 0) { - if (sender->owner->notify != 0) - { - wnd->owner->notify(wnd->owner, wnd, 100, 1, 0); /* ok */ - } + return 0; } - } - else if (msg == WM_PAINT) /* 3 */ - { - p = (struct xrdp_painter*)param1; - if (p != 0) + + if (sender == 0) { - p->fg_color = wnd->wm->black; - xrdp_painter_draw_text(p, wnd, 10, 30, "You must be authenticated \ + return 0; + } + + if (wnd->owner == 0) + { + return 0; + } + + if (msg == 1) /* click */ + { + if (sender->id == 1) /* ok button */ + { + if (sender->owner->notify != 0) + { + wnd->owner->notify(wnd->owner, wnd, 100, 1, 0); /* ok */ + } + } + } + else if (msg == WM_PAINT) /* 3 */ + { + p = (struct xrdp_painter *)param1; + + if (p != 0) + { + p->fg_color = wnd->wm->black; + xrdp_painter_draw_text(p, wnd, 10, 30, "You must be authenticated \ before using this"); - xrdp_painter_draw_text(p, wnd, 10, 46, "session."); - xrdp_painter_draw_text(p, wnd, 10, 78, "Enter a valid username in \ + xrdp_painter_draw_text(p, wnd, 10, 46, "session."); + xrdp_painter_draw_text(p, wnd, 10, 78, "Enter a valid username in \ the username edit box."); - xrdp_painter_draw_text(p, wnd, 10, 94, "Enter the password in \ + xrdp_painter_draw_text(p, wnd, 10, 94, "Enter the password in \ the password edit box."); - xrdp_painter_draw_text(p, wnd, 10, 110, "Both the username and \ + xrdp_painter_draw_text(p, wnd, 10, 110, "Both the username and \ password are case"); - xrdp_painter_draw_text(p, wnd, 10, 126, "sensitive."); - xrdp_painter_draw_text(p, wnd, 10, 158, "Contact your system \ + xrdp_painter_draw_text(p, wnd, 10, 126, "sensitive."); + xrdp_painter_draw_text(p, wnd, 10, 158, "Contact your system \ administrator if you are"); - xrdp_painter_draw_text(p, wnd, 10, 174, "having problems \ + xrdp_painter_draw_text(p, wnd, 10, 174, "having problems \ logging on."); + } } - } - return 0; + + return 0; } #if 0 /*****************************************************************************/ static int DEFAULT_CC -xrdp_wm_popup_notify(struct xrdp_bitmap* wnd, - struct xrdp_bitmap* sender, +xrdp_wm_popup_notify(struct xrdp_bitmap *wnd, + struct xrdp_bitmap *sender, int msg, int param1, int param2) { - return 0; + return 0; } #endif /*****************************************************************************/ int APP_CC -xrdp_wm_delete_all_childs(struct xrdp_wm* self) +xrdp_wm_delete_all_childs(struct xrdp_wm *self) { - int index; - struct xrdp_bitmap* b; - struct xrdp_rect rect; + int index; + struct xrdp_bitmap *b; + struct xrdp_rect rect; - for (index = self->screen->child_list->count - 1; index >= 0; index--) - { - b = (struct xrdp_bitmap*)list_get_item(self->screen->child_list, index); - MAKERECT(rect, b->left, b->top, b->width, b->height); - xrdp_bitmap_delete(b); - xrdp_bitmap_invalidate(self->screen, &rect); - } - return 0; -} - -/*****************************************************************************/ -static int APP_CC -set_mod_data_item(struct xrdp_mod_data* mod, char* name, char* value) -{ - int index; - - for (index = 0; index < mod->names->count; index++) - { - if (g_strncmp(name, (char*)list_get_item(mod->names, index), 255) == 0) + for (index = self->screen->child_list->count - 1; index >= 0; index--) { - list_remove_item(mod->values, index); - list_insert_item(mod->values, index, (long)g_strdup(value)); + b = (struct xrdp_bitmap *)list_get_item(self->screen->child_list, index); + MAKERECT(rect, b->left, b->top, b->width, b->height); + xrdp_bitmap_delete(b); + xrdp_bitmap_invalidate(self->screen, &rect); } - } - return 0; + + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_wm_help_clicked(struct xrdp_bitmap* wnd) +set_mod_data_item(struct xrdp_mod_data *mod, char *name, char *value) { - struct xrdp_bitmap* help; - struct xrdp_bitmap* but; + int index; - /* create help screen */ - help = xrdp_bitmap_create(DEFAULT_WND_HELP_W, DEFAULT_WND_HELP_H, wnd->wm->screen->bpp, - WND_TYPE_WND, wnd->wm); - list_insert_item(wnd->wm->screen->child_list, 0, (long)help); - help->parent = wnd->wm->screen; - help->owner = wnd; - wnd->modal_dialog = help; - help->bg_color = wnd->wm->grey; - help->left = wnd->wm->screen->width / 2 - help->width / 2; - help->top = wnd->wm->screen->height / 2 - help->height / 2; - help->notify = xrdp_wm_login_help_notify; - set_string(&help->caption1, "Login help"); - /* ok button */ - but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, wnd->wm->screen->bpp, - WND_TYPE_BUTTON, wnd->wm); - list_insert_item(help->child_list, 0, (long)but); - but->parent = help; - but->owner = help; - but->left = ((DEFAULT_WND_HELP_W / 2) - (DEFAULT_BUTTON_W / 2)); /* center */ - but->top = DEFAULT_WND_HELP_H - DEFAULT_BUTTON_H - 15; - but->id = 1; - but->tab_stop = 1; - set_string(&but->caption1, "OK"); - /* draw it */ - help->focused_control = but; - help->default_button = but; - help->esc_button = but; - xrdp_bitmap_invalidate(help, 0); - xrdp_wm_set_focused(wnd->wm, help); - return 0; -} - -/*****************************************************************************/ -static int APP_CC -xrdp_wm_cancel_clicked(struct xrdp_bitmap* wnd) -{ - if (wnd != 0) - { - if (wnd->wm != 0) + for (index = 0; index < mod->names->count; index++) { - if (wnd->wm->pro_layer != 0) - { - g_set_wait_obj(wnd->wm->pro_layer->self_term_event); - } + if (g_strncmp(name, (char *)list_get_item(mod->names, index), 255) == 0) + { + list_remove_item(mod->values, index); + list_insert_item(mod->values, index, (long)g_strdup(value)); + } } - } - return 0; + + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_wm_ok_clicked(struct xrdp_bitmap* wnd) +xrdp_wm_help_clicked(struct xrdp_bitmap *wnd) { - struct xrdp_bitmap* combo; - struct xrdp_bitmap* label; - struct xrdp_bitmap* edit; - struct xrdp_wm* wm; - struct xrdp_mod_data* mod_data; - int i; + struct xrdp_bitmap *help; + struct xrdp_bitmap *but; - wm = wnd->wm; - combo = xrdp_bitmap_get_child_by_id(wnd, 6); - if (combo != 0) - { - mod_data = (struct xrdp_mod_data*) - list_get_item(combo->data_list, combo->item_index); - if (mod_data != 0) + /* create help screen */ + help = xrdp_bitmap_create(DEFAULT_WND_HELP_W, DEFAULT_WND_HELP_H, wnd->wm->screen->bpp, + WND_TYPE_WND, wnd->wm); + list_insert_item(wnd->wm->screen->child_list, 0, (long)help); + help->parent = wnd->wm->screen; + help->owner = wnd; + wnd->modal_dialog = help; + help->bg_color = wnd->wm->grey; + help->left = wnd->wm->screen->width / 2 - help->width / 2; + help->top = wnd->wm->screen->height / 2 - help->height / 2; + help->notify = xrdp_wm_login_help_notify; + set_string(&help->caption1, "Login help"); + /* ok button */ + but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, wnd->wm->screen->bpp, + WND_TYPE_BUTTON, wnd->wm); + list_insert_item(help->child_list, 0, (long)but); + but->parent = help; + but->owner = help; + but->left = ((DEFAULT_WND_HELP_W / 2) - (DEFAULT_BUTTON_W / 2)); /* center */ + but->top = DEFAULT_WND_HELP_H - DEFAULT_BUTTON_H - 15; + but->id = 1; + but->tab_stop = 1; + set_string(&but->caption1, "OK"); + /* draw it */ + help->focused_control = but; + help->default_button = but; + help->esc_button = but; + xrdp_bitmap_invalidate(help, 0); + xrdp_wm_set_focused(wnd->wm, help); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_wm_cancel_clicked(struct xrdp_bitmap *wnd) +{ + if (wnd != 0) { - /* get the user typed values */ - i = 100; - label = xrdp_bitmap_get_child_by_id(wnd, i); - edit = xrdp_bitmap_get_child_by_id(wnd, i + 1); - while (label != 0 && edit != 0) - { - set_mod_data_item(mod_data, label->caption1, edit->caption1); - i += 2; - label = xrdp_bitmap_get_child_by_id(wnd, i); - edit = xrdp_bitmap_get_child_by_id(wnd, i + 1); - } - list_delete(wm->mm->login_names); - list_delete(wm->mm->login_values); - wm->mm->login_names = list_create(); - wm->mm->login_names->auto_free = 1; - wm->mm->login_values = list_create(); - wm->mm->login_values->auto_free = 1; - /* gota copy these cause dialog gets freed */ - list_append_list_strdup(mod_data->names, wm->mm->login_names, 0); - list_append_list_strdup(mod_data->values, wm->mm->login_values, 0); - xrdp_wm_set_login_mode(wm, 2); + if (wnd->wm != 0) + { + if (wnd->wm->pro_layer != 0) + { + g_set_wait_obj(wnd->wm->pro_layer->self_term_event); + } + } } - } - else - { - log_message(LOG_LEVEL_ERROR,"Combo is 0 - potential programming error"); - } - return 0; + + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd) +{ + struct xrdp_bitmap *combo; + struct xrdp_bitmap *label; + struct xrdp_bitmap *edit; + struct xrdp_wm *wm; + struct xrdp_mod_data *mod_data; + int i; + + wm = wnd->wm; + combo = xrdp_bitmap_get_child_by_id(wnd, 6); + + if (combo != 0) + { + mod_data = (struct xrdp_mod_data *) + list_get_item(combo->data_list, combo->item_index); + + if (mod_data != 0) + { + /* get the user typed values */ + i = 100; + label = xrdp_bitmap_get_child_by_id(wnd, i); + edit = xrdp_bitmap_get_child_by_id(wnd, i + 1); + + while (label != 0 && edit != 0) + { + set_mod_data_item(mod_data, label->caption1, edit->caption1); + i += 2; + label = xrdp_bitmap_get_child_by_id(wnd, i); + edit = xrdp_bitmap_get_child_by_id(wnd, i + 1); + } + + list_delete(wm->mm->login_names); + list_delete(wm->mm->login_values); + wm->mm->login_names = list_create(); + wm->mm->login_names->auto_free = 1; + wm->mm->login_values = list_create(); + wm->mm->login_values->auto_free = 1; + /* gota copy these cause dialog gets freed */ + list_append_list_strdup(mod_data->names, wm->mm->login_names, 0); + list_append_list_strdup(mod_data->values, wm->mm->login_values, 0); + xrdp_wm_set_login_mode(wm, 2); + } + } + else + { + log_message(LOG_LEVEL_ERROR, "Combo is 0 - potential programming error"); + } + + return 0; } /******************************************************************************/ static int APP_CC -xrdp_wm_show_edits(struct xrdp_wm* self, struct xrdp_bitmap* combo) +xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo) { - int count; - int index; - int insert_index; - int username_set; - char* name; - char* value; - struct xrdp_mod_data* mod; - struct xrdp_bitmap* b; + int count; + int index; + int insert_index; + int username_set; + char *name; + char *value; + struct xrdp_mod_data *mod; + struct xrdp_bitmap *b; - username_set = 0; - /* free labels and edits, cause we gota create them */ - /* creation or combo changed */ - for (index = 100; index < 200; index++) - { - b = xrdp_bitmap_get_child_by_id(combo->parent, index); - xrdp_bitmap_delete(b); - } + username_set = 0; - insert_index = list_index_of(self->login_window->child_list, - (long)combo); - insert_index++; - mod = (struct xrdp_mod_data*) - list_get_item(combo->data_list, combo->item_index); - if (mod != 0) - { - count = 0; - for (index = 0; index < mod->names->count; index++) + /* free labels and edits, cause we gota create them */ + /* creation or combo changed */ + for (index = 100; index < 200; index++) { - value = (char*)list_get_item(mod->values, index); - if (g_strncmp("ask", value, 3) == 0) - { - /* label */ - b = xrdp_bitmap_create(95, DEFAULT_EDIT_H, self->screen->bpp, - WND_TYPE_LABEL, self); - list_insert_item(self->login_window->child_list, insert_index, - (long)b); - insert_index++; - b->parent = self->login_window; - b->owner = self->login_window; - b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? 155 : 5; - b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H+5) * count; - b->id = 100 + 2 * count; - name = (char*)list_get_item(mod->names, index); - set_string(&b->caption1, name); - /* edit */ - b = xrdp_bitmap_create(DEFAULT_EDIT_W, DEFAULT_EDIT_H, self->screen->bpp, - WND_TYPE_EDIT, self); - list_insert_item(self->login_window->child_list, insert_index, - (long)b); - insert_index++; - b->parent = self->login_window; - b->owner = self->login_window; - b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? DEFAULT_WND_LOGIN_W - DEFAULT_EDIT_W - 30 : 70; - b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H+5) * count; - b->id = 100 + 2 * count + 1; - b->pointer = 1; - b->tab_stop = 1; - b->caption1 = (char*)g_malloc(256, 1); - g_strncpy(b->caption1, value + 3, 255); - b->edit_pos = g_mbstowcs(0, b->caption1, 0); - if (self->login_window->focused_control == 0) - { - self->login_window->focused_control = b; - } - if (g_strncmp(name, "username", 255) == 0) - { - g_strncpy(b->caption1, self->session->client_info->username, 255); - b->edit_pos = g_mbstowcs(0, b->caption1, 0); - if (b->edit_pos > 0) - { - username_set = 1; - } - } -#ifdef ACCESS - if ((g_strncmp(name, "password", 255) == 0) || (g_strncmp(name, "pampassword", 255) == 0)) -#else - if (g_strncmp(name, "password", 255) == 0) -#endif - { - b->password_char = '*'; - if (username_set) - { - if (b->parent != 0) - { - b->parent->focused_control = b; - } - } - } - count++; - } + b = xrdp_bitmap_get_child_by_id(combo->parent, index); + xrdp_bitmap_delete(b); } - } - return 0; + + insert_index = list_index_of(self->login_window->child_list, + (long)combo); + insert_index++; + mod = (struct xrdp_mod_data *) + list_get_item(combo->data_list, combo->item_index); + + if (mod != 0) + { + count = 0; + + for (index = 0; index < mod->names->count; index++) + { + value = (char *)list_get_item(mod->values, index); + + if (g_strncmp("ask", value, 3) == 0) + { + /* label */ + b = xrdp_bitmap_create(95, DEFAULT_EDIT_H, self->screen->bpp, + WND_TYPE_LABEL, self); + list_insert_item(self->login_window->child_list, insert_index, + (long)b); + insert_index++; + b->parent = self->login_window; + b->owner = self->login_window; + b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? 155 : 5; + b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count; + b->id = 100 + 2 * count; + name = (char *)list_get_item(mod->names, index); + set_string(&b->caption1, name); + /* edit */ + b = xrdp_bitmap_create(DEFAULT_EDIT_W, DEFAULT_EDIT_H, self->screen->bpp, + WND_TYPE_EDIT, self); + list_insert_item(self->login_window->child_list, insert_index, + (long)b); + insert_index++; + b->parent = self->login_window; + b->owner = self->login_window; + b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? DEFAULT_WND_LOGIN_W - DEFAULT_EDIT_W - 30 : 70; + b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count; + b->id = 100 + 2 * count + 1; + b->pointer = 1; + b->tab_stop = 1; + b->caption1 = (char *)g_malloc(256, 1); + g_strncpy(b->caption1, value + 3, 255); + b->edit_pos = g_mbstowcs(0, b->caption1, 0); + + if (self->login_window->focused_control == 0) + { + self->login_window->focused_control = b; + } + + if (g_strncmp(name, "username", 255) == 0) + { + g_strncpy(b->caption1, self->session->client_info->username, 255); + b->edit_pos = g_mbstowcs(0, b->caption1, 0); + + if (b->edit_pos > 0) + { + username_set = 1; + } + } + +#ifdef ACCESS + + if ((g_strncmp(name, "password", 255) == 0) || (g_strncmp(name, "pampassword", 255) == 0)) +#else + if (g_strncmp(name, "password", 255) == 0) +#endif + { + b->password_char = '*'; + + if (username_set) + { + if (b->parent != 0) + { + b->parent->focused_control = b; + } + } + } + + count++; + } + } + } + + return 0; } /*****************************************************************************/ /* all login screen events go here */ static int DEFAULT_CC -xrdp_wm_login_notify(struct xrdp_bitmap* wnd, - struct xrdp_bitmap* sender, +xrdp_wm_login_notify(struct xrdp_bitmap *wnd, + struct xrdp_bitmap *sender, int msg, long param1, long param2) { - struct xrdp_bitmap* b; - struct xrdp_rect rect; - int i; + struct xrdp_bitmap *b; + struct xrdp_rect rect; + int i; + + if (wnd->modal_dialog != 0 && msg != 100) + { + return 0; + } + + if (msg == 1) /* click */ + { + if (sender->id == 1) /* help button */ + { + xrdp_wm_help_clicked(wnd); + } + else if (sender->id == 2) /* cancel button */ + { + xrdp_wm_cancel_clicked(wnd); + } + else if (sender->id == 3) /* ok button */ + { + xrdp_wm_ok_clicked(wnd); + } + } + else if (msg == 2) /* mouse move */ + { + } + else if (msg == 100) /* modal result is done */ + { + i = list_index_of(wnd->wm->screen->child_list, (long)sender); + + if (i >= 0) + { + b = (struct xrdp_bitmap *) + list_get_item(wnd->wm->screen->child_list, i); + list_remove_item(sender->wm->screen->child_list, i); + MAKERECT(rect, b->left, b->top, b->width, b->height); + xrdp_bitmap_invalidate(wnd->wm->screen, &rect); + xrdp_bitmap_delete(sender); + wnd->modal_dialog = 0; + xrdp_wm_set_focused(wnd->wm, wnd); + } + } + else if (msg == CB_ITEMCHANGE) /* combo box change */ + { + xrdp_wm_show_edits(wnd->wm, sender); + xrdp_bitmap_invalidate(wnd, 0); /* invalidate the whole dialog for now */ + } - if (wnd->modal_dialog != 0 && msg != 100) - { return 0; - } - if (msg == 1) /* click */ - { - if (sender->id == 1) /* help button */ - { - xrdp_wm_help_clicked(wnd); - } - else if (sender->id == 2) /* cancel button */ - { - xrdp_wm_cancel_clicked(wnd); - } - else if (sender->id == 3) /* ok button */ - { - xrdp_wm_ok_clicked(wnd); - } - } - else if (msg == 2) /* mouse move */ - { - } - else if (msg == 100) /* modal result is done */ - { - i = list_index_of(wnd->wm->screen->child_list, (long)sender); - if (i >= 0) - { - b = (struct xrdp_bitmap*) - list_get_item(wnd->wm->screen->child_list, i); - list_remove_item(sender->wm->screen->child_list, i); - MAKERECT(rect, b->left, b->top, b->width, b->height); - xrdp_bitmap_invalidate(wnd->wm->screen, &rect); - xrdp_bitmap_delete(sender); - wnd->modal_dialog = 0; - xrdp_wm_set_focused(wnd->wm, wnd); - } - } - else if (msg == CB_ITEMCHANGE) /* combo box change */ - { - xrdp_wm_show_edits(wnd->wm, sender); - xrdp_bitmap_invalidate(wnd, 0); /* invalidate the whole dialog for now */ - } - return 0; } /******************************************************************************/ static int APP_CC -xrdp_wm_login_fill_in_combo(struct xrdp_wm* self, struct xrdp_bitmap* b) +xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b) { - struct list* sections; - struct list* section_names; - struct list* section_values; - int fd; - int i; - int j; - char* p; - char* q; - char* r; - char name[256]; - char cfg_file[256]; - struct xrdp_mod_data* mod_data; + struct list *sections; + struct list *section_names; + struct list *section_values; + int fd; + int i; + int j; + char *p; + char *q; + char *r; + char name[256]; + char cfg_file[256]; + struct xrdp_mod_data *mod_data; - sections = list_create(); - sections->auto_free = 1; - section_names = list_create(); - section_names->auto_free = 1; - section_values = list_create(); - section_values->auto_free = 1; - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); /* xrdp.ini */ - if (fd < 1) - { - log_message(LOG_LEVEL_ERROR,"Could not read xrdp ini file %s", cfg_file); - } - file_read_sections(fd, sections); - for (i = 0; i < sections->count; i++) - { - p = (char*)list_get_item(sections, i); - file_read_section(fd, p, section_names, section_values); - if ((g_strncmp(p, "globals", 255) == 0) - ||(g_strncmp(p, "channels", 255) == 0) - ||(g_strncmp(p, "Logging", 255) == 0)) + sections = list_create(); + sections->auto_free = 1; + section_names = list_create(); + section_names->auto_free = 1; + section_values = list_create(); + section_values->auto_free = 1; + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + fd = g_file_open(cfg_file); /* xrdp.ini */ + + if (fd < 1) { + log_message(LOG_LEVEL_ERROR, "Could not read xrdp ini file %s", cfg_file); } - else + + file_read_sections(fd, sections); + + for (i = 0; i < sections->count; i++) { - g_strncpy(name, p, 255); - mod_data = (struct xrdp_mod_data*) - g_malloc(sizeof(struct xrdp_mod_data), 1); - mod_data->names = list_create(); - mod_data->names->auto_free = 1; - mod_data->values = list_create(); - mod_data->values->auto_free = 1; - for (j = 0; j < section_names->count; j++) - { - q = (char*)list_get_item(section_names, j); - r = (char*)list_get_item(section_values, j); - if (g_strncmp("name", q, 255) == 0) + p = (char *)list_get_item(sections, i); + file_read_section(fd, p, section_names, section_values); + + if ((g_strncmp(p, "globals", 255) == 0) + || (g_strncmp(p, "channels", 255) == 0) + || (g_strncmp(p, "Logging", 255) == 0)) { - g_strncpy(name, r, 255); } - list_add_item(mod_data->names, (long)g_strdup(q)); - list_add_item(mod_data->values, (long)g_strdup(r)); - } - list_add_item(b->string_list, (long)g_strdup(name)); - list_add_item(b->data_list, (long)mod_data); + else + { + g_strncpy(name, p, 255); + mod_data = (struct xrdp_mod_data *) + g_malloc(sizeof(struct xrdp_mod_data), 1); + mod_data->names = list_create(); + mod_data->names->auto_free = 1; + mod_data->values = list_create(); + mod_data->values->auto_free = 1; + + for (j = 0; j < section_names->count; j++) + { + q = (char *)list_get_item(section_names, j); + r = (char *)list_get_item(section_values, j); + + if (g_strncmp("name", q, 255) == 0) + { + g_strncpy(name, r, 255); + } + + list_add_item(mod_data->names, (long)g_strdup(q)); + list_add_item(mod_data->values, (long)g_strdup(r)); + } + + list_add_item(b->string_list, (long)g_strdup(name)); + list_add_item(b->data_list, (long)mod_data); + } } - } - g_file_close(fd); - list_delete(sections); - list_delete(section_names); - list_delete(section_values); - return 0; + + g_file_close(fd); + list_delete(sections); + list_delete(section_names); + list_delete(section_values); + return 0; } /******************************************************************************/ int APP_CC -xrdp_login_wnd_create(struct xrdp_wm* self) +xrdp_login_wnd_create(struct xrdp_wm *self) { - struct xrdp_bitmap* but; - struct xrdp_bitmap* combo; - char file_path[256]; - int log_width; - int log_height; - int regular; + struct xrdp_bitmap *but; + struct xrdp_bitmap *combo; + char file_path[256]; + int log_width; + int log_height; + int regular; - log_width = DEFAULT_WND_LOGIN_W; - log_height = DEFAULT_WND_LOGIN_H; - regular = 1; - if (self->screen->width < log_width) - { - if (self->screen->width < 240) - { - log_width = self->screen->width - 4; - } - else - { - log_width = 240; - } - regular = 0; - } - /* draw login window */ - self->login_window = xrdp_bitmap_create(log_width, log_height, self->screen->bpp, - WND_TYPE_WND, self); - list_add_item(self->screen->child_list, (long)self->login_window); - self->login_window->parent = self->screen; - self->login_window->owner = self->screen; - self->login_window->bg_color = self->grey; - self->login_window->left = self->screen->width / 2 - - self->login_window->width / 2; - self->login_window->top = self->screen->height / 2 - - self->login_window->height / 2; - self->login_window->notify = xrdp_wm_login_notify; - set_string(&self->login_window->caption1, "Login to xrdp"); - if (regular) - { - /* image */ - but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self); - if (self->screen->bpp > 8) - { - g_snprintf(file_path, 255, "%s/xrdp24b.bmp", XRDP_SHARE_PATH); - } - else - { - g_snprintf(file_path, 255, "%s/xrdp256.bmp", XRDP_SHARE_PATH); - } - xrdp_bitmap_load(but, file_path, self->palette); - but->parent = self->screen; - but->owner = self->screen; - but->left = self->screen->width - but->width; - but->top = self->screen->height - but->height; - list_add_item(self->screen->child_list, (long)but); + log_width = DEFAULT_WND_LOGIN_W; + log_height = DEFAULT_WND_LOGIN_H; + regular = 1; - /* image */ - but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self); - if (self->screen->bpp > 8) + if (self->screen->width < log_width) { - g_snprintf(file_path, 255, "%s/ad24b.bmp", XRDP_SHARE_PATH); + if (self->screen->width < 240) + { + log_width = self->screen->width - 4; + } + else + { + log_width = 240; + } + + regular = 0; } - else + + /* draw login window */ + self->login_window = xrdp_bitmap_create(log_width, log_height, self->screen->bpp, + WND_TYPE_WND, self); + list_add_item(self->screen->child_list, (long)self->login_window); + self->login_window->parent = self->screen; + self->login_window->owner = self->screen; + self->login_window->bg_color = self->grey; + self->login_window->left = self->screen->width / 2 - + self->login_window->width / 2; + self->login_window->top = self->screen->height / 2 - + self->login_window->height / 2; + self->login_window->notify = xrdp_wm_login_notify; + set_string(&self->login_window->caption1, "Login to xrdp"); + + if (regular) { - g_snprintf(file_path, 255, "%s/ad256.bmp", XRDP_SHARE_PATH); + /* image */ + but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self); + + if (self->screen->bpp > 8) + { + g_snprintf(file_path, 255, "%s/xrdp24b.bmp", XRDP_SHARE_PATH); + } + else + { + g_snprintf(file_path, 255, "%s/xrdp256.bmp", XRDP_SHARE_PATH); + } + + xrdp_bitmap_load(but, file_path, self->palette); + but->parent = self->screen; + but->owner = self->screen; + but->left = self->screen->width - but->width; + but->top = self->screen->height - but->height; + list_add_item(self->screen->child_list, (long)but); + + /* image */ + but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self); + + if (self->screen->bpp > 8) + { + g_snprintf(file_path, 255, "%s/ad24b.bmp", XRDP_SHARE_PATH); + } + else + { + g_snprintf(file_path, 255, "%s/ad256.bmp", XRDP_SHARE_PATH); + } + + xrdp_bitmap_load(but, file_path, self->palette); + but->parent = self->login_window; + but->owner = self->login_window; + but->left = 10; + but->top = 30; + list_add_item(self->login_window->child_list, (long)but); } - xrdp_bitmap_load(but, file_path, self->palette); + + /* label */ + but = xrdp_bitmap_create(60, DEFAULT_EDIT_H, self->screen->bpp, WND_TYPE_LABEL, self); + list_add_item(self->login_window->child_list, (long)but); but->parent = self->login_window; but->owner = self->login_window; - but->left = 10; - but->top = 30; - list_add_item(self->login_window->child_list, (long)but); - } + but->left = regular ? 155 : 5; + but->top = DEFAULT_ELEMENT_TOP; + set_string(&but->caption1, "Module"); - /* label */ - but = xrdp_bitmap_create(60, DEFAULT_EDIT_H, self->screen->bpp, WND_TYPE_LABEL, self); - list_add_item(self->login_window->child_list, (long)but); - but->parent = self->login_window; - but->owner = self->login_window; - but->left = regular ? 155 : 5; - but->top = DEFAULT_ELEMENT_TOP; - set_string(&but->caption1, "Module"); + /* combo */ + combo = xrdp_bitmap_create(DEFAULT_COMBO_W, DEFAULT_COMBO_H, self->screen->bpp, WND_TYPE_COMBO, self); + list_add_item(self->login_window->child_list, (long)combo); + combo->parent = self->login_window; + combo->owner = self->login_window; + combo->left = regular ? DEFAULT_WND_LOGIN_W - DEFAULT_COMBO_W - 30 : 70; + combo->top = DEFAULT_ELEMENT_TOP; + combo->id = 6; + combo->tab_stop = 1; + xrdp_wm_login_fill_in_combo(self, combo); - /* combo */ - combo = xrdp_bitmap_create(DEFAULT_COMBO_W, DEFAULT_COMBO_H, self->screen->bpp, WND_TYPE_COMBO, self); - list_add_item(self->login_window->child_list, (long)combo); - combo->parent = self->login_window; - combo->owner = self->login_window; - combo->left = regular ? DEFAULT_WND_LOGIN_W - DEFAULT_COMBO_W - 30 : 70; - combo->top = DEFAULT_ELEMENT_TOP; - combo->id = 6; - combo->tab_stop = 1; - xrdp_wm_login_fill_in_combo(self, combo); - - /* button */ - but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); - list_add_item(self->login_window->child_list, (long)but); - but->parent = self->login_window; - but->owner = self->login_window; - but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W+10)*3) - 10 : 30; - but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15; - but->id = 3; - set_string(&but->caption1, "OK"); - but->tab_stop = 1; - self->login_window->default_button = but; - - /* button */ - but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); - list_add_item(self->login_window->child_list, (long)but); - but->parent = self->login_window; - but->owner = self->login_window; - but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W+10)*2) - 10 : ((log_width - 30) - DEFAULT_BUTTON_W); - but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15; - but->id = 2; - set_string(&but->caption1, "Cancel"); - but->tab_stop = 1; - self->login_window->esc_button = but; - - if (regular) - { /* button */ but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); list_add_item(self->login_window->child_list, (long)but); but->parent = self->login_window; but->owner = self->login_window; - but->left = DEFAULT_WND_LOGIN_W - (DEFAULT_BUTTON_W+10) - 10; + but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W + 10) * 3) - 10 : 30; but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15; - but->id = 1; - set_string(&but->caption1, "Help"); + but->id = 3; + set_string(&but->caption1, "OK"); but->tab_stop = 1; - } + self->login_window->default_button = but; - /* labels and edits */ - xrdp_wm_show_edits(self, combo); + /* button */ + but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); + list_add_item(self->login_window->child_list, (long)but); + but->parent = self->login_window; + but->owner = self->login_window; + but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W + 10) * 2) - 10 : ((log_width - 30) - DEFAULT_BUTTON_W); + but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15; + but->id = 2; + set_string(&but->caption1, "Cancel"); + but->tab_stop = 1; + self->login_window->esc_button = but; - return 0; + if (regular) + { + /* button */ + but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); + list_add_item(self->login_window->child_list, (long)but); + but->parent = self->login_window; + but->owner = self->login_window; + but->left = DEFAULT_WND_LOGIN_W - (DEFAULT_BUTTON_W + 10) - 10; + but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15; + but->id = 1; + set_string(&but->caption1, "Help"); + but->tab_stop = 1; + } + + /* labels and edits */ + xrdp_wm_show_edits(self, combo); + + return 0; } diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 0b764cc6..e13854ae 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -1,42 +1,40 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - module manager - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * module manager + */ #include "xrdp.h" #include "log.h" #define ACCESS /*****************************************************************************/ -struct xrdp_mm* APP_CC -xrdp_mm_create(struct xrdp_wm* owner) +struct xrdp_mm *APP_CC +xrdp_mm_create(struct xrdp_wm *owner) { - struct xrdp_mm* self; + struct xrdp_mm *self; - self = (struct xrdp_mm*)g_malloc(sizeof(struct xrdp_mm), 1); - self->wm = owner; - self->login_names = list_create(); - self->login_names->auto_free = 1; - self->login_values = list_create(); - self->login_values->auto_free = 1; - return self; + self = (struct xrdp_mm *)g_malloc(sizeof(struct xrdp_mm), 1); + self->wm = owner; + self->login_names = list_create(); + self->login_names->auto_free = 1; + self->login_values = list_create(); + self->login_values->auto_free = 1; + return self; } /*****************************************************************************/ @@ -44,7 +42,7 @@ xrdp_mm_create(struct xrdp_wm* owner) static long DEFAULT_CC xrdp_mm_sync_unload(long param1, long param2) { - return g_free_library(param1); + return g_free_library(param1); } /*****************************************************************************/ @@ -52,170 +50,178 @@ xrdp_mm_sync_unload(long param1, long param2) static long DEFAULT_CC xrdp_mm_sync_load(long param1, long param2) { - long rv; - char* libname; + long rv; + char *libname; - libname = (char*)param1; - rv = g_load_library(libname); - return rv; + libname = (char *)param1; + rv = g_load_library(libname); + return rv; } /*****************************************************************************/ static void APP_CC -xrdp_mm_module_cleanup(struct xrdp_mm* self) +xrdp_mm_module_cleanup(struct xrdp_mm *self) { - g_writeln("xrdp_mm_module_cleanup"); - if (self->mod != 0) - { - if (self->mod_exit != 0) + g_writeln("xrdp_mm_module_cleanup"); + + if (self->mod != 0) { - /* let the module cleanup */ - self->mod_exit(self->mod); + if (self->mod_exit != 0) + { + /* let the module cleanup */ + self->mod_exit(self->mod); + } } - } - if (self->mod_handle != 0) - { - /* Let the main thread unload the module.*/ - g_xrdp_sync(xrdp_mm_sync_unload, self->mod_handle, 0); - } - trans_delete(self->chan_trans); - self->chan_trans = 0; - self->chan_trans_up = 0; - self->mod_init = 0; - self->mod_exit = 0; - self->mod = 0; - self->mod_handle = 0; + + if (self->mod_handle != 0) + { + /* Let the main thread unload the module.*/ + g_xrdp_sync(xrdp_mm_sync_unload, self->mod_handle, 0); + } + + trans_delete(self->chan_trans); + self->chan_trans = 0; + self->chan_trans_up = 0; + self->mod_init = 0; + self->mod_exit = 0; + self->mod = 0; + self->mod_handle = 0; } /*****************************************************************************/ void APP_CC -xrdp_mm_delete(struct xrdp_mm* self) +xrdp_mm_delete(struct xrdp_mm *self) { - if (self == 0) - { - return; - } - /* free any module stuff */ - xrdp_mm_module_cleanup(self); - trans_delete(self->sesman_trans); - self->sesman_trans = 0; - self->sesman_trans_up = 0; - list_delete(self->login_names); - list_delete(self->login_values); - g_free(self); + if (self == 0) + { + return; + } + + /* free any module stuff */ + xrdp_mm_module_cleanup(self); + trans_delete(self->sesman_trans); + self->sesman_trans = 0; + self->sesman_trans_up = 0; + list_delete(self->login_names); + list_delete(self->login_values); + g_free(self); } /*****************************************************************************/ /* Send login information to sesman */ static int APP_CC -xrdp_mm_send_login(struct xrdp_mm* self) +xrdp_mm_send_login(struct xrdp_mm *self) { - struct stream* s; - int rv; - int index; - int count; - int xserverbpp; - char* username; - char* password; - char* name; - char* value; + struct stream *s; + int rv; + int index; + int count; + int xserverbpp; + char *username; + char *password; + char *name; + char *value; - xrdp_wm_log_msg(self->wm, "sending login info to session manager, " - "please wait..."); - username = 0; - password = 0; - self->code = 0; - xserverbpp = 0; - count = self->login_names->count; - for (index = 0; index < count; index++) - { - name = (char*)list_get_item(self->login_names, index); - value = (char*)list_get_item(self->login_values, index); - if (g_strcasecmp(name, "username") == 0) + xrdp_wm_log_msg(self->wm, "sending login info to session manager, " + "please wait..."); + username = 0; + password = 0; + self->code = 0; + xserverbpp = 0; + count = self->login_names->count; + + for (index = 0; index < count; index++) { - username = value; + name = (char *)list_get_item(self->login_names, index); + value = (char *)list_get_item(self->login_values, index); + + if (g_strcasecmp(name, "username") == 0) + { + username = value; + } + else if (g_strcasecmp(name, "password") == 0) + { + password = value; + } + else if (g_strcasecmp(name, "lib") == 0) + { + if ((g_strcasecmp(value, "libxup.so") == 0) || + (g_strcasecmp(value, "xup.dll") == 0)) + { + self->code = 10; + } + } + else if (g_strcasecmp(name, "xserverbpp") == 0) + { + xserverbpp = g_atoi(value); + } } - else if (g_strcasecmp(name, "password") == 0) + + if ((username == 0) || (password == 0)) { - password = value; + xrdp_wm_log_msg(self->wm, "Error finding username and password"); + return 1; } - else if (g_strcasecmp(name, "lib") == 0) + + s = trans_get_out_s(self->sesman_trans, 8192); + s_push_layer(s, channel_hdr, 8); + /* this code is either 0 for Xvnc or 10 for X11rdp */ + out_uint16_be(s, self->code); + index = g_strlen(username); + out_uint16_be(s, index); + out_uint8a(s, username, index); + index = g_strlen(password); + + out_uint16_be(s, index); + out_uint8a(s, password, index); + out_uint16_be(s, self->wm->screen->width); + out_uint16_be(s, self->wm->screen->height); + + if (xserverbpp > 0) { - if ((g_strcasecmp(value, "libxup.so") == 0) || - (g_strcasecmp(value, "xup.dll") == 0)) - { - self->code = 10; - } + out_uint16_be(s, xserverbpp); } - else if (g_strcasecmp(name, "xserverbpp") == 0) + else { - xserverbpp = g_atoi(value); + out_uint16_be(s, self->wm->screen->bpp); } - } - if ((username == 0) || (password == 0)) - { - xrdp_wm_log_msg(self->wm, "Error finding username and password"); - return 1; - } - s = trans_get_out_s(self->sesman_trans, 8192); - s_push_layer(s, channel_hdr, 8); - /* this code is either 0 for Xvnc or 10 for X11rdp */ - out_uint16_be(s, self->code); - index = g_strlen(username); - out_uint16_be(s, index); - out_uint8a(s, username, index); - index = g_strlen(password); + /* send domain */ + index = g_strlen(self->wm->client_info->domain); + out_uint16_be(s, index); + out_uint8a(s, self->wm->client_info->domain, index); - out_uint16_be(s, index); - out_uint8a(s, password, index); - out_uint16_be(s, self->wm->screen->width); - out_uint16_be(s, self->wm->screen->height); + /* send program / shell */ + index = g_strlen(self->wm->client_info->program); + out_uint16_be(s, index); + out_uint8a(s, self->wm->client_info->program, index); - if (xserverbpp > 0) - { - out_uint16_be(s, xserverbpp); - } - else - { - out_uint16_be(s, self->wm->screen->bpp); - } + /* send directory */ + index = g_strlen(self->wm->client_info->directory); + out_uint16_be(s, index); + out_uint8a(s, self->wm->client_info->directory, index); - /* send domain */ - index = g_strlen(self->wm->client_info->domain); - out_uint16_be(s, index); - out_uint8a(s, self->wm->client_info->domain, index); + /* send client ip */ + index = g_strlen(self->wm->client_info->client_ip); + out_uint16_be(s, index); + out_uint8a(s, self->wm->client_info->client_ip, index); - /* send program / shell */ - index = g_strlen(self->wm->client_info->program); - out_uint16_be(s, index); - out_uint8a(s, self->wm->client_info->program, index); + s_mark_end(s); - /* send directory */ - index = g_strlen(self->wm->client_info->directory); - out_uint16_be(s, index); - out_uint8a(s, self->wm->client_info->directory, index); + s_pop_layer(s, channel_hdr); + /* Version 0 of the protocol to sesman is currently used by XRDP */ + out_uint32_be(s, 0); /* version */ + index = (int)(s->end - s->data); + out_uint32_be(s, index); /* size */ - /* send client ip */ - index = g_strlen(self->wm->client_info->client_ip); - out_uint16_be(s, index); - out_uint8a(s, self->wm->client_info->client_ip, index); + rv = trans_force_write(self->sesman_trans); - s_mark_end(s); + if (rv != 0) + { + xrdp_wm_log_msg(self->wm, "xrdp_mm_send_login: xrdp_mm_send_login failed"); + } - s_pop_layer(s, channel_hdr); - /* Version 0 of the protocol to sesman is currently used by XRDP */ - out_uint32_be(s, 0); /* version */ - index = (int)(s->end - s->data); - out_uint32_be(s, index); /* size */ - - rv = trans_force_write(self->sesman_trans); - - if (rv != 0) { - xrdp_wm_log_msg(self->wm, "xrdp_mm_send_login: xrdp_mm_send_login failed"); - } - - return rv; + return rv; } /*****************************************************************************/ @@ -224,744 +230,828 @@ xrdp_mm_send_login(struct xrdp_mm* self) then it copies the corisponding login_values item into 'dest' 'dest' must be at least 'dest_len' + 1 bytes in size */ static int APP_CC -xrdp_mm_get_value(struct xrdp_mm* self, char* aname, char* dest, int dest_len) +xrdp_mm_get_value(struct xrdp_mm *self, char *aname, char *dest, int dest_len) { - char* name; - char* value; - int index; - int count; - int rv; + char *name; + char *value; + int index; + int count; + int rv; - rv = 1; - /* find the library name */ - dest[0] = 0; - count = self->login_names->count; - for (index = 0; index < count; index++) - { - name = (char*)list_get_item(self->login_names, index); - value = (char*)list_get_item(self->login_values, index); - if ((name == 0) || (value == 0)) - { - break; - } - if (g_strcasecmp(name, aname) == 0) - { - g_strncpy(dest, value, dest_len); - rv = 0; - } - } + rv = 1; + /* find the library name */ + dest[0] = 0; + count = self->login_names->count; - return rv; + for (index = 0; index < count; index++) + { + name = (char *)list_get_item(self->login_names, index); + value = (char *)list_get_item(self->login_values, index); + + if ((name == 0) || (value == 0)) + { + break; + } + + if (g_strcasecmp(name, aname) == 0) + { + g_strncpy(dest, value, dest_len); + rv = 0; + } + } + + return rv; } /*****************************************************************************/ static int APP_CC -xrdp_mm_setup_mod1(struct xrdp_mm* self) +xrdp_mm_setup_mod1(struct xrdp_mm *self) { - void* func; - char lib[256]; - char text[256]; + void *func; + char lib[256]; + char text[256]; - if (self == 0) - { - return 1; - } - lib[0] = 0; - if (xrdp_mm_get_value(self, "lib", lib, 255) != 0) - { - g_snprintf(text, 255, "no library name specified in xrdp.ini, please add " - "lib=libxrdp-vnc.so or similar"); - xrdp_wm_log_msg(self->wm, text); - - return 1; - } - if (lib[0] == 0) - { - g_snprintf(text, 255, "empty library name specified in xrdp.ini, please " - "add lib=libxrdp-vnc.so or similar"); - xrdp_wm_log_msg(self->wm, text); - - return 1; - } - if (self->mod_handle == 0) - { - /* Let the main thread load the lib,*/ - self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (long)lib, 0); - if (self->mod_handle != 0) + if (self == 0) { - func = g_get_proc_address(self->mod_handle, "mod_init"); - if (func == 0) - { - func = g_get_proc_address(self->mod_handle, "_mod_init"); - } - if (func == 0) - { - g_snprintf(text, 255, "error finding proc mod_init in %s, not a valid " - "xrdp backend", lib); + return 1; + } + + lib[0] = 0; + + if (xrdp_mm_get_value(self, "lib", lib, 255) != 0) + { + g_snprintf(text, 255, "no library name specified in xrdp.ini, please add " + "lib=libxrdp-vnc.so or similar"); xrdp_wm_log_msg(self->wm, text); - } - self->mod_init = (struct xrdp_mod* (*)(void))func; - func = g_get_proc_address(self->mod_handle, "mod_exit"); - if (func == 0) - { - func = g_get_proc_address(self->mod_handle, "_mod_exit"); - } - if (func == 0) - { - g_snprintf(text, 255, "error finding proc mod_exit in %s, not a valid " - "xrdp backend", lib); + + return 1; + } + + if (lib[0] == 0) + { + g_snprintf(text, 255, "empty library name specified in xrdp.ini, please " + "add lib=libxrdp-vnc.so or similar"); xrdp_wm_log_msg(self->wm, text); - } - self->mod_exit = (int (*)(struct xrdp_mod*))func; - if ((self->mod_init != 0) && (self->mod_exit != 0)) - { - self->mod = self->mod_init(); - if (self->mod != 0) - { - g_writeln("loaded module '%s' ok, interface size %d, version %d", lib, - self->mod->size, self->mod->version); - } - }else{ - g_writeln("no mod_init or mod_exit address found"); - } - } - else - { - g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please " - "add a valid entry like lib=libxrdp-vnc.so or similar", lib); - xrdp_wm_log_msg(self->wm, text); - return 1; - } - if (self->mod != 0) - { - self->mod->wm = (long)(self->wm); - self->mod->server_begin_update = server_begin_update; - self->mod->server_end_update = server_end_update; - self->mod->server_bell_trigger = server_bell_trigger; - self->mod->server_fill_rect = server_fill_rect; - self->mod->server_screen_blt = server_screen_blt; - self->mod->server_paint_rect = server_paint_rect; - self->mod->server_set_pointer = server_set_pointer; - self->mod->server_palette = server_palette; - self->mod->server_msg = server_msg; - self->mod->server_is_term = server_is_term; - self->mod->server_set_clip = server_set_clip; - self->mod->server_reset_clip = server_reset_clip; - self->mod->server_set_fgcolor = server_set_fgcolor; - self->mod->server_set_bgcolor = server_set_bgcolor; - self->mod->server_set_opcode = server_set_opcode; - self->mod->server_set_mixmode = server_set_mixmode; - self->mod->server_set_brush = server_set_brush; - self->mod->server_set_pen = server_set_pen; - self->mod->server_draw_line = server_draw_line; - self->mod->server_add_char = server_add_char; - self->mod->server_draw_text = server_draw_text; - self->mod->server_reset = server_reset; - self->mod->server_query_channel = server_query_channel; - self->mod->server_get_channel_id = server_get_channel_id; - self->mod->server_send_to_channel = server_send_to_channel; - self->mod->server_create_os_surface = server_create_os_surface; - self->mod->server_switch_os_surface = server_switch_os_surface; - self->mod->server_delete_os_surface = server_delete_os_surface; - self->mod->server_paint_rect_os = server_paint_rect_os; - self->mod->server_set_hints = server_set_hints; - self->mod->server_window_new_update = server_window_new_update; - self->mod->server_window_delete = server_window_delete; - self->mod->server_window_icon = server_window_icon; - self->mod->server_window_cached_icon = server_window_cached_icon; - self->mod->server_notify_new_update = server_notify_new_update; - self->mod->server_notify_delete = server_notify_delete; - self->mod->server_monitored_desktop = server_monitored_desktop; - } - } - /* id self->mod is null, there must be a problem */ - if (self->mod == 0) - { - DEBUG(("problem loading lib in xrdp_mm_setup_mod1")); - return 1; - } - return 0; -} -/*****************************************************************************/ -static int APP_CC -xrdp_mm_setup_mod2(struct xrdp_mm* self) -{ - char text[256]; - char* name; - char* value; - int i; - int rv; - int key_flags; - int device_flags; - int use_uds; - - rv = 1; /* failure */ - g_memset(text, 0, sizeof(text)); - if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event)) - { - if (self->mod->mod_start(self->mod, self->wm->screen->width, - self->wm->screen->height, - self->wm->screen->bpp) != 0) - { - g_set_wait_obj(self->wm->pro_layer->self_term_event); /* kill session */ + return 1; } - } - if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event)) - { - if (self->display > 0) + + if (self->mod_handle == 0) { - if (self->code == 0) /* Xvnc */ - { - g_snprintf(text, 255, "%d", 5900 + self->display); - } - else if (self->code == 10) /* X11rdp */ - { - use_uds = 1; - if (xrdp_mm_get_value(self, "ip", text, 255) == 0) + /* Let the main thread load the lib,*/ + self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (long)lib, 0); + + if (self->mod_handle != 0) { - if (g_strcmp(text, "127.0.0.1") != 0) - { - use_uds = 0; - } - } - if (use_uds) - { - g_snprintf(text, 255, "/tmp/.xrdp/xrdp_display_%d", self->display); + func = g_get_proc_address(self->mod_handle, "mod_init"); + + if (func == 0) + { + func = g_get_proc_address(self->mod_handle, "_mod_init"); + } + + if (func == 0) + { + g_snprintf(text, 255, "error finding proc mod_init in %s, not a valid " + "xrdp backend", lib); + xrdp_wm_log_msg(self->wm, text); + } + + self->mod_init = (struct xrdp_mod * ( *)(void))func; + func = g_get_proc_address(self->mod_handle, "mod_exit"); + + if (func == 0) + { + func = g_get_proc_address(self->mod_handle, "_mod_exit"); + } + + if (func == 0) + { + g_snprintf(text, 255, "error finding proc mod_exit in %s, not a valid " + "xrdp backend", lib); + xrdp_wm_log_msg(self->wm, text); + } + + self->mod_exit = (int ( *)(struct xrdp_mod *))func; + + if ((self->mod_init != 0) && (self->mod_exit != 0)) + { + self->mod = self->mod_init(); + + if (self->mod != 0) + { + g_writeln("loaded module '%s' ok, interface size %d, version %d", lib, + self->mod->size, self->mod->version); + } + } + else + { + g_writeln("no mod_init or mod_exit address found"); + } } else { - g_snprintf(text, 255, "%d", 6200 + self->display); + g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please " + "add a valid entry like lib=libxrdp-vnc.so or similar", lib); + xrdp_wm_log_msg(self->wm, text); + return 1; } - } - else - { - g_set_wait_obj(self->wm->pro_layer->self_term_event); /* kill session */ - } - } - } - if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event)) - { - /* this adds the port to the end of the list, it will already be in - the list as -1 - the module should use the last one */ - if (g_strlen(text) > 0) - { - list_add_item(self->login_names, (long)g_strdup("port")); - list_add_item(self->login_values, (long)g_strdup(text)); - } - /* always set these */ - self->mod->mod_set_param(self->mod, "client_info", - (char*)(self->wm->session->client_info)); + if (self->mod != 0) + { + self->mod->wm = (long)(self->wm); + self->mod->server_begin_update = server_begin_update; + self->mod->server_end_update = server_end_update; + self->mod->server_bell_trigger = server_bell_trigger; + self->mod->server_fill_rect = server_fill_rect; + self->mod->server_screen_blt = server_screen_blt; + self->mod->server_paint_rect = server_paint_rect; + self->mod->server_set_pointer = server_set_pointer; + self->mod->server_palette = server_palette; + self->mod->server_msg = server_msg; + self->mod->server_is_term = server_is_term; + self->mod->server_set_clip = server_set_clip; + self->mod->server_reset_clip = server_reset_clip; + self->mod->server_set_fgcolor = server_set_fgcolor; + self->mod->server_set_bgcolor = server_set_bgcolor; + self->mod->server_set_opcode = server_set_opcode; + self->mod->server_set_mixmode = server_set_mixmode; + self->mod->server_set_brush = server_set_brush; + self->mod->server_set_pen = server_set_pen; + self->mod->server_draw_line = server_draw_line; + self->mod->server_add_char = server_add_char; + self->mod->server_draw_text = server_draw_text; + self->mod->server_reset = server_reset; + self->mod->server_query_channel = server_query_channel; + self->mod->server_get_channel_id = server_get_channel_id; + self->mod->server_send_to_channel = server_send_to_channel; + self->mod->server_create_os_surface = server_create_os_surface; + self->mod->server_switch_os_surface = server_switch_os_surface; + self->mod->server_delete_os_surface = server_delete_os_surface; + self->mod->server_paint_rect_os = server_paint_rect_os; + self->mod->server_set_hints = server_set_hints; + self->mod->server_window_new_update = server_window_new_update; + self->mod->server_window_delete = server_window_delete; + self->mod->server_window_icon = server_window_icon; + self->mod->server_window_cached_icon = server_window_cached_icon; + self->mod->server_notify_new_update = server_notify_new_update; + self->mod->server_notify_delete = server_notify_delete; + self->mod->server_monitored_desktop = server_monitored_desktop; + } + } - name = self->wm->session->client_info->hostname; - self->mod->mod_set_param(self->mod, "hostname", name); - g_snprintf(text, 255, "%d", self->wm->session->client_info->keylayout); - self->mod->mod_set_param(self->mod, "keylayout", text); - for (i = 0; i < self->login_names->count; i++) + /* id self->mod is null, there must be a problem */ + if (self->mod == 0) { - name = (char*)list_get_item(self->login_names, i); - value = (char*)list_get_item(self->login_values, i); - self->mod->mod_set_param(self->mod, name, value); + DEBUG(("problem loading lib in xrdp_mm_setup_mod1")); + return 1; } - /* connect */ - if (self->mod->mod_connect(self->mod) == 0) + + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_mm_setup_mod2(struct xrdp_mm *self) +{ + char text[256]; + char *name; + char *value; + int i; + int rv; + int key_flags; + int device_flags; + int use_uds; + + rv = 1; /* failure */ + g_memset(text, 0, sizeof(text)); + + if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event)) { - rv = 0; /* connect success */ + if (self->mod->mod_start(self->mod, self->wm->screen->width, + self->wm->screen->height, + self->wm->screen->bpp) != 0) + { + g_set_wait_obj(self->wm->pro_layer->self_term_event); /* kill session */ + } } - } - if (rv == 0) - { - /* sync modifiers */ - key_flags = 0; - device_flags = 0; - if (self->wm->scroll_lock) + + if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event)) { - key_flags |= 1; + if (self->display > 0) + { + if (self->code == 0) /* Xvnc */ + { + g_snprintf(text, 255, "%d", 5900 + self->display); + } + else if (self->code == 10) /* X11rdp */ + { + use_uds = 1; + + if (xrdp_mm_get_value(self, "ip", text, 255) == 0) + { + if (g_strcmp(text, "127.0.0.1") != 0) + { + use_uds = 0; + } + } + + if (use_uds) + { + g_snprintf(text, 255, "/tmp/.xrdp/xrdp_display_%d", self->display); + } + else + { + g_snprintf(text, 255, "%d", 6200 + self->display); + } + } + else + { + g_set_wait_obj(self->wm->pro_layer->self_term_event); /* kill session */ + } + } } - if (self->wm->num_lock) + + if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event)) { - key_flags |= 2; + /* this adds the port to the end of the list, it will already be in + the list as -1 + the module should use the last one */ + if (g_strlen(text) > 0) + { + list_add_item(self->login_names, (long)g_strdup("port")); + list_add_item(self->login_values, (long)g_strdup(text)); + } + + /* always set these */ + + self->mod->mod_set_param(self->mod, "client_info", + (char *)(self->wm->session->client_info)); + + name = self->wm->session->client_info->hostname; + self->mod->mod_set_param(self->mod, "hostname", name); + g_snprintf(text, 255, "%d", self->wm->session->client_info->keylayout); + self->mod->mod_set_param(self->mod, "keylayout", text); + + for (i = 0; i < self->login_names->count; i++) + { + name = (char *)list_get_item(self->login_names, i); + value = (char *)list_get_item(self->login_values, i); + self->mod->mod_set_param(self->mod, name, value); + } + + /* connect */ + if (self->mod->mod_connect(self->mod) == 0) + { + rv = 0; /* connect success */ + } } - if (self->wm->caps_lock) + + if (rv == 0) { - key_flags |= 4; + /* sync modifiers */ + key_flags = 0; + device_flags = 0; + + if (self->wm->scroll_lock) + { + key_flags |= 1; + } + + if (self->wm->num_lock) + { + key_flags |= 2; + } + + if (self->wm->caps_lock) + { + key_flags |= 4; + } + + if (self->mod != 0) + { + if (self->mod->mod_event != 0) + { + self->mod->mod_event(self->mod, 17, key_flags, device_flags, + key_flags, device_flags); + } + } } - if (self->mod != 0) - { - if (self->mod->mod_event != 0) - { - self->mod->mod_event(self->mod, 17, key_flags, device_flags, - key_flags, device_flags); - } - } - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error send a list of channels to the channel handler */ static int APP_CC -xrdp_mm_trans_send_channel_setup(struct xrdp_mm* self, struct trans* trans) +xrdp_mm_trans_send_channel_setup(struct xrdp_mm *self, struct trans *trans) { - int index; - int chan_id; - int chan_flags; - int size; - struct stream* s; - char chan_name[256]; + int index; + int chan_id; + int chan_flags; + int size; + struct stream *s; + char chan_name[256]; - g_memset(chan_name,0,sizeof(char) * 256); + g_memset(chan_name, 0, sizeof(char) * 256); - s = trans_get_out_s(trans, 8192); - if (s == 0) - { - return 1; - } - s_push_layer(s, iso_hdr, 8); - s_push_layer(s, mcs_hdr, 8); - s_push_layer(s, sec_hdr, 2); - index = 0; - while (libxrdp_query_channel(self->wm->session, index, chan_name, - &chan_flags) == 0) - { - chan_id = libxrdp_get_channel_id(self->wm->session, chan_name); - out_uint8a(s, chan_name, 8); - out_uint16_le(s, chan_id); - out_uint16_le(s, chan_flags); - index++; - } - s_mark_end(s); - s_pop_layer(s, sec_hdr); - out_uint16_le(s, index); - s_pop_layer(s, mcs_hdr); - size = (int)(s->end - s->p); - out_uint32_le(s, 3); /* msg id */ - out_uint32_le(s, size); /* msg size */ - s_pop_layer(s, iso_hdr); - size = (int)(s->end - s->p); - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, size); /* block size */ - return trans_force_write(trans); + s = trans_get_out_s(trans, 8192); + + if (s == 0) + { + return 1; + } + + s_push_layer(s, iso_hdr, 8); + s_push_layer(s, mcs_hdr, 8); + s_push_layer(s, sec_hdr, 2); + index = 0; + + while (libxrdp_query_channel(self->wm->session, index, chan_name, + &chan_flags) == 0) + { + chan_id = libxrdp_get_channel_id(self->wm->session, chan_name); + out_uint8a(s, chan_name, 8); + out_uint16_le(s, chan_id); + out_uint16_le(s, chan_flags); + index++; + } + + s_mark_end(s); + s_pop_layer(s, sec_hdr); + out_uint16_le(s, index); + s_pop_layer(s, mcs_hdr); + size = (int)(s->end - s->p); + out_uint32_le(s, 3); /* msg id */ + out_uint32_le(s, size); /* msg size */ + s_pop_layer(s, iso_hdr); + size = (int)(s->end - s->p); + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, size); /* block size */ + return trans_force_write(trans); } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mm_trans_send_channel_data_response(struct xrdp_mm* self, - struct trans* trans) +xrdp_mm_trans_send_channel_data_response(struct xrdp_mm *self, + struct trans *trans) { - struct stream* s; + struct stream *s; - s = trans_get_out_s(trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 7); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(trans); + s = trans_get_out_s(trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 7); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(trans); } /*****************************************************************************/ /* returns error init is done, sent channel setup */ static int APP_CC -xrdp_mm_trans_process_init_response(struct xrdp_mm* self, struct trans* trans) +xrdp_mm_trans_process_init_response(struct xrdp_mm *self, struct trans *trans) { - return xrdp_mm_trans_send_channel_setup(self, trans); + return xrdp_mm_trans_send_channel_setup(self, trans); } /*****************************************************************************/ /* returns error data coming in from the channel handler, send it to the client */ static int APP_CC -xrdp_mm_trans_process_channel_data(struct xrdp_mm* self, struct trans* trans) +xrdp_mm_trans_process_channel_data(struct xrdp_mm *self, struct trans *trans) { - struct stream* s; - int size; - int total_size; - int chan_id; - int chan_flags; - int rv; + struct stream *s; + int size; + int total_size; + int chan_id; + int chan_flags; + int rv; - s = trans_get_in_s(trans); - if (s == 0) - { - return 1; - } - in_uint16_le(s, chan_id); - in_uint16_le(s, chan_flags); - in_uint16_le(s, size); - in_uint32_le(s, total_size); - rv = xrdp_mm_trans_send_channel_data_response(self, trans); - if (rv == 0) - { - rv = libxrdp_send_to_channel(self->wm->session, chan_id, s->p, size, total_size, - chan_flags); - } - return rv; + s = trans_get_in_s(trans); + + if (s == 0) + { + return 1; + } + + in_uint16_le(s, chan_id); + in_uint16_le(s, chan_flags); + in_uint16_le(s, size); + in_uint32_le(s, total_size); + rv = xrdp_mm_trans_send_channel_data_response(self, trans); + + if (rv == 0) + { + rv = libxrdp_send_to_channel(self->wm->session, chan_id, s->p, size, total_size, + chan_flags); + } + + return rv; } /*****************************************************************************/ /* returns error process a message for the channel handler */ static int APP_CC -xrdp_mm_chan_process_msg(struct xrdp_mm* self, struct trans* trans, - struct stream* s) +xrdp_mm_chan_process_msg(struct xrdp_mm *self, struct trans *trans, + struct stream *s) { - int rv; - int id; - int size; - char* next_msg; + int rv; + int id; + int size; + char *next_msg; - rv = 0; - while (s_check_rem(s, 8)) - { - next_msg = s->p; - in_uint32_le(s, id); - in_uint32_le(s, size); - next_msg += size; - switch (id) + rv = 0; + + while (s_check_rem(s, 8)) { - case 2: /* channel init response */ - rv = xrdp_mm_trans_process_init_response(self, trans); - break; - case 4: /* channel setup response */ - break; - case 6: /* channel data response */ - break; - case 8: /* channel data */ - rv = xrdp_mm_trans_process_channel_data(self, trans); - break; - default: - g_writeln("xrdp_mm_chan_process_msg: unknown id %d", id); - break; + next_msg = s->p; + in_uint32_le(s, id); + in_uint32_le(s, size); + next_msg += size; + + switch (id) + { + case 2: /* channel init response */ + rv = xrdp_mm_trans_process_init_response(self, trans); + break; + case 4: /* channel setup response */ + break; + case 6: /* channel data response */ + break; + case 8: /* channel data */ + rv = xrdp_mm_trans_process_channel_data(self, trans); + break; + default: + g_writeln("xrdp_mm_chan_process_msg: unknown id %d", id); + break; + } + + if (rv != 0) + { + break; + } + + s->p = next_msg; } - if (rv != 0) - { - break; - } - s->p = next_msg; - } - return rv; + + return rv; } /*****************************************************************************/ /* this is callback from trans obj returns error */ static int APP_CC -xrdp_mm_chan_data_in(struct trans* trans) +xrdp_mm_chan_data_in(struct trans *trans) { - struct xrdp_mm* self; - struct stream* s; - int id; - int size; - int error; + struct xrdp_mm *self; + struct stream *s; + int id; + int size; + int error; - if (trans == 0) - { - return 1; - } - self = (struct xrdp_mm*)(trans->callback_data); - s = trans_get_in_s(trans); - if (s == 0) - { - return 1; - } - in_uint32_le(s, id); - in_uint32_le(s, size); - error = trans_force_read(trans, size - 8); - if (error == 0) - { - /* here, the entire message block is read in, process it */ - error = xrdp_mm_chan_process_msg(self, trans, s); - } - return error; + if (trans == 0) + { + return 1; + } + + self = (struct xrdp_mm *)(trans->callback_data); + s = trans_get_in_s(trans); + + if (s == 0) + { + return 1; + } + + in_uint32_le(s, id); + in_uint32_le(s, size); + error = trans_force_read(trans, size - 8); + + if (error == 0) + { + /* here, the entire message block is read in, process it */ + error = xrdp_mm_chan_process_msg(self, trans, s); + } + + return error; } /*****************************************************************************/ static int APP_CC -xrdp_mm_chan_send_init(struct xrdp_mm* self) +xrdp_mm_chan_send_init(struct xrdp_mm *self) { - struct stream* s; + struct stream *s; - s = trans_get_out_s(self->chan_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 1); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(self->chan_trans); + s = trans_get_out_s(self->chan_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 1); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(self->chan_trans); } /*****************************************************************************/ /* connect to chansrv */ static int APP_CC -xrdp_mm_connect_chansrv(struct xrdp_mm* self, char* ip, char* port) +xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port) { - int index; + int index; - self->usechansrv = 1; + self->usechansrv = 1; - /* connect channel redir */ - if ((ip == 0) || (g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0)) - { - /* unix socket */ - self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192); - } - else - { - /* tcp */ - self->chan_trans = trans_create(TRANS_MODE_TCP, 8192, 8192); - } - self->chan_trans->trans_data_in = xrdp_mm_chan_data_in; - self->chan_trans->header_size = 8; - self->chan_trans->callback_data = self; - /* try to connect up to 4 times */ - for (index = 0; index < 4; index++) - { - if (trans_connect(self->chan_trans, ip, port, 3000) == 0) + /* connect channel redir */ + if ((ip == 0) || (g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0)) { - self->chan_trans_up = 1; - break; - } - g_sleep(1000); - g_writeln("xrdp_mm_connect_chansrv: connect failed " - "trying again..."); - } - if (!(self->chan_trans_up)) - { - g_writeln("xrdp_mm_connect_chansrv: error in trans_connect " - "chan"); - } - if (self->chan_trans_up) - { - if (xrdp_mm_chan_send_init(self) != 0) - { - g_writeln("xrdp_mm_connect_chansrv: error in " - "xrdp_mm_chan_send_init"); + /* unix socket */ + self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192); } else { - g_writeln("xrdp_mm_connect_chansrv: chansrv connect successful"); + /* tcp */ + self->chan_trans = trans_create(TRANS_MODE_TCP, 8192, 8192); } - } - return 0; + + self->chan_trans->trans_data_in = xrdp_mm_chan_data_in; + self->chan_trans->header_size = 8; + self->chan_trans->callback_data = self; + + /* try to connect up to 4 times */ + for (index = 0; index < 4; index++) + { + if (trans_connect(self->chan_trans, ip, port, 3000) == 0) + { + self->chan_trans_up = 1; + break; + } + + g_sleep(1000); + g_writeln("xrdp_mm_connect_chansrv: connect failed " + "trying again..."); + } + + if (!(self->chan_trans_up)) + { + g_writeln("xrdp_mm_connect_chansrv: error in trans_connect " + "chan"); + } + + if (self->chan_trans_up) + { + if (xrdp_mm_chan_send_init(self) != 0) + { + g_writeln("xrdp_mm_connect_chansrv: error in " + "xrdp_mm_chan_send_init"); + } + else + { + g_writeln("xrdp_mm_connect_chansrv: chansrv connect successful"); + } + } + + return 0; } -static void cleanup_sesman_connection(struct xrdp_mm* self) +static void cleanup_sesman_connection(struct xrdp_mm *self) { - self->delete_sesman_trans = 1; - self->connected_state = 0; - if (self->wm->login_mode != 10) - { - xrdp_wm_set_login_mode(self->wm, 11); - xrdp_mm_module_cleanup(self); - } + self->delete_sesman_trans = 1; + self->connected_state = 0; + + if (self->wm->login_mode != 10) + { + xrdp_wm_set_login_mode(self->wm, 11); + xrdp_mm_module_cleanup(self); + } } /*****************************************************************************/ static int APP_CC -xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s) +xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s) { - int ok; - int display; - int rv; - char text[256]; - char ip[256]; - char port[256]; + int ok; + int display; + int rv; + char text[256]; + char ip[256]; + char port[256]; - rv = 0; - in_uint16_be(s, ok); - in_uint16_be(s, display); - if (ok) - { - self->display = display; - g_snprintf(text, 255, "xrdp_mm_process_login_response: login successful " - "for display %d", display); - xrdp_wm_log_msg(self->wm, text); - if (xrdp_mm_setup_mod1(self) == 0) + rv = 0; + in_uint16_be(s, ok); + in_uint16_be(s, display); + + if (ok) { - if (xrdp_mm_setup_mod2(self) == 0) - { - xrdp_mm_get_value(self, "ip", ip, 255); - xrdp_wm_set_login_mode(self->wm, 10); - self->wm->dragging = 0; - /* connect channel redir */ - if ((ip == 0) || (g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0)) + self->display = display; + g_snprintf(text, 255, "xrdp_mm_process_login_response: login successful " + "for display %d", display); + xrdp_wm_log_msg(self->wm, text); + + if (xrdp_mm_setup_mod1(self) == 0) { - g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", 7200 + display); + if (xrdp_mm_setup_mod2(self) == 0) + { + xrdp_mm_get_value(self, "ip", ip, 255); + xrdp_wm_set_login_mode(self->wm, 10); + self->wm->dragging = 0; + + /* connect channel redir */ + if ((ip == 0) || (g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0)) + { + g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", 7200 + display); + } + else + { + g_snprintf(port, 255, "%d", 7200 + display); + } + + xrdp_mm_connect_chansrv(self, ip, port); + } } - else - { - g_snprintf(port, 255, "%d", 7200 + display); - } - xrdp_mm_connect_chansrv(self, ip, port); - } } - } - else - { - xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: " - "login failed"); - } - cleanup_sesman_connection(self); - return rv; + else + { + xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: " + "login failed"); + } + + cleanup_sesman_connection(self); + return rv; } /*****************************************************************************/ static int -xrdp_mm_get_sesman_port(char* port, int port_bytes) +xrdp_mm_get_sesman_port(char *port, int port_bytes) { - int fd; - int error; - int index; - char* val; - char cfg_file[256]; - struct list* names; - struct list* values; + int fd; + int error; + int index; + char *val; + char cfg_file[256]; + struct list *names; + struct list *values; - g_memset(cfg_file,0,sizeof(char) * 256); - /* default to port 3350 */ - g_strncpy(port, "3350", port_bytes - 1); - /* see if port is in xrdp.ini file */ - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); - if (fd > 0) - { - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - if (file_read_section(fd, "Globals", names, values) == 0) + g_memset(cfg_file, 0, sizeof(char) * 256); + /* default to port 3350 */ + g_strncpy(port, "3350", port_bytes - 1); + /* see if port is in xrdp.ini file */ + g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); + fd = g_file_open(cfg_file); + + if (fd > 0) { - for (index = 0; index < names->count; index++) - { - val = (char*)list_get_item(names, index); - if (val != 0) - { - if (g_strcasecmp(val, "ListenPort") == 0) - { - val = (char*)list_get_item(values, index); - error = g_atoi(val); - if ((error > 0) && (error < 65000)) - { - g_strncpy(port, val, port_bytes - 1); - } - break; - } - } - } - } - list_delete(names); - list_delete(values); - g_file_close(fd); - } + names = list_create(); + names->auto_free = 1; + values = list_create(); + values->auto_free = 1; - return 0; + if (file_read_section(fd, "Globals", names, values) == 0) + { + for (index = 0; index < names->count; index++) + { + val = (char *)list_get_item(names, index); + + if (val != 0) + { + if (g_strcasecmp(val, "ListenPort") == 0) + { + val = (char *)list_get_item(values, index); + error = g_atoi(val); + + if ((error > 0) && (error < 65000)) + { + g_strncpy(port, val, port_bytes - 1); + } + + break; + } + } + } + } + + list_delete(names); + list_delete(values); + g_file_close(fd); + } + + return 0; } /*****************************************************************************/ /* returns error data coming from client that need to go to channel handler */ int APP_CC -xrdp_mm_process_channel_data(struct xrdp_mm* self, tbus param1, tbus param2, +xrdp_mm_process_channel_data(struct xrdp_mm *self, tbus param1, tbus param2, tbus param3, tbus param4) { - struct stream* s; - int rv; - int length; - int total_length; - int flags; - int id; - char* data; + struct stream *s; + int rv; + int length; + int total_length; + int flags; + int id; + char *data; - rv = 0; - if ((self->chan_trans != 0) && self->chan_trans_up) - { - s = trans_get_out_s(self->chan_trans, 8192); - if (s != 0) + rv = 0; + + if ((self->chan_trans != 0) && self->chan_trans_up) { - id = LOWORD(param1); - flags = HIWORD(param1); - length = param2; - data = (char*)param3; - total_length = param4; - if (total_length < length) - { - g_writeln("WARNING in xrdp_mm_process_channel_data(): total_len < length"); - total_length = length; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + length); - out_uint32_le(s, 5); /* msg id */ - out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + length); - out_uint16_le(s, id); - out_uint16_le(s, flags); - out_uint16_le(s, length); - out_uint32_le(s, total_length); - out_uint8a(s, data, length); - s_mark_end(s); - rv = trans_force_write(self->chan_trans); - } - } + s = trans_get_out_s(self->chan_trans, 8192); - return rv; + if (s != 0) + { + id = LOWORD(param1); + flags = HIWORD(param1); + length = param2; + data = (char *)param3; + total_length = param4; + + if (total_length < length) + { + g_writeln("WARNING in xrdp_mm_process_channel_data(): total_len < length"); + total_length = length; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + length); + out_uint32_le(s, 5); /* msg id */ + out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + length); + out_uint16_le(s, id); + out_uint16_le(s, flags); + out_uint16_le(s, length); + out_uint32_le(s, total_length); + out_uint8a(s, data, length); + s_mark_end(s); + rv = trans_force_write(self->chan_trans); + } + } + + return rv; } /*****************************************************************************/ /* This is the callback registered for sesman communication replies. */ static int APP_CC -xrdp_mm_sesman_data_in(struct trans* trans) +xrdp_mm_sesman_data_in(struct trans *trans) { - struct xrdp_mm* self; - struct stream* s; - int version; - int size; - int error; - int code; + struct xrdp_mm *self; + struct stream *s; + int version; + int size; + int error; + int code; - if (trans == 0) - { - return 1; - } - self = (struct xrdp_mm*)(trans->callback_data); - s = trans_get_in_s(trans); - if (s == 0) - { - return 1; - } - in_uint32_be(s, version); - in_uint32_be(s, size); - error = trans_force_read(trans, size - 8); - if (error == 0) - { - in_uint16_be(s, code); - switch (code) + if (trans == 0) { - /* even when the request is denied the reply will hold 3 as the command. */ - case 3: - error = xrdp_mm_process_login_response(self, s); - break; - default: - xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman"); - g_writeln("Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code); - cleanup_sesman_connection(self); - break; + return 1; } - } - return error; + self = (struct xrdp_mm *)(trans->callback_data); + s = trans_get_in_s(trans); + + if (s == 0) + { + return 1; + } + + in_uint32_be(s, version); + in_uint32_be(s, size); + error = trans_force_read(trans, size - 8); + + if (error == 0) + { + in_uint16_be(s, code); + + switch (code) + { + /* even when the request is denied the reply will hold 3 as the command. */ + case 3: + error = xrdp_mm_process_login_response(self, s); + break; + default: + xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman"); + g_writeln("Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code); + cleanup_sesman_connection(self); + break; + } + } + + return error; } #ifdef ACCESS @@ -969,104 +1059,112 @@ xrdp_mm_sesman_data_in(struct trans* trans) /* return 0 on success */ int access_control(char *username, char *password, char *srv) { - int reply; - int rec = 1; // failure - struct stream* in_s; - struct stream* out_s; - unsigned long version; - unsigned short int dummy; - unsigned short int ok; - unsigned short int code; - unsigned long size; - int index; - int socket = g_tcp_socket(); - if (socket > 0) - { - /* we use a blocking socket here */ - reply = g_tcp_connect(socket, srv, "3350"); - if (reply == 0) - { - make_stream(in_s); - init_stream(in_s, 500); - make_stream(out_s); - init_stream(out_s, 500); - s_push_layer(out_s, channel_hdr, 8); - out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/ - index = g_strlen(username); - out_uint16_be(out_s, index); - out_uint8a(out_s, username, index); + int reply; + int rec = 1; // failure + struct stream *in_s; + struct stream *out_s; + unsigned long version; + unsigned short int dummy; + unsigned short int ok; + unsigned short int code; + unsigned long size; + int index; + int socket = g_tcp_socket(); - index = g_strlen(password); - out_uint16_be(out_s, index); - out_uint8a(out_s, password, index); - s_mark_end(out_s); - s_pop_layer(out_s, channel_hdr); - out_uint32_be(out_s, 0); /* version */ - index = (int)(out_s->end - out_s->data); - out_uint32_be(out_s, index); /* size */ - /* g_writeln("Number of data to send : %d",index); */ - reply = g_tcp_send(socket, out_s->data, index, 0); - free_stream(out_s); - if (reply > 0) - { - /* We wait in 5 sec for a reply from sesman*/ - if (g_tcp_can_recv(socket, 5000)) + if (socket > 0) + { + /* we use a blocking socket here */ + reply = g_tcp_connect(socket, srv, "3350"); + + if (reply == 0) { - reply = g_tcp_recv(socket, in_s->end, 500, 0); - if (reply > 0) - { - in_s->end = in_s->end + reply; - in_uint32_be(in_s, version); - /*g_writeln("Version number in reply from sesman: %d",version) ; */ - in_uint32_be(in_s, size); - if ((size == 14) && (version == 0)) + make_stream(in_s); + init_stream(in_s, 500); + make_stream(out_s); + init_stream(out_s, 500); + s_push_layer(out_s, channel_hdr, 8); + out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/ + index = g_strlen(username); + out_uint16_be(out_s, index); + out_uint8a(out_s, username, index); + + index = g_strlen(password); + out_uint16_be(out_s, index); + out_uint8a(out_s, password, index); + s_mark_end(out_s); + s_pop_layer(out_s, channel_hdr); + out_uint32_be(out_s, 0); /* version */ + index = (int)(out_s->end - out_s->data); + out_uint32_be(out_s, index); /* size */ + /* g_writeln("Number of data to send : %d",index); */ + reply = g_tcp_send(socket, out_s->data, index, 0); + free_stream(out_s); + + if (reply > 0) { - in_uint16_be(in_s, code); - in_uint16_be(in_s, ok); - in_uint16_be(in_s, dummy); - if (code != 4) - { - log_message(LOG_LEVEL_ERROR, "Returned cmd code from " - "sesman is corrupt"); - } - else - { - rec = ok; /* here we read the reply from the access control */ - } + /* We wait in 5 sec for a reply from sesman*/ + if (g_tcp_can_recv(socket, 5000)) + { + reply = g_tcp_recv(socket, in_s->end, 500, 0); + + if (reply > 0) + { + in_s->end = in_s->end + reply; + in_uint32_be(in_s, version); + /*g_writeln("Version number in reply from sesman: %d",version) ; */ + in_uint32_be(in_s, size); + + if ((size == 14) && (version == 0)) + { + in_uint16_be(in_s, code); + in_uint16_be(in_s, ok); + in_uint16_be(in_s, dummy); + + if (code != 4) + { + log_message(LOG_LEVEL_ERROR, "Returned cmd code from " + "sesman is corrupt"); + } + else + { + rec = ok; /* here we read the reply from the access control */ + } + } + else + { + log_message(LOG_LEVEL_ERROR, "Corrupt reply size or " + "version from sesman: %d", size); + } + } + else + { + log_message(LOG_LEVEL_ERROR, "No data received from sesman"); + } + } + else + { + log_message(LOG_LEVEL_ERROR, "Timeout when waiting for sesman"); + } } else { - log_message(LOG_LEVEL_ERROR, "Corrupt reply size or " - "version from sesman: %d", size); + log_message(LOG_LEVEL_ERROR, "No success sending to sesman"); } - } - else - { - log_message(LOG_LEVEL_ERROR, "No data received from sesman"); - } + + free_stream(in_s); + g_tcp_close(socket); } else { - log_message(LOG_LEVEL_ERROR, "Timeout when waiting for sesman"); + log_message(LOG_LEVEL_ERROR, "Failure connecting to socket sesman"); } - } - else - { - log_message(LOG_LEVEL_ERROR, "No success sending to sesman"); - } - free_stream(in_s); - g_tcp_close(socket); } else { - log_message(LOG_LEVEL_ERROR, "Failure connecting to socket sesman"); + log_message(LOG_LEVEL_ERROR, "Failure creating socket - for access control"); } - } - else - { - log_message(LOG_LEVEL_ERROR, "Failure creating socket - for access control"); - } - return rec; + + return rec; } #endif @@ -1074,1134 +1172,1244 @@ int access_control(char *username, char *password, char *srv) /* This routine clears all states to make sure that our next login will be * as expected. If the user does not press ok on the log window and try to * connect again we must make sure that no previous information is stored.*/ -void cleanup_states(struct xrdp_mm* self) +void cleanup_states(struct xrdp_mm *self) { - if (self != NULL) - { - self-> connected_state = 0; /* true if connected to sesman else false */ - self-> sesman_trans = NULL; /* connection to sesman */ - self-> sesman_trans_up = 0; /* true once connected to sesman */ - self-> delete_sesman_trans = 0; /* boolean set when done with sesman connection */ - self-> display = 0; /* 10 for :10.0, 11 for :11.0, etc */ - self-> code = 0; /* 0 Xvnc session 10 X11rdp session */ - self-> sesman_controlled = 0; /* true if this is a sesman session */ - self-> chan_trans = NULL; /* connection to chansrv */ - self-> chan_trans_up = 0; /* true once connected to chansrv */ - self-> delete_chan_trans = 0; /* boolean set when done with channel connection */ - self-> usechansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */ - } + if (self != NULL) + { + self-> connected_state = 0; /* true if connected to sesman else false */ + self-> sesman_trans = NULL; /* connection to sesman */ + self-> sesman_trans_up = 0; /* true once connected to sesman */ + self-> delete_sesman_trans = 0; /* boolean set when done with sesman connection */ + self-> display = 0; /* 10 for :10.0, 11 for :11.0, etc */ + self-> code = 0; /* 0 Xvnc session 10 X11rdp session */ + self-> sesman_controlled = 0; /* true if this is a sesman session */ + self-> chan_trans = NULL; /* connection to chansrv */ + self-> chan_trans_up = 0; /* true once connected to chansrv */ + self-> delete_chan_trans = 0; /* boolean set when done with channel connection */ + self-> usechansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */ + } } /*****************************************************************************/ int APP_CC -xrdp_mm_connect(struct xrdp_mm* self) +xrdp_mm_connect(struct xrdp_mm *self) { - struct list* names; - struct list* values; - int index; - int count; - int ok; - int rv; - char* name; - char* value; - char ip[256]; - char errstr[256]; - char text[256]; - char port[8]; - char chansrvport[256]; + struct list *names; + struct list *values; + int index; + int count; + int ok; + int rv; + char *name; + char *value; + char ip[256]; + char errstr[256]; + char text[256]; + char port[8]; + char chansrvport[256]; #ifdef ACCESS - int use_pam_auth = 0; - char pam_auth_sessionIP[256]; - char pam_auth_password[256]; - char pam_auth_username[256]; - char username[256]; - char password[256]; - username[0] = 0; - password[0] = 0; + int use_pam_auth = 0; + char pam_auth_sessionIP[256]; + char pam_auth_password[256]; + char pam_auth_username[256]; + char username[256]; + char password[256]; + username[0] = 0; + password[0] = 0; #endif - /* make sure we start in correct state */ - cleanup_states(self); - g_memset(ip, 0, sizeof(ip)); - g_memset(errstr, 0, sizeof(errstr)); - g_memset(text, 0, sizeof(text)); - g_memset(port, 0, sizeof(port)); - g_memset(chansrvport, 0, sizeof(chansrvport)); - rv = 0; /* success */ - names = self->login_names; - values = self->login_values; - count = names->count; - for (index = 0; index < count; index++) - { - name = (char*)list_get_item(names, index); - value = (char*)list_get_item(values, index); - if (g_strcasecmp(name, "ip") == 0) - { - g_strncpy(ip, value, 255); - } - else if (g_strcasecmp(name, "port") == 0) - { - if (g_strcasecmp(value, "-1") == 0) - { - self->sesman_controlled = 1; - } - } -#ifdef ACCESS - else if (g_strcasecmp(name, "pamusername") == 0) - { - use_pam_auth = 1; - g_strncpy(pam_auth_username, value, 255); - } - else if (g_strcasecmp(name, "pamsessionmng") == 0) - { - g_strncpy(pam_auth_sessionIP, value, 255); - } - else if (g_strcasecmp(name, "pampassword") == 0) - { - g_strncpy(pam_auth_password, value, 255); - } - else if (g_strcasecmp(name, "password") == 0) - { - g_strncpy(password, value, 255); - } - else if (g_strcasecmp(name, "username") == 0) - { - g_strncpy(username, value, 255); - } -#endif - else if (g_strcasecmp(name, "chansrvport") == 0) - { - g_strncpy(chansrvport, value, 255); - self->usechansrv = 1; - } - } -#ifdef ACCESS - if (use_pam_auth) - { - int reply; - char replytxt[80]; - char replymessage[4][80] = {"Ok","Sesman connect failure","User or password error","Privilege group error"}; - xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control..."); - /* g_writeln("we use pam modules to check if we can approve this user"); */ - if (!g_strncmp(pam_auth_username, "same", 255)) - { - log_message(LOG_LEVEL_DEBUG, "pamusername copied from username - same: %s", username); - g_strncpy(pam_auth_username,username, 255); - } - if (!g_strncmp(pam_auth_password, "same", 255)) - { - log_message(LOG_LEVEL_DEBUG,"pam_auth_password copied from username - same: %s", password); - g_strncpy(pam_auth_password, password, 255); - } - /* access_control return 0 on success */ - reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP); - if (reply >= 0 && reply < 4) - { - g_sprintf(replytxt,"Reply from access control: %s", replymessage[reply]); - } - else - { - g_sprintf(replytxt,"Reply from access control undefined"); - } - xrdp_wm_log_msg(self->wm,replytxt); - log_message(LOG_LEVEL_INFO,replytxt); - if (reply != 0) - { - rv = 1; - return rv; - } - } -#endif - if (self->sesman_controlled) - { - ok = 0; - trans_delete(self->sesman_trans); - self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192); - xrdp_mm_get_sesman_port(port, sizeof(port)); - g_snprintf(text, 255, "connecting to sesman ip %s port %s", ip, port); - xrdp_wm_log_msg(self->wm, text); - /* xrdp_mm_sesman_data_in is the callback that is called when data arrives */ - self->sesman_trans->trans_data_in = xrdp_mm_sesman_data_in; - self->sesman_trans->header_size = 8; - self->sesman_trans->callback_data = self; - /* try to connect up to 4 times */ - for (index = 0; index < 4; index++) - { - if (trans_connect(self->sesman_trans, ip, port, 3000) == 0) - { - self->sesman_trans_up = 1; - ok = 1; - break; - } - g_sleep(1000); - g_writeln("xrdp_mm_connect: connect failed " - "trying again..."); - } - if (ok) - { - /* fully connect */ - xrdp_wm_log_msg(self->wm, "sesman connect ok"); - self->connected_state = 1; - rv = xrdp_mm_send_login(self); - } - else - { - g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s", - ip, port); - xrdp_wm_log_msg(self->wm, errstr); - trans_delete(self->sesman_trans); - self->sesman_trans = 0; - self->sesman_trans_up = 0; - rv = 1; - } - } - else /* no sesman */ - { - if (xrdp_mm_setup_mod1(self) == 0) - { - if (xrdp_mm_setup_mod2(self) == 0) - { - xrdp_wm_set_login_mode(self->wm, 10); - rv = 0; /*sucess*/ - } - else - { - /* connect error */ - g_snprintf(errstr, 255, "Failure to connect to: %s", ip); - xrdp_wm_log_msg(self->wm, errstr); - rv = 1; /* failure */ - } - } - else - { - g_writeln("Failure setting up module"); - } - if (self->wm->login_mode != 10) - { - xrdp_wm_set_login_mode(self->wm, 11); - xrdp_mm_module_cleanup(self); - rv = 1; /* failure */ - } - } + /* make sure we start in correct state */ + cleanup_states(self); + g_memset(ip, 0, sizeof(ip)); + g_memset(errstr, 0, sizeof(errstr)); + g_memset(text, 0, sizeof(text)); + g_memset(port, 0, sizeof(port)); + g_memset(chansrvport, 0, sizeof(chansrvport)); + rv = 0; /* success */ + names = self->login_names; + values = self->login_values; + count = names->count; - if ((self->wm->login_mode == 10) && (self->sesman_controlled == 0) && - (self->usechansrv != 0)) - { - /* if sesman controlled, this will connect later */ - xrdp_mm_connect_chansrv(self, "", chansrvport); - } - g_writeln("returnvalue from xrdp_mm_connect %d", rv); + for (index = 0; index < count; index++) + { + name = (char *)list_get_item(names, index); + value = (char *)list_get_item(values, index); - return rv; + if (g_strcasecmp(name, "ip") == 0) + { + g_strncpy(ip, value, 255); + } + else if (g_strcasecmp(name, "port") == 0) + { + if (g_strcasecmp(value, "-1") == 0) + { + self->sesman_controlled = 1; + } + } + +#ifdef ACCESS + else if (g_strcasecmp(name, "pamusername") == 0) + { + use_pam_auth = 1; + g_strncpy(pam_auth_username, value, 255); + } + else if (g_strcasecmp(name, "pamsessionmng") == 0) + { + g_strncpy(pam_auth_sessionIP, value, 255); + } + else if (g_strcasecmp(name, "pampassword") == 0) + { + g_strncpy(pam_auth_password, value, 255); + } + else if (g_strcasecmp(name, "password") == 0) + { + g_strncpy(password, value, 255); + } + else if (g_strcasecmp(name, "username") == 0) + { + g_strncpy(username, value, 255); + } + +#endif + else if (g_strcasecmp(name, "chansrvport") == 0) + { + g_strncpy(chansrvport, value, 255); + self->usechansrv = 1; + } + } + +#ifdef ACCESS + + if (use_pam_auth) + { + int reply; + char replytxt[80]; + char replymessage[4][80] = {"Ok", "Sesman connect failure", "User or password error", "Privilege group error"}; + xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control..."); + + /* g_writeln("we use pam modules to check if we can approve this user"); */ + if (!g_strncmp(pam_auth_username, "same", 255)) + { + log_message(LOG_LEVEL_DEBUG, "pamusername copied from username - same: %s", username); + g_strncpy(pam_auth_username, username, 255); + } + + if (!g_strncmp(pam_auth_password, "same", 255)) + { + log_message(LOG_LEVEL_DEBUG, "pam_auth_password copied from username - same: %s", password); + g_strncpy(pam_auth_password, password, 255); + } + + /* access_control return 0 on success */ + reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP); + + if (reply >= 0 && reply < 4) + { + g_sprintf(replytxt, "Reply from access control: %s", replymessage[reply]); + } + else + { + g_sprintf(replytxt, "Reply from access control undefined"); + } + + xrdp_wm_log_msg(self->wm, replytxt); + log_message(LOG_LEVEL_INFO, replytxt); + + if (reply != 0) + { + rv = 1; + return rv; + } + } + +#endif + + if (self->sesman_controlled) + { + ok = 0; + trans_delete(self->sesman_trans); + self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192); + xrdp_mm_get_sesman_port(port, sizeof(port)); + g_snprintf(text, 255, "connecting to sesman ip %s port %s", ip, port); + xrdp_wm_log_msg(self->wm, text); + /* xrdp_mm_sesman_data_in is the callback that is called when data arrives */ + self->sesman_trans->trans_data_in = xrdp_mm_sesman_data_in; + self->sesman_trans->header_size = 8; + self->sesman_trans->callback_data = self; + + /* try to connect up to 4 times */ + for (index = 0; index < 4; index++) + { + if (trans_connect(self->sesman_trans, ip, port, 3000) == 0) + { + self->sesman_trans_up = 1; + ok = 1; + break; + } + + g_sleep(1000); + g_writeln("xrdp_mm_connect: connect failed " + "trying again..."); + } + + if (ok) + { + /* fully connect */ + xrdp_wm_log_msg(self->wm, "sesman connect ok"); + self->connected_state = 1; + rv = xrdp_mm_send_login(self); + } + else + { + g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s", + ip, port); + xrdp_wm_log_msg(self->wm, errstr); + trans_delete(self->sesman_trans); + self->sesman_trans = 0; + self->sesman_trans_up = 0; + rv = 1; + } + } + else /* no sesman */ + { + if (xrdp_mm_setup_mod1(self) == 0) + { + if (xrdp_mm_setup_mod2(self) == 0) + { + xrdp_wm_set_login_mode(self->wm, 10); + rv = 0; /*sucess*/ + } + else + { + /* connect error */ + g_snprintf(errstr, 255, "Failure to connect to: %s", ip); + xrdp_wm_log_msg(self->wm, errstr); + rv = 1; /* failure */ + } + } + else + { + g_writeln("Failure setting up module"); + } + + if (self->wm->login_mode != 10) + { + xrdp_wm_set_login_mode(self->wm, 11); + xrdp_mm_module_cleanup(self); + rv = 1; /* failure */ + } + } + + if ((self->wm->login_mode == 10) && (self->sesman_controlled == 0) && + (self->usechansrv != 0)) + { + /* if sesman controlled, this will connect later */ + xrdp_mm_connect_chansrv(self, "", chansrvport); + } + + g_writeln("returnvalue from xrdp_mm_connect %d", rv); + + return rv; } /*****************************************************************************/ int APP_CC -xrdp_mm_get_wait_objs(struct xrdp_mm* self, - tbus* read_objs, int* rcount, - tbus* write_objs, int* wcount, int* timeout) +xrdp_mm_get_wait_objs(struct xrdp_mm *self, + tbus *read_objs, int *rcount, + tbus *write_objs, int *wcount, int *timeout) { - int rv = 0; + int rv = 0; - if (self == 0) - { - return 0; - } - rv = 0; - if ((self->sesman_trans != 0) && self->sesman_trans_up) - { - trans_get_wait_objs(self->sesman_trans, read_objs, rcount); - } - if ((self->chan_trans != 0) && self->chan_trans_up) - { - trans_get_wait_objs(self->chan_trans, read_objs, rcount); - } - if (self->mod != 0) - { - if (self->mod->mod_get_wait_objs != 0) + if (self == 0) { - rv = self->mod->mod_get_wait_objs(self->mod, read_objs, rcount, - write_objs, wcount, timeout); + return 0; } - } - return rv; + rv = 0; + + if ((self->sesman_trans != 0) && self->sesman_trans_up) + { + trans_get_wait_objs(self->sesman_trans, read_objs, rcount); + } + + if ((self->chan_trans != 0) && self->chan_trans_up) + { + trans_get_wait_objs(self->chan_trans, read_objs, rcount); + } + + if (self->mod != 0) + { + if (self->mod->mod_get_wait_objs != 0) + { + rv = self->mod->mod_get_wait_objs(self->mod, read_objs, rcount, + write_objs, wcount, timeout); + } + } + + return rv; } /*****************************************************************************/ int APP_CC -xrdp_mm_check_wait_objs(struct xrdp_mm* self) +xrdp_mm_check_wait_objs(struct xrdp_mm *self) { - int rv; + int rv; - if (self == 0) - { - return 0; - } - rv = 0; - if ((self->sesman_trans != 0) && self->sesman_trans_up) - { - if (trans_check_wait_objs(self->sesman_trans) != 0) + if (self == 0) { - self->delete_sesman_trans = 1; + return 0; } - } - if ((self->chan_trans != 0) && self->chan_trans_up) - { - if (trans_check_wait_objs(self->chan_trans) != 0) - { - self->delete_chan_trans = 1; - } - } - if (self->mod != 0) - { - if (self->mod->mod_check_wait_objs != 0) - { - rv = self->mod->mod_check_wait_objs(self->mod); - } - } - if (self->delete_sesman_trans) - { - trans_delete(self->sesman_trans); - self->sesman_trans = 0; - self->sesman_trans_up = 0; - self->delete_sesman_trans = 0; - } - if (self->delete_chan_trans) - { - trans_delete(self->chan_trans); - self->chan_trans = 0; - self->chan_trans_up = 0; - self->delete_chan_trans = 0; - } - return rv; + rv = 0; + + if ((self->sesman_trans != 0) && self->sesman_trans_up) + { + if (trans_check_wait_objs(self->sesman_trans) != 0) + { + self->delete_sesman_trans = 1; + } + } + + if ((self->chan_trans != 0) && self->chan_trans_up) + { + if (trans_check_wait_objs(self->chan_trans) != 0) + { + self->delete_chan_trans = 1; + } + } + + if (self->mod != 0) + { + if (self->mod->mod_check_wait_objs != 0) + { + rv = self->mod->mod_check_wait_objs(self->mod); + } + } + + if (self->delete_sesman_trans) + { + trans_delete(self->sesman_trans); + self->sesman_trans = 0; + self->sesman_trans_up = 0; + self->delete_sesman_trans = 0; + } + + if (self->delete_chan_trans) + { + trans_delete(self->chan_trans); + self->chan_trans = 0; + self->chan_trans_up = 0; + self->delete_chan_trans = 0; + } + + return rv; } #if 0 /*****************************************************************************/ -struct xrdp_painter* APP_CC -get_painter(struct xrdp_mod* mod) +struct xrdp_painter *APP_CC +get_painter(struct xrdp_mod *mod) { - struct xrdp_wm* wm; - struct xrdp_painter* p; + struct xrdp_wm *wm; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { - wm = (struct xrdp_wm*)(mod->wm); - p = xrdp_painter_create(wm, wm->session); - mod->painter = (tintptr)p; - } - return p; + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + wm = (struct xrdp_wm *)(mod->wm); + p = xrdp_painter_create(wm, wm->session); + mod->painter = (tintptr)p; + } + + return p; } #endif /*****************************************************************************/ int DEFAULT_CC -server_begin_update(struct xrdp_mod* mod) +server_begin_update(struct xrdp_mod *mod) { - struct xrdp_wm* wm; - struct xrdp_painter* p; + struct xrdp_wm *wm; + struct xrdp_painter *p; - wm = (struct xrdp_wm*)(mod->wm); - p = xrdp_painter_create(wm, wm->session); - xrdp_painter_begin_update(p); - mod->painter = (long)p; - return 0; + wm = (struct xrdp_wm *)(mod->wm); + p = xrdp_painter_create(wm, wm->session); + xrdp_painter_begin_update(p); + mod->painter = (long)p; + return 0; } /*****************************************************************************/ int DEFAULT_CC -server_end_update(struct xrdp_mod* mod) +server_end_update(struct xrdp_mod *mod) { - struct xrdp_painter* p; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + xrdp_painter_end_update(p); + xrdp_painter_delete(p); + mod->painter = 0; return 0; - } - xrdp_painter_end_update(p); - xrdp_painter_delete(p); - mod->painter = 0; - return 0; } /*****************************************************************************/ /* got bell signal... try to send to client */ int DEFAULT_CC -server_bell_trigger(struct xrdp_mod* mod) +server_bell_trigger(struct xrdp_mod *mod) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - xrdp_wm_send_bell(wm); - return 0; -} - - -/*****************************************************************************/ -int DEFAULT_CC -server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy) -{ - struct xrdp_wm* wm; - struct xrdp_painter* p; - - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { + wm = (struct xrdp_wm *)(mod->wm); + xrdp_wm_send_bell(wm); + return 0; +} + + +/*****************************************************************************/ +int DEFAULT_CC +server_fill_rect(struct xrdp_mod *mod, int x, int y, int cx, int cy) +{ + struct xrdp_wm *wm; + struct xrdp_painter *p; + + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + wm = (struct xrdp_wm *)(mod->wm); + xrdp_painter_fill_rect(p, wm->target_surface, x, y, cx, cy); return 0; - } - wm = (struct xrdp_wm*)(mod->wm); - xrdp_painter_fill_rect(p, wm->target_surface, x, y, cx, cy); - return 0; } /*****************************************************************************/ int DEFAULT_CC -server_screen_blt(struct xrdp_mod* mod, int x, int y, int cx, int cy, +server_screen_blt(struct xrdp_mod *mod, int x, int y, int cx, int cy, int srcx, int srcy) { - struct xrdp_wm* wm; - struct xrdp_painter* p; + struct xrdp_wm *wm; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + wm = (struct xrdp_wm *)(mod->wm); + p->rop = 0xcc; + xrdp_painter_copy(p, wm->screen, wm->target_surface, x, y, cx, cy, srcx, srcy); return 0; - } - wm = (struct xrdp_wm*)(mod->wm); - p->rop = 0xcc; - xrdp_painter_copy(p, wm->screen, wm->target_surface, x, y, cx, cy, srcx, srcy); - return 0; } /*****************************************************************************/ int DEFAULT_CC -server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy, - char* data, int width, int height, int srcx, int srcy) +server_paint_rect(struct xrdp_mod *mod, int x, int y, int cx, int cy, + char *data, int width, int height, int srcx, int srcy) { - struct xrdp_wm* wm; - struct xrdp_bitmap* b; - struct xrdp_painter* p; + struct xrdp_wm *wm; + struct xrdp_bitmap *b; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + wm = (struct xrdp_wm *)(mod->wm); + b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp, data, wm); + xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy); + xrdp_bitmap_delete(b); return 0; - } - wm = (struct xrdp_wm*)(mod->wm); - b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp, data, wm); - xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy); - xrdp_bitmap_delete(b); - return 0; } /*****************************************************************************/ int DEFAULT_CC -server_set_pointer(struct xrdp_mod* mod, int x, int y, - char* data, char* mask) +server_set_pointer(struct xrdp_mod *mod, int x, int y, + char *data, char *mask) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - xrdp_wm_pointer(wm, data, mask, x, y); - return 0; -} - -/*****************************************************************************/ -int DEFAULT_CC -server_palette(struct xrdp_mod* mod, int* palette) -{ - struct xrdp_wm* wm; - - wm = (struct xrdp_wm*)(mod->wm); - if (g_memcmp(wm->palette, palette, 255 * sizeof(int)) != 0) - { - g_memcpy(wm->palette, palette, 256 * sizeof(int)); - xrdp_wm_send_palette(wm); - } - return 0; -} - -/*****************************************************************************/ -int DEFAULT_CC -server_msg(struct xrdp_mod* mod, char* msg, int code) -{ - struct xrdp_wm* wm; - - if (code == 1) - { - g_writeln(msg); + wm = (struct xrdp_wm *)(mod->wm); + xrdp_wm_pointer(wm, data, mask, x, y); return 0; - } - wm = (struct xrdp_wm*)(mod->wm); - return xrdp_wm_log_msg(wm, msg); } /*****************************************************************************/ int DEFAULT_CC -server_is_term(struct xrdp_mod* mod) +server_palette(struct xrdp_mod *mod, int *palette) { - return g_is_term(); -} + struct xrdp_wm *wm; -/*****************************************************************************/ -int DEFAULT_CC -server_set_clip(struct xrdp_mod* mod, int x, int y, int cx, int cy) -{ - struct xrdp_painter* p; + wm = (struct xrdp_wm *)(mod->wm); + + if (g_memcmp(wm->palette, palette, 255 * sizeof(int)) != 0) + { + g_memcpy(wm->palette, palette, 256 * sizeof(int)); + xrdp_wm_send_palette(wm); + } - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { return 0; - } - return xrdp_painter_set_clip(p, x, y, cx, cy); } /*****************************************************************************/ int DEFAULT_CC -server_reset_clip(struct xrdp_mod* mod) +server_msg(struct xrdp_mod *mod, char *msg, int code) { - struct xrdp_painter* p; + struct xrdp_wm *wm; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { - return 0; - } - return xrdp_painter_clr_clip(p); + if (code == 1) + { + g_writeln(msg); + return 0; + } + + wm = (struct xrdp_wm *)(mod->wm); + return xrdp_wm_log_msg(wm, msg); } /*****************************************************************************/ int DEFAULT_CC -server_set_fgcolor(struct xrdp_mod* mod, int fgcolor) +server_is_term(struct xrdp_mod *mod) { - struct xrdp_painter* p; - - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { - return 0; - } - p->fg_color = fgcolor; - p->pen.color = p->fg_color; - return 0; + return g_is_term(); } /*****************************************************************************/ int DEFAULT_CC -server_set_bgcolor(struct xrdp_mod* mod, int bgcolor) +server_set_clip(struct xrdp_mod *mod, int x, int y, int cx, int cy) { - struct xrdp_painter* p; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { - return 0; - } - p->bg_color = bgcolor; - return 0; + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + return xrdp_painter_set_clip(p, x, y, cx, cy); } /*****************************************************************************/ int DEFAULT_CC -server_set_opcode(struct xrdp_mod* mod, int opcode) +server_reset_clip(struct xrdp_mod *mod) { - struct xrdp_painter* p; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { - return 0; - } - p->rop = opcode; - return 0; + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + return xrdp_painter_clr_clip(p); } /*****************************************************************************/ int DEFAULT_CC -server_set_mixmode(struct xrdp_mod* mod, int mixmode) +server_set_fgcolor(struct xrdp_mod *mod, int fgcolor) { - struct xrdp_painter* p; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + p->fg_color = fgcolor; + p->pen.color = p->fg_color; return 0; - } - p->mix_mode = mixmode; - return 0; } /*****************************************************************************/ int DEFAULT_CC -server_set_brush(struct xrdp_mod* mod, int x_orgin, int y_orgin, - int style, char* pattern) +server_set_bgcolor(struct xrdp_mod *mod, int bgcolor) { - struct xrdp_painter* p; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + p->bg_color = bgcolor; return 0; - } - p->brush.x_orgin = x_orgin; - p->brush.y_orgin = y_orgin; - p->brush.style = style; - g_memcpy(p->brush.pattern, pattern, 8); - return 0; } /*****************************************************************************/ int DEFAULT_CC -server_set_pen(struct xrdp_mod* mod, int style, int width) +server_set_opcode(struct xrdp_mod *mod, int opcode) { - struct xrdp_painter* p; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + p->rop = opcode; return 0; - } - p->pen.style = style; - p->pen.width = width; - return 0; } /*****************************************************************************/ int DEFAULT_CC -server_draw_line(struct xrdp_mod* mod, int x1, int y1, int x2, int y2) +server_set_mixmode(struct xrdp_mod *mod, int mixmode) { - struct xrdp_wm* wm; - struct xrdp_painter* p; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + p->mix_mode = mixmode; return 0; - } - wm = (struct xrdp_wm*)(mod->wm); - return xrdp_painter_line(p, wm->target_surface, x1, y1, x2, y2); } /*****************************************************************************/ int DEFAULT_CC -server_add_char(struct xrdp_mod* mod, int font, int charactor, +server_set_brush(struct xrdp_mod *mod, int x_orgin, int y_orgin, + int style, char *pattern) +{ + struct xrdp_painter *p; + + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + p->brush.x_orgin = x_orgin; + p->brush.y_orgin = y_orgin; + p->brush.style = style; + g_memcpy(p->brush.pattern, pattern, 8); + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_set_pen(struct xrdp_mod *mod, int style, int width) +{ + struct xrdp_painter *p; + + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + p->pen.style = style; + p->pen.width = width; + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_draw_line(struct xrdp_mod *mod, int x1, int y1, int x2, int y2) +{ + struct xrdp_wm *wm; + struct xrdp_painter *p; + + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + wm = (struct xrdp_wm *)(mod->wm); + return xrdp_painter_line(p, wm->target_surface, x1, y1, x2, y2); +} + +/*****************************************************************************/ +int DEFAULT_CC +server_add_char(struct xrdp_mod *mod, int font, int charactor, int offset, int baseline, - int width, int height, char* data) + int width, int height, char *data) { - struct xrdp_font_char fi; + struct xrdp_font_char fi; - fi.offset = offset; - fi.baseline = baseline; - fi.width = width; - fi.height = height; - fi.incby = 0; - fi.data = data; - return libxrdp_orders_send_font(((struct xrdp_wm*)mod->wm)->session, - &fi, font, charactor); + fi.offset = offset; + fi.baseline = baseline; + fi.width = width; + fi.height = height; + fi.incby = 0; + fi.data = data; + return libxrdp_orders_send_font(((struct xrdp_wm *)mod->wm)->session, + &fi, font, charactor); } /*****************************************************************************/ int DEFAULT_CC -server_draw_text(struct xrdp_mod* mod, int font, +server_draw_text(struct xrdp_mod *mod, int font, int flags, int mixmode, int clip_left, int clip_top, int clip_right, int clip_bottom, int box_left, int box_top, int box_right, int box_bottom, - int x, int y, char* data, int data_len) + int x, int y, char *data, int data_len) { - struct xrdp_wm* wm; - struct xrdp_painter* p; + struct xrdp_wm *wm; + struct xrdp_painter *p; - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { - return 0; - } - wm = (struct xrdp_wm*)(mod->wm); - return xrdp_painter_draw_text2(p, wm->target_surface, font, flags, - mixmode, clip_left, clip_top, - clip_right, clip_bottom, - box_left, box_top, - box_right, box_bottom, - x, y, data, data_len); + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + wm = (struct xrdp_wm *)(mod->wm); + return xrdp_painter_draw_text2(p, wm->target_surface, font, flags, + mixmode, clip_left, clip_top, + clip_right, clip_bottom, + box_left, box_top, + box_right, box_bottom, + x, y, data, data_len); } /*****************************************************************************/ int DEFAULT_CC -server_reset(struct xrdp_mod* mod, int width, int height, int bpp) +server_reset(struct xrdp_mod *mod, int width, int height, int bpp) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - if (wm->client_info == 0) - { - return 1; - } - /* older client can't resize */ - if (wm->client_info->build <= 419) - { + wm = (struct xrdp_wm *)(mod->wm); + + if (wm->client_info == 0) + { + return 1; + } + + /* older client can't resize */ + if (wm->client_info->build <= 419) + { + return 0; + } + + /* if same, don't need to do anything */ + if (wm->client_info->width == width && + wm->client_info->height == height && + wm->client_info->bpp == bpp) + { + return 0; + } + + /* reset lib, client_info gets updated in libxrdp_reset */ + if (libxrdp_reset(wm->session, width, height, bpp) != 0) + { + return 1; + } + + /* reset cache */ + xrdp_cache_reset(wm->cache, wm->client_info); + /* resize the main window */ + xrdp_bitmap_resize(wm->screen, wm->client_info->width, + wm->client_info->height); + /* load some stuff */ + xrdp_wm_load_static_colors_plus(wm, 0); + xrdp_wm_load_static_pointers(wm); return 0; - } - /* if same, don't need to do anything */ - if (wm->client_info->width == width && - wm->client_info->height == height && - wm->client_info->bpp == bpp) - { - return 0; - } - /* reset lib, client_info gets updated in libxrdp_reset */ - if (libxrdp_reset(wm->session, width, height, bpp) != 0) - { - return 1; - } - /* reset cache */ - xrdp_cache_reset(wm->cache, wm->client_info); - /* resize the main window */ - xrdp_bitmap_resize(wm->screen, wm->client_info->width, - wm->client_info->height); - /* load some stuff */ - xrdp_wm_load_static_colors_plus(wm, 0); - xrdp_wm_load_static_pointers(wm); - return 0; } /* read the channel section of the ini file into lists * return 1 on success 0 on failure */ -int read_allowed_channel_names(struct list* names, struct list* values) +int read_allowed_channel_names(struct list *names, struct list *values) { - int fd; - int ret = 0; - char cfg_file[256]; - int pos; - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); - if (fd > 0) - { - names->auto_free = 1; - values->auto_free = 1; - pos = 0; - /* all values in this section can be valid channel names */ - if (file_read_section(fd, "channels", names, values) == 0) + int fd; + int ret = 0; + char cfg_file[256]; + int pos; + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + fd = g_file_open(cfg_file); + + if (fd > 0) { - ret = 1; + names->auto_free = 1; + values->auto_free = 1; + pos = 0; + + /* all values in this section can be valid channel names */ + if (file_read_section(fd, "channels", names, values) == 0) + { + ret = 1; + } + else + { + g_writeln("Failure reading channel section of configuration"); + } + + g_file_close(fd); + return ret; } - else - { - g_writeln("Failure reading channel section of configuration"); - } - g_file_close(fd); - return ret; - } } /* internal function return 1 if name is in list of channels * and if the value is allowed */ int DEFAULT_CC -is_name_in_lists(char* inName, struct list* names, struct list* values) +is_name_in_lists(char *inName, struct list *names, struct list *values) { - int reply = 0; /*means not in the list*/ - int index; - char* val; - char* name; - for (index = 0; index < names->count; index++) - { - name = (char*)list_get_item(names, index); - if (name != 0) + int reply = 0; /*means not in the list*/ + int index; + char *val; + char *name; + + for (index = 0; index < names->count; index++) { - /* ex rdpdr ;rdpsnd ; drdynvc ; cliprdr */ - if (!g_strncmp(name, inName, MAX_CHANNEL_NAME)) - { - val = (char*)list_get_item(values, index); - if ((g_strcasecmp(val, "yes") == 0) || - (g_strcasecmp(val, "on") == 0) || - (g_strcasecmp(val, "true") == 0) || - (g_atoi(val) != 0)) + name = (char *)list_get_item(names, index); + + if (name != 0) { - reply = 1; + /* ex rdpdr ;rdpsnd ; drdynvc ; cliprdr */ + if (!g_strncmp(name, inName, MAX_CHANNEL_NAME)) + { + val = (char *)list_get_item(values, index); + + if ((g_strcasecmp(val, "yes") == 0) || + (g_strcasecmp(val, "on") == 0) || + (g_strcasecmp(val, "true") == 0) || + (g_atoi(val) != 0)) + { + reply = 1; + } + else + { + g_writeln("This channel is disabled: %s", name); + } + + break; /* stop loop - item found*/ + } } - else - { - g_writeln("This channel is disabled: %s", name); - } - break; /* stop loop - item found*/ - } } - } - return reply; + + return reply; } /* internal function only used once per session * creates the list of allowed channels and store the information * in wm struct */ -void init_channel_allowed(struct xrdp_wm* wm) +void init_channel_allowed(struct xrdp_wm *wm) { - int error; - int i; - char channelname[MAX_CHANNEL_NAME]; - int index = 0; - int allowindex = 0; - struct list* names; - struct list* values; - /* first reset allowedchannels */ - for (i = 0; i < MAX_NR_CHANNELS; i++) - { - /* 0 is a valid channel so we use -1 to mark the index as unused */ - wm->allowedchannels[i] = -1; - } - names = list_create(); - values = list_create(); - if (read_allowed_channel_names(names, values)) - { - do + int error; + int i; + char channelname[MAX_CHANNEL_NAME]; + int index = 0; + int allowindex = 0; + struct list *names; + struct list *values; + + /* first reset allowedchannels */ + for (i = 0; i < MAX_NR_CHANNELS; i++) { - /* libxrdp_query_channel return 1 on error*/ - error = libxrdp_query_channel(wm->session, index, channelname,NULL); - if (error == 0) - { - /* examples of channel names: rdpdr ; rdpsnd ; drdynvc ; cliprdr */ - if (is_name_in_lists(channelname, names, values)) + /* 0 is a valid channel so we use -1 to mark the index as unused */ + wm->allowedchannels[i] = -1; + } + + names = list_create(); + values = list_create(); + + if (read_allowed_channel_names(names, values)) + { + do { - g_writeln("The following channel is allowed: %s", channelname); - wm->allowedchannels[allowindex] = index; - allowindex++; - if (allowindex >= MAX_NR_CHANNELS) - { - g_writeln("Programming error in is_channel_allowed"); - error = 1; /* end loop */ - } + /* libxrdp_query_channel return 1 on error*/ + error = libxrdp_query_channel(wm->session, index, channelname, NULL); + + if (error == 0) + { + /* examples of channel names: rdpdr ; rdpsnd ; drdynvc ; cliprdr */ + if (is_name_in_lists(channelname, names, values)) + { + g_writeln("The following channel is allowed: %s", channelname); + wm->allowedchannels[allowindex] = index; + allowindex++; + + if (allowindex >= MAX_NR_CHANNELS) + { + g_writeln("Programming error in is_channel_allowed"); + error = 1; /* end loop */ + } + } + else + { + g_writeln("The following channel is not allowed: %s", channelname); + } + + index++; + } } - else - { - g_writeln("The following channel is not allowed: %s",channelname); - } - index++; - } - } while ((error == 0) && (index < MAX_NR_CHANNELS)); - } - else - { - g_writeln("Error reading channel section in inifile"); - } - list_delete(names); - list_delete(values); + while ((error == 0) && (index < MAX_NR_CHANNELS)); + } + else + { + g_writeln("Error reading channel section in inifile"); + } + + list_delete(names); + list_delete(values); } /*****************************************************************************/ /* This function returns 1 if the channelID is allowed by rule set * returns 0 if not allowed */ -int DEFAULT_CC is_channel_allowed(struct xrdp_wm* wm, int channel_id) +int DEFAULT_CC is_channel_allowed(struct xrdp_wm *wm, int channel_id) { - int i; - int reply = 0; /* not allowed */ - /* The first time each client is using this function we have to - * define the list of allowed channels */ - if (wm->allowedinitialized == 0) - { - init_channel_allowed(wm); - g_writeln("allow channel list initialized"); - wm->allowedinitialized = 1; - } - for(i = 0; i < MAX_NR_CHANNELS; i++) - { - if (channel_id == wm->allowedchannels[i]) + int i; + int reply = 0; /* not allowed */ + + /* The first time each client is using this function we have to + * define the list of allowed channels */ + if (wm->allowedinitialized == 0) { - /*g_writeln("Channel allowed: %d",channel_id);*/ - reply = 1; /*channel allowed*/ - break; + init_channel_allowed(wm); + g_writeln("allow channel list initialized"); + wm->allowedinitialized = 1; } - else if (wm->allowedchannels[i] == -1) + + for (i = 0; i < MAX_NR_CHANNELS; i++) { - /* We are in the unused space of the allowedchannels list - * We can end the loop */ - break; + if (channel_id == wm->allowedchannels[i]) + { + /*g_writeln("Channel allowed: %d",channel_id);*/ + reply = 1; /*channel allowed*/ + break; + } + else if (wm->allowedchannels[i] == -1) + { + /* We are in the unused space of the allowedchannels list + * We can end the loop */ + break; + } } - } - /*if (reply == 0) - { - g_writeln("This channel is NOT allowed: %d",channel_id) ; - }*/ - return reply; + + /*if (reply == 0) + { + g_writeln("This channel is NOT allowed: %d",channel_id) ; + }*/ + return reply; } /*****************************************************************************/ /*return 0 if the index is not found*/ int DEFAULT_CC -server_query_channel(struct xrdp_mod* mod, int index, char* channel_name, - int* channel_flags) +server_query_channel(struct xrdp_mod *mod, int index, char *channel_name, + int *channel_flags) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - if (wm->mm->usechansrv) - { - return 1; - } - return libxrdp_query_channel(wm->session, index, channel_name, - channel_flags); + wm = (struct xrdp_wm *)(mod->wm); + + if (wm->mm->usechansrv) + { + return 1; + } + + return libxrdp_query_channel(wm->session, index, channel_name, + channel_flags); } /*****************************************************************************/ /* returns -1 on error */ int DEFAULT_CC -server_get_channel_id(struct xrdp_mod* mod, char* name) +server_get_channel_id(struct xrdp_mod *mod, char *name) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - if (wm->mm->usechansrv) - { - return -1; - } - return libxrdp_get_channel_id(wm->session, name); -} + wm = (struct xrdp_wm *)(mod->wm); -/*****************************************************************************/ -int DEFAULT_CC -server_send_to_channel(struct xrdp_mod* mod, int channel_id, - char* data, int data_len, - int total_data_len, int flags) -{ - struct xrdp_wm* wm; - - wm = (struct xrdp_wm*)(mod->wm); - if (is_channel_allowed(wm, channel_id)) - { if (wm->mm->usechansrv) { - return 1; + return -1; } - return libxrdp_send_to_channel(wm->session, channel_id, data, data_len, - total_data_len, flags); - } - else - { - return 1; - } + + return libxrdp_get_channel_id(wm->session, name); } /*****************************************************************************/ int DEFAULT_CC -server_create_os_surface(struct xrdp_mod* mod, int rdpindex, - int width, int height) +server_send_to_channel(struct xrdp_mod *mod, int channel_id, + char *data, int data_len, + int total_data_len, int flags) { - struct xrdp_wm* wm; - struct xrdp_bitmap* bitmap; - int error; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - bitmap = xrdp_bitmap_create(width, height, wm->screen->bpp, - WND_TYPE_OFFSCREEN, wm); - error = xrdp_cache_add_os_bitmap(wm->cache, bitmap, rdpindex); - if (error != 0) - { - g_writeln("server_create_os_surface: xrdp_cache_add_os_bitmap failed"); - return 1; - } - bitmap->item_index = rdpindex; - bitmap->id = rdpindex; - return 0; -} + wm = (struct xrdp_wm *)(mod->wm); -/*****************************************************************************/ -int DEFAULT_CC -server_switch_os_surface(struct xrdp_mod* mod, int rdpindex) -{ - struct xrdp_wm* wm; - struct xrdp_os_bitmap_item* bi; - struct xrdp_painter* p; - - //g_writeln("server_switch_os_surface: id 0x%x", id); - wm = (struct xrdp_wm*)(mod->wm); - if (rdpindex == -1) - { - //g_writeln("server_switch_os_surface: setting target_surface to screen"); - wm->target_surface = wm->screen; - p = (struct xrdp_painter*)(mod->painter); - if (p != 0) + if (is_channel_allowed(wm, channel_id)) { - //g_writeln("setting target"); - wm_painter_set_target(p); - } - return 0; - } - bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex); - if (bi != 0) - { - //g_writeln("server_switch_os_surface: setting target_surface to rdpid %d", id); - wm->target_surface = bi->bitmap; - p = (struct xrdp_painter*)(mod->painter); - if (p != 0) - { - //g_writeln("setting target"); - wm_painter_set_target(p); - } - } - else - { - g_writeln("server_switch_os_surface: error finding id %d", rdpindex); - } - return 0; -} + if (wm->mm->usechansrv) + { + return 1; + } -/*****************************************************************************/ -int DEFAULT_CC -server_delete_os_surface(struct xrdp_mod* mod, int rdpindex) -{ - struct xrdp_wm* wm; - struct xrdp_painter* p; - - //g_writeln("server_delete_os_surface: id 0x%x", id); - wm = (struct xrdp_wm*)(mod->wm); - if (wm->target_surface->type == WND_TYPE_OFFSCREEN) - { - if (wm->target_surface->id == rdpindex) - { - g_writeln("server_delete_os_surface: setting target_surface to screen"); - wm->target_surface = wm->screen; - p = (struct xrdp_painter*)(mod->painter); - if (p != 0) - { - //g_writeln("setting target"); - wm_painter_set_target(p); - } - } - } - xrdp_cache_remove_os_bitmap(wm->cache, rdpindex); - return 0; -} - -/*****************************************************************************/ -int DEFAULT_CC -server_paint_rect_os(struct xrdp_mod* mod, int x, int y, int cx, int cy, - int rdpindex, int srcx, int srcy) -{ - struct xrdp_wm* wm; - struct xrdp_bitmap* b; - struct xrdp_painter* p; - struct xrdp_os_bitmap_item* bi; - - p = (struct xrdp_painter*)(mod->painter); - if (p == 0) - { - return 0; - } - wm = (struct xrdp_wm*)(mod->wm); - bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex); - if (bi != 0) - { - b = bi->bitmap; - xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy); - } - else - { - g_writeln("server_paint_rect_os: error finding id %d", rdpindex); - } - return 0; -} - -/*****************************************************************************/ -int DEFAULT_CC -server_set_hints(struct xrdp_mod* mod, int hints, int mask) -{ - struct xrdp_wm* wm; - - wm = (struct xrdp_wm*)(mod->wm); - if (mask & 1) - { - if (hints & 1) - { - wm->hints |= 1; + return libxrdp_send_to_channel(wm->session, channel_id, data, data_len, + total_data_len, flags); } else { - wm->hints &= ~1; + return 1; } - } - return 0; } /*****************************************************************************/ int DEFAULT_CC -server_window_new_update(struct xrdp_mod* mod, int window_id, - struct rail_window_state_order* window_state, +server_create_os_surface(struct xrdp_mod *mod, int rdpindex, + int width, int height) +{ + struct xrdp_wm *wm; + struct xrdp_bitmap *bitmap; + int error; + + wm = (struct xrdp_wm *)(mod->wm); + bitmap = xrdp_bitmap_create(width, height, wm->screen->bpp, + WND_TYPE_OFFSCREEN, wm); + error = xrdp_cache_add_os_bitmap(wm->cache, bitmap, rdpindex); + + if (error != 0) + { + g_writeln("server_create_os_surface: xrdp_cache_add_os_bitmap failed"); + return 1; + } + + bitmap->item_index = rdpindex; + bitmap->id = rdpindex; + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_switch_os_surface(struct xrdp_mod *mod, int rdpindex) +{ + struct xrdp_wm *wm; + struct xrdp_os_bitmap_item *bi; + struct xrdp_painter *p; + + //g_writeln("server_switch_os_surface: id 0x%x", id); + wm = (struct xrdp_wm *)(mod->wm); + + if (rdpindex == -1) + { + //g_writeln("server_switch_os_surface: setting target_surface to screen"); + wm->target_surface = wm->screen; + p = (struct xrdp_painter *)(mod->painter); + + if (p != 0) + { + //g_writeln("setting target"); + wm_painter_set_target(p); + } + + return 0; + } + + bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex); + + if (bi != 0) + { + //g_writeln("server_switch_os_surface: setting target_surface to rdpid %d", id); + wm->target_surface = bi->bitmap; + p = (struct xrdp_painter *)(mod->painter); + + if (p != 0) + { + //g_writeln("setting target"); + wm_painter_set_target(p); + } + } + else + { + g_writeln("server_switch_os_surface: error finding id %d", rdpindex); + } + + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_delete_os_surface(struct xrdp_mod *mod, int rdpindex) +{ + struct xrdp_wm *wm; + struct xrdp_painter *p; + + //g_writeln("server_delete_os_surface: id 0x%x", id); + wm = (struct xrdp_wm *)(mod->wm); + + if (wm->target_surface->type == WND_TYPE_OFFSCREEN) + { + if (wm->target_surface->id == rdpindex) + { + g_writeln("server_delete_os_surface: setting target_surface to screen"); + wm->target_surface = wm->screen; + p = (struct xrdp_painter *)(mod->painter); + + if (p != 0) + { + //g_writeln("setting target"); + wm_painter_set_target(p); + } + } + } + + xrdp_cache_remove_os_bitmap(wm->cache, rdpindex); + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_paint_rect_os(struct xrdp_mod *mod, int x, int y, int cx, int cy, + int rdpindex, int srcx, int srcy) +{ + struct xrdp_wm *wm; + struct xrdp_bitmap *b; + struct xrdp_painter *p; + struct xrdp_os_bitmap_item *bi; + + p = (struct xrdp_painter *)(mod->painter); + + if (p == 0) + { + return 0; + } + + wm = (struct xrdp_wm *)(mod->wm); + bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex); + + if (bi != 0) + { + b = bi->bitmap; + xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy); + } + else + { + g_writeln("server_paint_rect_os: error finding id %d", rdpindex); + } + + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_set_hints(struct xrdp_mod *mod, int hints, int mask) +{ + struct xrdp_wm *wm; + + wm = (struct xrdp_wm *)(mod->wm); + + if (mask & 1) + { + if (hints & 1) + { + wm->hints |= 1; + } + else + { + wm->hints &= ~1; + } + } + + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_window_new_update(struct xrdp_mod *mod, int window_id, + struct rail_window_state_order *window_state, int flags) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - return libxrdp_window_new_update(wm->session, window_id, - window_state, flags); + wm = (struct xrdp_wm *)(mod->wm); + return libxrdp_window_new_update(wm->session, window_id, + window_state, flags); } /*****************************************************************************/ int DEFAULT_CC -server_window_delete(struct xrdp_mod* mod, int window_id) +server_window_delete(struct xrdp_mod *mod, int window_id) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - return libxrdp_window_delete(wm->session, window_id); + wm = (struct xrdp_wm *)(mod->wm); + return libxrdp_window_delete(wm->session, window_id); } /*****************************************************************************/ int DEFAULT_CC -server_window_icon(struct xrdp_mod* mod, int window_id, int cache_entry, - int cache_id, struct rail_icon_info* icon_info, +server_window_icon(struct xrdp_mod *mod, int window_id, int cache_entry, + int cache_id, struct rail_icon_info *icon_info, int flags) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - return libxrdp_window_icon(wm->session, window_id, cache_entry, cache_id, - icon_info, flags); + wm = (struct xrdp_wm *)(mod->wm); + return libxrdp_window_icon(wm->session, window_id, cache_entry, cache_id, + icon_info, flags); } /*****************************************************************************/ int DEFAULT_CC -server_window_cached_icon(struct xrdp_mod* mod, +server_window_cached_icon(struct xrdp_mod *mod, int window_id, int cache_entry, int cache_id, int flags) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - return libxrdp_window_cached_icon(wm->session, window_id, cache_entry, - cache_id, flags); + wm = (struct xrdp_wm *)(mod->wm); + return libxrdp_window_cached_icon(wm->session, window_id, cache_entry, + cache_id, flags); } /*****************************************************************************/ int DEFAULT_CC -server_notify_new_update(struct xrdp_mod* mod, +server_notify_new_update(struct xrdp_mod *mod, int window_id, int notify_id, - struct rail_notify_state_order* notify_state, + struct rail_notify_state_order *notify_state, int flags) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - return libxrdp_notify_new_update(wm->session, window_id, notify_id, - notify_state, flags); + wm = (struct xrdp_wm *)(mod->wm); + return libxrdp_notify_new_update(wm->session, window_id, notify_id, + notify_state, flags); } /*****************************************************************************/ int DEFAULT_CC -server_notify_delete(struct xrdp_mod* mod, int window_id, +server_notify_delete(struct xrdp_mod *mod, int window_id, int notify_id) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - return libxrdp_notify_delete(wm->session, window_id, notify_id); + wm = (struct xrdp_wm *)(mod->wm); + return libxrdp_notify_delete(wm->session, window_id, notify_id); } /*****************************************************************************/ int DEFAULT_CC -server_monitored_desktop(struct xrdp_mod* mod, - struct rail_monitored_desktop_order* mdo, +server_monitored_desktop(struct xrdp_mod *mod, + struct rail_monitored_desktop_order *mdo, int flags) { - struct xrdp_wm* wm; + struct xrdp_wm *wm; - wm = (struct xrdp_wm*)(mod->wm); - return libxrdp_monitored_desktop(wm->session, mdo, flags); + wm = (struct xrdp_wm *)(mod->wm); + return libxrdp_monitored_desktop(wm->session, mdo, flags); } diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index b91be16d..0b867089 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -1,205 +1,218 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2012 - - painter, gc - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * painter, gc + */ #include "xrdp.h" /*****************************************************************************/ -struct xrdp_painter* APP_CC -xrdp_painter_create(struct xrdp_wm* wm, struct xrdp_session* session) +struct xrdp_painter *APP_CC +xrdp_painter_create(struct xrdp_wm *wm, struct xrdp_session *session) { - struct xrdp_painter* self; + struct xrdp_painter *self; - self = (struct xrdp_painter*)g_malloc(sizeof(struct xrdp_painter), 1); - self->wm = wm; - self->session = session; - self->rop = 0xcc; /* copy gota use 0xcc*/ - self->clip_children = 1; - return self; + self = (struct xrdp_painter *)g_malloc(sizeof(struct xrdp_painter), 1); + self->wm = wm; + self->session = session; + self->rop = 0xcc; /* copy gota use 0xcc*/ + self->clip_children = 1; + return self; } /*****************************************************************************/ void APP_CC -xrdp_painter_delete(struct xrdp_painter* self) +xrdp_painter_delete(struct xrdp_painter *self) { - if (self == 0) - { - return; - } - g_free(self); -} - -/*****************************************************************************/ -int APP_CC -wm_painter_set_target(struct xrdp_painter* self) -{ - int surface_index; - int index; - struct list* del_list; - - if (self->wm->target_surface->type == WND_TYPE_SCREEN) - { - if (self->wm->current_surface_index != 0xffff) + if (self == 0) { - libxrdp_orders_send_switch_os_surface(self->session, 0xffff); - self->wm->current_surface_index = 0xffff; + return; } - } - else if (self->wm->target_surface->type == WND_TYPE_OFFSCREEN) - { - surface_index = self->wm->target_surface->item_index; - if (surface_index != self->wm->current_surface_index) + + g_free(self); +} + +/*****************************************************************************/ +int APP_CC +wm_painter_set_target(struct xrdp_painter *self) +{ + int surface_index; + int index; + struct list *del_list; + + if (self->wm->target_surface->type == WND_TYPE_SCREEN) { - if (self->wm->target_surface->tab_stop == 0) /* tab_stop is hack */ - { - del_list = self->wm->cache->xrdp_os_del_list; - index = list_index_of(del_list, surface_index); - list_remove_item(del_list, index); - libxrdp_orders_send_create_os_surface(self->session, surface_index, - self->wm->target_surface->width, - self->wm->target_surface->height, - del_list); - self->wm->target_surface->tab_stop = 1; - list_clear(del_list); - } - libxrdp_orders_send_switch_os_surface(self->session, surface_index); - self->wm->current_surface_index = surface_index; + if (self->wm->current_surface_index != 0xffff) + { + libxrdp_orders_send_switch_os_surface(self->session, 0xffff); + self->wm->current_surface_index = 0xffff; + } + } + else if (self->wm->target_surface->type == WND_TYPE_OFFSCREEN) + { + surface_index = self->wm->target_surface->item_index; + + if (surface_index != self->wm->current_surface_index) + { + if (self->wm->target_surface->tab_stop == 0) /* tab_stop is hack */ + { + del_list = self->wm->cache->xrdp_os_del_list; + index = list_index_of(del_list, surface_index); + list_remove_item(del_list, index); + libxrdp_orders_send_create_os_surface(self->session, surface_index, + self->wm->target_surface->width, + self->wm->target_surface->height, + del_list); + self->wm->target_surface->tab_stop = 1; + list_clear(del_list); + } + + libxrdp_orders_send_switch_os_surface(self->session, surface_index); + self->wm->current_surface_index = surface_index; + } + } + else + { + g_writeln("xrdp_painter_begin_update: bad target_surface"); } - } - else - { - g_writeln("xrdp_painter_begin_update: bad target_surface"); - } - return 0; -} -/*****************************************************************************/ -int APP_CC -xrdp_painter_begin_update(struct xrdp_painter* self) -{ - if (self == 0) - { return 0; - } - libxrdp_orders_init(self->session); - wm_painter_set_target(self); - return 0; } /*****************************************************************************/ int APP_CC -xrdp_painter_end_update(struct xrdp_painter* self) +xrdp_painter_begin_update(struct xrdp_painter *self) { - if (self == 0) - { + if (self == 0) + { + return 0; + } + + libxrdp_orders_init(self->session); + wm_painter_set_target(self); return 0; - } - libxrdp_orders_send(self->session); - return 0; } /*****************************************************************************/ int APP_CC -xrdp_painter_font_needed(struct xrdp_painter* self) +xrdp_painter_end_update(struct xrdp_painter *self) { - if (self->font == 0) - { - self->font = self->wm->default_font; - } - return 0; + if (self == 0) + { + return 0; + } + + libxrdp_orders_send(self->session); + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_painter_font_needed(struct xrdp_painter *self) +{ + if (self->font == 0) + { + self->font = self->wm->default_font; + } + + return 0; } #if 0 /*****************************************************************************/ /* returns boolean, true if there is something to draw */ static int APP_CC -xrdp_painter_clip_adj(struct xrdp_painter* self, int* x, int* y, - int* cx, int* cy) +xrdp_painter_clip_adj(struct xrdp_painter *self, int *x, int *y, + int *cx, int *cy) { - int dx; - int dy; + int dx; + int dy; - if (!self->use_clip) - { + if (!self->use_clip) + { + return 1; + } + + if (self->clip.left > *x) + { + dx = self->clip.left - *x; + } + else + { + dx = 0; + } + + if (self->clip.top > *y) + { + dy = self->clip.top - *y; + } + else + { + dy = 0; + } + + if (*x + *cx > self->clip.right) + { + *cx = *cx - ((*x + *cx) - self->clip.right); + } + + if (*y + *cy > self->clip.bottom) + { + *cy = *cy - ((*y + *cy) - self->clip.bottom); + } + + *cx = *cx - dx; + *cy = *cy - dy; + + if (*cx <= 0) + { + return 0; + } + + if (*cy <= 0) + { + return 0; + } + + *x = *x + dx; + *y = *y + dy; return 1; - } - if (self->clip.left > *x) - { - dx = self->clip.left - *x; - } - else - { - dx = 0; - } - if (self->clip.top > *y) - { - dy = self->clip.top - *y; - } - else - { - dy = 0; - } - if (*x + *cx > self->clip.right) - { - *cx = *cx - ((*x + *cx) - self->clip.right); - } - if (*y + *cy > self->clip.bottom) - { - *cy = *cy - ((*y + *cy) - self->clip.bottom); - } - *cx = *cx - dx; - *cy = *cy - dy; - if (*cx <= 0) - { - return 0; - } - if (*cy <= 0) - { - return 0; - } - *x = *x + dx; - *y = *y + dy; - return 1; } #endif /*****************************************************************************/ int APP_CC -xrdp_painter_set_clip(struct xrdp_painter* self, +xrdp_painter_set_clip(struct xrdp_painter *self, int x, int y, int cx, int cy) { - self->use_clip = &self->clip; - self->clip.left = x; - self->clip.top = y; - self->clip.right = x + cx; - self->clip.bottom = y + cy; - return 0; + self->use_clip = &self->clip; + self->clip.left = x; + self->clip.top = y; + self->clip.right = x + cx; + self->clip.bottom = y + cy; + return 0; } /*****************************************************************************/ int APP_CC -xrdp_painter_clr_clip(struct xrdp_painter* self) +xrdp_painter_clr_clip(struct xrdp_painter *self) { - self->use_clip = 0; - return 0; + self->use_clip = 0; + return 0; } #if 0 @@ -207,631 +220,720 @@ xrdp_painter_clr_clip(struct xrdp_painter* self) static int APP_CC xrdp_painter_rop(int rop, int src, int dst) { - switch (rop & 0x0f) - { - case 0x0: return 0; - case 0x1: return ~(src | dst); - case 0x2: return (~src) & dst; - case 0x3: return ~src; - case 0x4: return src & (~dst); - case 0x5: return ~(dst); - case 0x6: return src ^ dst; - case 0x7: return ~(src & dst); - case 0x8: return src & dst; - case 0x9: return ~(src) ^ dst; - case 0xa: return dst; - case 0xb: return (~src) | dst; - case 0xc: return src; - case 0xd: return src | (~dst); - case 0xe: return src | dst; - case 0xf: return ~0; - } - return dst; + switch (rop & 0x0f) + { + case 0x0: + return 0; + case 0x1: + return ~(src | dst); + case 0x2: + return (~src) & dst; + case 0x3: + return ~src; + case 0x4: + return src & (~dst); + case 0x5: + return ~(dst); + case 0x6: + return src ^ dst; + case 0x7: + return ~(src & dst); + case 0x8: + return src & dst; + case 0x9: + return ~(src) ^ dst; + case 0xa: + return dst; + case 0xb: + return (~src) | dst; + case 0xc: + return src; + case 0xd: + return src | (~dst); + case 0xe: + return src | dst; + case 0xf: + return ~0; + } + + return dst; } #endif /*****************************************************************************/ int APP_CC -xrdp_painter_text_width(struct xrdp_painter* self, char* text) +xrdp_painter_text_width(struct xrdp_painter *self, char *text) { - int index; - int rv; - int len; - struct xrdp_font_char* font_item; - twchar* wstr; + int index; + int rv; + int len; + struct xrdp_font_char *font_item; + twchar *wstr; - xrdp_painter_font_needed(self); - if (self->font == 0) - { - return 0; - } - if (text == 0) - { - return 0; - } - rv = 0; - len = g_mbstowcs(0, text, 0); - wstr = (twchar*)g_malloc((len + 2) * sizeof(twchar), 0); - g_mbstowcs(wstr, text, len + 1); - for (index = 0; index < len; index++) - { - font_item = self->font->font_items + wstr[index]; - rv = rv + font_item->incby; - } - g_free(wstr); - return rv; + xrdp_painter_font_needed(self); + + if (self->font == 0) + { + return 0; + } + + if (text == 0) + { + return 0; + } + + rv = 0; + len = g_mbstowcs(0, text, 0); + wstr = (twchar *)g_malloc((len + 2) * sizeof(twchar), 0); + g_mbstowcs(wstr, text, len + 1); + + for (index = 0; index < len; index++) + { + font_item = self->font->font_items + wstr[index]; + rv = rv + font_item->incby; + } + + g_free(wstr); + return rv; } /*****************************************************************************/ int APP_CC -xrdp_painter_text_height(struct xrdp_painter* self, char* text) +xrdp_painter_text_height(struct xrdp_painter *self, char *text) { - int index; - int rv; - int len; - struct xrdp_font_char* font_item; - twchar* wstr; + int index; + int rv; + int len; + struct xrdp_font_char *font_item; + twchar *wstr; - xrdp_painter_font_needed(self); - if (self->font == 0) - { - return 0; - } - if (text == 0) - { - return 0; - } - rv = 0; - len = g_mbstowcs(0, text, 0); - wstr = (twchar*)g_malloc((len + 2) * sizeof(twchar), 0); - g_mbstowcs(wstr, text, len + 1); - for (index = 0; index < len; index++) - { - font_item = self->font->font_items + wstr[index]; - rv = MAX(rv, font_item->height); - } - g_free(wstr); - return rv; + xrdp_painter_font_needed(self); + + if (self->font == 0) + { + return 0; + } + + if (text == 0) + { + return 0; + } + + rv = 0; + len = g_mbstowcs(0, text, 0); + wstr = (twchar *)g_malloc((len + 2) * sizeof(twchar), 0); + g_mbstowcs(wstr, text, len + 1); + + for (index = 0; index < len; index++) + { + font_item = self->font->font_items + wstr[index]; + rv = MAX(rv, font_item->height); + } + + g_free(wstr); + return rv; } /*****************************************************************************/ static int APP_CC -xrdp_painter_setup_brush(struct xrdp_painter* self, - struct xrdp_brush* out_brush, - struct xrdp_brush* in_brush) +xrdp_painter_setup_brush(struct xrdp_painter *self, + struct xrdp_brush *out_brush, + struct xrdp_brush *in_brush) { - int cache_id; + int cache_id; - g_memcpy(out_brush, in_brush, sizeof(struct xrdp_brush)); - if (in_brush->style == 3) - { - if (self->session->client_info->brush_cache_code == 1) + g_memcpy(out_brush, in_brush, sizeof(struct xrdp_brush)); + + if (in_brush->style == 3) { - cache_id = xrdp_cache_add_brush(self->wm->cache, in_brush->pattern); - g_memset(out_brush->pattern, 0, 8); - out_brush->pattern[0] = cache_id; - out_brush->style = 0x81; + if (self->session->client_info->brush_cache_code == 1) + { + cache_id = xrdp_cache_add_brush(self->wm->cache, in_brush->pattern); + g_memset(out_brush->pattern, 0, 8); + out_brush->pattern[0] = cache_id; + out_brush->style = 0x81; + } } - } - return 0; + + return 0; } /*****************************************************************************/ /* fill in an area of the screen with one color */ int APP_CC -xrdp_painter_fill_rect(struct xrdp_painter* self, - struct xrdp_bitmap* dst, +xrdp_painter_fill_rect(struct xrdp_painter *self, + struct xrdp_bitmap *dst, int x, int y, int cx, int cy) { - struct xrdp_rect clip_rect; - struct xrdp_rect draw_rect; - struct xrdp_rect rect; - struct xrdp_region* region; - struct xrdp_brush brush; - int k; - int dx; - int dy; - int rop; + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect; + struct xrdp_region *region; + struct xrdp_brush brush; + int k; + int dx; + int dy; + int rop; - if (self == 0) - { - return 0; - } - - /* todo data */ - - if (dst->type == WND_TYPE_BITMAP) /* 0 */ - { - return 0; - } - xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); - region = xrdp_region_create(self->wm); - if (dst->type != WND_TYPE_OFFSCREEN) - { - xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, region, - self->clip_children); - } - else - { - xrdp_region_add_rect(region, &clip_rect); - } - x += dx; - y += dy; - if (self->mix_mode == 0 && self->rop == 0xcc) - { - k = 0; - while (xrdp_region_get_rect(region, k, &rect) == 0) + if (self == 0) { - if (rect_intersect(&rect, &clip_rect, &draw_rect)) - { - libxrdp_orders_rect(self->session, x, y, cx, cy, - self->fg_color, &draw_rect); - } - k++; + return 0; } - } - else if (self->mix_mode == 0 && + + /* todo data */ + + if (dst->type == WND_TYPE_BITMAP) /* 0 */ + { + return 0; + } + + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + + if (dst->type != WND_TYPE_OFFSCREEN) + { + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, region, + self->clip_children); + } + else + { + xrdp_region_add_rect(region, &clip_rect); + } + + x += dx; + y += dy; + + if (self->mix_mode == 0 && self->rop == 0xcc) + { + k = 0; + + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_rect(self->session, x, y, cx, cy, + self->fg_color, &draw_rect); + } + + k++; + } + } + else if (self->mix_mode == 0 && ((self->rop & 0xf) == 0x0 || /* black */ (self->rop & 0xf) == 0xf || /* white */ (self->rop & 0xf) == 0x5)) /* DSTINVERT */ - { - k = 0; - while (xrdp_region_get_rect(region, k, &rect) == 0) { - if (rect_intersect(&rect, &clip_rect, &draw_rect)) - { - libxrdp_orders_dest_blt(self->session, x, y, cx, cy, - self->rop, &draw_rect); - } - k++; + k = 0; + + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_dest_blt(self->session, x, y, cx, cy, + self->rop, &draw_rect); + } + + k++; + } } - } - else - { - k = 0; - rop = self->rop; - /* if opcode is in the form 0x00, 0x11, 0x22, ... convert it */ - if (((rop & 0xf0) >> 4) == (rop & 0xf)) + else { - switch (rop) - { - case 0x66: /* xor */ - rop = 0x5a; - break; - case 0xaa: /* noop */ - rop = 0xfb; - break; - case 0xcc: /* copy */ - rop = 0xf0; - break; - case 0x88: /* and */ - rop = 0xc0; - break; - } + k = 0; + rop = self->rop; + + /* if opcode is in the form 0x00, 0x11, 0x22, ... convert it */ + if (((rop & 0xf0) >> 4) == (rop & 0xf)) + { + switch (rop) + { + case 0x66: /* xor */ + rop = 0x5a; + break; + case 0xaa: /* noop */ + rop = 0xfb; + break; + case 0xcc: /* copy */ + rop = 0xf0; + break; + case 0x88: /* and */ + rop = 0xc0; + break; + } + } + + xrdp_painter_setup_brush(self, &brush, &self->brush); + + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_pat_blt(self->session, x, y, cx, cy, + rop, self->bg_color, self->fg_color, + &brush, &draw_rect); + } + + k++; + } } - xrdp_painter_setup_brush(self, &brush, &self->brush); - while (xrdp_region_get_rect(region, k, &rect) == 0) - { - if (rect_intersect(&rect, &clip_rect, &draw_rect)) - { - libxrdp_orders_pat_blt(self->session, x, y, cx, cy, - rop, self->bg_color, self->fg_color, - &brush, &draw_rect); - } - k++; - } - } - xrdp_region_delete(region); - return 0; + + xrdp_region_delete(region); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_painter_draw_text(struct xrdp_painter* self, - struct xrdp_bitmap* dst, - int x, int y, const char* text) +xrdp_painter_draw_text(struct xrdp_painter *self, + struct xrdp_bitmap *dst, + int x, int y, const char *text) { - int i; - int f; - int c; - int k; - int x1; - int y1; - int flags; - int len; - int index; - int total_width; - int total_height; - int dx; - int dy; - char* data; - struct xrdp_region* region; - struct xrdp_rect rect; - struct xrdp_rect clip_rect; - struct xrdp_rect draw_rect; - struct xrdp_font* font; - struct xrdp_font_char* font_item; - twchar* wstr; + int i; + int f; + int c; + int k; + int x1; + int y1; + int flags; + int len; + int index; + int total_width; + int total_height; + int dx; + int dy; + char *data; + struct xrdp_region *region; + struct xrdp_rect rect; + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_font *font; + struct xrdp_font_char *font_item; + twchar *wstr; - if (self == 0) - { - return 0; - } - len = g_mbstowcs(0, text, 0); - if (len < 1) - { - return 0; - } - - /* todo data */ - - if (dst->type == 0) - { - return 0; - } - xrdp_painter_font_needed(self); - if (self->font == 0) - { - return 0; - } - /* convert to wide char */ - wstr = (twchar*)g_malloc((len + 2) * sizeof(twchar), 0); - g_mbstowcs(wstr, text, len + 1); - font = self->font; - f = 0; - k = 0; - total_width = 0; - total_height = 0; - data = (char*)g_malloc(len * 4, 1); - for (index = 0; index < len; index++) - { - font_item = font->font_items + wstr[index]; - i = xrdp_cache_add_char(self->wm->cache, font_item); - f = HIWORD(i); - c = LOWORD(i); - data[index * 2] = c; - data[index * 2 + 1] = k; - k = font_item->incby; - total_width += k; - total_height = MAX(total_height, font_item->height); - } - xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); - region = xrdp_region_create(self->wm); - if (dst->type != WND_TYPE_OFFSCREEN) - { - xrdp_wm_get_vis_region(self->wm, dst, x, y, total_width, total_height, - region, self->clip_children); - } - else - { - xrdp_region_add_rect(region, &clip_rect); - } - x += dx; - y += dy; - k = 0; - while (xrdp_region_get_rect(region, k, &rect) == 0) - { - if (rect_intersect(&rect, &clip_rect, &draw_rect)) + if (self == 0) { - x1 = x; - y1 = y + total_height; - flags = 0x03; /* 0x03 0x73; TEXT2_IMPLICIT_X and something else */ - libxrdp_orders_text(self->session, f, flags, 0, - self->fg_color, 0, - x - 1, y - 1, x + total_width, y + total_height, - 0, 0, 0, 0, - x1, y1, data, len * 2, &draw_rect); + return 0; } - k++; - } - xrdp_region_delete(region); - g_free(data); - g_free(wstr); - return 0; + + len = g_mbstowcs(0, text, 0); + + if (len < 1) + { + return 0; + } + + /* todo data */ + + if (dst->type == 0) + { + return 0; + } + + xrdp_painter_font_needed(self); + + if (self->font == 0) + { + return 0; + } + + /* convert to wide char */ + wstr = (twchar *)g_malloc((len + 2) * sizeof(twchar), 0); + g_mbstowcs(wstr, text, len + 1); + font = self->font; + f = 0; + k = 0; + total_width = 0; + total_height = 0; + data = (char *)g_malloc(len * 4, 1); + + for (index = 0; index < len; index++) + { + font_item = font->font_items + wstr[index]; + i = xrdp_cache_add_char(self->wm->cache, font_item); + f = HIWORD(i); + c = LOWORD(i); + data[index * 2] = c; + data[index * 2 + 1] = k; + k = font_item->incby; + total_width += k; + total_height = MAX(total_height, font_item->height); + } + + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + + if (dst->type != WND_TYPE_OFFSCREEN) + { + xrdp_wm_get_vis_region(self->wm, dst, x, y, total_width, total_height, + region, self->clip_children); + } + else + { + xrdp_region_add_rect(region, &clip_rect); + } + + x += dx; + y += dy; + k = 0; + + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + x1 = x; + y1 = y + total_height; + flags = 0x03; /* 0x03 0x73; TEXT2_IMPLICIT_X and something else */ + libxrdp_orders_text(self->session, f, flags, 0, + self->fg_color, 0, + x - 1, y - 1, x + total_width, y + total_height, + 0, 0, 0, 0, + x1, y1, data, len * 2, &draw_rect); + } + + k++; + } + + xrdp_region_delete(region); + g_free(data); + g_free(wstr); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_painter_draw_text2(struct xrdp_painter* self, - struct xrdp_bitmap* dst, +xrdp_painter_draw_text2(struct xrdp_painter *self, + struct xrdp_bitmap *dst, int font, int flags, int mixmode, int clip_left, int clip_top, int clip_right, int clip_bottom, int box_left, int box_top, int box_right, int box_bottom, - int x, int y, char* data, int data_len) + int x, int y, char *data, int data_len) { - struct xrdp_rect clip_rect; - struct xrdp_rect draw_rect; - struct xrdp_rect rect; - struct xrdp_region* region; - int k; - int dx; - int dy; + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect; + struct xrdp_region *region; + int k; + int dx; + int dy; - if (self == 0) - { - return 0; - } - - /* todo data */ - - if (dst->type == WND_TYPE_BITMAP) - { - return 0; - } - xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); - region = xrdp_region_create(self->wm); - if (dst->type != WND_TYPE_OFFSCREEN) - { - if (box_right - box_left > 1) + if (self == 0) { - xrdp_wm_get_vis_region(self->wm, dst, box_left, box_top, - box_right - box_left, box_bottom - box_top, - region, self->clip_children); + return 0; + } + + /* todo data */ + + if (dst->type == WND_TYPE_BITMAP) + { + return 0; + } + + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + + if (dst->type != WND_TYPE_OFFSCREEN) + { + if (box_right - box_left > 1) + { + xrdp_wm_get_vis_region(self->wm, dst, box_left, box_top, + box_right - box_left, box_bottom - box_top, + region, self->clip_children); + } + else + { + xrdp_wm_get_vis_region(self->wm, dst, clip_left, clip_top, + clip_right - clip_left, clip_bottom - clip_top, + region, self->clip_children); + } } else { - xrdp_wm_get_vis_region(self->wm, dst, clip_left, clip_top, - clip_right - clip_left, clip_bottom - clip_top, - region, self->clip_children); + xrdp_region_add_rect(region, &clip_rect); } - } - else - { - xrdp_region_add_rect(region, &clip_rect); - } - clip_left += dx; - clip_top += dy; - clip_right += dx; - clip_bottom += dy; - box_left += dx; - box_top += dy; - box_right += dx; - box_bottom += dy; - x += dx; - y += dy; - k = 0; - while (xrdp_region_get_rect(region, k, &rect) == 0) - { - if (rect_intersect(&rect, &clip_rect, &draw_rect)) + clip_left += dx; + clip_top += dy; + clip_right += dx; + clip_bottom += dy; + box_left += dx; + box_top += dy; + box_right += dx; + box_bottom += dy; + x += dx; + y += dy; + k = 0; + + while (xrdp_region_get_rect(region, k, &rect) == 0) { - libxrdp_orders_text(self->session, font, flags, mixmode, - self->fg_color, self->bg_color, - clip_left, clip_top, clip_right, clip_bottom, - box_left, box_top, box_right, box_bottom, - x, y, data, data_len, &draw_rect); + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_text(self->session, font, flags, mixmode, + self->fg_color, self->bg_color, + clip_left, clip_top, clip_right, clip_bottom, + box_left, box_top, box_right, box_bottom, + x, y, data, data_len, &draw_rect); + } + + k++; } - k++; - } - xrdp_region_delete(region); - return 0; + + xrdp_region_delete(region); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_painter_copy(struct xrdp_painter* self, - struct xrdp_bitmap* src, - struct xrdp_bitmap* dst, +xrdp_painter_copy(struct xrdp_painter *self, + struct xrdp_bitmap *src, + struct xrdp_bitmap *dst, int x, int y, int cx, int cy, int srcx, int srcy) { - struct xrdp_rect clip_rect; - struct xrdp_rect draw_rect; - struct xrdp_rect rect1; - struct xrdp_rect rect2; - struct xrdp_region* region; - struct xrdp_bitmap* b; - int i; - int j; - int k; - int dx; - int dy; - int palette_id; - int bitmap_id; - int cache_id; - int cache_idx; - int dstx; - int dsty; - int w; - int h; + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect1; + struct xrdp_rect rect2; + struct xrdp_region *region; + struct xrdp_bitmap *b; + int i; + int j; + int k; + int dx; + int dy; + int palette_id; + int bitmap_id; + int cache_id; + int cache_idx; + int dstx; + int dsty; + int w; + int h; - if (self == 0 || src == 0 || dst == 0) - { - return 0; - } - - /* todo data */ - - if (dst->type == WND_TYPE_BITMAP) - { - return 0; - } - if (src->type == WND_TYPE_SCREEN) - { - xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); - region = xrdp_region_create(self->wm); - if (dst->type != WND_TYPE_OFFSCREEN) + if (self == 0 || src == 0 || dst == 0) { - xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, - region, self->clip_children); + return 0; } - else - { - xrdp_region_add_rect(region, &clip_rect); - } - x += dx; - y += dy; - srcx += dx; - srcy += dy; - k = 0; - while (xrdp_region_get_rect(region, k, &rect1) == 0) - { - if (rect_intersect(&rect1, &clip_rect, &draw_rect)) - { - libxrdp_orders_screen_blt(self->session, x, y, cx, cy, - srcx, srcy, self->rop, &draw_rect); - } - k++; - } - xrdp_region_delete(region); - } - else if (src->type == WND_TYPE_OFFSCREEN) - { - //g_writeln("xrdp_painter_copy: todo"); - xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); - region = xrdp_region_create(self->wm); - if (dst->type != WND_TYPE_OFFSCREEN) - { - //g_writeln("off screen to screen"); - xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, - region, self->clip_children); - } - else - { - //g_writeln("off screen to off screen"); - xrdp_region_add_rect(region, &clip_rect); - } - x += dx; - y += dy; + /* todo data */ - palette_id = 0; - cache_id = 255; // todo - cache_idx = src->item_index; // todo - - k = 0; - while (xrdp_region_get_rect(region, k, &rect1) == 0) + if (dst->type == WND_TYPE_BITMAP) { - if (rect_intersect(&rect1, &clip_rect, &rect2)) - { - MAKERECT(rect1, x, y, cx, cy); - if (rect_intersect(&rect2, &rect1, &draw_rect)) + return 0; + } + + if (src->type == WND_TYPE_SCREEN) + { + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + + if (dst->type != WND_TYPE_OFFSCREEN) { - libxrdp_orders_mem_blt(self->session, cache_id, palette_id, - x, y, cx, cy, self->rop, srcx, srcy, - cache_idx, &draw_rect); + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, + region, self->clip_children); } - } - k++; - } - xrdp_region_delete(region); - } - else if (src->data != 0) - /* todo, the non bitmap cache part is gone, it should be put back */ - { - xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); - region = xrdp_region_create(self->wm); - if (dst->type != WND_TYPE_OFFSCREEN) - { - xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, - region, self->clip_children); - } - else - { - xrdp_region_add_rect(region, &clip_rect); - } - x += dx; - y += dy; - palette_id = 0; - j = srcy; - while (j < (srcy + cy)) - { - i = srcx; - while (i < (srcx + cx)) - { - w = MIN(64, ((srcx + cx) - i)); - h = MIN(64, ((srcy + cy) - j)); - b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm); - xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h); - bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b, self->wm->hints); - cache_id = HIWORD(bitmap_id); - cache_idx = LOWORD(bitmap_id); - dstx = (x + i) - srcx; - dsty = (y + j) - srcy; + else + { + xrdp_region_add_rect(region, &clip_rect); + } + + x += dx; + y += dy; + srcx += dx; + srcy += dy; k = 0; + while (xrdp_region_get_rect(region, k, &rect1) == 0) { - if (rect_intersect(&rect1, &clip_rect, &rect2)) - { - MAKERECT(rect1, dstx, dsty, w, h); - if (rect_intersect(&rect2, &rect1, &draw_rect)) + if (rect_intersect(&rect1, &clip_rect, &draw_rect)) { - libxrdp_orders_mem_blt(self->session, cache_id, palette_id, - dstx, dsty, w, h, self->rop, 0, 0, - cache_idx, &draw_rect); + libxrdp_orders_screen_blt(self->session, x, y, cx, cy, + srcx, srcy, self->rop, &draw_rect); } - } - k++; + + k++; } - i += 64; - } - j += 64; + + xrdp_region_delete(region); } - xrdp_region_delete(region); - } - return 0; + else if (src->type == WND_TYPE_OFFSCREEN) + { + //g_writeln("xrdp_painter_copy: todo"); + + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + + if (dst->type != WND_TYPE_OFFSCREEN) + { + //g_writeln("off screen to screen"); + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, + region, self->clip_children); + } + else + { + //g_writeln("off screen to off screen"); + xrdp_region_add_rect(region, &clip_rect); + } + + x += dx; + y += dy; + + palette_id = 0; + cache_id = 255; // todo + cache_idx = src->item_index; // todo + + k = 0; + + while (xrdp_region_get_rect(region, k, &rect1) == 0) + { + if (rect_intersect(&rect1, &clip_rect, &rect2)) + { + MAKERECT(rect1, x, y, cx, cy); + + if (rect_intersect(&rect2, &rect1, &draw_rect)) + { + libxrdp_orders_mem_blt(self->session, cache_id, palette_id, + x, y, cx, cy, self->rop, srcx, srcy, + cache_idx, &draw_rect); + } + } + + k++; + } + + xrdp_region_delete(region); + } + else if (src->data != 0) + /* todo, the non bitmap cache part is gone, it should be put back */ + { + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + + if (dst->type != WND_TYPE_OFFSCREEN) + { + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, + region, self->clip_children); + } + else + { + xrdp_region_add_rect(region, &clip_rect); + } + + x += dx; + y += dy; + palette_id = 0; + j = srcy; + + while (j < (srcy + cy)) + { + i = srcx; + + while (i < (srcx + cx)) + { + w = MIN(64, ((srcx + cx) - i)); + h = MIN(64, ((srcy + cy) - j)); + b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm); + xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h); + bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b, self->wm->hints); + cache_id = HIWORD(bitmap_id); + cache_idx = LOWORD(bitmap_id); + dstx = (x + i) - srcx; + dsty = (y + j) - srcy; + k = 0; + + while (xrdp_region_get_rect(region, k, &rect1) == 0) + { + if (rect_intersect(&rect1, &clip_rect, &rect2)) + { + MAKERECT(rect1, dstx, dsty, w, h); + + if (rect_intersect(&rect2, &rect1, &draw_rect)) + { + libxrdp_orders_mem_blt(self->session, cache_id, palette_id, + dstx, dsty, w, h, self->rop, 0, 0, + cache_idx, &draw_rect); + } + } + + k++; + } + + i += 64; + } + + j += 64; + } + + xrdp_region_delete(region); + } + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_painter_line(struct xrdp_painter* self, - struct xrdp_bitmap* dst, +xrdp_painter_line(struct xrdp_painter *self, + struct xrdp_bitmap *dst, int x1, int y1, int x2, int y2) { - struct xrdp_rect clip_rect; - struct xrdp_rect draw_rect; - struct xrdp_rect rect; - struct xrdp_region* region; - int k; - int dx; - int dy; - int rop; + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect; + struct xrdp_region *region; + int k; + int dx; + int dy; + int rop; - if (self == 0) - { - return 0; - } - - /* todo data */ - - if (dst->type == WND_TYPE_BITMAP) - { - return 0; - } - xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); - region = xrdp_region_create(self->wm); - if (dst->type != WND_TYPE_OFFSCREEN) - { - xrdp_wm_get_vis_region(self->wm, dst, MIN(x1, x2), MIN(y1, y2), - g_abs(x1 - x2) + 1, g_abs(y1 - y2) + 1, - region, self->clip_children); - } - else - { - xrdp_region_add_rect(region, &clip_rect); - } - x1 += dx; - y1 += dy; - x2 += dx; - y2 += dy; - k = 0; - rop = self->rop; - if (rop < 0x01 || rop > 0x10) - { - rop = (rop & 0xf) + 1; - } - while (xrdp_region_get_rect(region, k, &rect) == 0) - { - if (rect_intersect(&rect, &clip_rect, &draw_rect)) + if (self == 0) { - libxrdp_orders_line(self->session, 1, x1, y1, x2, y2, - rop, self->bg_color, - &self->pen, &draw_rect); + return 0; } - k++; - } - xrdp_region_delete(region); - return 0; + + /* todo data */ + + if (dst->type == WND_TYPE_BITMAP) + { + return 0; + } + + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + + if (dst->type != WND_TYPE_OFFSCREEN) + { + xrdp_wm_get_vis_region(self->wm, dst, MIN(x1, x2), MIN(y1, y2), + g_abs(x1 - x2) + 1, g_abs(y1 - y2) + 1, + region, self->clip_children); + } + else + { + xrdp_region_add_rect(region, &clip_rect); + } + + x1 += dx; + y1 += dy; + x2 += dx; + y2 += dy; + k = 0; + rop = self->rop; + + if (rop < 0x01 || rop > 0x10) + { + rop = (rop & 0xf) + 1; + } + + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_line(self->session, 1, x1, y1, x2, y2, + rop, self->bg_color, + &self->pen, &draw_rect); + } + + k++; + } + + xrdp_region_delete(region); + return 0; } diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index 7a88d524..e3b846ea 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - main rdp process - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * main rdp process + */ #include "xrdp.h" @@ -26,60 +24,64 @@ static int g_session_id = 0; /*****************************************************************************/ /* always called from xrdp_listen thread */ -struct xrdp_process* APP_CC -xrdp_process_create(struct xrdp_listen* owner, tbus done_event) +struct xrdp_process *APP_CC +xrdp_process_create(struct xrdp_listen *owner, tbus done_event) { - struct xrdp_process* self; - char event_name[256]; - int pid; + struct xrdp_process *self; + char event_name[256]; + int pid; - self = (struct xrdp_process*)g_malloc(sizeof(struct xrdp_process), 1); - self->lis_layer = owner; - self->done_event = done_event; - g_session_id++; - self->session_id = g_session_id; - pid = g_getpid(); - g_snprintf(event_name, 255, "xrdp_%8.8x_process_self_term_event_%8.8x", - pid, self->session_id); - self->self_term_event = g_create_wait_obj(event_name); - return self; + self = (struct xrdp_process *)g_malloc(sizeof(struct xrdp_process), 1); + self->lis_layer = owner; + self->done_event = done_event; + g_session_id++; + self->session_id = g_session_id; + pid = g_getpid(); + g_snprintf(event_name, 255, "xrdp_%8.8x_process_self_term_event_%8.8x", + pid, self->session_id); + self->self_term_event = g_create_wait_obj(event_name); + return self; } /*****************************************************************************/ void APP_CC -xrdp_process_delete(struct xrdp_process* self) +xrdp_process_delete(struct xrdp_process *self) { - if (self == 0) - { - return; - } - g_delete_wait_obj(self->self_term_event); - libxrdp_exit(self->session); - xrdp_wm_delete(self->wm); - trans_delete(self->server_trans); - g_free(self); + if (self == 0) + { + return; + } + + g_delete_wait_obj(self->self_term_event); + libxrdp_exit(self->session); + xrdp_wm_delete(self->wm); + trans_delete(self->server_trans); + g_free(self); } /*****************************************************************************/ static int APP_CC -xrdp_process_loop(struct xrdp_process* self) +xrdp_process_loop(struct xrdp_process *self) { - int rv; + int rv; - rv = 0; - if (self->session != 0) - { - rv = libxrdp_process_data(self->session); - } - if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0)) - { - DEBUG(("calling xrdp_wm_init and creating wm")); - self->wm = xrdp_wm_create(self, self->session->client_info); - /* at this point the wm(window manager) is create and wm::login_mode is - zero and login_mode_event is set so xrdp_wm_init should be called by - xrdp_wm_check_wait_objs */ - } - return rv; + rv = 0; + + if (self->session != 0) + { + rv = libxrdp_process_data(self->session); + } + + if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0)) + { + DEBUG(("calling xrdp_wm_init and creating wm")); + self->wm = xrdp_wm_create(self, self->session->client_info); + /* at this point the wm(window manager) is create and wm::login_mode is + zero and login_mode_event is set so xrdp_wm_init should be called by + xrdp_wm_check_wait_objs */ + } + + return rv; } /*****************************************************************************/ @@ -88,113 +90,125 @@ xrdp_process_loop(struct xrdp_process* self) static int DEFAULT_CC xrdp_is_term(void) { - return g_is_term(); + return g_is_term(); } /*****************************************************************************/ static int APP_CC -xrdp_process_mod_end(struct xrdp_process* self) +xrdp_process_mod_end(struct xrdp_process *self) { - if (self->wm != 0) - { - if (self->wm->mm != 0) + if (self->wm != 0) { - if (self->wm->mm->mod != 0) - { - if (self->wm->mm->mod->mod_end != 0) + if (self->wm->mm != 0) { - return self->wm->mm->mod->mod_end(self->wm->mm->mod); + if (self->wm->mm->mod != 0) + { + if (self->wm->mm->mod->mod_end != 0) + { + return self->wm->mm->mod->mod_end(self->wm->mm->mod); + } + } } - } } - } - return 0; + + return 0; } /*****************************************************************************/ static int DEFAULT_CC -xrdp_process_data_in(struct trans* self) +xrdp_process_data_in(struct trans *self) { - struct xrdp_process* pro; + struct xrdp_process *pro; - DEBUG(("xrdp_process_data_in")); - pro = (struct xrdp_process*)(self->callback_data); - if (xrdp_process_loop(pro) != 0) - { - return 1; - } - return 0; + DEBUG(("xrdp_process_data_in")); + pro = (struct xrdp_process *)(self->callback_data); + + if (xrdp_process_loop(pro) != 0) + { + return 1; + } + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_process_main_loop(struct xrdp_process* self) +xrdp_process_main_loop(struct xrdp_process *self) { - int robjs_count; - int wobjs_count; - int cont; - int timeout = 0; - tbus robjs[32]; - tbus wobjs[32]; - tbus term_obj; + int robjs_count; + int wobjs_count; + int cont; + int timeout = 0; + tbus robjs[32]; + tbus wobjs[32]; + tbus term_obj; - DEBUG(("xrdp_process_main_loop")); - self->status = 1; - self->server_trans->trans_data_in = xrdp_process_data_in; - self->server_trans->callback_data = self; - self->session = libxrdp_init((tbus)self, self->server_trans); - /* this callback function is in xrdp_wm.c */ - self->session->callback = callback; - /* this function is just above */ - self->session->is_term = xrdp_is_term; - if (libxrdp_process_incomming(self->session) == 0) - { - term_obj = g_get_term_event(); - cont = 1; - while (cont) + DEBUG(("xrdp_process_main_loop")); + self->status = 1; + self->server_trans->trans_data_in = xrdp_process_data_in; + self->server_trans->callback_data = self; + self->session = libxrdp_init((tbus)self, self->server_trans); + /* this callback function is in xrdp_wm.c */ + self->session->callback = callback; + /* this function is just above */ + self->session->is_term = xrdp_is_term; + + if (libxrdp_process_incomming(self->session) == 0) { - /* build the wait obj list */ - timeout = -1; - robjs_count = 0; - wobjs_count = 0; - robjs[robjs_count++] = term_obj; - robjs[robjs_count++] = self->self_term_event; - xrdp_wm_get_wait_objs(self->wm, robjs, &robjs_count, - wobjs, &wobjs_count, &timeout); - trans_get_wait_objs(self->server_trans, robjs, &robjs_count); - /* wait */ - if (g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout) != 0) - { - /* error, should not get here */ - g_sleep(100); - } - if (g_is_wait_obj_set(term_obj)) /* term */ - { - break; - } - if (g_is_wait_obj_set(self->self_term_event)) - { - break; - } - if (xrdp_wm_check_wait_objs(self->wm) != 0) - { - break; - } - if (trans_check_wait_objs(self->server_trans) != 0) - { - break; - } + term_obj = g_get_term_event(); + cont = 1; + + while (cont) + { + /* build the wait obj list */ + timeout = -1; + robjs_count = 0; + wobjs_count = 0; + robjs[robjs_count++] = term_obj; + robjs[robjs_count++] = self->self_term_event; + xrdp_wm_get_wait_objs(self->wm, robjs, &robjs_count, + wobjs, &wobjs_count, &timeout); + trans_get_wait_objs(self->server_trans, robjs, &robjs_count); + + /* wait */ + if (g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout) != 0) + { + /* error, should not get here */ + g_sleep(100); + } + + if (g_is_wait_obj_set(term_obj)) /* term */ + { + break; + } + + if (g_is_wait_obj_set(self->self_term_event)) + { + break; + } + + if (xrdp_wm_check_wait_objs(self->wm) != 0) + { + break; + } + + if (trans_check_wait_objs(self->server_trans) != 0) + { + break; + } + } + + libxrdp_disconnect(self->session); } - libxrdp_disconnect(self->session); - } - else - { - g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed"); - } - xrdp_process_mod_end(self); - libxrdp_exit(self->session); - self->session = 0; - self->status = -1; - g_set_wait_obj(self->done_event); - return 0; + else + { + g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed"); + } + + xrdp_process_mod_end(self); + libxrdp_exit(self->session); + self->session = 0; + self->status = -1; + g_set_wait_obj(self->done_event); + return 0; } diff --git a/xrdp/xrdp_region.c b/xrdp/xrdp_region.c index db046a30..8dc6854b 100644 --- a/xrdp/xrdp_region.c +++ b/xrdp/xrdp_region.c @@ -1,297 +1,316 @@ - -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - region - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * region + */ #include "xrdp.h" /*****************************************************************************/ -struct xrdp_region* APP_CC -xrdp_region_create(struct xrdp_wm* wm) +struct xrdp_region *APP_CC +xrdp_region_create(struct xrdp_wm *wm) { - struct xrdp_region* self; + struct xrdp_region *self; - self = (struct xrdp_region*)g_malloc(sizeof(struct xrdp_region), 1); - self->wm = wm; - self->rects = list_create(); - self->rects->auto_free = 1; - return self; + self = (struct xrdp_region *)g_malloc(sizeof(struct xrdp_region), 1); + self->wm = wm; + self->rects = list_create(); + self->rects->auto_free = 1; + return self; } /*****************************************************************************/ void APP_CC -xrdp_region_delete(struct xrdp_region* self) +xrdp_region_delete(struct xrdp_region *self) { - if (self == 0) - { - return; - } - list_delete(self->rects); - g_free(self); + if (self == 0) + { + return; + } + + list_delete(self->rects); + g_free(self); } /*****************************************************************************/ int APP_CC -xrdp_region_add_rect(struct xrdp_region* self, struct xrdp_rect* rect) +xrdp_region_add_rect(struct xrdp_region *self, struct xrdp_rect *rect) { - struct xrdp_rect* r; + struct xrdp_rect *r; - r = (struct xrdp_rect*)g_malloc(sizeof(struct xrdp_rect), 1); - *r = *rect; - list_add_item(self->rects, (long)r); - return 0; + r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1); + *r = *rect; + list_add_item(self->rects, (long)r); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_region_insert_rect(struct xrdp_region* self, int i, int left, +xrdp_region_insert_rect(struct xrdp_region *self, int i, int left, int top, int right, int bottom) { - struct xrdp_rect* r; + struct xrdp_rect *r; - r = (struct xrdp_rect*)g_malloc(sizeof(struct xrdp_rect), 1); - r->left = left; - r->top = top; - r->right = right; - r->bottom = bottom; - list_insert_item(self->rects, i, (long)r); - return 0; + r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1); + r->left = left; + r->top = top; + r->right = right; + r->bottom = bottom; + list_insert_item(self->rects, i, (long)r); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_region_subtract_rect(struct xrdp_region* self, - struct xrdp_rect* rect) +xrdp_region_subtract_rect(struct xrdp_region *self, + struct xrdp_rect *rect) { - struct xrdp_rect* r; - struct xrdp_rect rect1; - int i; + struct xrdp_rect *r; + struct xrdp_rect rect1; + int i; - for (i = self->rects->count - 1; i >= 0; i--) - { - r = (struct xrdp_rect*)list_get_item(self->rects, i); - rect1 = *r; - r = &rect1; - if (rect->left <= r->left && - rect->top <= r->top && - rect->right >= r->right && - rect->bottom >= r->bottom) - { /* rect is not visible */ - list_remove_item(self->rects, i); - } - else if (rect->right < r->left || - rect->bottom < r->top || - rect->top > r->bottom || - rect->left > r->right) - { /* rect are not related */ - } - else if (rect->left <= r->left && - rect->right >= r->right && - rect->bottom < r->bottom && - rect->top <= r->top) - { /* partially covered(whole top) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, rect->bottom, - r->right, r->bottom); - } - else if (rect->top <= r->top && - rect->bottom >= r->bottom && - rect->right < r->right && - rect->left <= r->left) - { /* partially covered(left) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, rect->right, r->top, - r->right, r->bottom); - } - else if (rect->left <= r->left && - rect->right >= r->right && - rect->top > r->top && - rect->bottom >= r->bottom) - { /* partially covered(bottom) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - r->right, rect->top); - } - else if (rect->top <= r->top && - rect->bottom >= r->bottom && - rect->left > r->left && - rect->right >= r->right) - { /* partially covered(right) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - rect->left, r->bottom); - } - else if (rect->left <= r->left && - rect->top <= r->top && - rect->right < r->right && - rect->bottom < r->bottom) - { /* partially covered(top left) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, rect->right, r->top, - r->right, rect->bottom); - xrdp_region_insert_rect(self, i, r->left, rect->bottom, - r->right, r->bottom); - } - else if (rect->left <= r->left && - rect->bottom >= r->bottom && - rect->right < r->right && - rect->top > r->top) - { /* partially covered(bottom left) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - r->right, rect->top); - xrdp_region_insert_rect(self, i, rect->right, rect->top, - r->right, r->bottom); - } - else if (rect->left > r->left && - rect->right >= r->right && - rect->top <= r->top && - rect->bottom < r->bottom) - { /* partially covered(top right) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - rect->left, r->bottom); - xrdp_region_insert_rect(self, i, rect->left, rect->bottom, - r->right, r->bottom); - } - else if (rect->left > r->left && - rect->right >= r->right && - rect->top > r->top && - rect->bottom >= r->bottom) - { /* partially covered(bottom right) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - r->right, rect->top); - xrdp_region_insert_rect(self, i, r->left, rect->top, - rect->left, r->bottom); - } - else if (rect->left > r->left && - rect->top <= r->top && - rect->right < r->right && - rect->bottom >= r->bottom) - { /* 2 rects, one on each end */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - rect->left, r->bottom); - xrdp_region_insert_rect(self, i, rect->right, r->top, - r->right, r->bottom); - } - else if (rect->left <= r->left && - rect->top > r->top && - rect->right >= r->right && - rect->bottom < r->bottom) - { /* 2 rects, one on each end */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - r->right, rect->top); - xrdp_region_insert_rect(self, i, r->left, rect->bottom, - r->right, r->bottom); - } - else if (rect->left > r->left && - rect->right < r->right && - rect->top <= r->top && - rect->bottom < r->bottom) - { /* partially covered(top) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - rect->left, r->bottom); - xrdp_region_insert_rect(self, i, rect->left, rect->bottom, - rect->right, r->bottom); - xrdp_region_insert_rect(self, i, rect->right, r->top, - r->right, r->bottom); - } - else if (rect->top > r->top && - rect->bottom < r->bottom && - rect->left <= r->left && - rect->right < r->right) - { /* partially covered(left) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - r->right, rect->top); - xrdp_region_insert_rect(self, i, rect->right, rect->top, - r->right, rect->bottom); - xrdp_region_insert_rect(self, i, r->left, rect->bottom, - r->right, r->bottom); - } - else if (rect->left > r->left && - rect->right < r->right && - rect->bottom >= r->bottom && - rect->top > r->top) - { /* partially covered(bottom) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - rect->left, r->bottom); - xrdp_region_insert_rect(self, i, rect->left, r->top, - rect->right, rect->top); - xrdp_region_insert_rect(self, i, rect->right, r->top, - r->right, r->bottom); - } - else if (rect->top > r->top && - rect->bottom < r->bottom && - rect->right >= r->right && - rect->left > r->left) - { /* partially covered(right) */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - r->right, rect->top); - xrdp_region_insert_rect(self, i, r->left, rect->top, - rect->left, rect->bottom); - xrdp_region_insert_rect(self, i, r->left, rect->bottom, - r->right, r->bottom); - } - else if (rect->left > r->left && - rect->top > r->top && - rect->right < r->right && - rect->bottom < r->bottom) - { /* totally contained, 4 rects */ - list_remove_item(self->rects, i); - xrdp_region_insert_rect(self, i, r->left, r->top, - r->right, rect->top); - xrdp_region_insert_rect(self, i, r->left, rect->top, - rect->left, rect->bottom); - xrdp_region_insert_rect(self, i, r->left, rect->bottom, - r->right, r->bottom); - xrdp_region_insert_rect(self, i, rect->right, rect->top, - r->right, rect->bottom); - } - else + for (i = self->rects->count - 1; i >= 0; i--) { - g_writeln("error in xrdp_region_subtract_rect"); + r = (struct xrdp_rect *)list_get_item(self->rects, i); + rect1 = *r; + r = &rect1; + + if (rect->left <= r->left && + rect->top <= r->top && + rect->right >= r->right && + rect->bottom >= r->bottom) + { + /* rect is not visible */ + list_remove_item(self->rects, i); + } + else if (rect->right < r->left || + rect->bottom < r->top || + rect->top > r->bottom || + rect->left > r->right) + { + /* rect are not related */ + } + else if (rect->left <= r->left && + rect->right >= r->right && + rect->bottom < r->bottom && + rect->top <= r->top) + { + /* partially covered(whole top) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, rect->bottom, + r->right, r->bottom); + } + else if (rect->top <= r->top && + rect->bottom >= r->bottom && + rect->right < r->right && + rect->left <= r->left) + { + /* partially covered(left) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, rect->right, r->top, + r->right, r->bottom); + } + else if (rect->left <= r->left && + rect->right >= r->right && + rect->top > r->top && + rect->bottom >= r->bottom) + { + /* partially covered(bottom) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + r->right, rect->top); + } + else if (rect->top <= r->top && + rect->bottom >= r->bottom && + rect->left > r->left && + rect->right >= r->right) + { + /* partially covered(right) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + rect->left, r->bottom); + } + else if (rect->left <= r->left && + rect->top <= r->top && + rect->right < r->right && + rect->bottom < r->bottom) + { + /* partially covered(top left) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, rect->right, r->top, + r->right, rect->bottom); + xrdp_region_insert_rect(self, i, r->left, rect->bottom, + r->right, r->bottom); + } + else if (rect->left <= r->left && + rect->bottom >= r->bottom && + rect->right < r->right && + rect->top > r->top) + { + /* partially covered(bottom left) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + r->right, rect->top); + xrdp_region_insert_rect(self, i, rect->right, rect->top, + r->right, r->bottom); + } + else if (rect->left > r->left && + rect->right >= r->right && + rect->top <= r->top && + rect->bottom < r->bottom) + { + /* partially covered(top right) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + rect->left, r->bottom); + xrdp_region_insert_rect(self, i, rect->left, rect->bottom, + r->right, r->bottom); + } + else if (rect->left > r->left && + rect->right >= r->right && + rect->top > r->top && + rect->bottom >= r->bottom) + { + /* partially covered(bottom right) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + r->right, rect->top); + xrdp_region_insert_rect(self, i, r->left, rect->top, + rect->left, r->bottom); + } + else if (rect->left > r->left && + rect->top <= r->top && + rect->right < r->right && + rect->bottom >= r->bottom) + { + /* 2 rects, one on each end */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + rect->left, r->bottom); + xrdp_region_insert_rect(self, i, rect->right, r->top, + r->right, r->bottom); + } + else if (rect->left <= r->left && + rect->top > r->top && + rect->right >= r->right && + rect->bottom < r->bottom) + { + /* 2 rects, one on each end */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + r->right, rect->top); + xrdp_region_insert_rect(self, i, r->left, rect->bottom, + r->right, r->bottom); + } + else if (rect->left > r->left && + rect->right < r->right && + rect->top <= r->top && + rect->bottom < r->bottom) + { + /* partially covered(top) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + rect->left, r->bottom); + xrdp_region_insert_rect(self, i, rect->left, rect->bottom, + rect->right, r->bottom); + xrdp_region_insert_rect(self, i, rect->right, r->top, + r->right, r->bottom); + } + else if (rect->top > r->top && + rect->bottom < r->bottom && + rect->left <= r->left && + rect->right < r->right) + { + /* partially covered(left) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + r->right, rect->top); + xrdp_region_insert_rect(self, i, rect->right, rect->top, + r->right, rect->bottom); + xrdp_region_insert_rect(self, i, r->left, rect->bottom, + r->right, r->bottom); + } + else if (rect->left > r->left && + rect->right < r->right && + rect->bottom >= r->bottom && + rect->top > r->top) + { + /* partially covered(bottom) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + rect->left, r->bottom); + xrdp_region_insert_rect(self, i, rect->left, r->top, + rect->right, rect->top); + xrdp_region_insert_rect(self, i, rect->right, r->top, + r->right, r->bottom); + } + else if (rect->top > r->top && + rect->bottom < r->bottom && + rect->right >= r->right && + rect->left > r->left) + { + /* partially covered(right) */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + r->right, rect->top); + xrdp_region_insert_rect(self, i, r->left, rect->top, + rect->left, rect->bottom); + xrdp_region_insert_rect(self, i, r->left, rect->bottom, + r->right, r->bottom); + } + else if (rect->left > r->left && + rect->top > r->top && + rect->right < r->right && + rect->bottom < r->bottom) + { + /* totally contained, 4 rects */ + list_remove_item(self->rects, i); + xrdp_region_insert_rect(self, i, r->left, r->top, + r->right, rect->top); + xrdp_region_insert_rect(self, i, r->left, rect->top, + rect->left, rect->bottom); + xrdp_region_insert_rect(self, i, r->left, rect->bottom, + r->right, r->bottom); + xrdp_region_insert_rect(self, i, rect->right, rect->top, + r->right, rect->bottom); + } + else + { + g_writeln("error in xrdp_region_subtract_rect"); + } } - } - return 0; + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_region_get_rect(struct xrdp_region* self, int index, - struct xrdp_rect* rect) +xrdp_region_get_rect(struct xrdp_region *self, int index, + struct xrdp_rect *rect) { - struct xrdp_rect* r; + struct xrdp_rect *r; - r = (struct xrdp_rect*)list_get_item(self->rects, index); - if (r == 0) - { - return 1; - } - *rect = *r; - return 0; + r = (struct xrdp_rect *)list_get_item(self->rects, index); + + if (r == 0) + { + return 1; + } + + *rect = *r; + return 0; } diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index e907e2a0..fdaed059 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -1,24 +1,23 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * types + */ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - types - -*/ #define DEFAULT_STRING_LEN 255 #define LOG_WINDOW_CHAR_PER_LINE 60 diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 7883d33e..24362f54 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -1,1383 +1,1528 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - simple window manager - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * simple window manager + */ #include "xrdp.h" /*****************************************************************************/ -struct xrdp_wm* APP_CC -xrdp_wm_create(struct xrdp_process* owner, - struct xrdp_client_info* client_info) +struct xrdp_wm *APP_CC +xrdp_wm_create(struct xrdp_process *owner, + struct xrdp_client_info *client_info) { - struct xrdp_wm* self = (struct xrdp_wm *)NULL; - char event_name[256]; - int pid = 0; + struct xrdp_wm *self = (struct xrdp_wm *)NULL; + char event_name[256]; + int pid = 0; - /* initialize (zero out) local variables: */ - g_memset(event_name,0,sizeof(char) * 256); + /* initialize (zero out) local variables: */ + g_memset(event_name, 0, sizeof(char) * 256); - self = (struct xrdp_wm*)g_malloc(sizeof(struct xrdp_wm), 1); - self->client_info = client_info; - self->screen = xrdp_bitmap_create(client_info->width, - client_info->height, - client_info->bpp, - WND_TYPE_SCREEN, self); - self->screen->wm = self; - self->pro_layer = owner; - self->session = owner->session; - pid = g_getpid(); - g_snprintf(event_name, 255, "xrdp_%8.8x_wm_login_mode_event_%8.8x", - pid, owner->session_id); - self->login_mode_event = g_create_wait_obj(event_name); - self->painter = xrdp_painter_create(self, self->session); - self->cache = xrdp_cache_create(self, self->session, self->client_info); - self->log = list_create(); - self->log->auto_free = 1; - self->mm = xrdp_mm_create(self); - self->default_font = xrdp_font_create(self); - /* this will use built in keymap or load from file */ - get_keymaps(self->session->client_info->keylayout, &(self->keymap)); - xrdp_wm_set_login_mode(self, 0); - self->target_surface = self->screen; - self->current_surface_index = 0xffff; /* screen */ - return self; + self = (struct xrdp_wm *)g_malloc(sizeof(struct xrdp_wm), 1); + self->client_info = client_info; + self->screen = xrdp_bitmap_create(client_info->width, + client_info->height, + client_info->bpp, + WND_TYPE_SCREEN, self); + self->screen->wm = self; + self->pro_layer = owner; + self->session = owner->session; + pid = g_getpid(); + g_snprintf(event_name, 255, "xrdp_%8.8x_wm_login_mode_event_%8.8x", + pid, owner->session_id); + self->login_mode_event = g_create_wait_obj(event_name); + self->painter = xrdp_painter_create(self, self->session); + self->cache = xrdp_cache_create(self, self->session, self->client_info); + self->log = list_create(); + self->log->auto_free = 1; + self->mm = xrdp_mm_create(self); + self->default_font = xrdp_font_create(self); + /* this will use built in keymap or load from file */ + get_keymaps(self->session->client_info->keylayout, &(self->keymap)); + xrdp_wm_set_login_mode(self, 0); + self->target_surface = self->screen; + self->current_surface_index = 0xffff; /* screen */ + return self; } /*****************************************************************************/ void APP_CC -xrdp_wm_delete(struct xrdp_wm* self) +xrdp_wm_delete(struct xrdp_wm *self) { - if (self == 0) - { - return; - } - xrdp_mm_delete(self->mm); - xrdp_cache_delete(self->cache); - xrdp_painter_delete(self->painter); - xrdp_bitmap_delete(self->screen); - /* free the log */ - list_delete(self->log); - /* free default font */ - xrdp_font_delete(self->default_font); - g_delete_wait_obj(self->login_mode_event); - /* free self */ - g_free(self); + if (self == 0) + { + return; + } + + xrdp_mm_delete(self->mm); + xrdp_cache_delete(self->cache); + xrdp_painter_delete(self->painter); + xrdp_bitmap_delete(self->screen); + /* free the log */ + list_delete(self->log); + /* free default font */ + xrdp_font_delete(self->default_font); + g_delete_wait_obj(self->login_mode_event); + /* free self */ + g_free(self); } /*****************************************************************************/ int APP_CC -xrdp_wm_send_palette(struct xrdp_wm* self) +xrdp_wm_send_palette(struct xrdp_wm *self) { - return libxrdp_send_palette(self->session, self->palette); + return libxrdp_send_palette(self->session, self->palette); } /*****************************************************************************/ int APP_CC -xrdp_wm_send_bell(struct xrdp_wm* self) +xrdp_wm_send_bell(struct xrdp_wm *self) { - return libxrdp_send_bell(self->session); + return libxrdp_send_bell(self->session); } /*****************************************************************************/ int APP_CC -xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap, +xrdp_wm_send_bitmap(struct xrdp_wm *self, struct xrdp_bitmap *bitmap, int x, int y, int cx, int cy) { - return libxrdp_send_bitmap(self->session, bitmap->width, bitmap->height, - bitmap->bpp, bitmap->data, x, y, cx, cy); + return libxrdp_send_bitmap(self->session, bitmap->width, bitmap->height, + bitmap->bpp, bitmap->data, x, y, cx, cy); } /*****************************************************************************/ int APP_CC -xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd) +xrdp_wm_set_focused(struct xrdp_wm *self, struct xrdp_bitmap *wnd) { - struct xrdp_bitmap* focus_out_control; - struct xrdp_bitmap* focus_in_control; + struct xrdp_bitmap *focus_out_control; + struct xrdp_bitmap *focus_in_control; - if (self == 0) - { + if (self == 0) + { + return 0; + } + + if (self->focused_window == wnd) + { + return 0; + } + + focus_out_control = 0; + focus_in_control = 0; + + if (self->focused_window != 0) + { + xrdp_bitmap_set_focus(self->focused_window, 0); + focus_out_control = self->focused_window->focused_control; + } + + self->focused_window = wnd; + + if (self->focused_window != 0) + { + xrdp_bitmap_set_focus(self->focused_window, 1); + focus_in_control = self->focused_window->focused_control; + } + + xrdp_bitmap_invalidate(focus_out_control, 0); + xrdp_bitmap_invalidate(focus_in_control, 0); return 0; - } - if (self->focused_window == wnd) - { - return 0; - } - focus_out_control = 0; - focus_in_control = 0; - if (self->focused_window != 0) - { - xrdp_bitmap_set_focus(self->focused_window, 0); - focus_out_control = self->focused_window->focused_control; - } - self->focused_window = wnd; - if (self->focused_window != 0) - { - xrdp_bitmap_set_focus(self->focused_window, 1); - focus_in_control = self->focused_window->focused_control; - } - xrdp_bitmap_invalidate(focus_out_control, 0); - xrdp_bitmap_invalidate(focus_in_control, 0); - return 0; } /******************************************************************************/ static int APP_CC -xrdp_wm_get_pixel(char* data, int x, int y, int width, int bpp) +xrdp_wm_get_pixel(char *data, int x, int y, int width, int bpp) { - int start; - int shift; + int start; + int shift; - if (bpp == 1) - { - width = (width + 7) / 8; - start = (y * width) + x / 8; - shift = x % 8; - return (data[start] & (0x80 >> shift)) != 0; - } - else if (bpp == 4) - { - width = (width + 1) / 2; - start = y * width + x / 2; - shift = x % 2; - if (shift == 0) + if (bpp == 1) { - return (data[start] & 0xf0) >> 4; + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + return (data[start] & (0x80 >> shift)) != 0; } - else + else if (bpp == 4) { - return data[start] & 0x0f; + width = (width + 1) / 2; + start = y * width + x / 2; + shift = x % 2; + + if (shift == 0) + { + return (data[start] & 0xf0) >> 4; + } + else + { + return data[start] & 0x0f; + } } - } - return 0; + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_wm_pointer(struct xrdp_wm* self, char* data, char* mask, int x, int y) +xrdp_wm_pointer(struct xrdp_wm *self, char *data, char *mask, int x, int y) { - struct xrdp_pointer_item pointer_item; + struct xrdp_pointer_item pointer_item; - g_memset(&pointer_item, 0, sizeof(struct xrdp_pointer_item)); - pointer_item.x = x; - pointer_item.y = y; - g_memcpy(pointer_item.data, data, 32 * 32 * 3); - g_memcpy(pointer_item.mask, mask, 32 * 32 / 8); - self->screen->pointer = xrdp_cache_add_pointer(self->cache, &pointer_item); - return 0; + g_memset(&pointer_item, 0, sizeof(struct xrdp_pointer_item)); + pointer_item.x = x; + pointer_item.y = y; + g_memcpy(pointer_item.data, data, 32 * 32 * 3); + g_memcpy(pointer_item.mask, mask, 32 * 32 / 8); + self->screen->pointer = xrdp_cache_add_pointer(self->cache, &pointer_item); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_wm_load_pointer(struct xrdp_wm* self, char* file_name, char* data, - char* mask, int* x, int* y) +xrdp_wm_load_pointer(struct xrdp_wm *self, char *file_name, char *data, + char *mask, int *x, int *y) { - int fd; - int bpp; - int w; - int h; - int i; - int j; - int pixel; - int palette[16]; - struct stream* fs; + int fd; + int bpp; + int w; + int h; + int i; + int j; + int pixel; + int palette[16]; + struct stream *fs; - if (!g_file_exist(file_name)) - { - g_writeln("xrdp_wm_load_pointer: error pointer file [%s] does not exist", - file_name); - return 1; - } - make_stream(fs); - init_stream(fs, 8192); - fd = g_file_open(file_name); - if (fd < 1) - { - g_writeln("xrdp_wm_load_pointer: error loading pointer from file [%s]", - file_name); - return 1; - } - g_file_read(fd, fs->data, 8192); - g_file_close(fd); - in_uint8s(fs, 6); - in_uint8(fs, w); - in_uint8(fs, h); - in_uint8s(fs, 2); - in_uint16_le(fs, *x); - in_uint16_le(fs, *y); - in_uint8s(fs, 22); - in_uint8(fs, bpp); - in_uint8s(fs, 25); - if (w == 32 && h == 32) - { - if (bpp == 1) + if (!g_file_exist(file_name)) { - in_uint8a(fs, palette, 8); - for (i = 0; i < 32; i++) - { - for (j = 0; j < 32; j++) - { - pixel = palette[xrdp_wm_get_pixel(fs->p, j, i, 32, 1)]; - *data = pixel; - data++; - *data = pixel >> 8; - data++; - *data = pixel >> 16; - data++; - } - } - in_uint8s(fs, 128); + g_writeln("xrdp_wm_load_pointer: error pointer file [%s] does not exist", + file_name); + return 1; } - else if (bpp == 4) + + make_stream(fs); + init_stream(fs, 8192); + fd = g_file_open(file_name); + + if (fd < 1) { - in_uint8a(fs, palette, 64); - for (i = 0; i < 32; i++) - { - for (j = 0; j < 32; j++) - { - pixel = palette[xrdp_wm_get_pixel(fs->p, j, i, 32, 1)]; - *data = pixel; - data++; - *data = pixel >> 8; - data++; - *data = pixel >> 16; - data++; - } - } - in_uint8s(fs, 512); + g_writeln("xrdp_wm_load_pointer: error loading pointer from file [%s]", + file_name); + return 1; } - g_memcpy(mask, fs->p, 128); /* mask */ - } - free_stream(fs); - return 0; + + g_file_read(fd, fs->data, 8192); + g_file_close(fd); + in_uint8s(fs, 6); + in_uint8(fs, w); + in_uint8(fs, h); + in_uint8s(fs, 2); + in_uint16_le(fs, *x); + in_uint16_le(fs, *y); + in_uint8s(fs, 22); + in_uint8(fs, bpp); + in_uint8s(fs, 25); + + if (w == 32 && h == 32) + { + if (bpp == 1) + { + in_uint8a(fs, palette, 8); + + for (i = 0; i < 32; i++) + { + for (j = 0; j < 32; j++) + { + pixel = palette[xrdp_wm_get_pixel(fs->p, j, i, 32, 1)]; + *data = pixel; + data++; + *data = pixel >> 8; + data++; + *data = pixel >> 16; + data++; + } + } + + in_uint8s(fs, 128); + } + else if (bpp == 4) + { + in_uint8a(fs, palette, 64); + + for (i = 0; i < 32; i++) + { + for (j = 0; j < 32; j++) + { + pixel = palette[xrdp_wm_get_pixel(fs->p, j, i, 32, 1)]; + *data = pixel; + data++; + *data = pixel >> 8; + data++; + *data = pixel >> 16; + data++; + } + } + + in_uint8s(fs, 512); + } + + g_memcpy(mask, fs->p, 128); /* mask */ + } + + free_stream(fs); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_wm_send_pointer(struct xrdp_wm* self, int cache_idx, - char* data, char* mask, int x, int y) +xrdp_wm_send_pointer(struct xrdp_wm *self, int cache_idx, + char *data, char *mask, int x, int y) { - return libxrdp_send_pointer(self->session, cache_idx, data, mask, x, y); + return libxrdp_send_pointer(self->session, cache_idx, data, mask, x, y); } /*****************************************************************************/ int APP_CC -xrdp_wm_set_pointer(struct xrdp_wm* self, int cache_idx) +xrdp_wm_set_pointer(struct xrdp_wm *self, int cache_idx) { - return libxrdp_set_pointer(self->session, cache_idx); + return libxrdp_set_pointer(self->session, cache_idx); } /*****************************************************************************/ /* convert hex string to int */ unsigned int xrdp_wm_htoi (const char *ptr) { - unsigned int value = 0; - char ch = *ptr; + unsigned int value = 0; + char ch = *ptr; - while (ch == ' ' || ch == '\t') - ch = *(++ptr); + while (ch == ' ' || ch == '\t') + { + ch = *(++ptr); + } - for (;;) - { - if (ch >= '0' && ch <= '9') - value = (value << 4) + (ch - '0'); - else if (ch >= 'A' && ch <= 'F') - value = (value << 4) + (ch - 'A' + 10); - else if (ch >= 'a' && ch <= 'f') - value = (value << 4) + (ch - 'a' + 10); - else - return value; - ch = *(++ptr); - } + for (;;) + { + if (ch >= '0' && ch <= '9') + { + value = (value << 4) + (ch - '0'); + } + else if (ch >= 'A' && ch <= 'F') + { + value = (value << 4) + (ch - 'A' + 10); + } + else if (ch >= 'a' && ch <= 'f') + { + value = (value << 4) + (ch - 'a' + 10); + } + else + { + return value; + } + + ch = *(++ptr); + } } /*****************************************************************************/ int APP_CC -xrdp_wm_load_static_colors_plus(struct xrdp_wm* self, char* autorun_name) +xrdp_wm_load_static_colors_plus(struct xrdp_wm *self, char *autorun_name) { - int bindex; - int gindex; - int rindex; + int bindex; + int gindex; + int rindex; - int fd; - int index; - char* val; - struct list* names; - struct list* values; - char cfg_file[256]; + int fd; + int index; + char *val; + struct list *names; + struct list *values; + char cfg_file[256]; - if (autorun_name != 0) - { - autorun_name[0] = 0; - } - - /* initialize with defaults */ - self->black = HCOLOR(self->screen->bpp,0x000000); - self->grey = HCOLOR(self->screen->bpp,0xc0c0c0); - self->dark_grey = HCOLOR(self->screen->bpp,0x808080); - self->blue = HCOLOR(self->screen->bpp,0x0000ff); - self->dark_blue = HCOLOR(self->screen->bpp,0x00007f); - self->white = HCOLOR(self->screen->bpp,0xffffff); - self->red = HCOLOR(self->screen->bpp,0xff0000); - self->green = HCOLOR(self->screen->bpp,0x00ff00); - self->background = HCOLOR(self->screen->bpp,0x000000); - - /* now load them from the globals in xrdp.ini if defined */ - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); - if (fd > 0) - { - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - if (file_read_section(fd, "globals", names, values) == 0) + if (autorun_name != 0) { - for (index = 0; index < names->count; index++) - { - val = (char*)list_get_item(names, index); - if (val != 0) - { - if (g_strcasecmp(val, "black") == 0) - { - val = (char*)list_get_item(values, index); - self->black = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val)); - } - else if (g_strcasecmp(val, "grey") == 0) - { - val = (char*)list_get_item(values, index); - self->grey = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val)); - } - else if (g_strcasecmp(val, "dark_grey") == 0) - { - val = (char*)list_get_item(values, index); - self->dark_grey = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val)); - } - else if (g_strcasecmp(val, "blue") == 0) - { - val = (char*)list_get_item(values, index); - self->blue = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val)); - } - else if (g_strcasecmp(val, "dark_blue") == 0) - { - val = (char*)list_get_item(values, index); - self->dark_blue = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val)); - } - else if (g_strcasecmp(val, "white") == 0) - { - val = (char*)list_get_item(values, index); - self->white = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val)); - } - else if (g_strcasecmp(val, "red") == 0) - { - val = (char*)list_get_item(values, index); - self->red = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val)); - } - else if (g_strcasecmp(val, "green") == 0) - { - val = (char*)list_get_item(values, index); - self->green = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val)); - } - else if (g_strcasecmp(val, "background") == 0) - { - val = (char*)list_get_item(values, index); - self->background = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val)); - } - else if (g_strcasecmp(val, "autorun") == 0) - { - val = (char*)list_get_item(values, index); - if (autorun_name != 0) - { - g_strncpy(autorun_name, val, 255); - } - } - else if (g_strcasecmp(val, "hidelogwindow") == 0) - { - val = (char*)list_get_item(values, index); - if ((g_strcasecmp(val, "yes") == 0) || - (g_strcasecmp(val, "1") == 0) || - (g_strcasecmp(val, "true") == 0)) - { - self->hide_log_window = 1; - } - } - } - } + autorun_name[0] = 0; } - list_delete(names); - list_delete(values); - g_file_close(fd); - } - else - { - g_writeln("xrdp_wm_load_static_colors: Could not read xrdp.ini file %s", cfg_file); - } - if (self->screen->bpp == 8) - { - /* rgb332 */ - for (bindex = 0; bindex < 4; bindex++) + /* initialize with defaults */ + self->black = HCOLOR(self->screen->bpp, 0x000000); + self->grey = HCOLOR(self->screen->bpp, 0xc0c0c0); + self->dark_grey = HCOLOR(self->screen->bpp, 0x808080); + self->blue = HCOLOR(self->screen->bpp, 0x0000ff); + self->dark_blue = HCOLOR(self->screen->bpp, 0x00007f); + self->white = HCOLOR(self->screen->bpp, 0xffffff); + self->red = HCOLOR(self->screen->bpp, 0xff0000); + self->green = HCOLOR(self->screen->bpp, 0x00ff00); + self->background = HCOLOR(self->screen->bpp, 0x000000); + + /* now load them from the globals in xrdp.ini if defined */ + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + fd = g_file_open(cfg_file); + + if (fd > 0) { - for (gindex = 0; gindex < 8; gindex++) - { - for (rindex = 0; rindex < 8; rindex++) + names = list_create(); + names->auto_free = 1; + values = list_create(); + values->auto_free = 1; + + if (file_read_section(fd, "globals", names, values) == 0) { - self->palette[(bindex << 6) | (gindex << 3) | rindex] = - (((rindex << 5) | (rindex << 2) | (rindex >> 1)) << 16) | - (((gindex << 5) | (gindex << 2) | (gindex >> 1)) << 8) | - ((bindex << 6) | (bindex << 4) | (bindex << 2) | (bindex)); + for (index = 0; index < names->count; index++) + { + val = (char *)list_get_item(names, index); + + if (val != 0) + { + if (g_strcasecmp(val, "black") == 0) + { + val = (char *)list_get_item(values, index); + self->black = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); + } + else if (g_strcasecmp(val, "grey") == 0) + { + val = (char *)list_get_item(values, index); + self->grey = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); + } + else if (g_strcasecmp(val, "dark_grey") == 0) + { + val = (char *)list_get_item(values, index); + self->dark_grey = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); + } + else if (g_strcasecmp(val, "blue") == 0) + { + val = (char *)list_get_item(values, index); + self->blue = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); + } + else if (g_strcasecmp(val, "dark_blue") == 0) + { + val = (char *)list_get_item(values, index); + self->dark_blue = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); + } + else if (g_strcasecmp(val, "white") == 0) + { + val = (char *)list_get_item(values, index); + self->white = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); + } + else if (g_strcasecmp(val, "red") == 0) + { + val = (char *)list_get_item(values, index); + self->red = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); + } + else if (g_strcasecmp(val, "green") == 0) + { + val = (char *)list_get_item(values, index); + self->green = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); + } + else if (g_strcasecmp(val, "background") == 0) + { + val = (char *)list_get_item(values, index); + self->background = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); + } + else if (g_strcasecmp(val, "autorun") == 0) + { + val = (char *)list_get_item(values, index); + + if (autorun_name != 0) + { + g_strncpy(autorun_name, val, 255); + } + } + else if (g_strcasecmp(val, "hidelogwindow") == 0) + { + val = (char *)list_get_item(values, index); + + if ((g_strcasecmp(val, "yes") == 0) || + (g_strcasecmp(val, "1") == 0) || + (g_strcasecmp(val, "true") == 0)) + { + self->hide_log_window = 1; + } + } + } + } } - } + + list_delete(names); + list_delete(values); + g_file_close(fd); } - xrdp_wm_send_palette(self); - } - return 0; + else + { + g_writeln("xrdp_wm_load_static_colors: Could not read xrdp.ini file %s", cfg_file); + } + + if (self->screen->bpp == 8) + { + /* rgb332 */ + for (bindex = 0; bindex < 4; bindex++) + { + for (gindex = 0; gindex < 8; gindex++) + { + for (rindex = 0; rindex < 8; rindex++) + { + self->palette[(bindex << 6) | (gindex << 3) | rindex] = + (((rindex << 5) | (rindex << 2) | (rindex >> 1)) << 16) | + (((gindex << 5) | (gindex << 2) | (gindex >> 1)) << 8) | + ((bindex << 6) | (bindex << 4) | (bindex << 2) | (bindex)); + } + } + } + + xrdp_wm_send_palette(self); + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_wm_load_static_pointers(struct xrdp_wm* self) +xrdp_wm_load_static_pointers(struct xrdp_wm *self) { - struct xrdp_pointer_item pointer_item; - char file_path[256]; + struct xrdp_pointer_item pointer_item; + char file_path[256]; - DEBUG(("sending cursor")); - g_snprintf(file_path, 255, "%s/cursor1.cur", XRDP_SHARE_PATH); - g_memset(&pointer_item, 0, sizeof(pointer_item)); - xrdp_wm_load_pointer(self, file_path, pointer_item.data, - pointer_item.mask, &pointer_item.x, &pointer_item.y); - xrdp_cache_add_pointer_static(self->cache, &pointer_item, 1); - DEBUG(("sending cursor")); - g_snprintf(file_path, 255, "%s/cursor0.cur", XRDP_SHARE_PATH); - g_memset(&pointer_item, 0, sizeof(pointer_item)); - xrdp_wm_load_pointer(self, file_path, pointer_item.data, - pointer_item.mask, &pointer_item.x, &pointer_item.y); - xrdp_cache_add_pointer_static(self->cache, &pointer_item, 0); - return 0; + DEBUG(("sending cursor")); + g_snprintf(file_path, 255, "%s/cursor1.cur", XRDP_SHARE_PATH); + g_memset(&pointer_item, 0, sizeof(pointer_item)); + xrdp_wm_load_pointer(self, file_path, pointer_item.data, + pointer_item.mask, &pointer_item.x, &pointer_item.y); + xrdp_cache_add_pointer_static(self->cache, &pointer_item, 1); + DEBUG(("sending cursor")); + g_snprintf(file_path, 255, "%s/cursor0.cur", XRDP_SHARE_PATH); + g_memset(&pointer_item, 0, sizeof(pointer_item)); + xrdp_wm_load_pointer(self, file_path, pointer_item.data, + pointer_item.mask, &pointer_item.x, &pointer_item.y); + xrdp_cache_add_pointer_static(self->cache, &pointer_item, 0); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_wm_init(struct xrdp_wm* self) +xrdp_wm_init(struct xrdp_wm *self) { - int fd; - int index; - struct list* names; - struct list* values; - char* q; - char* r; - char section_name[256]; - char cfg_file[256]; - char autorun_name[256]; + int fd; + int index; + struct list *names; + struct list *values; + char *q; + char *r; + char section_name[256]; + char cfg_file[256]; + char autorun_name[256]; - xrdp_wm_load_static_colors_plus(self, autorun_name); - xrdp_wm_load_static_pointers(self); - self->screen->bg_color = self->background; - if (self->session->client_info->rdp_autologin || (autorun_name[0] != 0)) - { - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); /* xrdp.ini */ - if (fd > 0) + xrdp_wm_load_static_colors_plus(self, autorun_name); + xrdp_wm_load_static_pointers(self); + self->screen->bg_color = self->background; + + if (self->session->client_info->rdp_autologin || (autorun_name[0] != 0)) { - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - g_strncpy(section_name, self->session->client_info->domain, 255); - if (section_name[0] == 0) - { - if (autorun_name[0] == 0) + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + fd = g_file_open(cfg_file); /* xrdp.ini */ + + if (fd > 0) { - /* if no doamin is passed, and no autorun in xrdp.ini, - use the first item in the xrdp.ini - file thats not named 'globals' */ - file_read_sections(fd, names); - for (index = 0; index < names->count; index++) - { - q = (char*)list_get_item(names, index); - if (g_strncasecmp("globals", q, 8) != 0) + names = list_create(); + names->auto_free = 1; + values = list_create(); + values->auto_free = 1; + g_strncpy(section_name, self->session->client_info->domain, 255); + + if (section_name[0] == 0) { - g_strncpy(section_name, q, 255); - break; + if (autorun_name[0] == 0) + { + /* if no doamin is passed, and no autorun in xrdp.ini, + use the first item in the xrdp.ini + file thats not named 'globals' */ + file_read_sections(fd, names); + + for (index = 0; index < names->count; index++) + { + q = (char *)list_get_item(names, index); + + if (g_strncasecmp("globals", q, 8) != 0) + { + g_strncpy(section_name, q, 255); + break; + } + } + } + else + { + g_strncpy(section_name, autorun_name, 255); + } } - } + + list_clear(names); + + if (file_read_section(fd, section_name, names, values) == 0) + { + for (index = 0; index < names->count; index++) + { + q = (char *)list_get_item(names, index); + r = (char *)list_get_item(values, index); + + if (g_strncmp("password", q, 255) == 0) + { + /* if the password has been asked for by the module, use what the + client says. + if the password has been manually set in the config, use that + instead of what the client says. */ + if (g_strncmp("ask", r, 3) == 0) + { + r = self->session->client_info->password; + } + } + else if (g_strncmp("username", q, 255) == 0) + { + /* if the username has been asked for by the module, use what the + client says. + if the username has been manually set in the config, use that + instead of what the client says. */ + if (g_strncmp("ask", r, 3) == 0) + { + r = self->session->client_info->username; + } + } + + list_add_item(self->mm->login_names, (long)g_strdup(q)); + list_add_item(self->mm->login_values, (long)g_strdup(r)); + } + + xrdp_wm_set_login_mode(self, 2); + } + + list_delete(names); + list_delete(values); + g_file_close(fd); } else { - g_strncpy(section_name, autorun_name, 255); + g_writeln("xrdp_wm_init: Could not read xrdp.ini file %s", cfg_file); } - } - list_clear(names); - if (file_read_section(fd, section_name, names, values) == 0) - { - for (index = 0; index < names->count; index++) - { - q = (char*)list_get_item(names, index); - r = (char*)list_get_item(values, index); - if (g_strncmp("password", q, 255) == 0) - { - /* if the password has been asked for by the module, use what the - client says. - if the password has been manually set in the config, use that - instead of what the client says. */ - if (g_strncmp("ask", r, 3) == 0) - { - r = self->session->client_info->password; - } - } - else if (g_strncmp("username", q, 255) == 0) - { - /* if the username has been asked for by the module, use what the - client says. - if the username has been manually set in the config, use that - instead of what the client says. */ - if (g_strncmp("ask", r, 3) == 0) - { - r = self->session->client_info->username; - } - } - list_add_item(self->mm->login_names, (long)g_strdup(q)); - list_add_item(self->mm->login_values, (long)g_strdup(r)); - } - xrdp_wm_set_login_mode(self, 2); - } - list_delete(names); - list_delete(values); - g_file_close(fd); } else { - g_writeln("xrdp_wm_init: Could not read xrdp.ini file %s", cfg_file); + xrdp_login_wnd_create(self); + /* clear screen */ + xrdp_bitmap_invalidate(self->screen, 0); + xrdp_wm_set_focused(self, self->login_window); + xrdp_wm_set_login_mode(self, 1); } - } - else - { - xrdp_login_wnd_create(self); - /* clear screen */ - xrdp_bitmap_invalidate(self->screen, 0); - xrdp_wm_set_focused(self, self->login_window); - xrdp_wm_set_login_mode(self, 1); - } - return 0; + + return 0; } /*****************************************************************************/ /* returns the number for rects visible for an area relative to a drawable */ /* putting the rects in region */ int APP_CC -xrdp_wm_get_vis_region(struct xrdp_wm* self, struct xrdp_bitmap* bitmap, +xrdp_wm_get_vis_region(struct xrdp_wm *self, struct xrdp_bitmap *bitmap, int x, int y, int cx, int cy, - struct xrdp_region* region, int clip_children) + struct xrdp_region *region, int clip_children) { - int i; - struct xrdp_bitmap* p; - struct xrdp_rect a; - struct xrdp_rect b; + int i; + struct xrdp_bitmap *p; + struct xrdp_rect a; + struct xrdp_rect b; - /* area we are drawing */ - MAKERECT(a, bitmap->left + x, bitmap->top + y, cx, cy); - p = bitmap->parent; - while (p != 0) - { - RECTOFFSET(a, p->left, p->top); - p = p->parent; - } - a.left = MAX(self->screen->left, a.left); - a.top = MAX(self->screen->top, a.top); - a.right = MIN(self->screen->left + self->screen->width, a.right); - a.bottom = MIN(self->screen->top + self->screen->height, a.bottom); - xrdp_region_add_rect(region, &a); - if (clip_children) - { - /* loop through all windows in z order */ - for (i = 0; i < self->screen->child_list->count; i++) + /* area we are drawing */ + MAKERECT(a, bitmap->left + x, bitmap->top + y, cx, cy); + p = bitmap->parent; + + while (p != 0) { - p = (struct xrdp_bitmap*)list_get_item(self->screen->child_list, i); - if (p == bitmap || p == bitmap->parent) - { - return 0; - } - MAKERECT(b, p->left, p->top, p->width, p->height); - xrdp_region_subtract_rect(region, &b); + RECTOFFSET(a, p->left, p->top); + p = p->parent; } - } - return 0; + + a.left = MAX(self->screen->left, a.left); + a.top = MAX(self->screen->top, a.top); + a.right = MIN(self->screen->left + self->screen->width, a.right); + a.bottom = MIN(self->screen->top + self->screen->height, a.bottom); + xrdp_region_add_rect(region, &a); + + if (clip_children) + { + /* loop through all windows in z order */ + for (i = 0; i < self->screen->child_list->count; i++) + { + p = (struct xrdp_bitmap *)list_get_item(self->screen->child_list, i); + + if (p == bitmap || p == bitmap->parent) + { + return 0; + } + + MAKERECT(b, p->left, p->top, p->width, p->height); + xrdp_region_subtract_rect(region, &b); + } + } + + return 0; } /*****************************************************************************/ /* return the window at x, y on the screen */ -static struct xrdp_bitmap* APP_CC -xrdp_wm_at_pos(struct xrdp_bitmap* wnd, int x, int y, - struct xrdp_bitmap** wnd1) +static struct xrdp_bitmap *APP_CC +xrdp_wm_at_pos(struct xrdp_bitmap *wnd, int x, int y, + struct xrdp_bitmap **wnd1) { - int i; - struct xrdp_bitmap* p; - struct xrdp_bitmap* q; + int i; + struct xrdp_bitmap *p; + struct xrdp_bitmap *q; - /* loop through all windows in z order */ - for (i = 0; i < wnd->child_list->count; i++) - { - p = (struct xrdp_bitmap*)list_get_item(wnd->child_list, i); - if (x >= p->left && y >= p->top && x < p->left + p->width && - y < p->top + p->height) + /* loop through all windows in z order */ + for (i = 0; i < wnd->child_list->count; i++) { - if (wnd1 != 0) - { - *wnd1 = p; - } - q = xrdp_wm_at_pos(p, x - p->left, y - p->top, 0); - if (q == 0) - { - return p; - } - else - { - return q; - } + p = (struct xrdp_bitmap *)list_get_item(wnd->child_list, i); + + if (x >= p->left && y >= p->top && x < p->left + p->width && + y < p->top + p->height) + { + if (wnd1 != 0) + { + *wnd1 = p; + } + + q = xrdp_wm_at_pos(p, x - p->left, y - p->top, 0); + + if (q == 0) + { + return p; + } + else + { + return q; + } + } } - } - return 0; + + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_wm_xor_pat(struct xrdp_wm* self, int x, int y, int cx, int cy) +xrdp_wm_xor_pat(struct xrdp_wm *self, int x, int y, int cx, int cy) { - self->painter->clip_children = 0; - self->painter->rop = 0x5a; - xrdp_painter_begin_update(self->painter); - self->painter->use_clip = 0; - self->painter->mix_mode = 1; - self->painter->brush.pattern[0] = 0xaa; - self->painter->brush.pattern[1] = 0x55; - self->painter->brush.pattern[2] = 0xaa; - self->painter->brush.pattern[3] = 0x55; - self->painter->brush.pattern[4] = 0xaa; - self->painter->brush.pattern[5] = 0x55; - self->painter->brush.pattern[6] = 0xaa; - self->painter->brush.pattern[7] = 0x55; - self->painter->brush.x_orgin = 0; - self->painter->brush.x_orgin = 0; - self->painter->brush.style = 3; - self->painter->bg_color = self->black; - self->painter->fg_color = self->white; - /* top */ - xrdp_painter_fill_rect(self->painter, self->screen, x, y, cx, 5); - /* bottom */ - xrdp_painter_fill_rect(self->painter, self->screen, x, y + (cy - 5), cx, 5); - /* left */ - xrdp_painter_fill_rect(self->painter, self->screen, x, y + 5, 5, cy - 10); - /* right */ - xrdp_painter_fill_rect(self->painter, self->screen, x + (cx - 5), y + 5, 5, - cy - 10); - xrdp_painter_end_update(self->painter); - self->painter->rop = 0xcc; - self->painter->clip_children = 1; - self->painter->mix_mode = 0; - return 0; + self->painter->clip_children = 0; + self->painter->rop = 0x5a; + xrdp_painter_begin_update(self->painter); + self->painter->use_clip = 0; + self->painter->mix_mode = 1; + self->painter->brush.pattern[0] = 0xaa; + self->painter->brush.pattern[1] = 0x55; + self->painter->brush.pattern[2] = 0xaa; + self->painter->brush.pattern[3] = 0x55; + self->painter->brush.pattern[4] = 0xaa; + self->painter->brush.pattern[5] = 0x55; + self->painter->brush.pattern[6] = 0xaa; + self->painter->brush.pattern[7] = 0x55; + self->painter->brush.x_orgin = 0; + self->painter->brush.x_orgin = 0; + self->painter->brush.style = 3; + self->painter->bg_color = self->black; + self->painter->fg_color = self->white; + /* top */ + xrdp_painter_fill_rect(self->painter, self->screen, x, y, cx, 5); + /* bottom */ + xrdp_painter_fill_rect(self->painter, self->screen, x, y + (cy - 5), cx, 5); + /* left */ + xrdp_painter_fill_rect(self->painter, self->screen, x, y + 5, 5, cy - 10); + /* right */ + xrdp_painter_fill_rect(self->painter, self->screen, x + (cx - 5), y + 5, 5, + cy - 10); + xrdp_painter_end_update(self->painter); + self->painter->rop = 0xcc; + self->painter->clip_children = 1; + self->painter->mix_mode = 0; + return 0; } /*****************************************************************************/ /* this don't are about nothing, just copy the bits */ /* no clipping rects, no windows in the way, nothing */ static int APP_CC -xrdp_wm_bitblt(struct xrdp_wm* self, - struct xrdp_bitmap* dst, int dx, int dy, - struct xrdp_bitmap* src, int sx, int sy, +xrdp_wm_bitblt(struct xrdp_wm *self, + struct xrdp_bitmap *dst, int dx, int dy, + struct xrdp_bitmap *src, int sx, int sy, int sw, int sh, int rop) { -// int i; -// int line_size; -// int Bpp; -// char* s; -// char* d; + // int i; + // int line_size; + // int Bpp; + // char* s; + // char* d; -// if (sw <= 0 || sh <= 0) -// return 0; - if (self->screen == dst && self->screen == src) - { /* send a screen blt */ -// Bpp = (dst->bpp + 7) / 8; -// line_size = sw * Bpp; -// s = src->data + (sy * src->width + sx) * Bpp; -// d = dst->data + (dy * dst->width + dx) * Bpp; -// for (i = 0; i < sh; i++) -// { -// //g_memcpy(d, s, line_size); -// s += src->width * Bpp; -// d += dst->width * Bpp; -// } - libxrdp_orders_init(self->session); - libxrdp_orders_screen_blt(self->session, dx, dy, sw, sh, sx, sy, rop, 0); - libxrdp_orders_send(self->session); - } - return 0; + // if (sw <= 0 || sh <= 0) + // return 0; + if (self->screen == dst && self->screen == src) + { + /* send a screen blt */ + // Bpp = (dst->bpp + 7) / 8; + // line_size = sw * Bpp; + // s = src->data + (sy * src->width + sx) * Bpp; + // d = dst->data + (dy * dst->width + dx) * Bpp; + // for (i = 0; i < sh; i++) + // { + // //g_memcpy(d, s, line_size); + // s += src->width * Bpp; + // d += dst->width * Bpp; + // } + libxrdp_orders_init(self->session); + libxrdp_orders_screen_blt(self->session, dx, dy, sw, sh, sx, sy, rop, 0); + libxrdp_orders_send(self->session); + } + + return 0; } /*****************************************************************************/ /* return true is rect is totaly exposed going in reverse z order */ /* from wnd up */ static int APP_CC -xrdp_wm_is_rect_vis(struct xrdp_wm* self, struct xrdp_bitmap* wnd, - struct xrdp_rect* rect) +xrdp_wm_is_rect_vis(struct xrdp_wm *self, struct xrdp_bitmap *wnd, + struct xrdp_rect *rect) { - struct xrdp_rect wnd_rect; - struct xrdp_bitmap* b; - int i;; + struct xrdp_rect wnd_rect; + struct xrdp_bitmap *b; + int i;; - /* if rect is part off screen */ - if (rect->left < 0) - { - return 0; - } - if (rect->top < 0) - { - return 0; - } - if (rect->right >= self->screen->width) - { - return 0; - } - if (rect->bottom >= self->screen->height) - { - return 0; - } - - i = list_index_of(self->screen->child_list, (long)wnd); - i--; - while (i >= 0) - { - b = (struct xrdp_bitmap*)list_get_item(self->screen->child_list, i); - MAKERECT(wnd_rect, b->left, b->top, b->width, b->height); - if (rect_intersect(rect, &wnd_rect, 0)) + /* if rect is part off screen */ + if (rect->left < 0) { - return 0; + return 0; } + + if (rect->top < 0) + { + return 0; + } + + if (rect->right >= self->screen->width) + { + return 0; + } + + if (rect->bottom >= self->screen->height) + { + return 0; + } + + i = list_index_of(self->screen->child_list, (long)wnd); i--; - } - return 1; + + while (i >= 0) + { + b = (struct xrdp_bitmap *)list_get_item(self->screen->child_list, i); + MAKERECT(wnd_rect, b->left, b->top, b->width, b->height); + + if (rect_intersect(rect, &wnd_rect, 0)) + { + return 0; + } + + i--; + } + + return 1; } /*****************************************************************************/ static int APP_CC -xrdp_wm_move_window(struct xrdp_wm* self, struct xrdp_bitmap* wnd, +xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd, int dx, int dy) { - struct xrdp_rect rect1; - struct xrdp_rect rect2; - struct xrdp_region* r; - int i; + struct xrdp_rect rect1; + struct xrdp_rect rect2; + struct xrdp_region *r; + int i; - MAKERECT(rect1, wnd->left, wnd->top, wnd->width, wnd->height); - if (xrdp_wm_is_rect_vis(self, wnd, &rect1)) - { - rect2 = rect1; - RECTOFFSET(rect2, dx, dy); - if (xrdp_wm_is_rect_vis(self, wnd, &rect2)) - { /* if both src and dst are unobscured, we can do a bitblt move */ - xrdp_wm_bitblt(self, self->screen, wnd->left + dx, wnd->top + dy, - self->screen, wnd->left, wnd->top, - wnd->width, wnd->height, 0xcc); - wnd->left += dx; - wnd->top += dy; - r = xrdp_region_create(self); - xrdp_region_add_rect(r, &rect1); - xrdp_region_subtract_rect(r, &rect2); - i = 0; - while (xrdp_region_get_rect(r, i, &rect1) == 0) - { - xrdp_bitmap_invalidate(self->screen, &rect1); - i++; - } - xrdp_region_delete(r); - return 0; - } - } - wnd->left += dx; - wnd->top += dy; - xrdp_bitmap_invalidate(self->screen, &rect1); - xrdp_bitmap_invalidate(wnd, 0); - return 0; -} + MAKERECT(rect1, wnd->left, wnd->top, wnd->width, wnd->height); -/*****************************************************************************/ -static int APP_CC -xrdp_wm_undraw_dragging_box(struct xrdp_wm* self, int do_begin_end) -{ - int boxx; - int boxy; + if (xrdp_wm_is_rect_vis(self, wnd, &rect1)) + { + rect2 = rect1; + RECTOFFSET(rect2, dx, dy); - if (self == 0) - { - return 0; - } - if (self->dragging) - { - if (self->draggingxorstate) - { - if (do_begin_end) - { - xrdp_painter_begin_update(self->painter); - } - boxx = self->draggingx - self->draggingdx; - boxy = self->draggingy - self->draggingdy; - xrdp_wm_xor_pat(self, boxx, boxy, self->draggingcx, self->draggingcy); - self->draggingxorstate = 0; - if (do_begin_end) - { - xrdp_painter_end_update(self->painter); - } - } - } - return 0; -} - -/*****************************************************************************/ -static int APP_CC -xrdp_wm_draw_dragging_box(struct xrdp_wm* self, int do_begin_end) -{ - int boxx; - int boxy; - - if (self == 0) - { - return 0; - } - if (self->dragging) - { - if (!self->draggingxorstate) - { - if (do_begin_end) - { - xrdp_painter_begin_update(self->painter); - } - boxx = self->draggingx - self->draggingdx; - boxy = self->draggingy - self->draggingdy; - xrdp_wm_xor_pat(self, boxx, boxy, self->draggingcx, self->draggingcy); - self->draggingxorstate = 1; - if (do_begin_end) - { - xrdp_painter_end_update(self->painter); - } - } - } - return 0; -} - -/*****************************************************************************/ -int APP_CC -xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y) -{ - struct xrdp_bitmap* b; - - if (self == 0) - { - return 0; - } - if (x < 0) - { - x = 0; - } - if (y < 0) - { - y = 0; - } - if (x >= self->screen->width) - { - x = self->screen->width; - } - if (y >= self->screen->height) - { - y = self->screen->height; - } - self->mouse_x = x; - self->mouse_y = y; - if (self->dragging) - { - xrdp_painter_begin_update(self->painter); - xrdp_wm_undraw_dragging_box(self, 0); - self->draggingx = x; - self->draggingy = y; - xrdp_wm_draw_dragging_box(self, 0); - xrdp_painter_end_update(self->painter); - return 0; - } - b = xrdp_wm_at_pos(self->screen, x, y, 0); - if (b == 0) /* if b is null, the movment must be over the screen */ - { - if (self->screen->pointer != self->current_pointer) - { - xrdp_wm_set_pointer(self, self->screen->pointer); - self->current_pointer = self->screen->pointer; - } - if (self->mm->mod != 0) /* if screen is mod controled */ - { - if (self->mm->mod->mod_event != 0) - { - self->mm->mod->mod_event(self->mm->mod, WM_MOUSEMOVE, x, y, 0, 0); - } - } - } - if (self->button_down != 0) - { - if (b == self->button_down && self->button_down->state == 0) - { - self->button_down->state = 1; - xrdp_bitmap_invalidate(self->button_down, 0); - } - else if (b != self->button_down) - { - self->button_down->state = 0; - xrdp_bitmap_invalidate(self->button_down, 0); - } - } - if (b != 0) - { - if (!self->dragging) - { - if (b->pointer != self->current_pointer) - { - xrdp_wm_set_pointer(self, b->pointer); - self->current_pointer = b->pointer; - } - xrdp_bitmap_def_proc(b, WM_MOUSEMOVE, - xrdp_bitmap_from_screenx(b, x), - xrdp_bitmap_from_screeny(b, y)); - if (self->button_down == 0) - { - if (b->notify != 0) + if (xrdp_wm_is_rect_vis(self, wnd, &rect2)) { - b->notify(b->owner, b, 2, x, y); - } - } - } - } - return 0; -} + /* if both src and dst are unobscured, we can do a bitblt move */ + xrdp_wm_bitblt(self, self->screen, wnd->left + dx, wnd->top + dy, + self->screen, wnd->left, wnd->top, + wnd->width, wnd->height, 0xcc); + wnd->left += dx; + wnd->top += dy; + r = xrdp_region_create(self); + xrdp_region_add_rect(r, &rect1); + xrdp_region_subtract_rect(r, &rect2); + i = 0; -/*****************************************************************************/ -static int APP_CC -xrdp_wm_clear_popup(struct xrdp_wm* self) -{ - int i; - struct xrdp_rect rect; - //struct xrdp_bitmap* b; - - //b = 0; - if (self->popup_wnd != 0) - { - //b = self->popup_wnd->popped_from; - i = list_index_of(self->screen->child_list, (long)self->popup_wnd); - list_remove_item(self->screen->child_list, i); - MAKERECT(rect, self->popup_wnd->left, self->popup_wnd->top, - self->popup_wnd->width, self->popup_wnd->height); - xrdp_bitmap_invalidate(self->screen, &rect); - xrdp_bitmap_delete(self->popup_wnd); - } - //xrdp_wm_set_focused(self, b->parent); - return 0; -} - -/*****************************************************************************/ -int APP_CC -xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down) -{ - struct xrdp_bitmap* control; - struct xrdp_bitmap* focus_out_control; - struct xrdp_bitmap* wnd; - int newx; - int newy; - int oldx; - int oldy; - - if (self == 0) - { - return 0; - } - if (x < 0) - { - x = 0; - } - if (y < 0) - { - y = 0; - } - if (x >= self->screen->width) - { - x = self->screen->width; - } - if (y >= self->screen->height) - { - y = self->screen->height; - } - if (self->dragging && but == 1 && !down && self->dragging_window != 0) - { /* if done dragging */ - self->draggingx = x; - self->draggingy = y; - newx = self->draggingx - self->draggingdx; - newy = self->draggingy - self->draggingdy; - oldx = self->dragging_window->left; - oldy = self->dragging_window->top; - /* draw xor box one more time */ - if (self->draggingxorstate) - { - xrdp_wm_xor_pat(self, newx, newy, self->draggingcx, self->draggingcy); - } - self->draggingxorstate = 0; - /* move screen to new location */ - xrdp_wm_move_window(self, self->dragging_window, newx - oldx, newy - oldy); - self->dragging_window = 0; - self->dragging = 0; - } - wnd = 0; - control = xrdp_wm_at_pos(self->screen, x, y, &wnd); - if (control == 0) - { - if (self->mm->mod != 0) /* if screen is mod controled */ - { - if (self->mm->mod->mod_event != 0) - { - if (but == 1 && down) - { - self->mm->mod->mod_event(self->mm->mod, WM_LBUTTONDOWN, x, y, 0, 0); - } - else if (but == 1 && !down) - { - self->mm->mod->mod_event(self->mm->mod, WM_LBUTTONUP, x, y, 0, 0); - } - if (but == 2 && down) - { - self->mm->mod->mod_event(self->mm->mod, WM_RBUTTONDOWN, x, y, 0, 0); - } - else if (but == 2 && !down) - { - self->mm->mod->mod_event(self->mm->mod, WM_RBUTTONUP, x, y, 0, 0); - } - if (but == 3 && down) - { - self->mm->mod->mod_event(self->mm->mod, WM_BUTTON3DOWN, x, y, 0, 0); - } - else if (but == 3 && !down) - { - self->mm->mod->mod_event(self->mm->mod, WM_BUTTON3UP, x, y, 0, 0); - } - if (but == 4) - { - self->mm->mod->mod_event(self->mm->mod, WM_BUTTON4DOWN, - self->mouse_x, self->mouse_y, 0, 0); - self->mm->mod->mod_event(self->mm->mod, WM_BUTTON4UP, - self->mouse_x, self->mouse_y, 0, 0); - } - if (but == 5) - { - self->mm->mod->mod_event(self->mm->mod, WM_BUTTON5DOWN, - self->mouse_x, self->mouse_y, 0, 0); - self->mm->mod->mod_event(self->mm->mod, WM_BUTTON5UP, - self->mouse_x, self->mouse_y, 0, 0); - } - } - } - } - if (self->popup_wnd != 0) - { - if (self->popup_wnd == control && !down) - { - xrdp_bitmap_def_proc(self->popup_wnd, WM_LBUTTONUP, x, y); - xrdp_wm_clear_popup(self); - self->button_down = 0; - return 0; - } - else if (self->popup_wnd != control && down) - { - xrdp_wm_clear_popup(self); - self->button_down = 0; - return 0; - } - } - if (control != 0) - { - if (wnd != 0) - { - if (wnd->modal_dialog != 0) /* if window has a modal dialog */ - { - return 0; - } - if (control == wnd) - { - } - else if (control->tab_stop) - { - focus_out_control = wnd->focused_control; - wnd->focused_control = control; - xrdp_bitmap_invalidate(focus_out_control, 0); - xrdp_bitmap_invalidate(control, 0); - } - } - if ((control->type == WND_TYPE_BUTTON || - control->type == WND_TYPE_COMBO) && - but == 1 && !down && self->button_down == control) - { /* if clicking up on a button that was clicked down */ - self->button_down = 0; - control->state = 0; - xrdp_bitmap_invalidate(control, 0); - if (control->parent != 0) - { - if (control->parent->notify != 0) - { - /* control can be invalid after this */ - control->parent->notify(control->owner, control, 1, x, y); - } - } - } - else if ((control->type == WND_TYPE_BUTTON || - control->type == WND_TYPE_COMBO) && - but == 1 && down) - { /* if clicking down on a button or combo */ - self->button_down = control; - control->state = 1; - xrdp_bitmap_invalidate(control, 0); - if (control->type == WND_TYPE_COMBO) - { - xrdp_wm_pu(self, control); - } - } - else if (but == 1 && down) - { - if (self->popup_wnd == 0) - { - xrdp_wm_set_focused(self, wnd); - if (control->type == WND_TYPE_WND && y < (control->top + 21)) - { /* if dragging */ - if (self->dragging) /* rarely happens */ - { - newx = self->draggingx - self->draggingdx; - newy = self->draggingy - self->draggingdy; - if (self->draggingxorstate) + while (xrdp_region_get_rect(r, i, &rect1) == 0) { - xrdp_wm_xor_pat(self, newx, newy, - self->draggingcx, self->draggingcy); + xrdp_bitmap_invalidate(self->screen, &rect1); + i++; } - self->draggingxorstate = 0; - } - self->dragging = 1; - self->dragging_window = control; - self->draggingorgx = control->left; - self->draggingorgy = control->top; - self->draggingx = x; - self->draggingy = y; - self->draggingdx = x - control->left; - self->draggingdy = y - control->top; - self->draggingcx = control->width; - self->draggingcy = control->height; + + xrdp_region_delete(r); + return 0; } - } } - } - else - { - xrdp_wm_set_focused(self, 0); - } - /* no matter what, mouse is up, reset button_down */ - if (but == 1 && !down && self->button_down != 0) - { - self->button_down = 0; - } - return 0; + + wnd->left += dx; + wnd->top += dy; + xrdp_bitmap_invalidate(self->screen, &rect1); + xrdp_bitmap_invalidate(wnd, 0); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_wm_undraw_dragging_box(struct xrdp_wm *self, int do_begin_end) +{ + int boxx; + int boxy; + + if (self == 0) + { + return 0; + } + + if (self->dragging) + { + if (self->draggingxorstate) + { + if (do_begin_end) + { + xrdp_painter_begin_update(self->painter); + } + + boxx = self->draggingx - self->draggingdx; + boxy = self->draggingy - self->draggingdy; + xrdp_wm_xor_pat(self, boxx, boxy, self->draggingcx, self->draggingcy); + self->draggingxorstate = 0; + + if (do_begin_end) + { + xrdp_painter_end_update(self->painter); + } + } + } + + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_wm_draw_dragging_box(struct xrdp_wm *self, int do_begin_end) +{ + int boxx; + int boxy; + + if (self == 0) + { + return 0; + } + + if (self->dragging) + { + if (!self->draggingxorstate) + { + if (do_begin_end) + { + xrdp_painter_begin_update(self->painter); + } + + boxx = self->draggingx - self->draggingdx; + boxy = self->draggingy - self->draggingdy; + xrdp_wm_xor_pat(self, boxx, boxy, self->draggingcx, self->draggingcy); + self->draggingxorstate = 1; + + if (do_begin_end) + { + xrdp_painter_end_update(self->painter); + } + } + } + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_wm_key(struct xrdp_wm* self, int device_flags, int scan_code) +xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y) { - int msg; - struct xrdp_key_info* ki; + struct xrdp_bitmap *b; + + if (self == 0) + { + return 0; + } + + if (x < 0) + { + x = 0; + } + + if (y < 0) + { + y = 0; + } + + if (x >= self->screen->width) + { + x = self->screen->width; + } + + if (y >= self->screen->height) + { + y = self->screen->height; + } + + self->mouse_x = x; + self->mouse_y = y; + + if (self->dragging) + { + xrdp_painter_begin_update(self->painter); + xrdp_wm_undraw_dragging_box(self, 0); + self->draggingx = x; + self->draggingy = y; + xrdp_wm_draw_dragging_box(self, 0); + xrdp_painter_end_update(self->painter); + return 0; + } + + b = xrdp_wm_at_pos(self->screen, x, y, 0); + + if (b == 0) /* if b is null, the movment must be over the screen */ + { + if (self->screen->pointer != self->current_pointer) + { + xrdp_wm_set_pointer(self, self->screen->pointer); + self->current_pointer = self->screen->pointer; + } + + if (self->mm->mod != 0) /* if screen is mod controled */ + { + if (self->mm->mod->mod_event != 0) + { + self->mm->mod->mod_event(self->mm->mod, WM_MOUSEMOVE, x, y, 0, 0); + } + } + } + + if (self->button_down != 0) + { + if (b == self->button_down && self->button_down->state == 0) + { + self->button_down->state = 1; + xrdp_bitmap_invalidate(self->button_down, 0); + } + else if (b != self->button_down) + { + self->button_down->state = 0; + xrdp_bitmap_invalidate(self->button_down, 0); + } + } + + if (b != 0) + { + if (!self->dragging) + { + if (b->pointer != self->current_pointer) + { + xrdp_wm_set_pointer(self, b->pointer); + self->current_pointer = b->pointer; + } + + xrdp_bitmap_def_proc(b, WM_MOUSEMOVE, + xrdp_bitmap_from_screenx(b, x), + xrdp_bitmap_from_screeny(b, y)); + + if (self->button_down == 0) + { + if (b->notify != 0) + { + b->notify(b->owner, b, 2, x, y); + } + } + } + } - /*g_printf("count %d\n", self->key_down_list->count);*/ - scan_code = scan_code % 128; - if (self->popup_wnd != 0) - { - xrdp_wm_clear_popup(self); return 0; - } - if (device_flags & KBD_FLAG_UP) /* 0x8000 */ - { - self->keys[scan_code] = 0; - msg = WM_KEYUP; - } - else /* key down */ - { - self->keys[scan_code] = 1 | device_flags; - msg = WM_KEYDOWN; - switch (scan_code) +} + +/*****************************************************************************/ +static int APP_CC +xrdp_wm_clear_popup(struct xrdp_wm *self) +{ + int i; + struct xrdp_rect rect; + //struct xrdp_bitmap* b; + + //b = 0; + if (self->popup_wnd != 0) { - case 58: - self->caps_lock = !self->caps_lock; - break; /* caps lock */ - case 69: - self->num_lock = !self->num_lock; - break; /* num lock */ - case 70: - self->scroll_lock = !self->scroll_lock; - break; /* scroll lock */ + //b = self->popup_wnd->popped_from; + i = list_index_of(self->screen->child_list, (long)self->popup_wnd); + list_remove_item(self->screen->child_list, i); + MAKERECT(rect, self->popup_wnd->left, self->popup_wnd->top, + self->popup_wnd->width, self->popup_wnd->height); + xrdp_bitmap_invalidate(self->screen, &rect); + xrdp_bitmap_delete(self->popup_wnd); } - } - if (self->mm->mod != 0) - { - if (self->mm->mod->mod_event != 0) + + //xrdp_wm_set_focused(self, b->parent); + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down) +{ + struct xrdp_bitmap *control; + struct xrdp_bitmap *focus_out_control; + struct xrdp_bitmap *wnd; + int newx; + int newy; + int oldx; + int oldy; + + if (self == 0) { - ki = get_key_info_from_scan_code - (device_flags, scan_code, self->keys, self->caps_lock, - self->num_lock, self->scroll_lock, - &(self->keymap)); - if (ki != 0) - { - self->mm->mod->mod_event(self->mm->mod, msg, ki->chr, ki->sym, - scan_code, device_flags); - } + return 0; } - } - else if (self->focused_window != 0) - { - xrdp_bitmap_def_proc(self->focused_window, - msg, scan_code, device_flags); - } - return 0; + + if (x < 0) + { + x = 0; + } + + if (y < 0) + { + y = 0; + } + + if (x >= self->screen->width) + { + x = self->screen->width; + } + + if (y >= self->screen->height) + { + y = self->screen->height; + } + + if (self->dragging && but == 1 && !down && self->dragging_window != 0) + { + /* if done dragging */ + self->draggingx = x; + self->draggingy = y; + newx = self->draggingx - self->draggingdx; + newy = self->draggingy - self->draggingdy; + oldx = self->dragging_window->left; + oldy = self->dragging_window->top; + + /* draw xor box one more time */ + if (self->draggingxorstate) + { + xrdp_wm_xor_pat(self, newx, newy, self->draggingcx, self->draggingcy); + } + + self->draggingxorstate = 0; + /* move screen to new location */ + xrdp_wm_move_window(self, self->dragging_window, newx - oldx, newy - oldy); + self->dragging_window = 0; + self->dragging = 0; + } + + wnd = 0; + control = xrdp_wm_at_pos(self->screen, x, y, &wnd); + + if (control == 0) + { + if (self->mm->mod != 0) /* if screen is mod controled */ + { + if (self->mm->mod->mod_event != 0) + { + if (but == 1 && down) + { + self->mm->mod->mod_event(self->mm->mod, WM_LBUTTONDOWN, x, y, 0, 0); + } + else if (but == 1 && !down) + { + self->mm->mod->mod_event(self->mm->mod, WM_LBUTTONUP, x, y, 0, 0); + } + + if (but == 2 && down) + { + self->mm->mod->mod_event(self->mm->mod, WM_RBUTTONDOWN, x, y, 0, 0); + } + else if (but == 2 && !down) + { + self->mm->mod->mod_event(self->mm->mod, WM_RBUTTONUP, x, y, 0, 0); + } + + if (but == 3 && down) + { + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON3DOWN, x, y, 0, 0); + } + else if (but == 3 && !down) + { + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON3UP, x, y, 0, 0); + } + + if (but == 4) + { + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON4DOWN, + self->mouse_x, self->mouse_y, 0, 0); + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON4UP, + self->mouse_x, self->mouse_y, 0, 0); + } + + if (but == 5) + { + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON5DOWN, + self->mouse_x, self->mouse_y, 0, 0); + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON5UP, + self->mouse_x, self->mouse_y, 0, 0); + } + } + } + } + + if (self->popup_wnd != 0) + { + if (self->popup_wnd == control && !down) + { + xrdp_bitmap_def_proc(self->popup_wnd, WM_LBUTTONUP, x, y); + xrdp_wm_clear_popup(self); + self->button_down = 0; + return 0; + } + else if (self->popup_wnd != control && down) + { + xrdp_wm_clear_popup(self); + self->button_down = 0; + return 0; + } + } + + if (control != 0) + { + if (wnd != 0) + { + if (wnd->modal_dialog != 0) /* if window has a modal dialog */ + { + return 0; + } + + if (control == wnd) + { + } + else if (control->tab_stop) + { + focus_out_control = wnd->focused_control; + wnd->focused_control = control; + xrdp_bitmap_invalidate(focus_out_control, 0); + xrdp_bitmap_invalidate(control, 0); + } + } + + if ((control->type == WND_TYPE_BUTTON || + control->type == WND_TYPE_COMBO) && + but == 1 && !down && self->button_down == control) + { + /* if clicking up on a button that was clicked down */ + self->button_down = 0; + control->state = 0; + xrdp_bitmap_invalidate(control, 0); + + if (control->parent != 0) + { + if (control->parent->notify != 0) + { + /* control can be invalid after this */ + control->parent->notify(control->owner, control, 1, x, y); + } + } + } + else if ((control->type == WND_TYPE_BUTTON || + control->type == WND_TYPE_COMBO) && + but == 1 && down) + { + /* if clicking down on a button or combo */ + self->button_down = control; + control->state = 1; + xrdp_bitmap_invalidate(control, 0); + + if (control->type == WND_TYPE_COMBO) + { + xrdp_wm_pu(self, control); + } + } + else if (but == 1 && down) + { + if (self->popup_wnd == 0) + { + xrdp_wm_set_focused(self, wnd); + + if (control->type == WND_TYPE_WND && y < (control->top + 21)) + { + /* if dragging */ + if (self->dragging) /* rarely happens */ + { + newx = self->draggingx - self->draggingdx; + newy = self->draggingy - self->draggingdy; + + if (self->draggingxorstate) + { + xrdp_wm_xor_pat(self, newx, newy, + self->draggingcx, self->draggingcy); + } + + self->draggingxorstate = 0; + } + + self->dragging = 1; + self->dragging_window = control; + self->draggingorgx = control->left; + self->draggingorgy = control->top; + self->draggingx = x; + self->draggingy = y; + self->draggingdx = x - control->left; + self->draggingdy = y - control->top; + self->draggingcx = control->width; + self->draggingcy = control->height; + } + } + } + } + else + { + xrdp_wm_set_focused(self, 0); + } + + /* no matter what, mouse is up, reset button_down */ + if (but == 1 && !down && self->button_down != 0) + { + self->button_down = 0; + } + + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_wm_key(struct xrdp_wm *self, int device_flags, int scan_code) +{ + int msg; + struct xrdp_key_info *ki; + + /*g_printf("count %d\n", self->key_down_list->count);*/ + scan_code = scan_code % 128; + + if (self->popup_wnd != 0) + { + xrdp_wm_clear_popup(self); + return 0; + } + + if (device_flags & KBD_FLAG_UP) /* 0x8000 */ + { + self->keys[scan_code] = 0; + msg = WM_KEYUP; + } + else /* key down */ + { + self->keys[scan_code] = 1 | device_flags; + msg = WM_KEYDOWN; + + switch (scan_code) + { + case 58: + self->caps_lock = !self->caps_lock; + break; /* caps lock */ + case 69: + self->num_lock = !self->num_lock; + break; /* num lock */ + case 70: + self->scroll_lock = !self->scroll_lock; + break; /* scroll lock */ + } + } + + if (self->mm->mod != 0) + { + if (self->mm->mod->mod_event != 0) + { + ki = get_key_info_from_scan_code + (device_flags, scan_code, self->keys, self->caps_lock, + self->num_lock, self->scroll_lock, + &(self->keymap)); + + if (ki != 0) + { + self->mm->mod->mod_event(self->mm->mod, msg, ki->chr, ki->sym, + scan_code, device_flags); + } + } + } + else if (self->focused_window != 0) + { + xrdp_bitmap_def_proc(self->focused_window, + msg, scan_code, device_flags); + } + + return 0; } /*****************************************************************************/ /* happens when client gets focus and sends key modifier info */ int APP_CC -xrdp_wm_key_sync(struct xrdp_wm* self, int device_flags, int key_flags) +xrdp_wm_key_sync(struct xrdp_wm *self, int device_flags, int key_flags) { - self->num_lock = 0; - self->scroll_lock = 0; - self->caps_lock = 0; - if (key_flags & 1) - { - self->scroll_lock = 1; - } - if (key_flags & 2) - { - self->num_lock = 1; - } - if (key_flags & 4) - { - self->caps_lock = 1; - } - if (self->mm->mod != 0) - { - if (self->mm->mod->mod_event != 0) + self->num_lock = 0; + self->scroll_lock = 0; + self->caps_lock = 0; + + if (key_flags & 1) { - self->mm->mod->mod_event(self->mm->mod, 17, key_flags, device_flags, - key_flags, device_flags); + self->scroll_lock = 1; } - } - return 0; + + if (key_flags & 2) + { + self->num_lock = 1; + } + + if (key_flags & 4) + { + self->caps_lock = 1; + } + + if (self->mm->mod != 0) + { + if (self->mm->mod->mod_event != 0) + { + self->mm->mod->mod_event(self->mm->mod, 17, key_flags, device_flags, + key_flags, device_flags); + } + } + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_wm_pu(struct xrdp_wm* self, struct xrdp_bitmap* control) +xrdp_wm_pu(struct xrdp_wm *self, struct xrdp_bitmap *control) { - int x; - int y; + int x; + int y; - if (self == 0) - { + if (self == 0) + { + return 0; + } + + if (control == 0) + { + return 0; + } + + self->popup_wnd = xrdp_bitmap_create(control->width, DEFAULT_WND_SPECIAL_H, + self->screen->bpp, + WND_TYPE_SPECIAL, self); + self->popup_wnd->popped_from = control; + self->popup_wnd->parent = self->screen; + self->popup_wnd->owner = self->screen; + x = xrdp_bitmap_to_screenx(control, 0); + y = xrdp_bitmap_to_screeny(control, 0); + self->popup_wnd->left = x; + self->popup_wnd->top = y + control->height; + self->popup_wnd->item_index = control->item_index; + list_insert_item(self->screen->child_list, 0, (long)self->popup_wnd); + xrdp_bitmap_invalidate(self->popup_wnd, 0); return 0; - } - if (control == 0) - { - return 0; - } - self->popup_wnd = xrdp_bitmap_create(control->width, DEFAULT_WND_SPECIAL_H, - self->screen->bpp, - WND_TYPE_SPECIAL, self); - self->popup_wnd->popped_from = control; - self->popup_wnd->parent = self->screen; - self->popup_wnd->owner = self->screen; - x = xrdp_bitmap_to_screenx(control, 0); - y = xrdp_bitmap_to_screeny(control, 0); - self->popup_wnd->left = x; - self->popup_wnd->top = y + control->height; - self->popup_wnd->item_index = control->item_index; - list_insert_item(self->screen->child_list, 0, (long)self->popup_wnd); - xrdp_bitmap_invalidate(self->popup_wnd, 0); - return 0; } /*****************************************************************************/ static int APP_CC -xrdp_wm_process_input_mouse(struct xrdp_wm* self, int device_flags, +xrdp_wm_process_input_mouse(struct xrdp_wm *self, int device_flags, int x, int y) { - DEBUG(("mouse event flags %4.4x x %d y %d", device_flags, x, y)); - if (device_flags & MOUSE_FLAG_MOVE) /* 0x0800 */ - { - xrdp_wm_mouse_move(self, x, y); - } - if (device_flags & MOUSE_FLAG_BUTTON1) /* 0x1000 */ - { - if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */ + DEBUG(("mouse event flags %4.4x x %d y %d", device_flags, x, y)); + + if (device_flags & MOUSE_FLAG_MOVE) /* 0x0800 */ { - xrdp_wm_mouse_click(self, x, y, 1, 1); + xrdp_wm_mouse_move(self, x, y); } - else + + if (device_flags & MOUSE_FLAG_BUTTON1) /* 0x1000 */ { - xrdp_wm_mouse_click(self, x, y, 1, 0); + if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */ + { + xrdp_wm_mouse_click(self, x, y, 1, 1); + } + else + { + xrdp_wm_mouse_click(self, x, y, 1, 0); + } } - } - if (device_flags & MOUSE_FLAG_BUTTON2) /* 0x2000 */ - { - if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */ + + if (device_flags & MOUSE_FLAG_BUTTON2) /* 0x2000 */ { - xrdp_wm_mouse_click(self, x, y, 2, 1); + if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */ + { + xrdp_wm_mouse_click(self, x, y, 2, 1); + } + else + { + xrdp_wm_mouse_click(self, x, y, 2, 0); + } } - else + + if (device_flags & MOUSE_FLAG_BUTTON3) /* 0x4000 */ { - xrdp_wm_mouse_click(self, x, y, 2, 0); + if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */ + { + xrdp_wm_mouse_click(self, x, y, 3, 1); + } + else + { + xrdp_wm_mouse_click(self, x, y, 3, 0); + } } - } - if (device_flags & MOUSE_FLAG_BUTTON3) /* 0x4000 */ - { - if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */ + + if (device_flags == MOUSE_FLAG_BUTTON4 || /* 0x0280 */ + device_flags == 0x0278) { - xrdp_wm_mouse_click(self, x, y, 3, 1); + xrdp_wm_mouse_click(self, 0, 0, 4, 0); } - else + + if (device_flags == MOUSE_FLAG_BUTTON5 || /* 0x0380 */ + device_flags == 0x0388) { - xrdp_wm_mouse_click(self, x, y, 3, 0); + xrdp_wm_mouse_click(self, 0, 0, 5, 0); } - } - if (device_flags == MOUSE_FLAG_BUTTON4 || /* 0x0280 */ - device_flags == 0x0278) - { - xrdp_wm_mouse_click(self, 0, 0, 4, 0); - } - if (device_flags == MOUSE_FLAG_BUTTON5 || /* 0x0380 */ - device_flags == 0x0388) - { - xrdp_wm_mouse_click(self, 0, 0, 5, 0); - } - return 0; + + return 0; } /******************************************************************************/ @@ -1386,34 +1531,37 @@ xrdp_wm_process_input_mouse(struct xrdp_wm* self, int device_flags, param3 = pointer to data param4 = total size */ static int APP_CC -xrdp_wm_process_channel_data(struct xrdp_wm* self, - tbus param1, tbus param2, - tbus param3, tbus param4) +xrdp_wm_process_channel_data(struct xrdp_wm *self, + tbus param1, tbus param2, + tbus param3, tbus param4) { - int rv; - int chanid ; - rv = 1; - if (self->mm->mod != 0) - { - chanid = LOWORD(param1); - if(is_channel_allowed(self, chanid)) + int rv; + int chanid ; + rv = 1; + + if (self->mm->mod != 0) { - if (self->mm->usechansrv) - { - rv = xrdp_mm_process_channel_data(self->mm, param1, param2, - param3, param4); - } - else - { - if (self->mm->mod->mod_event != 0) + chanid = LOWORD(param1); + + if (is_channel_allowed(self, chanid)) { - rv = self->mm->mod->mod_event(self->mm->mod, 0x5555, param1, param2, - param3, param4); + if (self->mm->usechansrv) + { + rv = xrdp_mm_process_channel_data(self->mm, param1, param2, + param3, param4); + } + else + { + if (self->mm->mod->mod_event != 0) + { + rv = self->mm->mod->mod_event(self->mm->mod, 0x5555, param1, param2, + param3, param4); + } + } } - } } - } - return rv; + + return rv; } /******************************************************************************/ @@ -1421,266 +1569,295 @@ xrdp_wm_process_channel_data(struct xrdp_wm* self, int DEFAULT_CC callback(long id, int msg, long param1, long param2, long param3, long param4) { - int rv; - struct xrdp_wm* wm; - struct xrdp_rect rect; + int rv; + struct xrdp_wm *wm; + struct xrdp_rect rect; - if (id == 0) /* "id" should be "struct xrdp_process*" as long */ - { - return 0; - } - wm = ((struct xrdp_process*)id)->wm; - if (wm == 0) - { - return 0; - } - rv = 0; - switch (msg) - { - case 0: /* RDP_INPUT_SYNCHRONIZE */ - rv = xrdp_wm_key_sync(wm, param3, param1); - break; - case 4: /* RDP_INPUT_SCANCODE */ - rv = xrdp_wm_key(wm, param3, param1); - break; - case 0x8001: /* RDP_INPUT_MOUSE */ - rv = xrdp_wm_process_input_mouse(wm, param3, param1, param2); - break; - case 0x4444: /* invalidate, this is not from RDP_DATA_PDU_INPUT */ - /* like the rest, its from RDP_PDU_DATA with code 33 */ - /* its the rdp client asking for a screen update */ - MAKERECT(rect, param1, param2, param3, param4); - rv = xrdp_bitmap_invalidate(wm->screen, &rect); - break; - case 0x5555: /* called from xrdp_channel.c, channel data has come in, + if (id == 0) /* "id" should be "struct xrdp_process*" as long */ + { + return 0; + } + + wm = ((struct xrdp_process *)id)->wm; + + if (wm == 0) + { + return 0; + } + + rv = 0; + + switch (msg) + { + case 0: /* RDP_INPUT_SYNCHRONIZE */ + rv = xrdp_wm_key_sync(wm, param3, param1); + break; + case 4: /* RDP_INPUT_SCANCODE */ + rv = xrdp_wm_key(wm, param3, param1); + break; + case 0x8001: /* RDP_INPUT_MOUSE */ + rv = xrdp_wm_process_input_mouse(wm, param3, param1, param2); + break; + case 0x4444: /* invalidate, this is not from RDP_DATA_PDU_INPUT */ + /* like the rest, its from RDP_PDU_DATA with code 33 */ + /* its the rdp client asking for a screen update */ + MAKERECT(rect, param1, param2, param3, param4); + rv = xrdp_bitmap_invalidate(wm->screen, &rect); + break; + case 0x5555: /* called from xrdp_channel.c, channel data has come in, pass it to module if there is one */ - rv = xrdp_wm_process_channel_data(wm, param1, param2, param3, param4); - break; - } - return rv; + rv = xrdp_wm_process_channel_data(wm, param1, param2, param3, param4); + break; + } + + return rv; } /******************************************************************************/ /* returns error */ /* this gets called when there is nothing on any socket */ static int APP_CC -xrdp_wm_login_mode_changed(struct xrdp_wm* self) +xrdp_wm_login_mode_changed(struct xrdp_wm *self) { - if (self == 0) - { + if (self == 0) + { + return 0; + } + + if (self->login_mode == 0) + { + /* this is the inital state of the login window */ + xrdp_wm_set_login_mode(self, 1); /* put the wm in login mode */ + list_clear(self->log); + xrdp_wm_delete_all_childs(self); + self->dragging = 0; + xrdp_wm_init(self); + } + else if (self->login_mode == 2) + { + if (xrdp_mm_connect(self->mm) == 0) + { + xrdp_wm_set_login_mode(self, 3); /* put the wm in connected mode */ + xrdp_wm_delete_all_childs(self); + self->dragging = 0; + } + else + { + /* we do nothing on connect error so far */ + } + } + else if (self->login_mode == 10) + { + xrdp_wm_delete_all_childs(self); + self->dragging = 0; + xrdp_wm_set_login_mode(self, 11); + } + return 0; - } - if (self->login_mode == 0) - { - /* this is the inital state of the login window */ - xrdp_wm_set_login_mode(self, 1); /* put the wm in login mode */ - list_clear(self->log); - xrdp_wm_delete_all_childs(self); - self->dragging = 0; - xrdp_wm_init(self); - } - else if (self->login_mode == 2) - { - if (xrdp_mm_connect(self->mm) == 0) - { - xrdp_wm_set_login_mode(self, 3); /* put the wm in connected mode */ - xrdp_wm_delete_all_childs(self); - self->dragging = 0; - } - else - { - /* we do nothing on connect error so far */ - } - } - else if (self->login_mode == 10) - { - xrdp_wm_delete_all_childs(self); - self->dragging = 0; - xrdp_wm_set_login_mode(self, 11); - } - return 0; } /*****************************************************************************/ /* this is the log windows nofity function */ static int DEFAULT_CC -xrdp_wm_log_wnd_notify(struct xrdp_bitmap* wnd, - struct xrdp_bitmap* sender, +xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd, + struct xrdp_bitmap *sender, int msg, long param1, long param2) { - struct xrdp_painter* painter; - struct xrdp_wm* wm; - struct xrdp_rect rect; - int index; - char* text; + struct xrdp_painter *painter; + struct xrdp_wm *wm; + struct xrdp_rect rect; + int index; + char *text; - if (wnd == 0) - { - return 0; - } - if (sender == 0) - { - return 0; - } - if (wnd->owner == 0) - { - return 0; - } - wm = wnd->wm; - if (msg == 1) /* click */ - { - if (sender->id == 1) /* ok button */ + if (wnd == 0) { - /* close the log window */ - MAKERECT(rect, wnd->left, wnd->top, wnd->width, wnd->height); - xrdp_bitmap_delete(wnd); - xrdp_bitmap_invalidate(wm->screen, &rect); - /* if module is gone, reset the session when ok is clicked */ - if (wm->mm->mod_handle == 0) - { - /* make sure autologin is off */ - wm->session->client_info->rdp_autologin = 0; - xrdp_wm_set_login_mode(wm, 0); /* reset session */ - } + return 0; } - } - else if (msg == WM_PAINT) /* 3 */ - { - painter = (struct xrdp_painter*)param1; - if (painter != 0) + + if (sender == 0) { - painter->fg_color = wnd->wm->black; - for (index = 0; index < wnd->wm->log->count; index++) - { - text = (char*)list_get_item(wnd->wm->log, index); - xrdp_painter_draw_text(painter, wnd, 10, 30 + index * 15, text); - } + return 0; } - } - return 0; + + if (wnd->owner == 0) + { + return 0; + } + + wm = wnd->wm; + + if (msg == 1) /* click */ + { + if (sender->id == 1) /* ok button */ + { + /* close the log window */ + MAKERECT(rect, wnd->left, wnd->top, wnd->width, wnd->height); + xrdp_bitmap_delete(wnd); + xrdp_bitmap_invalidate(wm->screen, &rect); + + /* if module is gone, reset the session when ok is clicked */ + if (wm->mm->mod_handle == 0) + { + /* make sure autologin is off */ + wm->session->client_info->rdp_autologin = 0; + xrdp_wm_set_login_mode(wm, 0); /* reset session */ + } + } + } + else if (msg == WM_PAINT) /* 3 */ + { + painter = (struct xrdp_painter *)param1; + + if (painter != 0) + { + painter->fg_color = wnd->wm->black; + + for (index = 0; index < wnd->wm->log->count; index++) + { + text = (char *)list_get_item(wnd->wm->log, index); + xrdp_painter_draw_text(painter, wnd, 10, 30 + index * 15, text); + } + } + } + + return 0; } - void add_string_to_logwindow(char *msg,struct list* log) - { - - char *new_part_message; - char *current_pointer = msg ; - int processedlen = 0; - do{ - new_part_message = g_strndup(current_pointer,LOG_WINDOW_CHAR_PER_LINE) ; - g_writeln(new_part_message); - list_add_item(log, (long)new_part_message); - processedlen = processedlen + g_strlen(new_part_message); - current_pointer = current_pointer + g_strlen(new_part_message) ; - }while((processedlenhide_log_window) - { - return 0; - } - add_string_to_logwindow(msg,self->log); - if (self->log_wnd == 0) - { - w = DEFAULT_WND_LOG_W; - h = DEFAULT_WND_LOG_H; - xoffset = 10; - yoffset = 10; - if (self->screen->width < w) + char *new_part_message; + char *current_pointer = msg ; + int processedlen = 0; + + do { - w = self->screen->width - 4; - xoffset = 2; + new_part_message = g_strndup(current_pointer, LOG_WINDOW_CHAR_PER_LINE) ; + g_writeln(new_part_message); + list_add_item(log, (long)new_part_message); + processedlen = processedlen + g_strlen(new_part_message); + current_pointer = current_pointer + g_strlen(new_part_message) ; } - if (self->screen->height < h) - { - h = self->screen->height - 4; - yoffset = 2; - } - /* log window */ - self->log_wnd = xrdp_bitmap_create(w, h, self->screen->bpp, - WND_TYPE_WND, self); - list_add_item(self->screen->child_list, (long)self->log_wnd); - self->log_wnd->parent = self->screen; - self->log_wnd->owner = self->screen; - self->log_wnd->bg_color = self->grey; - self->log_wnd->left = xoffset; - self->log_wnd->top = yoffset; - set_string(&(self->log_wnd->caption1), "Connection Log"); - /* ok button */ - but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); - list_insert_item(self->log_wnd->child_list, 0, (long)but); - but->parent = self->log_wnd; - but->owner = self->log_wnd; - but->left = (w - DEFAULT_BUTTON_W) - xoffset; - but->top = (h - DEFAULT_BUTTON_H) - yoffset; - but->id = 1; - but->tab_stop = 1; - set_string(&but->caption1, "OK"); - self->log_wnd->focused_control = but; - /* set notify function */ - self->log_wnd->notify = xrdp_wm_log_wnd_notify; - } - xrdp_wm_set_focused(self, self->log_wnd); - xrdp_bitmap_invalidate(self->log_wnd, 0); - g_sleep(100); - return 0; + while ((processedlen < g_strlen(msg)) && (processedlen < DEFAULT_STRING_LEN)); } /*****************************************************************************/ int APP_CC -xrdp_wm_get_wait_objs(struct xrdp_wm* self, tbus* robjs, int* rc, - tbus* wobjs, int* wc, int* timeout) +xrdp_wm_log_msg(struct xrdp_wm *self, char *msg) { - int i; + struct xrdp_bitmap *but; + int w; + int h; + int xoffset; + int yoffset; - if (self == 0) - { + if (self->hide_log_window) + { + return 0; + } + + add_string_to_logwindow(msg, self->log); + + if (self->log_wnd == 0) + { + w = DEFAULT_WND_LOG_W; + h = DEFAULT_WND_LOG_H; + xoffset = 10; + yoffset = 10; + + if (self->screen->width < w) + { + w = self->screen->width - 4; + xoffset = 2; + } + + if (self->screen->height < h) + { + h = self->screen->height - 4; + yoffset = 2; + } + + /* log window */ + self->log_wnd = xrdp_bitmap_create(w, h, self->screen->bpp, + WND_TYPE_WND, self); + list_add_item(self->screen->child_list, (long)self->log_wnd); + self->log_wnd->parent = self->screen; + self->log_wnd->owner = self->screen; + self->log_wnd->bg_color = self->grey; + self->log_wnd->left = xoffset; + self->log_wnd->top = yoffset; + set_string(&(self->log_wnd->caption1), "Connection Log"); + /* ok button */ + but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); + list_insert_item(self->log_wnd->child_list, 0, (long)but); + but->parent = self->log_wnd; + but->owner = self->log_wnd; + but->left = (w - DEFAULT_BUTTON_W) - xoffset; + but->top = (h - DEFAULT_BUTTON_H) - yoffset; + but->id = 1; + but->tab_stop = 1; + set_string(&but->caption1, "OK"); + self->log_wnd->focused_control = but; + /* set notify function */ + self->log_wnd->notify = xrdp_wm_log_wnd_notify; + } + + xrdp_wm_set_focused(self, self->log_wnd); + xrdp_bitmap_invalidate(self->log_wnd, 0); + g_sleep(100); return 0; - } - i = *rc; - robjs[i++] = self->login_mode_event; - *rc = i; - return xrdp_mm_get_wait_objs(self->mm, robjs, rc, wobjs, wc, timeout); +} + +/*****************************************************************************/ +int APP_CC +xrdp_wm_get_wait_objs(struct xrdp_wm *self, tbus *robjs, int *rc, + tbus *wobjs, int *wc, int *timeout) +{ + int i; + + if (self == 0) + { + return 0; + } + + i = *rc; + robjs[i++] = self->login_mode_event; + *rc = i; + return xrdp_mm_get_wait_objs(self->mm, robjs, rc, wobjs, wc, timeout); } /******************************************************************************/ int APP_CC -xrdp_wm_check_wait_objs(struct xrdp_wm* self) +xrdp_wm_check_wait_objs(struct xrdp_wm *self) { - int rv; + int rv; - if (self == 0) - { - return 0; - } - rv = 0; - if (g_is_wait_obj_set(self->login_mode_event)) - { - g_reset_wait_obj(self->login_mode_event); - xrdp_wm_login_mode_changed(self); - } - if (rv == 0) - { - rv = xrdp_mm_check_wait_objs(self->mm); - } - return rv; + if (self == 0) + { + return 0; + } + + rv = 0; + + if (g_is_wait_obj_set(self->login_mode_event)) + { + g_reset_wait_obj(self->login_mode_event); + xrdp_wm_login_mode_changed(self); + } + + if (rv == 0) + { + rv = xrdp_mm_check_wait_objs(self->mm); + } + + return rv; } /*****************************************************************************/ int APP_CC -xrdp_wm_set_login_mode(struct xrdp_wm* self, int login_mode) +xrdp_wm_set_login_mode(struct xrdp_wm *self, int login_mode) { - self->login_mode = login_mode; - g_set_wait_obj(self->login_mode_event); - return 0; + self->login_mode = login_mode; + g_set_wait_obj(self->login_mode_event); + return 0; } diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c index 849f7112..ed6fa4c5 100644 --- a/xrdp/xrdpwin.c +++ b/xrdp/xrdpwin.c @@ -1,31 +1,29 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2012 - - main program - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * main program + */ #if defined(_WIN32) #include #endif #include "xrdp.h" -static struct xrdp_listen* g_listen = 0; +static struct xrdp_listen *g_listen = 0; static long g_threadid = 0; /* main threadid */ #if defined(_WIN32) @@ -48,113 +46,120 @@ long APP_CC g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, long sync_param2) { - long sync_result; - int sync_command; + long sync_result; + int sync_command; - if (tc_threadid_equal(tc_get_threadid(), g_threadid)) - { - /* this is the main thread, call the function directly */ - sync_result = sync_func(sync_param1, sync_param2); - } - else - { - tc_mutex_lock(g_sync1_mutex); - tc_mutex_lock(g_sync_mutex); - g_sync_param1 = sync_param1; - g_sync_param2 = sync_param2; - g_sync_func = sync_func; - g_sync_command = 100; - tc_mutex_unlock(g_sync_mutex); - g_set_wait_obj(g_sync_event); - do + if (tc_threadid_equal(tc_get_threadid(), g_threadid)) { - g_sleep(100); - tc_mutex_lock(g_sync_mutex); - sync_command = g_sync_command; - sync_result = g_sync_result; - tc_mutex_unlock(g_sync_mutex); + /* this is the main thread, call the function directly */ + sync_result = sync_func(sync_param1, sync_param2); } - while (sync_command != 0); - tc_mutex_unlock(g_sync1_mutex); - } - return sync_result; + else + { + tc_mutex_lock(g_sync1_mutex); + tc_mutex_lock(g_sync_mutex); + g_sync_param1 = sync_param1; + g_sync_param2 = sync_param2; + g_sync_func = sync_func; + g_sync_command = 100; + tc_mutex_unlock(g_sync_mutex); + g_set_wait_obj(g_sync_event); + + do + { + g_sleep(100); + tc_mutex_lock(g_sync_mutex); + sync_command = g_sync_command; + sync_result = g_sync_result; + tc_mutex_unlock(g_sync_mutex); + } + while (sync_command != 0); + + tc_mutex_unlock(g_sync1_mutex); + } + + return sync_result; } /*****************************************************************************/ void DEFAULT_CC xrdp_shutdown(int sig) { - tbus threadid; + tbus threadid; - threadid = tc_get_threadid(); - g_writeln("shutting down"); - g_writeln("signal %d threadid %p", sig, threadid); - if (!g_is_wait_obj_set(g_term_event)) - { - g_set_wait_obj(g_term_event); - } + threadid = tc_get_threadid(); + g_writeln("shutting down"); + g_writeln("signal %d threadid %p", sig, threadid); + + if (!g_is_wait_obj_set(g_term_event)) + { + g_set_wait_obj(g_term_event); + } } /*****************************************************************************/ int APP_CC g_is_term(void) { - return g_is_wait_obj_set(g_term_event); + return g_is_wait_obj_set(g_term_event); } /*****************************************************************************/ void APP_CC g_set_term(int in_val) { - if (in_val) - { - g_set_wait_obj(g_term_event); - } - else - { - g_reset_wait_obj(g_term_event); - } + if (in_val) + { + g_set_wait_obj(g_term_event); + } + else + { + g_reset_wait_obj(g_term_event); + } } /*****************************************************************************/ tbus APP_CC g_get_term_event(void) { - return g_term_event; + return g_term_event; } /*****************************************************************************/ tbus APP_CC g_get_sync_event(void) { - return g_sync_event; + return g_sync_event; } /*****************************************************************************/ void DEFAULT_CC pipe_sig(int sig_num) { - /* do nothing */ - g_writeln("got SIGPIPE(%d)", sig_num); + /* do nothing */ + g_writeln("got SIGPIPE(%d)", sig_num); } /*****************************************************************************/ void APP_CC g_process_waiting_function(void) { - tc_mutex_lock(g_sync_mutex); - if (g_sync_command != 0) - { - if (g_sync_func != 0) + tc_mutex_lock(g_sync_mutex); + + if (g_sync_command != 0) { - if (g_sync_command == 100) - { - g_sync_result = g_sync_func(g_sync_param1, g_sync_param2); - } + if (g_sync_func != 0) + { + if (g_sync_command == 100) + { + g_sync_result = g_sync_func(g_sync_param1, g_sync_param2); + } + } + + g_sync_command = 0; } - g_sync_command = 0; - } - tc_mutex_unlock(g_sync_mutex); + + tc_mutex_unlock(g_sync_mutex); } /* win32 service control functions */ @@ -164,444 +169,484 @@ g_process_waiting_function(void) VOID WINAPI MyHandler(DWORD fdwControl) { - if (g_ssh == 0) - { - return; - } - if (fdwControl == SERVICE_CONTROL_STOP) - { - g_service_status.dwCurrentState = SERVICE_STOP_PENDING; - g_set_term(1); - } - else if (fdwControl == SERVICE_CONTROL_PAUSE) - { - /* shouldn't happen */ - } - else if (fdwControl == SERVICE_CONTROL_CONTINUE) - { - /* shouldn't happen */ - } - else if (fdwControl == SERVICE_CONTROL_INTERROGATE) - { - } - else if (fdwControl == SERVICE_CONTROL_SHUTDOWN) - { - g_service_status.dwCurrentState = SERVICE_STOP_PENDING; - g_set_term(1); - } - SetServiceStatus(g_ssh, &g_service_status); + if (g_ssh == 0) + { + return; + } + + if (fdwControl == SERVICE_CONTROL_STOP) + { + g_service_status.dwCurrentState = SERVICE_STOP_PENDING; + g_set_term(1); + } + else if (fdwControl == SERVICE_CONTROL_PAUSE) + { + /* shouldn't happen */ + } + else if (fdwControl == SERVICE_CONTROL_CONTINUE) + { + /* shouldn't happen */ + } + else if (fdwControl == SERVICE_CONTROL_INTERROGATE) + { + } + else if (fdwControl == SERVICE_CONTROL_SHUTDOWN) + { + g_service_status.dwCurrentState = SERVICE_STOP_PENDING; + g_set_term(1); + } + + SetServiceStatus(g_ssh, &g_service_status); } /*****************************************************************************/ static void DEFAULT_CC -log_event(HANDLE han, char* msg) +log_event(HANDLE han, char *msg) { - ReportEvent(han, EVENTLOG_INFORMATION_TYPE, 0, 0, 0, 1, 0, &msg, 0); + ReportEvent(han, EVENTLOG_INFORMATION_TYPE, 0, 0, 0, 1, 0, &msg, 0); } /*****************************************************************************/ VOID WINAPI -MyServiceMain(DWORD dwArgc, LPTSTR* lpszArgv) +MyServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) { - WSADATA w; - char text[256]; - int pid; - //HANDLE event_han; -// int fd; -// char text[256]; + WSADATA w; + char text[256]; + int pid; + //HANDLE event_han; + // int fd; + // char text[256]; -// fd = g_file_open("c:\\temp\\xrdp\\log.txt"); -// g_file_write(fd, "hi\r\n", 4); - //event_han = RegisterEventSource(0, "xrdp"); - //log_event(event_han, "hi xrdp log"); - g_threadid = tc_get_threadid(); - g_set_current_dir("c:\\temp\\xrdp"); - g_listen = 0; - WSAStartup(2, &w); - g_sync_mutex = tc_mutex_create(); - g_sync1_mutex = tc_mutex_create(); - pid = g_getpid(); - g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); - g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); - g_sync_event = g_create_wait_obj(text); - g_memset(&g_service_status, 0, sizeof(SERVICE_STATUS)); - g_service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - g_service_status.dwCurrentState = SERVICE_RUNNING; - g_service_status.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE | - SERVICE_ACCEPT_STOP | - SERVICE_ACCEPT_SHUTDOWN; - g_service_status.dwWin32ExitCode = NO_ERROR; - g_service_status.dwServiceSpecificExitCode = 0; - g_service_status.dwCheckPoint = 0; - g_service_status.dwWaitHint = 0; -// g_sprintf(text, "calling RegisterServiceCtrlHandler\r\n"); -// g_file_write(fd, text, g_strlen(text)); - g_ssh = RegisterServiceCtrlHandler("xrdp", MyHandler); - if (g_ssh != 0) - { -// g_sprintf(text, "ok\r\n"); -// g_file_write(fd, text, g_strlen(text)); - SetServiceStatus(g_ssh, &g_service_status); - g_listen = xrdp_listen_create(); - xrdp_listen_main_loop(g_listen); - g_sleep(100); - g_service_status.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(g_ssh, &g_service_status); - } - else - { - //g_sprintf(text, "RegisterServiceCtrlHandler failed\r\n"); - //g_file_write(fd, text, g_strlen(text)); - } - xrdp_listen_delete(g_listen); - tc_mutex_delete(g_sync_mutex); - tc_mutex_delete(g_sync1_mutex); - g_destroy_wait_obj(g_term_event); - g_destroy_wait_obj(g_sync_event); - WSACleanup(); - //CloseHandle(event_han); + // fd = g_file_open("c:\\temp\\xrdp\\log.txt"); + // g_file_write(fd, "hi\r\n", 4); + //event_han = RegisterEventSource(0, "xrdp"); + //log_event(event_han, "hi xrdp log"); + g_threadid = tc_get_threadid(); + g_set_current_dir("c:\\temp\\xrdp"); + g_listen = 0; + WSAStartup(2, &w); + g_sync_mutex = tc_mutex_create(); + g_sync1_mutex = tc_mutex_create(); + pid = g_getpid(); + g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); + g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); + g_sync_event = g_create_wait_obj(text); + g_memset(&g_service_status, 0, sizeof(SERVICE_STATUS)); + g_service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + g_service_status.dwCurrentState = SERVICE_RUNNING; + g_service_status.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE | + SERVICE_ACCEPT_STOP | + SERVICE_ACCEPT_SHUTDOWN; + g_service_status.dwWin32ExitCode = NO_ERROR; + g_service_status.dwServiceSpecificExitCode = 0; + g_service_status.dwCheckPoint = 0; + g_service_status.dwWaitHint = 0; + // g_sprintf(text, "calling RegisterServiceCtrlHandler\r\n"); + // g_file_write(fd, text, g_strlen(text)); + g_ssh = RegisterServiceCtrlHandler("xrdp", MyHandler); + + if (g_ssh != 0) + { + // g_sprintf(text, "ok\r\n"); + // g_file_write(fd, text, g_strlen(text)); + SetServiceStatus(g_ssh, &g_service_status); + g_listen = xrdp_listen_create(); + xrdp_listen_main_loop(g_listen); + g_sleep(100); + g_service_status.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(g_ssh, &g_service_status); + } + else + { + //g_sprintf(text, "RegisterServiceCtrlHandler failed\r\n"); + //g_file_write(fd, text, g_strlen(text)); + } + + xrdp_listen_delete(g_listen); + tc_mutex_delete(g_sync_mutex); + tc_mutex_delete(g_sync1_mutex); + g_destroy_wait_obj(g_term_event); + g_destroy_wait_obj(g_sync_event); + WSACleanup(); + //CloseHandle(event_han); } #endif /*****************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - int test; - int host_be; + int test; + int host_be; #if defined(_WIN32) - WSADATA w; - SC_HANDLE sc_man; - SC_HANDLE sc_ser; - int run_as_service; - SERVICE_TABLE_ENTRY te[2]; + WSADATA w; + SC_HANDLE sc_man; + SC_HANDLE sc_ser; + int run_as_service; + SERVICE_TABLE_ENTRY te[2]; #else - int pid; - int fd; - int no_daemon; - char text[256]; - char pid_file[256]; + int pid; + int fd; + int no_daemon; + char text[256]; + char pid_file[256]; #endif - g_init(); - ssl_init(); - /* check compiled endian with actual endian */ - test = 1; - host_be = !((int)(*(unsigned char*)(&test))); + g_init(); + ssl_init(); + /* check compiled endian with actual endian */ + test = 1; + host_be = !((int)(*(unsigned char *)(&test))); #if defined(B_ENDIAN) - if (!host_be) + + if (!host_be) #endif #if defined(L_ENDIAN) - if (host_be) + if (host_be) #endif - { - g_writeln("endian wrong, edit arch.h"); - return 0; - } - /* check long, int and void* sizes */ - if (sizeof(int) != 4) - { - g_writeln("unusable int size, must be 4"); - return 0; - } - if (sizeof(long) != sizeof(void*)) - { - g_writeln("long size must match void* size"); - return 0; - } - if (sizeof(long) != 4 && sizeof(long) != 8) - { - g_writeln("unusable long size, must be 4 or 8"); - return 0; - } - if (sizeof(tui64) != 8) - { - g_writeln("unusable tui64 size, must be 8"); - return 0; - } -#if defined(_WIN32) - run_as_service = 1; - if (argc == 2) - { - if (g_strncasecmp(argv[1], "-help", 255) == 0 || - g_strncasecmp(argv[1], "--help", 255) == 0 || - g_strncasecmp(argv[1], "-h", 255) == 0) - { - g_writeln(""); - g_writeln("xrdp: A Remote Desktop Protocol server."); - g_writeln("Copyright (C) Jay Sorg 2004-2011"); - g_writeln("See http://xrdp.sourceforge.net for more information."); - g_writeln(""); - g_writeln("Usage: xrdp [options]"); - g_writeln(" -h: show help"); - g_writeln(" -install: install service"); - g_writeln(" -remove: remove service"); - g_writeln(""); - g_exit(0); - } - else if (g_strncasecmp(argv[1], "-install", 255) == 0 || - g_strncasecmp(argv[1], "--install", 255) == 0 || - g_strncasecmp(argv[1], "-i", 255) == 0) - { - /* open service manager */ - sc_man = OpenSCManager(0, 0, GENERIC_WRITE); - if (sc_man == 0) - { - g_writeln("error OpenSCManager, do you have rights?"); - g_exit(0); - } - /* check if service is allready installed */ - sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); - if (sc_ser == 0) - { - /* install service */ - CreateService(sc_man, "xrdp", "xrdp", SERVICE_ALL_ACCESS, - SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, - SERVICE_ERROR_IGNORE, "c:\\temp\\xrdp\\xrdp.exe", - 0, 0, 0, 0, 0); - - } - else - { - g_writeln("error service is allready installed"); - CloseServiceHandle(sc_ser); - CloseServiceHandle(sc_man); - g_exit(0); - } - CloseServiceHandle(sc_man); - g_exit(0); - } - else if (g_strncasecmp(argv[1], "-remove", 255) == 0 || - g_strncasecmp(argv[1], "--remove", 255) == 0 || - g_strncasecmp(argv[1], "-r", 255) == 0) - { - /* open service manager */ - sc_man = OpenSCManager(0, 0, GENERIC_WRITE); - if (sc_man == 0) - { - g_writeln("error OpenSCManager, do you have rights?"); - g_exit(0); - } - /* check if service is allready installed */ - sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); - if (sc_ser == 0) - { - g_writeln("error service is not installed"); - CloseServiceHandle(sc_man); - g_exit(0); - } - DeleteService(sc_ser); - CloseServiceHandle(sc_man); - g_exit(0); - } - else - { - g_writeln("Unknown Parameter"); - g_writeln("xrdp -h for help"); - g_writeln(""); - g_exit(0); - } - } - else if (argc > 1) - { - g_writeln("Unknown Parameter"); - g_writeln("xrdp -h for help"); - g_writeln(""); - g_exit(0); - } - if (run_as_service) - { - g_memset(&te, 0, sizeof(te)); - te[0].lpServiceName = "xrdp"; - te[0].lpServiceProc = MyServiceMain; - StartServiceCtrlDispatcher(&te); - g_exit(0); - } - WSAStartup(2, &w); -#else /* _WIN32 */ - g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH); - no_daemon = 0; - if (argc == 2) - { - if ((g_strncasecmp(argv[1], "-kill", 255) == 0) || - (g_strncasecmp(argv[1], "--kill", 255) == 0) || - (g_strncasecmp(argv[1], "-k", 255) == 0)) - { - g_writeln("stopping xrdp"); - /* read the xrdp.pid file */ - fd = -1; - if (g_file_exist(pid_file)) /* xrdp.pid */ - { - fd = g_file_open(pid_file); /* xrdp.pid */ - } - if (fd == -1) - { - g_writeln("problem opening to xrdp.pid"); - g_writeln("maybe its not running"); - } - else - { - g_memset(text, 0, 32); - g_file_read(fd, text, 31); - pid = g_atoi(text); - g_writeln("stopping process id %d", pid); - if (pid > 0) { - g_sigterm(pid); + g_writeln("endian wrong, edit arch.h"); + return 0; } - g_file_close(fd); - } - g_exit(0); - } - else if (g_strncasecmp(argv[1], "-nodaemon", 255) == 0 || - g_strncasecmp(argv[1], "--nodaemon", 255) == 0 || - g_strncasecmp(argv[1], "-nd", 255) == 0 || - g_strncasecmp(argv[1], "--nd", 255) == 0 || - g_strncasecmp(argv[1], "-ns", 255) == 0 || - g_strncasecmp(argv[1], "--ns", 255) == 0) - { - no_daemon = 1; - } - else if (g_strncasecmp(argv[1], "-help", 255) == 0 || - g_strncasecmp(argv[1], "--help", 255) == 0 || - g_strncasecmp(argv[1], "-h", 255) == 0) - { - g_writeln(""); - g_writeln("xrdp: A Remote Desktop Protocol server."); - g_writeln("Copyright (C) Jay Sorg 2004-2011"); - g_writeln("See http://xrdp.sourceforge.net for more information."); - g_writeln(""); - g_writeln("Usage: xrdp [options]"); - g_writeln(" -h: show help"); - g_writeln(" -nodaemon: don't fork into background"); - g_writeln(" -kill: shut down xrdp"); - g_writeln(""); - g_exit(0); - } - else if ((g_strncasecmp(argv[1], "-v", 255) == 0) || - (g_strncasecmp(argv[1], "--version", 255) == 0)) - { - g_writeln(""); - g_writeln("xrdp: A Remote Desktop Protocol server."); - g_writeln("Copyright (C) Jay Sorg 2004-2011"); - g_writeln("See http://xrdp.sourceforge.net for more information."); - g_writeln("Version %s",PACKAGE_VERSION); - g_writeln(""); - g_exit(0); - } - else - { - g_writeln("Unknown Parameter"); - g_writeln("xrdp -h for help"); - g_writeln(""); - g_exit(0); - } - } - else if (argc > 1) - { - g_writeln("Unknown Parameter"); - g_writeln("xrdp -h for help"); - g_writeln(""); - g_exit(0); - } - if (g_file_exist(pid_file)) /* xrdp.pid */ - { - g_writeln("It looks like xrdp is allready running,"); - g_writeln("if not delete the xrdp.pid file and try again"); - g_exit(0); - } - if (!no_daemon) - { - /* make sure we can write to pid file */ - fd = g_file_open(pid_file); /* xrdp.pid */ - if (fd == -1) - { - g_writeln("running in daemon mode with no access to pid files, quitting"); - g_exit(0); - } - if (g_file_write(fd, "0", 1) == -1) - { - g_writeln("running in daemon mode with no access to pid files, quitting"); - g_exit(0); - } - g_file_close(fd); - g_file_delete(pid_file); - } - if (!no_daemon) - { - /* start of daemonizing code */ - pid = g_fork(); - if (pid == -1) - { - g_writeln("problem forking"); - g_exit(1); - } - if (0 != pid) - { - g_writeln("process %d started ok", pid); - /* exit, this is the main process */ - g_exit(0); - } - g_sleep(1000); - g_file_close(0); - g_file_close(1); - g_file_close(2); - g_file_open("/dev/null"); - g_file_open("/dev/null"); - g_file_open("/dev/null"); - /* end of daemonizing code */ - } - if (!no_daemon) - { - /* write the pid to file */ - pid = g_getpid(); - fd = g_file_open(pid_file); /* xrdp.pid */ - if (fd == -1) - { - g_writeln("trying to write process id to xrdp.pid"); - g_writeln("problem opening xrdp.pid"); - g_writeln("maybe no rights"); - } - else - { - g_sprintf(text, "%d", pid); - g_file_write(fd, text, g_strlen(text)); - g_file_close(fd); - } - } -#endif - g_threadid = tc_get_threadid(); - g_listen = xrdp_listen_create(); - g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */ - g_signal_kill(xrdp_shutdown); /* SIGKILL */ - g_signal_pipe(pipe_sig); /* SIGPIPE */ - g_signal_terminate(xrdp_shutdown); /* SIGTERM */ - g_sync_mutex = tc_mutex_create(); - g_sync1_mutex = tc_mutex_create(); - pid = g_getpid(); - g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); - g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); - g_sync_event = g_create_wait_obj(text); - if (g_term_event == 0) - { - g_writeln("error creating g_term_event"); - } - xrdp_listen_main_loop(g_listen); - xrdp_listen_delete(g_listen); - tc_mutex_delete(g_sync_mutex); - tc_mutex_delete(g_sync1_mutex); - g_delete_wait_obj(g_term_event); - g_delete_wait_obj(g_sync_event); -#if defined(_WIN32) - /* I don't think it ever gets here */ - /* when running in win32 app mode, control c exits right away */ - WSACleanup(); -#else - /* delete the xrdp.pid file */ - g_file_delete(pid_file); -#endif - return 0; -} + /* check long, int and void* sizes */ + if (sizeof(int) != 4) + { + g_writeln("unusable int size, must be 4"); + return 0; + } + + if (sizeof(long) != sizeof(void *)) + { + g_writeln("long size must match void* size"); + return 0; + } + + if (sizeof(long) != 4 && sizeof(long) != 8) + { + g_writeln("unusable long size, must be 4 or 8"); + return 0; + } + + if (sizeof(tui64) != 8) + { + g_writeln("unusable tui64 size, must be 8"); + return 0; + } + +#if defined(_WIN32) + run_as_service = 1; + + if (argc == 2) + { + if (g_strncasecmp(argv[1], "-help", 255) == 0 || + g_strncasecmp(argv[1], "--help", 255) == 0 || + g_strncasecmp(argv[1], "-h", 255) == 0) + { + g_writeln(""); + g_writeln("xrdp: A Remote Desktop Protocol server."); + g_writeln("Copyright (C) Jay Sorg 2004-2011"); + g_writeln("See http://xrdp.sourceforge.net for more information."); + g_writeln(""); + g_writeln("Usage: xrdp [options]"); + g_writeln(" -h: show help"); + g_writeln(" -install: install service"); + g_writeln(" -remove: remove service"); + g_writeln(""); + g_exit(0); + } + else if (g_strncasecmp(argv[1], "-install", 255) == 0 || + g_strncasecmp(argv[1], "--install", 255) == 0 || + g_strncasecmp(argv[1], "-i", 255) == 0) + { + /* open service manager */ + sc_man = OpenSCManager(0, 0, GENERIC_WRITE); + + if (sc_man == 0) + { + g_writeln("error OpenSCManager, do you have rights?"); + g_exit(0); + } + + /* check if service is allready installed */ + sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); + + if (sc_ser == 0) + { + /* install service */ + CreateService(sc_man, "xrdp", "xrdp", SERVICE_ALL_ACCESS, + SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, + SERVICE_ERROR_IGNORE, "c:\\temp\\xrdp\\xrdp.exe", + 0, 0, 0, 0, 0); + + } + else + { + g_writeln("error service is allready installed"); + CloseServiceHandle(sc_ser); + CloseServiceHandle(sc_man); + g_exit(0); + } + + CloseServiceHandle(sc_man); + g_exit(0); + } + else if (g_strncasecmp(argv[1], "-remove", 255) == 0 || + g_strncasecmp(argv[1], "--remove", 255) == 0 || + g_strncasecmp(argv[1], "-r", 255) == 0) + { + /* open service manager */ + sc_man = OpenSCManager(0, 0, GENERIC_WRITE); + + if (sc_man == 0) + { + g_writeln("error OpenSCManager, do you have rights?"); + g_exit(0); + } + + /* check if service is allready installed */ + sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); + + if (sc_ser == 0) + { + g_writeln("error service is not installed"); + CloseServiceHandle(sc_man); + g_exit(0); + } + + DeleteService(sc_ser); + CloseServiceHandle(sc_man); + g_exit(0); + } + else + { + g_writeln("Unknown Parameter"); + g_writeln("xrdp -h for help"); + g_writeln(""); + g_exit(0); + } + } + else if (argc > 1) + { + g_writeln("Unknown Parameter"); + g_writeln("xrdp -h for help"); + g_writeln(""); + g_exit(0); + } + + if (run_as_service) + { + g_memset(&te, 0, sizeof(te)); + te[0].lpServiceName = "xrdp"; + te[0].lpServiceProc = MyServiceMain; + StartServiceCtrlDispatcher(&te); + g_exit(0); + } + + WSAStartup(2, &w); +#else /* _WIN32 */ + g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH); + no_daemon = 0; + + if (argc == 2) + { + if ((g_strncasecmp(argv[1], "-kill", 255) == 0) || + (g_strncasecmp(argv[1], "--kill", 255) == 0) || + (g_strncasecmp(argv[1], "-k", 255) == 0)) + { + g_writeln("stopping xrdp"); + /* read the xrdp.pid file */ + fd = -1; + + if (g_file_exist(pid_file)) /* xrdp.pid */ + { + fd = g_file_open(pid_file); /* xrdp.pid */ + } + + if (fd == -1) + { + g_writeln("problem opening to xrdp.pid"); + g_writeln("maybe its not running"); + } + else + { + g_memset(text, 0, 32); + g_file_read(fd, text, 31); + pid = g_atoi(text); + g_writeln("stopping process id %d", pid); + + if (pid > 0) + { + g_sigterm(pid); + } + + g_file_close(fd); + } + + g_exit(0); + } + else if (g_strncasecmp(argv[1], "-nodaemon", 255) == 0 || + g_strncasecmp(argv[1], "--nodaemon", 255) == 0 || + g_strncasecmp(argv[1], "-nd", 255) == 0 || + g_strncasecmp(argv[1], "--nd", 255) == 0 || + g_strncasecmp(argv[1], "-ns", 255) == 0 || + g_strncasecmp(argv[1], "--ns", 255) == 0) + { + no_daemon = 1; + } + else if (g_strncasecmp(argv[1], "-help", 255) == 0 || + g_strncasecmp(argv[1], "--help", 255) == 0 || + g_strncasecmp(argv[1], "-h", 255) == 0) + { + g_writeln(""); + g_writeln("xrdp: A Remote Desktop Protocol server."); + g_writeln("Copyright (C) Jay Sorg 2004-2011"); + g_writeln("See http://xrdp.sourceforge.net for more information."); + g_writeln(""); + g_writeln("Usage: xrdp [options]"); + g_writeln(" -h: show help"); + g_writeln(" -nodaemon: don't fork into background"); + g_writeln(" -kill: shut down xrdp"); + g_writeln(""); + g_exit(0); + } + else if ((g_strncasecmp(argv[1], "-v", 255) == 0) || + (g_strncasecmp(argv[1], "--version", 255) == 0)) + { + g_writeln(""); + g_writeln("xrdp: A Remote Desktop Protocol server."); + g_writeln("Copyright (C) Jay Sorg 2004-2011"); + g_writeln("See http://xrdp.sourceforge.net for more information."); + g_writeln("Version %s", PACKAGE_VERSION); + g_writeln(""); + g_exit(0); + } + else + { + g_writeln("Unknown Parameter"); + g_writeln("xrdp -h for help"); + g_writeln(""); + g_exit(0); + } + } + else if (argc > 1) + { + g_writeln("Unknown Parameter"); + g_writeln("xrdp -h for help"); + g_writeln(""); + g_exit(0); + } + + if (g_file_exist(pid_file)) /* xrdp.pid */ + { + g_writeln("It looks like xrdp is allready running,"); + g_writeln("if not delete the xrdp.pid file and try again"); + g_exit(0); + } + + if (!no_daemon) + { + /* make sure we can write to pid file */ + fd = g_file_open(pid_file); /* xrdp.pid */ + + if (fd == -1) + { + g_writeln("running in daemon mode with no access to pid files, quitting"); + g_exit(0); + } + + if (g_file_write(fd, "0", 1) == -1) + { + g_writeln("running in daemon mode with no access to pid files, quitting"); + g_exit(0); + } + + g_file_close(fd); + g_file_delete(pid_file); + } + + if (!no_daemon) + { + /* start of daemonizing code */ + pid = g_fork(); + + if (pid == -1) + { + g_writeln("problem forking"); + g_exit(1); + } + + if (0 != pid) + { + g_writeln("process %d started ok", pid); + /* exit, this is the main process */ + g_exit(0); + } + + g_sleep(1000); + g_file_close(0); + g_file_close(1); + g_file_close(2); + g_file_open("/dev/null"); + g_file_open("/dev/null"); + g_file_open("/dev/null"); + /* end of daemonizing code */ + } + + if (!no_daemon) + { + /* write the pid to file */ + pid = g_getpid(); + fd = g_file_open(pid_file); /* xrdp.pid */ + + if (fd == -1) + { + g_writeln("trying to write process id to xrdp.pid"); + g_writeln("problem opening xrdp.pid"); + g_writeln("maybe no rights"); + } + else + { + g_sprintf(text, "%d", pid); + g_file_write(fd, text, g_strlen(text)); + g_file_close(fd); + } + } + +#endif + g_threadid = tc_get_threadid(); + g_listen = xrdp_listen_create(); + g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */ + g_signal_kill(xrdp_shutdown); /* SIGKILL */ + g_signal_pipe(pipe_sig); /* SIGPIPE */ + g_signal_terminate(xrdp_shutdown); /* SIGTERM */ + g_sync_mutex = tc_mutex_create(); + g_sync1_mutex = tc_mutex_create(); + pid = g_getpid(); + g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); + g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); + g_sync_event = g_create_wait_obj(text); + + if (g_term_event == 0) + { + g_writeln("error creating g_term_event"); + } + + xrdp_listen_main_loop(g_listen); + xrdp_listen_delete(g_listen); + tc_mutex_delete(g_sync_mutex); + tc_mutex_delete(g_sync1_mutex); + g_delete_wait_obj(g_term_event); + g_delete_wait_obj(g_sync_event); +#if defined(_WIN32) + /* I don't think it ever gets here */ + /* when running in win32 app mode, control c exits right away */ + WSACleanup(); +#else + /* delete the xrdp.pid file */ + g_file_delete(pid_file); +#endif + return 0; +} diff --git a/xrdpapi/simple.c b/xrdpapi/simple.c index a2c0f875..7f309ab8 100644 --- a/xrdpapi/simple.c +++ b/xrdpapi/simple.c @@ -1,6 +1,24 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - -// xrdp_chan_test.cpp : Basic test for virtual channel use. +/* + * Basic test for virtual channel use + */ // These headers are required for the windows terminal services calls. #include "xrdpapi.h" @@ -15,80 +33,87 @@ int main() { - // Initialize the data for send/receive - void* hFile; - char* data; - char* data1; - data = (char*)malloc(DSIZE); - data1 = (char*)malloc(DSIZE); - int ret; - void* vcFileHandlePtr = NULL; - memset(data, 0xca, DSIZE); - memset(data1, 0, DSIZE); - unsigned int written = 0; + // Initialize the data for send/receive + void *hFile; + char *data; + char *data1; + data = (char *)malloc(DSIZE); + data1 = (char *)malloc(DSIZE); + int ret; + void *vcFileHandlePtr = NULL; + memset(data, 0xca, DSIZE); + memset(data1, 0, DSIZE); + unsigned int written = 0; - // Open the skel channel in current session + // Open the skel channel in current session - //void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0); - void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "TSMF", WTS_CHANNEL_OPTION_DYNAMIC); - ret = WTSVirtualChannelQuery(channel, WTSVirtualFileHandle, vcFileHandlePtr, &written); + //void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0); + void *channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "TSMF", WTS_CHANNEL_OPTION_DYNAMIC); + ret = WTSVirtualChannelQuery(channel, WTSVirtualFileHandle, vcFileHandlePtr, &written); - // Write the data to the channel - ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written); - if (!ret) - { + // Write the data to the channel + ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written); - long err = errno; - printf("error 1 0x%8.8x\n", err); - usleep(100000); - return 1; - } - else - { - printf("Sent bytes!\n"); - } - if (written != DSIZE) - { - long err = errno; - printf("error 2 0x%8.8x\n", err); - usleep(100000); - return 1; - } - else - { - printf("Read bytes!\n"); - } - ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written); - if (!ret) - { - long err = errno; - printf("error 3 0x%8.8x\n", err); - usleep(100000); - return 1; - } - if (written != DSIZE) - { - long err = errno; - printf("error 4 0x%8.8x\n", err); - usleep(100000); - return 1; - } - else - { - printf("Read bytes!\n"); - } - ret = WTSVirtualChannelClose(channel); - if (memcmp(data, data1, DSIZE) == 0) - { - } - else - { - printf("error data no match\n"); - return 1; - } + if (!ret) + { - printf("Done!\n"); + long err = errno; + printf("error 1 0x%8.8x\n", err); + usleep(100000); + return 1; + } + else + { + printf("Sent bytes!\n"); + } - usleep(100000); - return 0; + if (written != DSIZE) + { + long err = errno; + printf("error 2 0x%8.8x\n", err); + usleep(100000); + return 1; + } + else + { + printf("Read bytes!\n"); + } + + ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written); + + if (!ret) + { + long err = errno; + printf("error 3 0x%8.8x\n", err); + usleep(100000); + return 1; + } + + if (written != DSIZE) + { + long err = errno; + printf("error 4 0x%8.8x\n", err); + usleep(100000); + return 1; + } + else + { + printf("Read bytes!\n"); + } + + ret = WTSVirtualChannelClose(channel); + + if (memcmp(data, data1, DSIZE) == 0) + { + } + else + { + printf("error data no match\n"); + return 1; + } + + printf("Done!\n"); + + usleep(100000); + return 0; } diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c index 694b3800..85a13a8e 100644 --- a/xrdpapi/xrdpapi.c +++ b/xrdpapi/xrdpapi.c @@ -21,9 +21,9 @@ #define LOG_LEVEL 1 #define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { printf _args ; printf("\n"); } } while (0) + do { if (_level < LOG_LEVEL) { printf _args ; printf("\n"); } } while (0) #include #include @@ -40,344 +40,382 @@ struct wts_obj { - int fd; - int status; - char name[8]; - char dname[128]; - int display_num; - int flags; + int fd; + int status; + char name[8]; + char dname[128]; + int display_num; + int flags; }; /*****************************************************************************/ static int -get_display_num_from_display(char* display_text) +get_display_num_from_display(char *display_text) { - int index; - int mode; - int host_index; - int disp_index; - int scre_index; - char host[256]; - char disp[256]; - char scre[256]; + int index; + int mode; + int host_index; + int disp_index; + int scre_index; + char host[256]; + char disp[256]; + char scre[256]; - index = 0; - host_index = 0; - disp_index = 0; - scre_index = 0; - mode = 0; - while (display_text[index] != 0) - { - if (display_text[index] == ':') + index = 0; + host_index = 0; + disp_index = 0; + scre_index = 0; + mode = 0; + + while (display_text[index] != 0) { - mode = 1; + if (display_text[index] == ':') + { + mode = 1; + } + else if (display_text[index] == '.') + { + mode = 2; + } + else if (mode == 0) + { + host[host_index] = display_text[index]; + host_index++; + } + else if (mode == 1) + { + disp[disp_index] = display_text[index]; + disp_index++; + } + else if (mode == 2) + { + scre[scre_index] = display_text[index]; + scre_index++; + } + + index++; } - else if (display_text[index] == '.') - { - mode = 2; - } - else if (mode == 0) - { - host[host_index] = display_text[index]; - host_index++; - } - else if (mode == 1) - { - disp[disp_index] = display_text[index]; - disp_index++; - } - else if (mode == 2) - { - scre[scre_index] = display_text[index]; - scre_index++; - } - index++; - } - host[host_index] = 0; - disp[disp_index] = 0; - scre[scre_index] = 0; - return atoi(disp); + + host[host_index] = 0; + disp[disp_index] = 0; + scre[scre_index] = 0; + return atoi(disp); } /*****************************************************************************/ -void* -WTSVirtualChannelOpen(void* hServer, unsigned int SessionId, - const char* pVirtualName) +void * +WTSVirtualChannelOpen(void *hServer, unsigned int SessionId, + const char *pVirtualName) { - if (hServer != WTS_CURRENT_SERVER_HANDLE) - { - return 0; - } - return WTSVirtualChannelOpenEx(SessionId, pVirtualName, 0); + if (hServer != WTS_CURRENT_SERVER_HANDLE) + { + return 0; + } + + return WTSVirtualChannelOpenEx(SessionId, pVirtualName, 0); } /*****************************************************************************/ static int can_send(int sck, int millis) { - struct timeval time; - fd_set wfds; - int select_rv; + struct timeval time; + fd_set wfds; + int select_rv; - FD_ZERO(&wfds); - FD_SET(sck, &wfds); - time.tv_sec = millis / 1000; - time.tv_usec = (millis * 1000) % 1000000; - select_rv = select(sck + 1, 0, &wfds, 0, &time); - if (select_rv > 0) - { - return 1; - } - return 0; + FD_ZERO(&wfds); + FD_SET(sck, &wfds); + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + select_rv = select(sck + 1, 0, &wfds, 0, &time); + + if (select_rv > 0) + { + return 1; + } + + return 0; } /*****************************************************************************/ static int can_recv(int sck, int millis) { - struct timeval time; - fd_set rfds; - int select_rv; + struct timeval time; + fd_set rfds; + int select_rv; - FD_ZERO(&rfds); - FD_SET(sck, &rfds); - time.tv_sec = millis / 1000; - time.tv_usec = (millis * 1000) % 1000000; - select_rv = select(sck + 1, &rfds, 0, 0, &time); - if (select_rv > 0) - { - return 1; - } - return 0; + FD_ZERO(&rfds); + FD_SET(sck, &rfds); + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + select_rv = select(sck + 1, &rfds, 0, 0, &time); + + if (select_rv > 0) + { + return 1; + } + + return 0; } /*****************************************************************************/ static int -send_init(struct wts_obj* wts) +send_init(struct wts_obj *wts) { - char initmsg[64]; + char initmsg[64]; - memset(initmsg, 0, 64); - strncpy(initmsg, wts->name, 8); - initmsg[16] = (wts->flags >> 0) & 0xff; - initmsg[17] = (wts->flags >> 8) & 0xff; - initmsg[18] = (wts->flags >> 16) & 0xff; - initmsg[19] = (wts->flags >> 24) & 0xff; - LLOGLN(10, ("send_init: sending %s", initmsg)); - if (!can_send(wts->fd, 500)) - { - return 1; - } - if (send(wts->fd, initmsg, 64, 0) != 64) - { - return 1; - } - LLOGLN(10, ("send_init: send ok!")); - return 0; + memset(initmsg, 0, 64); + strncpy(initmsg, wts->name, 8); + initmsg[16] = (wts->flags >> 0) & 0xff; + initmsg[17] = (wts->flags >> 8) & 0xff; + initmsg[18] = (wts->flags >> 16) & 0xff; + initmsg[19] = (wts->flags >> 24) & 0xff; + LLOGLN(10, ("send_init: sending %s", initmsg)); + + if (!can_send(wts->fd, 500)) + { + return 1; + } + + if (send(wts->fd, initmsg, 64, 0) != 64) + { + return 1; + } + + LLOGLN(10, ("send_init: send ok!")); + return 0; } /*****************************************************************************/ -void* +void * WTSVirtualChannelOpenEx(unsigned int SessionId, - const char* pVirtualName, + const char *pVirtualName, unsigned int flags) { - struct wts_obj* wts; - char* display_text; - struct sockaddr_un s; - int bytes; - unsigned long llong; + struct wts_obj *wts; + char *display_text; + struct sockaddr_un s; + int bytes; + unsigned long llong; - if (SessionId != WTS_CURRENT_SESSION) - { - LLOGLN(0, ("WTSVirtualChannelOpenEx: SessionId bad")); - return 0; - } - wts = (struct wts_obj*)malloc(sizeof(struct wts_obj)); - memset(wts, 0, sizeof(struct wts_obj)); - wts->fd = -1; - wts->flags = flags; - display_text = getenv("DISPLAY"); - if (display_text != 0) - { - wts->display_num = get_display_num_from_display(display_text); - } - if (wts->display_num > 0) - { - wts->fd = socket(AF_UNIX, SOCK_STREAM, 0); - /* set non blocking */ - llong = fcntl(wts->fd, F_GETFL); - llong = llong | O_NONBLOCK; - fcntl(wts->fd, F_SETFL, llong); - /* connect to session chansrv */ - memset(&s, 0, sizeof(struct sockaddr_un)); - s.sun_family = AF_UNIX; - bytes = sizeof(s.sun_path); - snprintf(s.sun_path, bytes - 1, "/tmp/.xrdp/xrdpapi_%d", wts->display_num); - s.sun_path[bytes - 1] = 0; - bytes = sizeof(struct sockaddr_un); - if (connect(wts->fd, (struct sockaddr*)&s, bytes) == 0) + if (SessionId != WTS_CURRENT_SESSION) { - LLOGLN(10, ("WTSVirtualChannelOpenEx: connected ok, name %s", pVirtualName)); - strncpy(wts->name, pVirtualName, 8); - /* wait for connection to complete and send init */ - if (send_init(wts) == 0) - { - /* all ok */ - wts->status = 1; - } + LLOGLN(0, ("WTSVirtualChannelOpenEx: SessionId bad")); + return 0; } - } - else - { - LLOGLN(0, ("WTSVirtualChannelOpenEx: display is 0")); - } - return wts; + + wts = (struct wts_obj *)malloc(sizeof(struct wts_obj)); + memset(wts, 0, sizeof(struct wts_obj)); + wts->fd = -1; + wts->flags = flags; + display_text = getenv("DISPLAY"); + + if (display_text != 0) + { + wts->display_num = get_display_num_from_display(display_text); + } + + if (wts->display_num > 0) + { + wts->fd = socket(AF_UNIX, SOCK_STREAM, 0); + /* set non blocking */ + llong = fcntl(wts->fd, F_GETFL); + llong = llong | O_NONBLOCK; + fcntl(wts->fd, F_SETFL, llong); + /* connect to session chansrv */ + memset(&s, 0, sizeof(struct sockaddr_un)); + s.sun_family = AF_UNIX; + bytes = sizeof(s.sun_path); + snprintf(s.sun_path, bytes - 1, "/tmp/.xrdp/xrdpapi_%d", wts->display_num); + s.sun_path[bytes - 1] = 0; + bytes = sizeof(struct sockaddr_un); + + if (connect(wts->fd, (struct sockaddr *)&s, bytes) == 0) + { + LLOGLN(10, ("WTSVirtualChannelOpenEx: connected ok, name %s", pVirtualName)); + strncpy(wts->name, pVirtualName, 8); + + /* wait for connection to complete and send init */ + if (send_init(wts) == 0) + { + /* all ok */ + wts->status = 1; + } + } + } + else + { + LLOGLN(0, ("WTSVirtualChannelOpenEx: display is 0")); + } + + return wts; } /*****************************************************************************/ int -WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer, - unsigned int Length, unsigned int* pBytesWritten) +WTSVirtualChannelWrite(void *hChannelHandle, const char *Buffer, + unsigned int Length, unsigned int *pBytesWritten) { - struct wts_obj* wts; - int error; - int lerrno; + struct wts_obj *wts; + int error; + int lerrno; - wts = (struct wts_obj*)hChannelHandle; - if (wts == 0) - { - return 0; - } - if (wts->status != 1) - { - return 0; - } - if (can_send(wts->fd, 0)) - { - error = send(wts->fd, Buffer, Length, 0); - if (error == -1) + wts = (struct wts_obj *)hChannelHandle; + + if (wts == 0) { - lerrno = errno; - if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) || - (lerrno == EINPROGRESS)) - { - *pBytesWritten = 0; - return 1; - } - return 0; + return 0; } - else if (error == 0) + + if (wts->status != 1) { - return 0; + return 0; } - else if (error > 0) + + if (can_send(wts->fd, 0)) { - *pBytesWritten = error; - return 1; + error = send(wts->fd, Buffer, Length, 0); + + if (error == -1) + { + lerrno = errno; + + if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) || + (lerrno == EINPROGRESS)) + { + *pBytesWritten = 0; + return 1; + } + + return 0; + } + else if (error == 0) + { + return 0; + } + else if (error > 0) + { + *pBytesWritten = error; + return 1; + } } - } - *pBytesWritten = 0; - return 1; + + *pBytesWritten = 0; + return 1; } /*****************************************************************************/ int -WTSVirtualChannelRead(void* hChannelHandle, unsigned int TimeOut, - char* Buffer, unsigned int BufferSize, - unsigned int* pBytesRead) +WTSVirtualChannelRead(void *hChannelHandle, unsigned int TimeOut, + char *Buffer, unsigned int BufferSize, + unsigned int *pBytesRead) { - struct wts_obj* wts; - int error; - int lerrno; + struct wts_obj *wts; + int error; + int lerrno; - wts = (struct wts_obj*)hChannelHandle; - if (wts == 0) - { - return 0; - } - if (wts->status != 1) - { - return 0; - } - if (can_recv(wts->fd, TimeOut)) - { - error = recv(wts->fd, Buffer, BufferSize, 0); - if (error == -1) + wts = (struct wts_obj *)hChannelHandle; + + if (wts == 0) { - lerrno = errno; - if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) || - (lerrno == EINPROGRESS)) - { - *pBytesRead = 0; - return 1; - } - return 0; + return 0; } - else if (error == 0) + + if (wts->status != 1) { - return 0; + return 0; } - else if (error > 0) + + if (can_recv(wts->fd, TimeOut)) { - *pBytesRead = error; - return 1; + error = recv(wts->fd, Buffer, BufferSize, 0); + + if (error == -1) + { + lerrno = errno; + + if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) || + (lerrno == EINPROGRESS)) + { + *pBytesRead = 0; + return 1; + } + + return 0; + } + else if (error == 0) + { + return 0; + } + else if (error > 0) + { + *pBytesRead = error; + return 1; + } } - } - *pBytesRead = 0; - return 1; + + *pBytesRead = 0; + return 1; } /*****************************************************************************/ int -WTSVirtualChannelClose(void* hChannelHandle) +WTSVirtualChannelClose(void *hChannelHandle) { - struct wts_obj* wts; + struct wts_obj *wts; - wts = (struct wts_obj*)hChannelHandle; - if (wts == 0) - { - return 0; - } - if (wts->fd != -1) - { - close(wts->fd); - } - free(wts); - return 1; + wts = (struct wts_obj *)hChannelHandle; + + if (wts == 0) + { + return 0; + } + + if (wts->fd != -1) + { + close(wts->fd); + } + + free(wts); + return 1; } /*****************************************************************************/ int -WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, - void** ppBuffer, unsigned int* pBytesReturned) +WTSVirtualChannelQuery(void *hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, + void **ppBuffer, unsigned int *pBytesReturned) { - struct wts_obj* wts; + struct wts_obj *wts; - wts = (struct wts_obj*)hChannelHandle; - if (wts == 0) - { - return 0; - } - if (wts->status != 1) - { - return 0; - } - if (WtsVirtualClass == WTSVirtualFileHandle) - { - *pBytesReturned = 4; - *ppBuffer = malloc(4); - memcpy(*ppBuffer, &(wts->fd), 4); - } - return 1; + wts = (struct wts_obj *)hChannelHandle; + + if (wts == 0) + { + return 0; + } + + if (wts->status != 1) + { + return 0; + } + + if (WtsVirtualClass == WTSVirtualFileHandle) + { + *pBytesReturned = 4; + *ppBuffer = malloc(4); + memcpy(*ppBuffer, &(wts->fd), 4); + } + + return 1; } /*****************************************************************************/ void -WTSFreeMemory(void* pMemory) +WTSFreeMemory(void *pMemory) { - if (pMemory != 0) - { - free(pMemory); - } + if (pMemory != 0) + { + free(pMemory); + } } diff --git a/xrdpapi/xrdpapi.h b/xrdpapi/xrdpapi.h index 65b6db42..82f9b809 100644 --- a/xrdpapi/xrdpapi.h +++ b/xrdpapi/xrdpapi.h @@ -16,10 +16,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /* - xrdpapi header, do not use os_calls.h, arch.h or any xrdp internal headers - this file is included in 3rd party apps -*/ + * xrdpapi header, do not use os_calls.h, arch.h or any xrdp internal headers + * this file is included in 3rd party apps + */ #if !defined(XRDPAPI_H_) #define XRDPAPI_H_ diff --git a/xup/xup.c b/xup/xup.c index 3c95c1e0..15498e64 100644 --- a/xup/xup.c +++ b/xup/xup.c @@ -1,828 +1,887 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2012 - - libxup main file - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * libxup main file + */ #include "xup.h" /******************************************************************************/ /* returns error */ int DEFAULT_CC -lib_recv(struct mod* mod, char* data, int len) +lib_recv(struct mod *mod, char *data, int len) { - int rcvd; + int rcvd; - if (mod->sck_closed) - { - return 1; - } - while (len > 0) - { - rcvd = g_tcp_recv(mod->sck, data, len, 0); - if (rcvd == -1) + if (mod->sck_closed) { - if (g_tcp_last_error_would_block(mod->sck)) - { - if (mod->server_is_term(mod)) - { - return 1; - } - g_tcp_can_recv(mod->sck, 10); - } - else - { return 1; - } } - else if (rcvd == 0) + + while (len > 0) { - mod->sck_closed = 1; - return 1; + rcvd = g_tcp_recv(mod->sck, data, len, 0); + + if (rcvd == -1) + { + if (g_tcp_last_error_would_block(mod->sck)) + { + if (mod->server_is_term(mod)) + { + return 1; + } + + g_tcp_can_recv(mod->sck, 10); + } + else + { + return 1; + } + } + else if (rcvd == 0) + { + mod->sck_closed = 1; + return 1; + } + else + { + data += rcvd; + len -= rcvd; + } } - else - { - data += rcvd; - len -= rcvd; - } - } - return 0; + + return 0; } /*****************************************************************************/ /* returns error */ int DEFAULT_CC -lib_send(struct mod* mod, char* data, int len) +lib_send(struct mod *mod, char *data, int len) { - int sent; + int sent; - if (mod->sck_closed) - { - return 1; - } - while (len > 0) - { - sent = g_tcp_send(mod->sck, data, len, 0); - if (sent == -1) + if (mod->sck_closed) { - if (g_tcp_last_error_would_block(mod->sck)) - { - if (mod->server_is_term(mod)) - { - return 1; - } - g_tcp_can_send(mod->sck, 10); - } - else - { return 1; - } } - else if (sent == 0) - { - mod->sck_closed = 1; - return 1; - } - else - { - data += sent; - len -= sent; - } - } - return 0; -} -/******************************************************************************/ -/* return error */ -int DEFAULT_CC -lib_mod_start(struct mod* mod, int w, int h, int bpp) -{ - LIB_DEBUG(mod, "in lib_mod_start"); - mod->width = w; - mod->height = h; - mod->bpp = bpp; - LIB_DEBUG(mod, "out lib_mod_start"); - return 0; -} + while (len > 0) + { + sent = g_tcp_send(mod->sck, data, len, 0); -/******************************************************************************/ -/* return error */ -int DEFAULT_CC -lib_mod_connect(struct mod* mod) -{ - int error; - int len; - int i; - int index; - int use_uds; - struct stream* s; - char con_port[256]; - - LIB_DEBUG(mod, "in lib_mod_connect"); - /* clear screen */ - mod->server_begin_update(mod); - mod->server_set_fgcolor(mod, 0); - mod->server_fill_rect(mod, 0, 0, mod->width, mod->height); - mod->server_end_update(mod); - mod->server_msg(mod, "started connecting", 0); - /* only support 8, 15, 16, and 24 bpp connections from rdp client */ - if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24) - { - mod->server_msg(mod, - "error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0); - LIB_DEBUG(mod, "out lib_mod_connect error"); - return 1; - } - if (g_strcmp(mod->ip, "") == 0) - { - mod->server_msg(mod, "error - no ip set", 0); - LIB_DEBUG(mod, "out lib_mod_connect error"); - return 1; - } - make_stream(s); - g_sprintf(con_port, "%s", mod->port); - use_uds = 0; - if (con_port[0] == '/') - { - use_uds = 1; - } - mod->sck_closed = 0; - i = 0; - while (1) - { - if (use_uds) - { - mod->sck = g_tcp_local_socket(); - } - else - { - mod->sck = g_tcp_socket(); - g_tcp_set_non_blocking(mod->sck); - g_tcp_set_no_delay(mod->sck); - } - mod->server_msg(mod, "connecting...", 0); - if (use_uds) - { - error = g_tcp_local_connect(mod->sck, con_port); - } - else - { - error = g_tcp_connect(mod->sck, mod->ip, con_port); - } - if (error == -1) - { - if (g_tcp_last_error_would_block(mod->sck)) - { - error = 0; - index = 0; - while (!g_tcp_can_send(mod->sck, 100)) + if (sent == -1) { - index++; - if ((index >= 30) || mod->server_is_term(mod)) - { - mod->server_msg(mod, "connect timeout", 0); - error = 1; - break; - } + if (g_tcp_last_error_would_block(mod->sck)) + { + if (mod->server_is_term(mod)) + { + return 1; + } + + g_tcp_can_send(mod->sck, 10); + } + else + { + return 1; + } + } + else if (sent == 0) + { + mod->sck_closed = 1; + return 1; + } + else + { + data += sent; + len -= sent; } - } - else - { - mod->server_msg(mod, "connect error", 0); - } } + + return 0; +} + +/******************************************************************************/ +/* return error */ +int DEFAULT_CC +lib_mod_start(struct mod *mod, int w, int h, int bpp) +{ + LIB_DEBUG(mod, "in lib_mod_start"); + mod->width = w; + mod->height = h; + mod->bpp = bpp; + LIB_DEBUG(mod, "out lib_mod_start"); + return 0; +} + +/******************************************************************************/ +/* return error */ +int DEFAULT_CC +lib_mod_connect(struct mod *mod) +{ + int error; + int len; + int i; + int index; + int use_uds; + struct stream *s; + char con_port[256]; + + LIB_DEBUG(mod, "in lib_mod_connect"); + /* clear screen */ + mod->server_begin_update(mod); + mod->server_set_fgcolor(mod, 0); + mod->server_fill_rect(mod, 0, 0, mod->width, mod->height); + mod->server_end_update(mod); + mod->server_msg(mod, "started connecting", 0); + + /* only support 8, 15, 16, and 24 bpp connections from rdp client */ + if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24) + { + mod->server_msg(mod, + "error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0); + LIB_DEBUG(mod, "out lib_mod_connect error"); + return 1; + } + + if (g_strcmp(mod->ip, "") == 0) + { + mod->server_msg(mod, "error - no ip set", 0); + LIB_DEBUG(mod, "out lib_mod_connect error"); + return 1; + } + + make_stream(s); + g_sprintf(con_port, "%s", mod->port); + use_uds = 0; + + if (con_port[0] == '/') + { + use_uds = 1; + } + + mod->sck_closed = 0; + i = 0; + + while (1) + { + if (use_uds) + { + mod->sck = g_tcp_local_socket(); + } + else + { + mod->sck = g_tcp_socket(); + g_tcp_set_non_blocking(mod->sck); + g_tcp_set_no_delay(mod->sck); + } + + mod->server_msg(mod, "connecting...", 0); + + if (use_uds) + { + error = g_tcp_local_connect(mod->sck, con_port); + } + else + { + error = g_tcp_connect(mod->sck, mod->ip, con_port); + } + + if (error == -1) + { + if (g_tcp_last_error_would_block(mod->sck)) + { + error = 0; + index = 0; + + while (!g_tcp_can_send(mod->sck, 100)) + { + index++; + + if ((index >= 30) || mod->server_is_term(mod)) + { + mod->server_msg(mod, "connect timeout", 0); + error = 1; + break; + } + } + } + else + { + mod->server_msg(mod, "connect error", 0); + } + } + + if (error == 0) + { + break; + } + + g_tcp_close(mod->sck); + mod->sck = 0; + i++; + + if (i >= 4) + { + mod->server_msg(mod, "connection problem, giving up", 0); + break; + } + + g_sleep(250); + } + if (error == 0) { - break; + /* send version message */ + init_stream(s, 8192); + s_push_layer(s, iso_hdr, 4); + out_uint16_le(s, 103); + out_uint32_le(s, 301); + out_uint32_le(s, 0); + out_uint32_le(s, 0); + out_uint32_le(s, 0); + out_uint32_le(s, 1); + s_mark_end(s); + len = (int)(s->end - s->data); + s_pop_layer(s, iso_hdr); + out_uint32_le(s, len); + lib_send(mod, s->data, len); } - g_tcp_close(mod->sck); - mod->sck = 0; - i++; - if (i >= 4) + + if (error == 0) { - mod->server_msg(mod, "connection problem, giving up", 0); - break; + /* send screen size message */ + init_stream(s, 8192); + s_push_layer(s, iso_hdr, 4); + out_uint16_le(s, 103); + out_uint32_le(s, 300); + out_uint32_le(s, mod->width); + out_uint32_le(s, mod->height); + out_uint32_le(s, mod->bpp); + out_uint32_le(s, 0); + s_mark_end(s); + len = (int)(s->end - s->data); + s_pop_layer(s, iso_hdr); + out_uint32_le(s, len); + lib_send(mod, s->data, len); } - g_sleep(250); - } - if (error == 0) - { - /* send version message */ - init_stream(s, 8192); - s_push_layer(s, iso_hdr, 4); - out_uint16_le(s, 103); - out_uint32_le(s, 301); - out_uint32_le(s, 0); - out_uint32_le(s, 0); - out_uint32_le(s, 0); - out_uint32_le(s, 1); - s_mark_end(s); - len = (int)(s->end - s->data); - s_pop_layer(s, iso_hdr); - out_uint32_le(s, len); - lib_send(mod, s->data, len); - } - if (error == 0) - { - /* send screen size message */ - init_stream(s, 8192); - s_push_layer(s, iso_hdr, 4); - out_uint16_le(s, 103); - out_uint32_le(s, 300); - out_uint32_le(s, mod->width); - out_uint32_le(s, mod->height); - out_uint32_le(s, mod->bpp); - out_uint32_le(s, 0); - s_mark_end(s); - len = (int)(s->end - s->data); - s_pop_layer(s, iso_hdr); - out_uint32_le(s, len); - lib_send(mod, s->data, len); - } - if (error == 0) - { - /* send invalidate message */ - init_stream(s, 8192); - s_push_layer(s, iso_hdr, 4); - out_uint16_le(s, 103); - out_uint32_le(s, 200); - /* x and y */ - i = 0; - out_uint32_le(s, i); - /* width and height */ - i = ((mod->width & 0xffff) << 16) | mod->height; - out_uint32_le(s, i); - out_uint32_le(s, 0); - out_uint32_le(s, 0); - s_mark_end(s); - len = (int)(s->end - s->data); - s_pop_layer(s, iso_hdr); - out_uint32_le(s, len); - lib_send(mod, s->data, len); - } - free_stream(s); - if (error != 0) - { - mod->server_msg(mod, "some problem", 0); - LIB_DEBUG(mod, "out lib_mod_connect error"); - return 1; - } - else - { - mod->server_msg(mod, "connected ok", 0); - mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0); - } - LIB_DEBUG(mod, "out lib_mod_connect"); - return 0; + + if (error == 0) + { + /* send invalidate message */ + init_stream(s, 8192); + s_push_layer(s, iso_hdr, 4); + out_uint16_le(s, 103); + out_uint32_le(s, 200); + /* x and y */ + i = 0; + out_uint32_le(s, i); + /* width and height */ + i = ((mod->width & 0xffff) << 16) | mod->height; + out_uint32_le(s, i); + out_uint32_le(s, 0); + out_uint32_le(s, 0); + s_mark_end(s); + len = (int)(s->end - s->data); + s_pop_layer(s, iso_hdr); + out_uint32_le(s, len); + lib_send(mod, s->data, len); + } + + free_stream(s); + + if (error != 0) + { + mod->server_msg(mod, "some problem", 0); + LIB_DEBUG(mod, "out lib_mod_connect error"); + return 1; + } + else + { + mod->server_msg(mod, "connected ok", 0); + mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0); + } + + LIB_DEBUG(mod, "out lib_mod_connect"); + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_event(struct mod* mod, int msg, tbus param1, tbus param2, +lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2, tbus param3, tbus param4) { - struct stream* s; - int len; - int key; - int rv; + struct stream *s; + int len; + int key; + int rv; - LIB_DEBUG(mod, "in lib_mod_event"); - make_stream(s); - if ((msg >= 15) && (msg <= 16)) /* key events */ - { - key = param2; - if (key > 0) + LIB_DEBUG(mod, "in lib_mod_event"); + make_stream(s); + + if ((msg >= 15) && (msg <= 16)) /* key events */ { - if (key == 65027) /* altgr */ - { - if (mod->shift_state) + key = param2; + + if (key > 0) { - g_writeln("special"); - /* fix for mstsc sending left control down with altgr */ - /* control down / up - msg param1 param2 param3 param4 - 15 0 65507 29 0 - 16 0 65507 29 49152 */ - init_stream(s, 8192); - s_push_layer(s, iso_hdr, 4); - out_uint16_le(s, 103); - out_uint32_le(s, 16); /* key up */ - out_uint32_le(s, 0); - out_uint32_le(s, 65507); /* left control */ - out_uint32_le(s, 29); /* RDP scan code */ - out_uint32_le(s, 0xc000); /* flags */ - s_mark_end(s); - len = (int)(s->end - s->data); - s_pop_layer(s, iso_hdr); - out_uint32_le(s, len); - lib_send(mod, s->data, len); + if (key == 65027) /* altgr */ + { + if (mod->shift_state) + { + g_writeln("special"); + /* fix for mstsc sending left control down with altgr */ + /* control down / up + msg param1 param2 param3 param4 + 15 0 65507 29 0 + 16 0 65507 29 49152 */ + init_stream(s, 8192); + s_push_layer(s, iso_hdr, 4); + out_uint16_le(s, 103); + out_uint32_le(s, 16); /* key up */ + out_uint32_le(s, 0); + out_uint32_le(s, 65507); /* left control */ + out_uint32_le(s, 29); /* RDP scan code */ + out_uint32_le(s, 0xc000); /* flags */ + s_mark_end(s); + len = (int)(s->end - s->data); + s_pop_layer(s, iso_hdr); + out_uint32_le(s, len); + lib_send(mod, s->data, len); + } + } + + if (key == 65507) /* left control */ + { + mod->shift_state = msg == 15; + } } - } - if (key == 65507) /* left control */ - { - mod->shift_state = msg == 15; - } } - } - init_stream(s, 8192); - s_push_layer(s, iso_hdr, 4); - out_uint16_le(s, 103); - out_uint32_le(s, msg); - out_uint32_le(s, param1); - out_uint32_le(s, param2); - out_uint32_le(s, param3); - out_uint32_le(s, param4); - s_mark_end(s); - len = (int)(s->end - s->data); - s_pop_layer(s, iso_hdr); - out_uint32_le(s, len); - rv = lib_send(mod, s->data, len); - free_stream(s); - LIB_DEBUG(mod, "out lib_mod_event"); - return rv; + + init_stream(s, 8192); + s_push_layer(s, iso_hdr, 4); + out_uint16_le(s, 103); + out_uint32_le(s, msg); + out_uint32_le(s, param1); + out_uint32_le(s, param2); + out_uint32_le(s, param3); + out_uint32_le(s, param4); + s_mark_end(s); + len = (int)(s->end - s->data); + s_pop_layer(s, iso_hdr); + out_uint32_le(s, len); + rv = lib_send(mod, s->data, len); + free_stream(s); + LIB_DEBUG(mod, "out lib_mod_event"); + return rv; } /******************************************************************************/ /* return error */ static int APP_CC -process_server_window_new_update(struct mod* mod, struct stream* s) +process_server_window_new_update(struct mod *mod, struct stream *s) { - int flags; - int window_id; - int title_bytes; - int index; - int bytes; - int rv; - struct rail_window_state_order rwso; + int flags; + int window_id; + int title_bytes; + int index; + int bytes; + int rv; + struct rail_window_state_order rwso; - g_memset(&rwso, 0, sizeof(rwso)); - in_uint32_le(s, window_id); - in_uint32_le(s, rwso.owner_window_id); - in_uint32_le(s, rwso.style); - in_uint32_le(s, rwso.extended_style); - in_uint32_le(s, rwso.show_state); - in_uint16_le(s, title_bytes); - if (title_bytes > 0) - { - rwso.title_info = g_malloc(title_bytes + 1, 0); - in_uint8a(s, rwso.title_info, title_bytes); - rwso.title_info[title_bytes] = 0; - } - in_uint32_le(s, rwso.client_offset_x); - in_uint32_le(s, rwso.client_offset_y); - in_uint32_le(s, rwso.client_area_width); - in_uint32_le(s, rwso.client_area_height); - in_uint32_le(s, rwso.rp_content); - in_uint32_le(s, rwso.root_parent_handle); - in_uint32_le(s, rwso.window_offset_x); - in_uint32_le(s, rwso.window_offset_y); - in_uint32_le(s, rwso.window_client_delta_x); - in_uint32_le(s, rwso.window_client_delta_y); - in_uint32_le(s, rwso.window_width); - in_uint32_le(s, rwso.window_height); - in_uint16_le(s, rwso.num_window_rects); - if (rwso.num_window_rects > 0) - { - bytes = sizeof(struct rail_window_rect) * rwso.num_window_rects; - rwso.window_rects = (struct rail_window_rect*)g_malloc(bytes, 0); - for (index = 0; index < rwso.num_window_rects; index++) + g_memset(&rwso, 0, sizeof(rwso)); + in_uint32_le(s, window_id); + in_uint32_le(s, rwso.owner_window_id); + in_uint32_le(s, rwso.style); + in_uint32_le(s, rwso.extended_style); + in_uint32_le(s, rwso.show_state); + in_uint16_le(s, title_bytes); + + if (title_bytes > 0) { - in_uint16_le(s, rwso.window_rects[index].left); - in_uint16_le(s, rwso.window_rects[index].top); - in_uint16_le(s, rwso.window_rects[index].right); - in_uint16_le(s, rwso.window_rects[index].bottom); + rwso.title_info = g_malloc(title_bytes + 1, 0); + in_uint8a(s, rwso.title_info, title_bytes); + rwso.title_info[title_bytes] = 0; } - } - in_uint32_le(s, rwso.visible_offset_x); - in_uint32_le(s, rwso.visible_offset_y); - in_uint16_le(s, rwso.num_visibility_rects); - if (rwso.num_visibility_rects > 0) - { - bytes = sizeof(struct rail_window_rect) * rwso.num_visibility_rects; - rwso.visibility_rects = (struct rail_window_rect*)g_malloc(bytes, 0); - for (index = 0; index < rwso.num_visibility_rects; index++) + + in_uint32_le(s, rwso.client_offset_x); + in_uint32_le(s, rwso.client_offset_y); + in_uint32_le(s, rwso.client_area_width); + in_uint32_le(s, rwso.client_area_height); + in_uint32_le(s, rwso.rp_content); + in_uint32_le(s, rwso.root_parent_handle); + in_uint32_le(s, rwso.window_offset_x); + in_uint32_le(s, rwso.window_offset_y); + in_uint32_le(s, rwso.window_client_delta_x); + in_uint32_le(s, rwso.window_client_delta_y); + in_uint32_le(s, rwso.window_width); + in_uint32_le(s, rwso.window_height); + in_uint16_le(s, rwso.num_window_rects); + + if (rwso.num_window_rects > 0) { - in_uint16_le(s, rwso.visibility_rects[index].left); - in_uint16_le(s, rwso.visibility_rects[index].top); - in_uint16_le(s, rwso.visibility_rects[index].right); - in_uint16_le(s, rwso.visibility_rects[index].bottom); + bytes = sizeof(struct rail_window_rect) * rwso.num_window_rects; + rwso.window_rects = (struct rail_window_rect *)g_malloc(bytes, 0); + + for (index = 0; index < rwso.num_window_rects; index++) + { + in_uint16_le(s, rwso.window_rects[index].left); + in_uint16_le(s, rwso.window_rects[index].top); + in_uint16_le(s, rwso.window_rects[index].right); + in_uint16_le(s, rwso.window_rects[index].bottom); + } } - } - in_uint32_le(s, flags); - mod->server_window_new_update(mod, window_id, &rwso, flags); - rv = 0; - g_free(rwso.title_info); - g_free(rwso.window_rects); - g_free(rwso.visibility_rects); - return rv; + + in_uint32_le(s, rwso.visible_offset_x); + in_uint32_le(s, rwso.visible_offset_y); + in_uint16_le(s, rwso.num_visibility_rects); + + if (rwso.num_visibility_rects > 0) + { + bytes = sizeof(struct rail_window_rect) * rwso.num_visibility_rects; + rwso.visibility_rects = (struct rail_window_rect *)g_malloc(bytes, 0); + + for (index = 0; index < rwso.num_visibility_rects; index++) + { + in_uint16_le(s, rwso.visibility_rects[index].left); + in_uint16_le(s, rwso.visibility_rects[index].top); + in_uint16_le(s, rwso.visibility_rects[index].right); + in_uint16_le(s, rwso.visibility_rects[index].bottom); + } + } + + in_uint32_le(s, flags); + mod->server_window_new_update(mod, window_id, &rwso, flags); + rv = 0; + g_free(rwso.title_info); + g_free(rwso.window_rects); + g_free(rwso.visibility_rects); + return rv; } /******************************************************************************/ /* return error */ static int APP_CC -process_server_window_delete(struct mod* mod, struct stream* s) +process_server_window_delete(struct mod *mod, struct stream *s) { - int window_id; - int rv; + int window_id; + int rv; - in_uint32_le(s, window_id); - mod->server_window_delete(mod, window_id); - rv = 0; - return rv; + in_uint32_le(s, window_id); + mod->server_window_delete(mod, window_id); + rv = 0; + return rv; } /******************************************************************************/ /* return error */ static int -lib_mod_process_orders(struct mod* mod, int type, struct stream* s) +lib_mod_process_orders(struct mod *mod, int type, struct stream *s) { - int rv; - int x; - int y; - int cx; - int cy; - int srcx; - int srcy; - int len_bmpdata; - int style; - int x1; - int y1; - int x2; - int y2; - int rdpid; - int hints; - int mask; - int width; - int height; - int fgcolor; - int opcode; - char* bmpdata; - char cur_data[32 * (32 * 3)]; - char cur_mask[32 * (32 / 8)]; + int rv; + int x; + int y; + int cx; + int cy; + int srcx; + int srcy; + int len_bmpdata; + int style; + int x1; + int y1; + int x2; + int y2; + int rdpid; + int hints; + int mask; + int width; + int height; + int fgcolor; + int opcode; + char *bmpdata; + char cur_data[32 * (32 * 3)]; + char cur_mask[32 * (32 / 8)]; - rv = 0; - switch (type) - { - case 1: /* server_begin_update */ - rv = mod->server_begin_update(mod); - break; - case 2: /* server_end_update */ - rv = mod->server_end_update(mod); - break; - case 3: /* server_fill_rect */ - in_sint16_le(s, x); - in_sint16_le(s, y); - in_uint16_le(s, cx); - in_uint16_le(s, cy); - rv = mod->server_fill_rect(mod, x, y, cx, cy); - break; - case 4: /* server_screen_blt */ - in_sint16_le(s, x); - in_sint16_le(s, y); - in_uint16_le(s, cx); - in_uint16_le(s, cy); - in_sint16_le(s, srcx); - in_sint16_le(s, srcy); - rv = mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy); - break; - case 5: /* server_paint_rect */ - in_sint16_le(s, x); - in_sint16_le(s, y); - in_uint16_le(s, cx); - in_uint16_le(s, cy); - in_uint32_le(s, len_bmpdata); - in_uint8p(s, bmpdata, len_bmpdata); - in_uint16_le(s, width); - in_uint16_le(s, height); - in_sint16_le(s, srcx); - in_sint16_le(s, srcy); - rv = mod->server_paint_rect(mod, x, y, cx, cy, - bmpdata, width, height, - srcx, srcy); - break; - case 10: /* server_set_clip */ - in_sint16_le(s, x); - in_sint16_le(s, y); - in_uint16_le(s, cx); - in_uint16_le(s, cy); - rv = mod->server_set_clip(mod, x, y, cx, cy); - break; - case 11: /* server_reset_clip */ - rv = mod->server_reset_clip(mod); - break; - case 12: /* server_set_fgcolor */ - in_uint32_le(s, fgcolor); - rv = mod->server_set_fgcolor(mod, fgcolor); - break; - case 14: - in_uint16_le(s, opcode); - rv = mod->server_set_opcode(mod, opcode); - break; - case 17: - in_uint16_le(s, style); - in_uint16_le(s, width); - rv = mod->server_set_pen(mod, style, width); - break; - case 18: - in_sint16_le(s, x1); - in_sint16_le(s, y1); - in_sint16_le(s, x2); - in_sint16_le(s, y2); - rv = mod->server_draw_line(mod, x1, y1, x2, y2); - break; - case 19: - in_sint16_le(s, x); - in_sint16_le(s, y); - in_uint8a(s, cur_data, 32 * (32 * 3)); - in_uint8a(s, cur_mask, 32 * (32 / 8)); - rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask); - break; - case 20: - in_uint32_le(s, rdpid); - in_uint16_le(s, width); - in_uint16_le(s, height); - rv = mod->server_create_os_surface(mod, rdpid, width, height); - break; - case 21: - in_uint32_le(s, rdpid); - rv = mod->server_switch_os_surface(mod, rdpid); - break; - case 22: - in_uint32_le(s, rdpid); - rv = mod->server_delete_os_surface(mod, rdpid); - break; - case 23: /* server_paint_rect_os */ - in_sint16_le(s, x); - in_sint16_le(s, y); - in_uint16_le(s, cx); - in_uint16_le(s, cy); - in_uint32_le(s, rdpid); - in_sint16_le(s, srcx); - in_sint16_le(s, srcy); - rv = mod->server_paint_rect_os(mod, x, y, cx, cy, - rdpid, srcx, srcy); - break; - case 24: /* server_set_hints */ - in_uint32_le(s, hints); - in_uint32_le(s, mask); - rv = mod->server_set_hints(mod, hints, mask); - break; - case 25: /* server_window_new_update */ - rv = process_server_window_new_update(mod, s); - break; - case 26: /* server_window_delete */ - rv = process_server_window_delete(mod, s); - break; - default: - g_writeln("lib_mod_process_orders: unknown order type %d", type); - rv = 0; - break; - } - return rv; + rv = 0; + + switch (type) + { + case 1: /* server_begin_update */ + rv = mod->server_begin_update(mod); + break; + case 2: /* server_end_update */ + rv = mod->server_end_update(mod); + break; + case 3: /* server_fill_rect */ + in_sint16_le(s, x); + in_sint16_le(s, y); + in_uint16_le(s, cx); + in_uint16_le(s, cy); + rv = mod->server_fill_rect(mod, x, y, cx, cy); + break; + case 4: /* server_screen_blt */ + in_sint16_le(s, x); + in_sint16_le(s, y); + in_uint16_le(s, cx); + in_uint16_le(s, cy); + in_sint16_le(s, srcx); + in_sint16_le(s, srcy); + rv = mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy); + break; + case 5: /* server_paint_rect */ + in_sint16_le(s, x); + in_sint16_le(s, y); + in_uint16_le(s, cx); + in_uint16_le(s, cy); + in_uint32_le(s, len_bmpdata); + in_uint8p(s, bmpdata, len_bmpdata); + in_uint16_le(s, width); + in_uint16_le(s, height); + in_sint16_le(s, srcx); + in_sint16_le(s, srcy); + rv = mod->server_paint_rect(mod, x, y, cx, cy, + bmpdata, width, height, + srcx, srcy); + break; + case 10: /* server_set_clip */ + in_sint16_le(s, x); + in_sint16_le(s, y); + in_uint16_le(s, cx); + in_uint16_le(s, cy); + rv = mod->server_set_clip(mod, x, y, cx, cy); + break; + case 11: /* server_reset_clip */ + rv = mod->server_reset_clip(mod); + break; + case 12: /* server_set_fgcolor */ + in_uint32_le(s, fgcolor); + rv = mod->server_set_fgcolor(mod, fgcolor); + break; + case 14: + in_uint16_le(s, opcode); + rv = mod->server_set_opcode(mod, opcode); + break; + case 17: + in_uint16_le(s, style); + in_uint16_le(s, width); + rv = mod->server_set_pen(mod, style, width); + break; + case 18: + in_sint16_le(s, x1); + in_sint16_le(s, y1); + in_sint16_le(s, x2); + in_sint16_le(s, y2); + rv = mod->server_draw_line(mod, x1, y1, x2, y2); + break; + case 19: + in_sint16_le(s, x); + in_sint16_le(s, y); + in_uint8a(s, cur_data, 32 * (32 * 3)); + in_uint8a(s, cur_mask, 32 * (32 / 8)); + rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask); + break; + case 20: + in_uint32_le(s, rdpid); + in_uint16_le(s, width); + in_uint16_le(s, height); + rv = mod->server_create_os_surface(mod, rdpid, width, height); + break; + case 21: + in_uint32_le(s, rdpid); + rv = mod->server_switch_os_surface(mod, rdpid); + break; + case 22: + in_uint32_le(s, rdpid); + rv = mod->server_delete_os_surface(mod, rdpid); + break; + case 23: /* server_paint_rect_os */ + in_sint16_le(s, x); + in_sint16_le(s, y); + in_uint16_le(s, cx); + in_uint16_le(s, cy); + in_uint32_le(s, rdpid); + in_sint16_le(s, srcx); + in_sint16_le(s, srcy); + rv = mod->server_paint_rect_os(mod, x, y, cx, cy, + rdpid, srcx, srcy); + break; + case 24: /* server_set_hints */ + in_uint32_le(s, hints); + in_uint32_le(s, mask); + rv = mod->server_set_hints(mod, hints, mask); + break; + case 25: /* server_window_new_update */ + rv = process_server_window_new_update(mod, s); + break; + case 26: /* server_window_delete */ + rv = process_server_window_delete(mod, s); + break; + default: + g_writeln("lib_mod_process_orders: unknown order type %d", type); + rv = 0; + break; + } + + return rv; } /******************************************************************************/ /* return error */ static int APP_CC -lib_send_client_info(struct mod* mod) +lib_send_client_info(struct mod *mod) { - struct stream* s; - int len; + struct stream *s; + int len; - make_stream(s); - init_stream(s, 8192); - s_push_layer(s, iso_hdr, 4); - out_uint16_le(s, 104); - g_memcpy(s->p, &(mod->client_info), sizeof(mod->client_info)); - s->p += sizeof(mod->client_info); - s_mark_end(s); - len = (int)(s->end - s->data); - s_pop_layer(s, iso_hdr); - out_uint32_le(s, len); - lib_send(mod, s->data, len); - free_stream(s); - return 0; + make_stream(s); + init_stream(s, 8192); + s_push_layer(s, iso_hdr, 4); + out_uint16_le(s, 104); + g_memcpy(s->p, &(mod->client_info), sizeof(mod->client_info)); + s->p += sizeof(mod->client_info); + s_mark_end(s); + len = (int)(s->end - s->data); + s_pop_layer(s, iso_hdr); + out_uint32_le(s, len); + lib_send(mod, s->data, len); + free_stream(s); + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_signal(struct mod* mod) +lib_mod_signal(struct mod *mod) { - struct stream* s; - int num_orders; - int index; - int rv; - int len; - int type; - char* phold; + struct stream *s; + int num_orders; + int index; + int rv; + int len; + int type; + char *phold; - LIB_DEBUG(mod, "in lib_mod_signal"); - make_stream(s); - init_stream(s, 8192); - rv = lib_recv(mod, s->data, 8); - if (rv == 0) - { - in_uint16_le(s, type); - in_uint16_le(s, num_orders); - in_uint32_le(s, len); - if (type == 1) /* original order list */ + LIB_DEBUG(mod, "in lib_mod_signal"); + make_stream(s); + init_stream(s, 8192); + rv = lib_recv(mod, s->data, 8); + + if (rv == 0) { - init_stream(s, len); - rv = lib_recv(mod, s->data, len); - if (rv == 0) - { - for (index = 0; index < num_orders; index++) + in_uint16_le(s, type); + in_uint16_le(s, num_orders); + in_uint32_le(s, len); + + if (type == 1) /* original order list */ { - in_uint16_le(s, type); - rv = lib_mod_process_orders(mod, type, s); - if (rv != 0) - { - break; - } + init_stream(s, len); + rv = lib_recv(mod, s->data, len); + + if (rv == 0) + { + for (index = 0; index < num_orders; index++) + { + in_uint16_le(s, type); + rv = lib_mod_process_orders(mod, type, s); + + if (rv != 0) + { + break; + } + } + } } - } - } - else if (type == 2) /* caps */ - { - g_writeln("lib_mod_signal: type 2 len %d", len); - init_stream(s, len); - rv = lib_recv(mod, s->data, len); - if (rv == 0) - { - for (index = 0; index < num_orders; index++) + else if (type == 2) /* caps */ { - phold = s->p; - in_uint16_le(s, type); - in_uint16_le(s, len); - switch (type) - { - default: - g_writeln("lib_mod_signal: unknown cap type %d len %d", - type, len); - break; - } - s->p = phold + len; + g_writeln("lib_mod_signal: type 2 len %d", len); + init_stream(s, len); + rv = lib_recv(mod, s->data, len); + + if (rv == 0) + { + for (index = 0; index < num_orders; index++) + { + phold = s->p; + in_uint16_le(s, type); + in_uint16_le(s, len); + + switch (type) + { + default: + g_writeln("lib_mod_signal: unknown cap type %d len %d", + type, len); + break; + } + + s->p = phold + len; + } + + lib_send_client_info(mod); + } } - lib_send_client_info(mod); - } - } - else if (type == 3) /* order list with len after type */ - { - init_stream(s, len); - rv = lib_recv(mod, s->data, len); - if (rv == 0) - { - for (index = 0; index < num_orders; index++) + else if (type == 3) /* order list with len after type */ { - phold = s->p; - in_uint16_le(s, type); - in_uint16_le(s, len); - rv = lib_mod_process_orders(mod, type, s); - if (rv != 0) - { - break; - } - s->p = phold + len; + init_stream(s, len); + rv = lib_recv(mod, s->data, len); + + if (rv == 0) + { + for (index = 0; index < num_orders; index++) + { + phold = s->p; + in_uint16_le(s, type); + in_uint16_le(s, len); + rv = lib_mod_process_orders(mod, type, s); + + if (rv != 0) + { + break; + } + + s->p = phold + len; + } + } + } + else + { + g_writeln("unknown type %d", type); } - } } - else + + free_stream(s); + LIB_DEBUG(mod, "out lib_mod_signal"); + return rv; +} + +/******************************************************************************/ +/* return error */ +int DEFAULT_CC +lib_mod_end(struct mod *mod) +{ + return 0; +} + +/******************************************************************************/ +/* return error */ +int DEFAULT_CC +lib_mod_set_param(struct mod *mod, char *name, char *value) +{ + if (g_strcasecmp(name, "username") == 0) { - g_writeln("unknown type %d", type); + g_strncpy(mod->username, value, 255); } - } - free_stream(s); - LIB_DEBUG(mod, "out lib_mod_signal"); - return rv; -} - -/******************************************************************************/ -/* return error */ -int DEFAULT_CC -lib_mod_end(struct mod* mod) -{ - return 0; -} - -/******************************************************************************/ -/* return error */ -int DEFAULT_CC -lib_mod_set_param(struct mod* mod, char* name, char* value) -{ - if (g_strcasecmp(name, "username") == 0) - { - g_strncpy(mod->username, value, 255); - } - else if (g_strcasecmp(name, "password") == 0) - { - g_strncpy(mod->password, value, 255); - } - else if (g_strcasecmp(name, "ip") == 0) - { - g_strncpy(mod->ip, value, 255); - } - else if (g_strcasecmp(name, "port") == 0) - { - g_strncpy(mod->port, value, 255); - } - else if (g_strcasecmp(name, "client_info") == 0) - { - g_memcpy(&(mod->client_info), value, sizeof(mod->client_info)); - } - return 0; -} - -/******************************************************************************/ -/* return error */ -int DEFAULT_CC -lib_mod_get_wait_objs(struct mod* mod, tbus* read_objs, int* rcount, - tbus* write_objs, int* wcount, int* timeout) -{ - int i; - - i = *rcount; - if (mod != 0) - { - if (mod->sck_obj != 0) + else if (g_strcasecmp(name, "password") == 0) { - read_objs[i++] = mod->sck_obj; + g_strncpy(mod->password, value, 255); } - } - *rcount = i; - return 0; + else if (g_strcasecmp(name, "ip") == 0) + { + g_strncpy(mod->ip, value, 255); + } + else if (g_strcasecmp(name, "port") == 0) + { + g_strncpy(mod->port, value, 255); + } + else if (g_strcasecmp(name, "client_info") == 0) + { + g_memcpy(&(mod->client_info), value, sizeof(mod->client_info)); + } + + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_check_wait_objs(struct mod* mod) +lib_mod_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount, + tbus *write_objs, int *wcount, int *timeout) { - int rv; + int i; - rv = 0; - if (mod != 0) - { - if (mod->sck_obj != 0) + i = *rcount; + + if (mod != 0) { - if (g_is_wait_obj_set(mod->sck_obj)) - { - rv = lib_mod_signal(mod); - } + if (mod->sck_obj != 0) + { + read_objs[i++] = mod->sck_obj; + } } - } - return rv; + + *rcount = i; + return 0; } /******************************************************************************/ -struct mod* EXPORT_CC +/* return error */ +int DEFAULT_CC +lib_mod_check_wait_objs(struct mod *mod) +{ + int rv; + + rv = 0; + + if (mod != 0) + { + if (mod->sck_obj != 0) + { + if (g_is_wait_obj_set(mod->sck_obj)) + { + rv = lib_mod_signal(mod); + } + } + } + + return rv; +} + +/******************************************************************************/ +struct mod *EXPORT_CC mod_init(void) { - struct mod* mod; + struct mod *mod; - mod = (struct mod*)g_malloc(sizeof(struct mod), 1); - mod->size = sizeof(struct mod); - mod->version = CURRENT_MOD_VER; - mod->handle = (tbus)mod; - mod->mod_connect = lib_mod_connect; - mod->mod_start = lib_mod_start; - mod->mod_event = lib_mod_event; - mod->mod_signal = lib_mod_signal; - mod->mod_end = lib_mod_end; - mod->mod_set_param = lib_mod_set_param; - mod->mod_get_wait_objs = lib_mod_get_wait_objs; - mod->mod_check_wait_objs = lib_mod_check_wait_objs; - return mod; + mod = (struct mod *)g_malloc(sizeof(struct mod), 1); + mod->size = sizeof(struct mod); + mod->version = CURRENT_MOD_VER; + mod->handle = (tbus)mod; + mod->mod_connect = lib_mod_connect; + mod->mod_start = lib_mod_start; + mod->mod_event = lib_mod_event; + mod->mod_signal = lib_mod_signal; + mod->mod_end = lib_mod_end; + mod->mod_set_param = lib_mod_set_param; + mod->mod_get_wait_objs = lib_mod_get_wait_objs; + mod->mod_check_wait_objs = lib_mod_check_wait_objs; + return mod; } /******************************************************************************/ int EXPORT_CC -mod_exit(struct mod* mod) +mod_exit(struct mod *mod) { - if (mod == 0) - { + if (mod == 0) + { + return 0; + } + + g_delete_wait_obj_from_socket(mod->sck_obj); + g_tcp_close(mod->sck); + g_free(mod); return 0; - } - g_delete_wait_obj_from_socket(mod->sck_obj); - g_tcp_close(mod->sck); - g_free(mod); - return 0; } diff --git a/xup/xup.h b/xup/xup.h index 110d3af4..ae98c5ff 100644 --- a/xup/xup.h +++ b/xup/xup.h @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2012 - - libxup main header file - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * libxup main header file + */ /* include other h files */ #include "arch.h"