Compare commits

..

No commits in common. "master" and "v1.4" have entirely different histories.
master ... v1.4

67 changed files with 4673 additions and 16734 deletions

6
.gitattributes vendored
View File

@ -1,6 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Plain text (Windows)
*.txt diff=astextplain eol=crlf
*.ini diff=astextplain eol=crlf

17
.gitignore vendored
View File

@ -1,17 +0,0 @@
# Delphi local files (user-specific info)
*.local
*.identcache
# Delphi history and backups
__history/
*.~*
# Compiled binaries
*.dcu
*.exe
*.dll
*.msi
# MSI local stuff
*.wixobj
*.wixpdb

217
LICENSE
View File

@ -1,202 +1,25 @@
Apache License This is free and unencumbered software released into the public domain.
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
1. Definitions. In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
"License" shall mean the terms and conditions for use, reproduction, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
and distribution as defined by Sections 1 through 9 of this document. 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 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.
"Licensor" shall mean the copyright owner or entity authorized by For more information, please refer to <http://unlicense.org>
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.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"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.
"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).
"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.
"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."
"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.
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.
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.
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:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) 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
(d) 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.
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.
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.
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.
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.
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.
END OF TERMS AND CONDITIONS
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.
Copyright [yyyy] [name of copyright owner]
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.

651
README.md
View File

@ -1,463 +1,188 @@
# RDP Wrapper Library by Stas'M <b>RDP Wrapper Library by Stas'M</b><br>
<br>
[![Telegram](https://img.shields.io/badge/chat-Telegram-blue.svg)](https://t.me/rdpwrap) The goal of this project is to enable Remote Desktop Host support and concurrent RDP sessions on reduced functionality systems for home usage.<br>
![Environment](https://img.shields.io/badge/Windows-Vista,%207,%208,%2010-brightgreen.svg) <br>
[![Release](https://img.shields.io/github/release/stascorp/rdpwrap.svg)](https://github.com/stascorp/rdpwrap/releases) RDP Wrapper works as a layer between Service Control Manager and Terminal Services, so the original termsrv.dll file remains untouched. Also this method is very strong against Windows Update.<br>
![License](https://img.shields.io/github/license/stascorp/rdpwrap.svg) <br>
![Downloads](https://img.shields.io/github/downloads/stascorp/rdpwrap/latest/total.svg) Screenshots:<br>
![TotalDownloads](https://img.shields.io/github/downloads/stascorp/rdpwrap/total.svg) <div style="padding-top: 4px; width: 534px; white-space: nowrap; overflow: auto; overflow-y: hidden">
<a href="http://stascorp.com/images/rdpwrap/VistaST.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pVistaST.jpg"></a>&nbsp;
The goal of this project is to enable Remote Desktop Host support and concurrent RDP sessions on reduced functionality systems for home usage. <a href="http://stascorp.com/images/rdpwrap/VistaHB.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pVistaHB.jpg"></a>&nbsp;
<a href="http://stascorp.com/images/rdpwrap/Win7ST.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin7ST.jpg"></a>&nbsp;
RDP Wrapper works as a layer between Service Control Manager and Terminal Services, so the original termsrv.dll file remains untouched. Also this method is very strong against Windows Update. <a href="http://stascorp.com/images/rdpwrap/Win7HB.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin7HB.jpg"></a>&nbsp;
<a href="http://stascorp.com/images/rdpwrap/Win8DP.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin8DP.jpg"></a>&nbsp;
[pVistaST]: http://stascorp.com/images/rdpwrap/pVistaST.jpg <a href="http://stascorp.com/images/rdpwrap/Win8CP.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin8CP.jpg"></a>&nbsp;
[pVistaHB]: http://stascorp.com/images/rdpwrap/pVistaHB.jpg <a href="http://stascorp.com/images/rdpwrap/Win8RP.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin8RP.jpg"></a>&nbsp;
[pWin7ST]: http://stascorp.com/images/rdpwrap/pWin7ST.jpg <a href="http://stascorp.com/images/rdpwrap/Win8.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin8.jpg"></a>&nbsp;
[pWin7HB]: http://stascorp.com/images/rdpwrap/pWin7HB.jpg <a href="http://stascorp.com/images/rdpwrap/Win81P.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin81P.jpg"></a>&nbsp;
[pWin8DP]: http://stascorp.com/images/rdpwrap/pWin8DP.jpg <a href="http://stascorp.com/images/rdpwrap/Win81.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin81.jpg"></a>&nbsp;
[pWin8CP]: http://stascorp.com/images/rdpwrap/pWin8CP.jpg <a href="http://stascorp.com/images/rdpwrap/Win10TP.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin10TP.jpg"></a>&nbsp;
[pWin8RP]: http://stascorp.com/images/rdpwrap/pWin8RP.jpg </div><br>
[pWin8]: http://stascorp.com/images/rdpwrap/pWin8.jpg This solution was inspired by <a href="http://forums.mydigitallife.info/threads/39411-Windows-Product-Policy-Editor" target="_blank">Windows Product Policy Editor</a>, big thanks to <b>kost</b> :)<br>
[pWin81P]: http://stascorp.com/images/rdpwrap/pWin81P.jpg - binarymaster<br>
[pWin81]: http://stascorp.com/images/rdpwrap/pWin81.jpg <br>
[pWin10TP]: http://stascorp.com/images/rdpwrap/pWin10TP.jpg Attention:<br>
[pWin10PTP]: http://stascorp.com/images/rdpwrap/pWin10PTP.jpg It's recommended to have original termsrv.dll file with the RDP Wrapper installation. If you have modified it before with other patchers, it may become unstable and crash in any moment.<br>
[pWin10]: http://stascorp.com/images/rdpwrap/pWin10.jpg <br>
Information:<br>
[fVistaST]: http://stascorp.com/images/rdpwrap/VistaST.png • Source code is available, so you can build it on your own<br>
[fVistaHB]: http://stascorp.com/images/rdpwrap/VistaHB.png • RDP Wrapper does not patch termsrv.dll, it loads termsrv with different parameters<br>
[fWin7ST]: http://stascorp.com/images/rdpwrap/Win7ST.png • RDPWInst and RDPChecker can be redistributed without development folder and batch files<br>
[fWin7HB]: http://stascorp.com/images/rdpwrap/Win7HB.png • RDPWInst can be used for unattended installation / deployment<br>
[fWin8DP]: http://stascorp.com/images/rdpwrap/Win8DP.png • Windows 2000, XP and Server 2003 will not be supported<br>
[fWin8CP]: http://stascorp.com/images/rdpwrap/Win8CP.png <br>
[fWin8RP]: http://stascorp.com/images/rdpwrap/Win8RP.png Porting to other platforms:<br>
[fWin8]: http://stascorp.com/images/rdpwrap/Win8.png <b>ARM</b> for Windows RT (see links below)<br>
[fWin81P]: http://stascorp.com/images/rdpwrap/Win81P.png <b>IA-64</b> for Itanium-based Windows Server? <i>Well, I have no idea</i> :)<br>
[fWin81]: http://stascorp.com/images/rdpwrap/Win81.png <br>
[fWin10TP]: http://stascorp.com/images/rdpwrap/Win10TP.png <b>Links:</b><br>
[fWin10PTP]: http://stascorp.com/images/rdpwrap/Win10PTP.png • Official GitHub repository:<br>
[fWin10]: http://stascorp.com/images/rdpwrap/Win10.png <a href="https://github.com/binarymaster/rdpwrap/" target="_blank">https://github.com/binarymaster/rdpwrap/</a><br>
• Active discussion in the comments here:<br>
| NT Version | Screenshots | <a href="http://andrewblock.net/2013/07/19/enable-remote-desktop-on-windows-8-core/" target="_blank" title="Enable remote desktop on Windows 8 core / basic">Enable remote desktop on Windows 8 core / basic - Andrew Block .net</a><br>
| ------------- | ----------- | • MDL Projects and Applications thread here:<br>
| Windows Vista | [![Windows Vista Starter][pVistaST]][fVistaST] [![Windows Vista Home Basic][pVistaHB]][fVistaHB] | <a href="http://forums.mydigitallife.info/threads/55935-RDP-Wrapper-Library-(works-with-Windows-8-1-Basic)" target="_blank" title="Enable remote desktop on Windows 8 core / basic">RDP Wrapper Library (works with Windows 8.1 Basic)</a><br>
| Windows 7 | [![Windows 7 Starter][pWin7ST]][fWin7ST] [![Windows 7 Home Basic][pWin7HB]][fWin7HB] | • Some ideas about porting to ARM for Windows RT (post #23):<br>
| Windows 8 | [![Windows 8 Developer Preview][pWin8DP]][fWin8DP] [![Windows 8 Consumer Preview][pWin8CP]][fWin8CP] [![Windows 8 Release Preview][pWin8RP]][fWin8RP] [![Windows 8][pWin8]][fWin8] | <a href="http://forum.xda-developers.com/showthread.php?t=2093525&page=3" target="_blank" title="Enable remote desktop on Windows 8 core / basic">[Q] Mod Windows RT to enable Remote Desktop</a><br>
| Windows 8.1 | [![Windows 8.1 Preview][pWin81P]][fWin81P] [![Windows 8.1][pWin81]][fWin81] | • Adding «Remote Desktop Users» group:<br>
| Windows 10 | [![Windows 10 Technical Preview][pWin10TP]][fWin10TP] [![Windows 10 Pro Technical Preview][pWin10PTP]][fWin10PTP] [![Windows 10][pWin10]][fWin10] | <a href="http://superuser.com/questions/680572/" target="_blank">http://superuser.com/questions/680572/</a><br>
--- <br>
[WinPPE]: http://forums.mydigitallife.info/threads/39411-Windows-Product-Policy-Editor Files description:<br>
<br>
This solution was inspired by [Windows Product Policy Editor][WinPPE], big thanks to **kost** :) <table style="border-collapse: collapse; width: 100%; border: 1px solid black;" width="" align="">
<tbody>
— binarymaster <tr><td style="border: 1px solid black;"><b>RDPWInst.exe</b></td><td style="border: 1px solid black;">RDP Wrapper Library installer/uninstaller</td></tr>
<tr><td style="border: 1px solid black;"><b>RDPCheck.exe</b></td><td style="border: 1px solid black;">Local RDP Checker (you can check the RDP is working)</td></tr>
### Attention: <tr><td style="border: 1px solid black;"><b>install.bat</b></td><td style="border: 1px solid black;">Quick install batch file</td></tr>
It's recommended to have original termsrv.dll file with the RDP Wrapper installation. If you have modified it before with other patchers, it may become unstable and crash in any moment. <tr><td style="border: 1px solid black;"><b>uninstall.bat</b></td><td style="border: 1px solid black;">Quick uninstall batch file</td></tr>
</tbody>
### Information: </table><br>
- Source code is available, so you can build it on your own Change log:<br>
- RDP Wrapper does not patch termsrv.dll, it loads termsrv with different parameters <br>
- RDPWInst and RDPChecker can be redistributed without development folder and batch files <b><u>2014.11.14</u></b><br>
- RDPWInst can be used for unattended installation / deployment • Version 1.4<br>
- Windows 2000, XP and Server 2003 will not be supported • Added support for Windows 10 Technical Preview Update 1<br>
• Added support for Windows Vista SP2 with KB3003743<br>
### Key features: • Added support for Windows 7 SP1 with KB3003743<br>
- RDP host server on any Windows edition beginning from Vista • Added new RDP Configuration Program<br>
- Console and remote sessions at the same time <br>
- Using the same user simultaneously for local and remote logon (see configuration app) <b><u>2014.10.21</u></b><br>
- Up to [15 concurrent sessions](https://github.com/stascorp/rdpwrap/issues/192) (the actual limitation depends on your hardware and OS version) • Installer updated<br>
- Console and RDP session shadowing (using [Task Manager in Windows 7](http://cdn.freshdesk.com/data/helpdesk/attachments/production/1009641577/original/remote_control.png?1413476051) and lower, and [Remote Desktop Connection in Windows 8](http://woshub.com/rds-shadow-how-to-connect-to-a-user-session-in-windows-server-2012-r2/) and higher) • Added feature to install RDP Wrapper to System32 directory<br>
- Full [multi-monitor support](https://github.com/stascorp/rdpwrap/issues/163) for RDP host • Fixed issue in the installer - NLA setting now remains unchanged<br>
- ...and if you find a new feature not listed here, [tell us](https://github.com/stascorp/rdpwrap/issues/new) ;) • Local RDP Checker updated<br>
• SecurityLayer and UserAuthentification values changed on check start<br>
### Porting to other platforms: • RDP Checker restores values on exit<br>
- **ARM** for Windows RT (see links below) <br>
- **IA-64** for Itanium-based Windows Server? *Well, I have no idea* :) <b><u>2014.10.20</u></b><br>
• Version 1.3<br>
### Building the binaries: • Added support for Windows 10 Technical Preview<br>
- **x86 Delphi version** can be built with *Embarcadero RAD Studio 2010* • Added support for Windows 7 with KB2984972<br>
- **x86/x64 C++ version** can be built with *Microsoft Visual Studio 2013* • Added support for Windows 8 with KB2973501<br>
• Added extended support for Windows Vista (SP0, SP1 and SP2)<br>
[andrewblock]: http://web.archive.org/web/20150810054558/http://andrewblock.net/enable-remote-desktop-on-windows-8-core/ • Added extended support for Windows 7 (SP0 and SP1)<br>
[mydigitallife]: http://forums.mydigitallife.info/threads/55935-RDP-Wrapper-Library-(works-with-Windows-8-1-Basic) • Some improvements in the source code<br>
[xda-dev]: http://forum.xda-developers.com/showthread.php?t=2093525&page=3 • Installer updated to v2.2<br>
[yt-updating]: http://www.youtube.com/watch?v=W9BpbEt1yJw • Fixed installation bug in Vista x64 (wrong expand path)<br>
[yt-offsets]: http://www.youtube.com/watch?v=FiD86tmRBtk • Local RDP Checker updated<br>
• Added description to error 0x708<br>
### Links: <br>
- Official GitHub repository: <b><u>2014.07.26</u></b><br>
<br>https://github.com/stascorp/rdpwrap/ • Version 1.2<br>
- Official Telegram chat: • Added support for Windows 8 Developer Preview<br>
<br>https://t.me/rdpwrap • Added support for Windows 8 Consumer Preview<br>
- Active discussion in the comments here: • Added support for Windows 8 Release Preview<br>
<br>[Enable remote desktop on Windows 8 core / basic - Andrew Block .net][andrewblock] • Added support for Windows 8.1 Preview<br>
- MDL Projects and Applications thread here: • Added support for Windows 8.1<br>
<br>[RDP Wrapper Library (works with Windows 8.1 Basic)][mydigitallife] • More details you will see in the source code<br>
- Some ideas about porting to ARM for Windows RT (post #23): • Installer updated to v2.1<br>
<br>[\[Q\] Mod Windows RT to enable Remote Desktop][xda-dev] <br>
- Adding «Remote Desktop Users» group: <b><u>2013.12.09</u></b><br>
<br>http://superuser.com/questions/680572/ • C++ port of RDP Wrapper was made by <b>Fusix</b><br>
• x64 architecture is supported now<br>
#### Tutorial videos: • Added new command line installer v2.0<br>
- [~~Updating RDP Wrapper INI file manually~~][yt-updating] (now use installer to update INI file) • Added local RDP checker<br>
- [How to find offsets for new termsrv.dll versions][yt-offsets] • Source code (C++ port, installer 2.0, local RDP checker) is also included<br>
<br>
### Files in release package: <b><u>2013.10.25</u></b><br>
• Version 1.1 source code is available<br>
| File name | Description | <br>
| --------- | ----------- | <b><u>2013.10.22</u></b><br>
| `RDPWInst.exe` | RDP Wrapper Library installer/uninstaller | • Version 1.1<br>
| `RDPCheck.exe` | Local RDP Checker (you can check the RDP is working) | • Stable release<br>
| `RDPConf.exe` | RDP Wrapper Configuration | • Improved wrapper (now it can wrap internal unexported termsrv.dll SL Policy function)<br>
| `install.bat` | Quick install batch file | • Added support for Windows 8 Single Language (tested on Acer Tablet PC with Intel Atom Z2760)<br>
| `uninstall.bat` | Quick uninstall batch file | <br>
| `update.bat` | Quick update batch file | <b><u>2013.10.19</u></b><br>
• Version 1.0<br>
### Frequently Asked Questions • First [beta] version<br>
• Basic SL Policy wrapper<br>
> Where can I download the installer or binaries? <br>
<b>Supported Terminal Services versions:</b><br>
In the [GitHub Releases](https://github.com/stascorp/rdpwrap/releases) section. <u>6.0.X.X</u> (Windows Vista / Server 2008)<br>
<u>6.0.6000.16386</u> (Windows Vista)<br>
> Is it legal to use this application? <u>6.0.6001.18000</u> (Windows Vista SP1)<br>
<u>6.0.6002.18005</u> (Windows Vista SP2)<br>
There is no definitive answer, see [this discussion](https://github.com/stascorp/rdpwrap/issues/26). <u>6.0.6002.19214</u> (Windows Vista SP2 with KB3003743 GDR)<br>
<u>6.0.6002.23521</u> (Windows Vista SP2 with KB3003743 LDR)<br>
> The installer tries to access the Internet, is it normal behaviour? <u>6.1.X.X</u> (Windows 7 / Server 2008 R2)<br>
<u>6.1.7600.16385</u> (Windows 7)<br>
Yes, it works in online mode by default. You may disable it by removing `-o` flag in the `install.bat` file. <u>6.1.7601.17514</u> (Windows 7 SP1)<br>
<u>6.1.7601.18540</u> (Windows 7 SP1 with KB2984972 GDR)<br>
> What is online install mode? <u>6.1.7601.22750</u> (Windows 7 SP1 with KB2984972 LDR)<br>
<u>6.1.7601.18637</u> (Windows 7 SP1 with KB3003743 GDR)<br>
Online install mode introduced in version 1.6.1. When you installing RDP Wrapper first time using this mode, it will download [latest INI file](https://github.com/stascorp/rdpwrap/blob/master/res/rdpwrap.ini) from GitHub. See [this discussion](https://github.com/stascorp/rdpwrap/issues/132). <u>6.1.7601.22843</u> (Windows 7 SP1 with KB3003743 LDR)<br>
<u>6.2.8102.0</u> (Windows 8 Developer Preview)<br>
> What is INI file and why we need it? <u>6.2.8250.0</u> (Windows 8 Consumer Preview)<br>
<u>6.2.8400.0</u> (Windows 8 Release Preview)<br>
INI file was introduced in version 1.5. It stores system configuration for RDP Wrapper — general wrapping settings, binary patch codes, and per build specific data. When new `termsrv.dll` build comes out, developer adds support for it by updating INI file in repository. <u>6.2.9200.16384</u> (Windows 8 / Server 2012)<br>
<u>6.2.9200.17048</u> (Windows 8 with KB2973501 GDR)<br>
> Config Tool reports version 1.5, but I installed higher version. What's the matter? <u>6.2.9200.21166</u> (Windows 8 with KB2973501 LDR)<br>
<u>6.3.9431.0</u> (Windows 8.1 Preview)<br>
Beginning with version 1.5 the `rdpwrap.dll` is not updated anymore, since all settings are stored in INI file. Deal with it. <u>6.3.9600.16384</u> (Windows 8.1 / Server 2012 R2)<br>
<u>6.3.9600.17095</u> (Windows 8.1 with KB2959626)<br>
> Config Tool shows `[not supported]` and RDP doesn't work. What can I do? <u>6.4.9841.0</u> (Windows 10 Technical Preview)<br>
<u>6.4.9860.0</u> (Windows 10 Technical Preview Update 1)<br>
Make sure you're connected to the Internet and run `update.bat`. <br>
<b>Confirmed working on:</b><br>
> Update doesn't help, it still shows `[not supported]`. • Windows Vista Starter (x86 - Service Pack 1 and higher)<br>
• Windows Vista Home Basic (x86 - Service Pack 1 and higher)<br>
Visit [issues](https://github.com/stascorp/rdpwrap/issues) section, and check whether your `termsrv.dll` build is listed here. If you can't find such issue, create a new — specify your build version for adding to support. • Windows Vista Home Premium (x86 - Service Pack 1 and higher)<br>
• Windows Vista Business (x86 - Service Pack 1 and higher)<br>
> Why `RDPCheck` doesn't allow to change resolution and other settings? • Windows Vista Enterprise (x86 - Service Pack 1 and higher)<br>
• Windows Vista Ultimate (x86 - Service Pack 1 and higher)<br>
`RDPCheck` is a very simple application and only for testing purposes. You need to use Microsoft Remote Desktop Client (`mstsc.exe`) if you want to customize the settings. You can use `127.0.0.1` or `127.0.0.2` address for loopback connection. • Windows 7 Starter<br>
• Windows 7 Home Basic<br>
### Known issues: • Windows 7 Home Premium<br>
- Beginning with Windows 8 **on tablet PCs** inactive sessions will be logged out by system - [more info](https://github.com/stascorp/rdpwrap/issues/37) • Windows 7 Professional<br>
- Beginning with Windows 10 you can accidentally lock yourself from PC - [more info](https://github.com/stascorp/rdpwrap/issues/50) • Windows 7 Enterprise<br>
- Beginning with the Creators Update for Windows 10 Home, RDP Wrapper will no longer work, claiming that the listener is `[not listening]` because of `rfxvmt.dll` is missing - [more info](https://github.com/stascorp/rdpwrap/issues/194#issuecomment-323564111), [download links](https://github.com/stascorp/rdpwrap/issues/194#issuecomment-325627235) • Windows 7 Ultimate<br>
- Terminal Service does not start after installing some updates or "Access Denied" issue - [#215](https://github.com/stascorp/rdpwrap/issues/215), [#101](https://github.com/stascorp/rdpwrap/issues/101) • Windows 8 Developer Preview<br>
- RDP Wrapper does not work with RemoteFX enabled hosts - [#127](https://github.com/stascorp/rdpwrap/issues/127), [#208](https://github.com/stascorp/rdpwrap/issues/208), [#216](https://github.com/stascorp/rdpwrap/issues/216) • Windows 8 Consumer Preview<br>
- RDP works, but termsrv.dll crashes on logon attempt - Windows Vista Starter RTM x86 (termsrv.dll `6.0.6000.16386`) • Windows 8 Release Preview<br>
- If Terminal Services hangs at startup, try to add **`rdpwrap.dll`** to antivirus exclusions. Also try to isolate RDP Wrapper from other shared services by the command: • Windows 8<br>
<br>`sc config TermService type= own` • Windows 8 Single Language<br>
- RDP Wrapper can be removed by AVG Free Antivirus and [Norton Antivirus](https://github.com/stascorp/rdpwrap/issues/191) - first make sure you downloaded [official release](https://github.com/stascorp/rdpwrap/releases) from GitHub, then add it to exclusions. • Windows 8 Pro<br>
• Windows 8 Enterprise<br>
--- • Windows 8.1 Preview<br>
• Windows 8.1<br>
### Change log: • Windows 8.1 Single Language<br>
• Windows 8.1 Pro<br>
#### 2017.12.27 • Windows 8.1 Enterprise<br>
- Version 1.6.2 • Windows 10 Technical Preview<br>
- Installer updated <br>
- Include updated INI file for latest Windows builds <b>Working partially:</b><br>
- Added check for supported Windows versions ([#155](https://github.com/stascorp/rdpwrap/issues/155)) • Windows Vista Starter RTM x86 (termsrv.dll 6.0.6000.16386 : RDP works, but termsrv.dll crashes on logon attempt)<br>
- Added feature to take INI file from current directory ([#300](https://github.com/stascorp/rdpwrap/issues/300)) <br>
- Added feature to restore rfxvmt.dll (missing in Windows 10 Home [#194](https://github.com/stascorp/rdpwrap/issues/194)) <u>Installation instructions:</u><br>
- RDP Config updated 1. Download and unpack files<br>
- Added feature to allow custom start programs ([#13 (comment)](https://github.com/stascorp/rdpwrap/issues/13#issuecomment-77651843)) 2. Run <b>Command Prompt (cmd)</b> as administrator<br>
- MSI installation package added ([#14](https://github.com/stascorp/rdpwrap/issues/14)) 3. Change directory to <b>/bin</b> (where binaries and batch files are placed)<br>
4. Type <b>install.bat</b> and press Enter<br>
#### 2016.08.01 5. See command output for details<br>
- Version 1.6.1 <br>
- Include updated INI file for latest Windows builds <u>To uninstall:</u><br>
- Installer updated 1. Run <b>Command Prompt</b> as administrator<br>
- Added online install mode 2. Change directory to <b>/bin</b><br>
- Added feature to keep settings on uninstall 3. Type <b>uninstall.bat</b> and press Enter<br>
- RDP Config updated 4. See command output for details<br>
- Fixed update firewall rule on RDP port change
- Added feature to hide users on logon
#### 2015.08.12
- Version 1.6
- Added support for Windows 10
- INI file has smaller size now - all comments are moved to KB file
- Installer updated
- Added workaround for 1056 error (although it isn't an error)
- Added update support to installer
- Newest RDPClip versions are included with installer
- RDP Checker updated
- Changed connect IP to 127.0.0.2
- Updated some text messages
- RDP Config updated
- Added all possible shadowing modes
- Also it will write settings to the group policy
#### 2014.12.11
- Version 1.5
- Added INI config support
- Configuration is stored in INI file now
- We can extend version support without building new binaries
- Added support for Windows 8.1 with KB3000850
- Added support for Windows 10 Technical Preview Update 2
- Installer updated
- RDP Config updated
- Diagnostics feature added to RDP Config
#### 2014.11.14
- Version 1.4
- Added support for Windows 10 Technical Preview Update 1
- Added support for Windows Vista SP2 with KB3003743
- Added support for Windows 7 SP1 with KB3003743
- Added new RDP Configuration Program
#### 2014.10.21
- Installer updated
- Added feature to install RDP Wrapper to System32 directory
- Fixed issue in the installer - NLA setting now remains unchanged
- Local RDP Checker updated
- SecurityLayer and UserAuthentification values changed on check start
- RDP Checker restores values on exit
#### 2014.10.20
- Version 1.3
- Added support for Windows 10 Technical Preview
- Added support for Windows 7 with KB2984972
- Added support for Windows 8 with KB2973501
- Added extended support for Windows Vista (SP0, SP1 and SP2)
- Added extended support for Windows 7 (SP0 and SP1)
- Some improvements in the source code
- Installer updated to v2.2
- Fixed installation bug in Vista x64 (wrong expand path)
- Local RDP Checker updated
- Added description to error 0x708
#### 2014.07.26
- Version 1.2
- Added support for Windows 8 Developer Preview
- Added support for Windows 8 Consumer Preview
- Added support for Windows 8 Release Preview
- Added support for Windows 8.1 Preview
- Added support for Windows 8.1
- More details you will see in the source code
- Installer updated to v2.1
#### 2013.12.09
- C++ port of RDP Wrapper was made by Fusix
- x64 architecture is supported now
- Added new command line installer v2.0
- Added local RDP checker
- Source code (C++ port, installer 2.0, local RDP checker) is also included
#### 2013.10.25
- Version 1.1 source code is available
#### 2013.10.22
- Version 1.1
- Stable release
- Improved wrapper (now it can wrap internal unexported termsrv.dll SL Policy function)
- Added support for Windows 8 Single Language (tested on Acer Tablet PC with Intel Atom Z2760)
#### 2013.10.19
- Version 1.0
- First [beta] version
- Basic SL Policy wrapper
---
#### Supported Terminal Services versions:
- 6.0.X.X (Windows Vista / Server 2008)
- 6.0.6000.16386 (Windows Vista)
- 6.0.6001.18000 (Windows Vista SP1)
- 6.0.6002.18005 (Windows Vista SP2)
- 6.0.6002.19214 (Windows Vista SP2 with KB3003743 GDR)
- 6.0.6002.23521 (Windows Vista SP2 with KB3003743 LDR)
- 6.1.X.X (Windows 7 / Server 2008 R2)
- 6.1.7600.16385 (Windows 7)
- 6.1.7600.20890 (Windows 7 with KB2479710)
- 6.1.7600.21316 (Windows 7 with KB2750090)
- 6.1.7601.17514 (Windows 7 SP1)
- 6.1.7601.21650 (Windows 7 SP1 with KB2479710)
- 6.1.7601.21866 (Windows 7 SP1 with KB2647409)
- 6.1.7601.22104 (Windows 7 SP1 with KB2750090)
- 6.1.7601.18540 (Windows 7 SP1 with KB2984972 GDR)
- 6.1.7601.22750 (Windows 7 SP1 with KB2984972 LDR)
- 6.1.7601.18637 (Windows 7 SP1 with KB3003743 GDR)
- 6.1.7601.22843 (Windows 7 SP1 with KB3003743 LDR)
- 6.1.7601.23403 (Windows 7 SP1 with KB3125574)
- 6.1.7601.24234 (Windows 7 SP1 with KB4462923)
- 6.2.8102.0 (Windows 8 Developer Preview)
- 6.2.8250.0 (Windows 8 Consumer Preview)
- 6.2.8400.0 (Windows 8 Release Preview)
- 6.2.9200.16384 (Windows 8 / Server 2012)
- 6.2.9200.17048 (Windows 8 with KB2973501 GDR)
- 6.2.9200.21166 (Windows 8 with KB2973501 LDR)
- 6.3.9431.0 (Windows 8.1 Preview)
- 6.3.9600.16384 (Windows 8.1 / Server 2012 R2)
- 6.3.9600.17095 (Windows 8.1 with KB2959626)
- 6.3.9600.17415 (Windows 8.1 with KB3000850)
- 6.3.9600.18692 (Windows 8.1 with KB4022720)
- 6.3.9600.18708 (Windows 8.1 with KB4025335)
- 6.3.9600.18928 (Windows 8.1 with KB4088876)
- 6.3.9600.19093 (Windows 8.1 with KB4343891)
- 6.4.9841.0 (Windows 10 Technical Preview)
- 6.4.9860.0 (Windows 10 Technical Preview Update 1)
- 6.4.9879.0 (Windows 10 Technical Preview Update 2)
- 10.0.9926.0 (Windows 10 Pro Technical Preview)
- 10.0.10041.0 (Windows 10 Pro Technical Preview Update 1)
- 10.0.10240.16384 (Windows 10 RTM)
- 10.0.10586.0 (Windows 10 TH2 Release 151029-1700)
- 10.0.10586.589 (Windows 10 TH2 Release 160906-1759 with KB3185614)
- 10.0.11082.1000 (Windows 10 RS1 Release 151210-2021)
- 10.0.11102.1000 (Windows 10 RS1 Release 160113-1800)
- 10.0.14251.1000 (Windows 10 RS1 Release 160124-1059)
- 10.0.14271.1000 (Windows 10 RS1 Release 160218-2310)
- 10.0.14279.1000 (Windows 10 RS1 Release 160229-1700)
- 10.0.14295.1000 (Windows 10 RS1 Release 160318-1628)
- 10.0.14300.1000 (Windows Server 2016 Technical Preview 5)
- 10.0.14316.1000 (Windows 10 RS1 Release 160402-2227)
- 10.0.14328.1000 (Windows 10 RS1 Release 160418-1609)
- 10.0.14332.1001 (Windows 10 RS1 Release 160422-1940)
- 10.0.14342.1000 (Windows 10 RS1 Release 160506-1708)
- 10.0.14352.1002 (Windows 10 RS1 Release 160522-1930)
- 10.0.14366.0 (Windows 10 RS1 Release 160610-1700)
- 10.0.14367.0 (Windows 10 RS1 Release 160613-1700)
- 10.0.14372.0 (Windows 10 RS1 Release 160620-2342)
- 10.0.14379.0 (Windows 10 RS1 Release 160627-1607)
- 10.0.14383.0 (Windows 10 RS1 Release 160701-1839)
- 10.0.14385.0 (Windows 10 RS1 Release 160706-1700)
- 10.0.14388.0 (Windows 10 RS1 Release 160709-1635)
- 10.0.14393.0 (Windows 10 RS1 Release 160715-1616)
- 10.0.14393.1198 (Windows 10 RS1 Release Sec 170427-1353 with KB4019472)
- 10.0.14393.1737 (Windows 10 RS1 Release Inmarket 170914-1249 with KB4041691)
- 10.0.14393.2457 (Windows 10 RS1 Release Inmarket 180822-1743 with KB4343884)
- 10.0.14901.1000 (Windows 10 RS Pre-Release 160805-1700)
- 10.0.14905.1000 (Windows 10 RS Pre-Release 160811-1739)
- 10.0.14915.1000 (Windows 10 RS Pre-Release 160826-1902)
- 10.0.14926.1000 (Windows 10 RS Pre-Release 160910-1529)
- 10.0.14931.1000 (Windows 10 RS Pre-Release 160916-1700)
- 10.0.14936.1000 (Windows 10 RS Pre-Release 160923-1700)
- 10.0.14942.1000 (Windows 10 RS Pre-Release 161003-1929)
- 10.0.14946.1000 (Windows 10 RS Pre-Release 161007-1700)
- 10.0.14951.1000 (Windows 10 RS Pre-Release 161014-1700)
- 10.0.14955.1000 (Windows 10 RS Pre-Release 161020-1700)
- 10.0.14959.1000 (Windows 10 RS Pre-Release 161026-1700)
- 10.0.14965.1001 (Windows 10 RS Pre-Release 161104-1700)
- 10.0.14971.1000 (Windows 10 RS Pre-Release 161111-1700)
- 10.0.14986.1000 (Windows 10 Build 160101.0800)
- 10.0.14997.1001 (Windows 10 Build 160101.0800)
- 10.0.15002.1001 (Windows 10 Build 160101.0800)
- 10.0.15007.1000 (Windows 10 Build 160101.0800)
- 10.0.15014.1000 (Windows 10 Build 160101.0800)
- 10.0.15019.1000 (Windows 10 RS Pre-Release 170121-1513)
- 10.0.15025.1000 (Windows 10 RS Pre-Release 170127-1750)
- 10.0.15031.0 (Windows 10 RS2 Release 170204-1546)
- 10.0.15042.0 (Windows 10 RS2 Release 170219-2329)
- 10.0.15046.0 (Windows 10 Build 160101.0800)
- 10.0.15048.0 (Windows 10 Build 160101.0800)
- 10.0.15055.0 (Windows 10 Build 160101.0800)
- 10.0.15058.0 (Windows 10 Build 160101.0800)
- 10.0.15061.0 (Windows 10 Build 160101.0800)
- 10.0.15063.0 (Windows 10 Build 160101.0800)
- 10.0.15063.296 (Windows 10 Build 160101.0800)
- 10.0.15063.994 (Windows 10 Build 160101.0800)
- 10.0.15063.1155 (Windows 10 Build 160101.0800)
- 10.0.16179.1000 (Windows 10 Build 160101.0800)
- 10.0.16184.1001 (Windows 10 Build 160101.0800)
- 10.0.16199.1000 (Windows 10 Build 160101.0800)
- 10.0.16215.1000 (Windows 10 Build 160101.0800)
- 10.0.16232.1000 (Windows 10 Build 160101.0800)
- 10.0.16237.1001 (Windows 10 Build 160101.0800)
- 10.0.16241.1001 (Windows 10 Build 160101.0800)
- 10.0.16251.0 (Windows 10 Build 160101.0800)
- 10.0.16251.1000 (Windows 10 Build 160101.0800)
- 10.0.16257.1 (Windows 10 Build 160101.0800)
- 10.0.16257.1000 (Windows 10 Build 160101.0800)
- 10.0.16273.1000 (Windows 10 Build 160101.0800)
- 10.0.16275.1000 (Windows 10 Build 160101.0800)
- 10.0.16278.1000 (Windows 10 Build 160101.0800)
- 10.0.16281.1000 (Windows 10 Build 160101.0800)
- 10.0.16288.1 (Windows 10 Build 160101.0800)
- 10.0.16291.0 (Windows 10 Build 160101.0800)
- 10.0.16294.1 (Windows 10 Build 160101.0800)
- 10.0.16296.0 (Windows 10 Build 160101.0800)
- 10.0.16299.0 (Windows 10 Build 160101.0800)
- 10.0.16299.15 (Windows 10 Build 160101.0800)
- 10.0.16353.1000 (Windows 10 Build 160101.0800)
- 10.0.16362.1000 (Windows 10 Build 160101.0800)
- 10.0.17004.1000 (Windows 10 Build 160101.0800)
- 10.0.17017.1000 (Windows 10 Build 160101.0800)
- 10.0.17025.1000 (Windows 10 Build 160101.0800)
- 10.0.17035.1000 (Windows 10 Build 160101.0800)
- 10.0.17046.1000 (Windows 10 Build 160101.0800)
- 10.0.17063.1000 (Windows 10 Build 160101.0800)
- 10.0.17115.1 (Windows 10 Build 160101.0800)
- 10.0.17128.1 (Windows 10 Build 160101.0800)
- 10.0.17133.1 (Windows 10 Build 160101.0800)
- 10.0.17134.1 (Windows 10 Build 160101.0800)
- 10.0.17723.1000 (Windows 10 Build 160101.0800)
- 10.0.17763.1 (Windows 10 Build 160101.0800)
#### Confirmed working on:
- Windows Vista Starter (x86 - Service Pack 1 and higher)
- Windows Vista Home Basic
- Windows Vista Home Premium
- Windows Vista Business
- Windows Vista Enterprise
- Windows Vista Ultimate
- Windows Server 2008
- Windows 7 Starter
- Windows 7 Home Basic
- Windows 7 Home Premium
- Windows 7 Professional
- Windows 7 Enterprise
- Windows 7 Ultimate
- Windows Server 2008 R2
- Windows 8 Developer Preview
- Windows 8 Consumer Preview
- Windows 8 Release Preview
- Windows 8
- Windows 8 Single Language
- Windows 8 Pro
- Windows 8 Enterprise
- Windows Server 2012
- Windows 8.1 Preview
- Windows 8.1
- Windows 8.1 Connected (with Bing)
- Windows 8.1 Single Language
- Windows 8.1 Connected Single Language (with Bing)
- Windows 8.1 Pro
- Windows 8.1 Enterprise
- Windows Server 2012 R2
- Windows 10 Technical Preview
- Windows 10 Pro Technical Preview
- Windows 10 Home
- Windows 10 Home Single Language
- Windows 10 Pro
- Windows 10 Enterprise
- Windows Server 2016 Technical Preview
Installation instructions:
- Download latest release binaries and unpack files
- Right-click on **`install.bat`** and select Run as Administrator
- See command output for details
To update INI file:
- Right-click on **`update.bat`** and select Run as Administrator
- See command output for details
To uninstall:
- Go to the directory where you extracted the files
- Right-click on **`uninstall.bat`** and select Run as Administrator
- See command output for details

BIN
bin/RDPCheck.exe Normal file

Binary file not shown.

BIN
bin/RDPConf.exe Normal file

Binary file not shown.

BIN
bin/RDPWInst.exe Normal file

Binary file not shown.

View File

@ -1,14 +1,8 @@
@echo off @echo off
if not exist "%~dp0RDPWInst.exe" goto :error RDPWInst -i
"%~dp0RDPWInst" -i -o
echo ______________________________________________________________ echo ______________________________________________________________
echo. echo.
echo You can check RDP functionality with RDPCheck program. echo You can check RDP functionality with RDPCheck program.
echo Also you can configure advanced settings with RDPConf program. echo Also you can configure advanced settings with RDPConf program.
echo. echo.
goto :anykey
:error
echo [-] Installer executable not found.
echo Please extract all files from the downloaded package or check your anti-virus.
:anykey
pause pause

View File

@ -1,10 +1,4 @@
@echo off @echo off
if not exist "%~dp0RDPWInst.exe" goto :error RDPWInst -u
"%~dp0RDPWInst" -u
echo. echo.
goto :anykey
:error
echo [-] Installer executable not found.
echo Please extract all files from the downloaded package or check your anti-virus.
:anykey
pause pause

View File

@ -1,10 +0,0 @@
@echo off
if not exist "%~dp0RDPWInst.exe" goto :error
"%~dp0RDPWInst" -w
echo.
goto :anykey
:error
echo [-] Installer executable not found.
echo Please extract all files from the downloaded package or check your anti-virus.
:anykey
pause

View File

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductName="RDP Wrapper Library" ?>
<?define ProductVersion="1.6.2" ?>
<?define ProductCode="37ea5771-3352-4a52-9fac-9297331daebd"?>
<?define UpgradeCode="6623f60c-e84f-41e7-a55b-f421165deeb5"?>
<?define Manufacturer="Stas'M Corp. and contributors"?>
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="200" Compressed="yes"/>
<Property Id="MSIFASTINSTALL" Value="1" />
<Property Id="DISABLEROLLBACK" Value="1" />
<MajorUpgrade AllowDowngrades="yes"/>
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="CommonAppDataFolder">
<Directory Id="PACKAGECACHE" Name="Package Cache">
<Directory Id="INSTALLLOCATION" Name="{$(var.ProductCode)}">
<Component Id="RDPWrap" Guid="affd77d1-b35c-46f3-a97f-1686dc57b8b8">
<File Id='RDPWInst' DiskId='1' Source='RDPWInst.exe'/>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
<Feature Id="RDPWrapInstall" Title="RDPWrapSetup" Level="1">
<ComponentRef Id="RDPWrap" />
</Feature>
<CustomAction Id='InstallAction' FileKey='RDPWInst' ExeCommand='-i -o' Execute='immediate' Return='check'/>
<CustomAction Id='UninstallAction' FileKey='RDPWInst' ExeCommand='-u' Execute='immediate' Return='check'/>
<CustomAction Id='UpdateAction' FileKey='RDPWInst' ExeCommand='-w' Execute='immediate' Return='check'/>
<!-- <CustomAction Id='ChangeAction' Directory='ProgramFilesFolder' ExeCommand='RDP Wrapper\RDPConf' Execute='immediate' Return='check'/>
<CustomAction Id='RepairAction' Directory='ProgramFilesFolder' ExeCommand='RDP Wrapper\RDPCheck' Execute='immediate' Return='check'/> -->
<InstallExecuteSequence>
<Custom Action='InstallAction' After='InstallFinalize'>NOT Installed AND NOT WIX_UPGRADE_DETECTED</Custom>
<Custom Action='UninstallAction' Before="RemoveFiles">REMOVE AND NOT UPGRADINGPRODUCTCODE</Custom>
<Custom Action='UpdateAction' Before="RemoveFiles">UPGRADINGPRODUCTCODE</Custom>
<!-- <Custom Action='ChangeAction' After='InstallFinalize'>Installed AND NOT REINSTALL AND NOT UPGRADINGPRODUCTCODE AND NOT REMOVE</Custom>
<Custom Action='RepairAction' After='InstallFinalize'>REINSTALL</Custom> -->
</InstallExecuteSequence>
</Product>
</Wix>

View File

@ -1,3 +0,0 @@
@echo off
"%ProgramFiles%\WiX Toolset v3.11\bin\candle" RDPWInst.wxs
"%ProgramFiles%\WiX Toolset v3.11\bin\light" RDPWInst.wixobj

View File

@ -50,7 +50,6 @@ if not !errorlevel!==0 (
echo [*] Setting firewall configuration... echo [*] Setting firewall configuration...
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=tcp localport=3389 profile=any action=allow netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=tcp localport=3389 profile=any action=allow
netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=udp localport=3389 profile=any action=allow
echo [*] Looking for TermService PID... echo [*] Looking for TermService PID...
tasklist /SVC /FI "SERVICES eq TermService" | find "PID" /V tasklist /SVC /FI "SERVICES eq TermService" | find "PID" /V
echo. echo.

BIN
res/rdpclip-x64.exe Normal file

Binary file not shown.

BIN
res/rdpclip-x86.exe Normal file

Binary file not shown.

View File

@ -1,172 +0,0 @@
; RDP Wrapper Library configuration
; for Windows RT (ARMv7)
; This is experimental file
[Main]
Updated=2016-03-07
LogFile=\rdpwrap.txt
[SLPolicy]
TerminalServices-RemoteConnectionManager-AllowRemoteConnections=1
TerminalServices-RemoteConnectionManager-AllowMultipleSessions=1
TerminalServices-RemoteConnectionManager-AllowAppServerMode=1
TerminalServices-RemoteConnectionManager-AllowMultimon=1
TerminalServices-RemoteConnectionManager-MaxUserSessions=0
TerminalServices-RemoteConnectionManager-ce0ad219-4670-4988-98fb-89b14c2f072b-MaxSessions=0
TerminalServices-RemoteConnectionManager-45344fe7-00e6-4ac6-9f01-d01fd4ffadfb-MaxSessions=2
TerminalServices-RDP-7-Advanced-Compression-Allowed=1
TerminalServices-RemoteConnectionManager-45344fe7-00e6-4ac6-9f01-d01fd4ffadfb-LocalOnly=0
TerminalServices-RemoteConnectionManager-8dc86f1d-9969-4379-91c1-06fe1dc60575-MaxSessions=1000
TerminalServices-DeviceRedirection-Licenses-TSEasyPrintAllowed=1
TerminalServices-DeviceRedirection-Licenses-PnpRedirectionAllowed=1
TerminalServices-DeviceRedirection-Licenses-TSMFPluginAllowed=1
TerminalServices-RemoteConnectionManager-UiEffects-DWMRemotingAllowed=1
[PatchCodes]
Zero=00
bjmp5=05E0
CDefPolicy_Query_r3_r5=40F20013C5F8203305E0
CDefPolicy_Query_r3_r0=40F20013C0F8203305E0
[6.2.9200.16384]
; Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled
; .text:10066DCC MOV.W R3, #0x11C
; .text:10066DD0 STR R3, [SP,#0x16C+var_13C]
; .text:10066DD2 LDR R3, =__imp_GetVersionExW
; .text:10066DD4 MOVS R4, #1 <- 0
; .text:10066DD6 ADD R0, SP, #0x16C+var_13C
; .text:10066DD8 LDR R3, [R3]
SingleUserPatch.arm=1
SingleUserOffset.arm=66DD4
SingleUserCode.arm=Zero
; Patch CDefPolicy::Query
; Original
; .text:10059164 LDR.W R2, [R5,#0x324] ; D5 F8 24 23 ; [R5,#0x324] -> R2
; .text:10059168 LDR.W R3, [R5,#0x320] ; D5 F8 20 33 ; [R5,#0x320] -> R3
; .text:1005916C CMP R2, R3 ; 9A 42 ; compare
; .text:1005916E BNE loc_1005917A ; 04 D1 ; jump if (R2 != R3)
; Changed
; .text:10059164 MOVW R3, #0x100 ; 40 F2 00 13 ; 0x100 -> R3
; .text:10059168 STR.W R3, [R5,#0x320] ; C5 F8 20 33 ; R3 -> [R5,#0x320]
; .text:1005916C B loc_1005917A ; 05 E0 ; jump
; .text:1005916E BNE loc_1005917A ; 04 D1 ; / never executed /
DefPolicyPatch.arm=1
DefPolicyOffset.arm=59164
DefPolicyCode.arm=CDefPolicy_Query_r3_r5
; Hook SLGetWindowsInformationDWORDWrapper
SLPolicyInternal.arm=1
SLPolicyOffset.arm=5F934
SLPolicyFunc.arm=New_Win8SL
[6.3.9600.16384]
; Patch CEnforcementCore::GetInstanceOfTSLicense
; .text:1008E6C2 BL _IsLicenseTypeLocalOnly_CSLQuery__SAJAAU_GUID__PAH_Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *)
; .text:1008E6C6 CMP R0, #0
; .text:1008E6C8 BLT loc_1008E6DA
; .text:1008E6CA LDR R3, [SP,#0x20+var_14]
; .text:1008E6CC CBZ R3, loc_1008E6DA ; 2B B1 ; jump if (R3 == 0)
; Changed
; .text:1008E6CC B loc_1008E6DA ; 05 E0 ; jump
LocalOnlyPatch.arm=1
LocalOnlyOffset.arm=8E6CC
LocalOnlyCode.arm=bjmp5
; Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled
; .text:10069E74 MOV.W R3, #0x11C
; .text:10069E78 STR R3, [SP,#0x164+var_13C]
; .text:10069E7A LDR R3, =__imp_GetVersionExW
; .text:10069E7C MOVS R4, #1 <- 0
; .text:10069E7E ADD R0, SP, #0x164+var_13C
; .text:10069E80 LDR R3, [R3]
SingleUserPatch.arm=1
SingleUserOffset.arm=69E7C
SingleUserCode.arm=Zero
; Patch CDefPolicy::Query
; Original
; .text:10064D54 LDR.W R2, [R0,#0x324] ; D0 F8 24 23 ; [R0,#0x324] -> R2
; .text:10064D58 LDR.W R3, [R0,#0x320] ; D0 F8 20 33 ; [R0,#0x320] -> R3
; .text:10064D5C CMP R2, R3 ; 9A 42 ; compare
; .text:10064D5E BNE loc_10064D6A ; 04 D1 ; jump if (R2 != R3)
; Changed
; .text:10064D54 MOVW R3, #0x100 ; 40 F2 00 13 ; 0x100 -> R3
; .text:10064D58 STR.W R3, [R0,#0x320] ; C0 F8 20 33 ; R3 -> [R0,#0x320]
; .text:10064D5C B loc_10064D6A ; 05 E0 ; jump
; .text:10064D5E BNE loc_10064D6A ; 04 D1 ; / never executed /
DefPolicyPatch.arm=1
DefPolicyOffset.arm=64D54
DefPolicyCode.arm=CDefPolicy_Query_r3_r0
; Hook CSLQuery::Initialize
SLInitHook.arm=1
SLInitOffset.arm=32188
SLInitFunc.arm=New_CSLQuery_Initialize
[6.3.9600.17095]
; Patch CEnforcementCore::GetInstanceOfTSLicense
; .text:1008E35A BL _IsLicenseTypeLocalOnly_CSLQuery__SAJAAU_GUID__PAH_Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *)
; .text:1008E35E CMP R0, #0
; .text:1008E360 BLT loc_1008E372
; .text:1008E362 LDR R3, [SP,#0x20+var_14]
; .text:1008E364 CBZ R3, loc_1008E372 ; 2B B1 ; jump if (R3 == 0)
; Changed
; .text:1008E364 B loc_1008E372 ; 05 E0 ; jump
LocalOnlyPatch.arm=1
LocalOnlyOffset.arm=8E364
LocalOnlyCode.arm=bjmp5
; Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled
; .text:10069C2C MOV.W R3, #0x11C
; .text:10069C30 STR R3, [SP,#0x164+var_13C]
; .text:10069C32 LDR R3, =GetVersionExW
; .text:10069C34 MOVS R4, #1 <- 0
; .text:10069C36 ADD R0, SP, #0x164+var_13C
; .text:10069C38 LDR R3, [R3]
SingleUserPatch.arm=1
SingleUserOffset.arm=69C34
SingleUserCode.arm=Zero
; Patch CDefPolicy::Query
; Original
; .text:100649E0 LDR.W R2, [R0,#0x324] ; D0 F8 24 23 ; [R0,#0x324] -> R2
; .text:100649E4 LDR.W R3, [R0,#0x320] ; D0 F8 20 33 ; [R0,#0x320] -> R3
; .text:100649E8 CMP R2, R3 ; 9A 42 ; compare
; .text:100649EA BNE loc_100649F6 ; 04 D1 ; jump if (R2 != R3)
; Changed
; .text:100649E0 MOVW R3, #0x100 ; 40 F2 00 13 ; 0x100 -> R3
; .text:100649E4 STR.W R3, [R0,#0x320] ; C0 F8 20 33 ; R3 -> [R0,#0x320]
; .text:100649E8 B loc_10064D6A ; 05 E0 ; jump
; .text:100649EA BNE loc_10064D6A ; 04 D1 ; / never executed /
DefPolicyPatch.arm=1
DefPolicyOffset.arm=649E0
DefPolicyCode.arm=CDefPolicy_Query_r3_r0
; Hook CSLQuery::Initialize
SLInitHook.arm=1
SLInitOffset.arm=32E3C
SLInitFunc.arm=New_CSLQuery_Initialize
[SLInit]
bServerSku=1
bRemoteConnAllowed=1
bFUSEnabled=1
bAppServerAllowed=1
bMultimonAllowed=1
lMaxUserSessions=0
ulMaxDebugSessions=0
bInitialized=1
[6.3.9600.16384-SLInit]
bFUSEnabled.arm =A57E0
lMaxUserSessions.arm =A57E4
bAppServerAllowed.arm =A57E8
bInitialized.arm =A57EC
bMultimonAllowed.arm =A57F0
bServerSku.arm =A57F4
ulMaxDebugSessions.arm=A57F8
bRemoteConnAllowed.arm=A57FC
[6.3.9600.17095-SLInit]
bFUSEnabled.arm =A67E0
lMaxUserSessions.arm =A67E4
bAppServerAllowed.arm =A67E8
bInitialized.arm =A67EC
bMultimonAllowed.arm =A67F0
bServerSku.arm =A67F4
ulMaxDebugSessions.arm=A67F8
bRemoteConnAllowed.arm=A67FC

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,3 @@
{
Copyright 2018 Stas'M Corp.
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.
}
program RDPWInst; program RDPWInst;
{$APPTYPE CONSOLE} {$APPTYPE CONSOLE}
@ -25,10 +9,7 @@ uses
Windows, Windows,
Classes, Classes,
WinSvc, WinSvc,
Registry, Registry;
WinInet,
AccCtrl,
AclAPI;
function EnumServicesStatusEx( function EnumServicesStatusEx(
hSCManager: SC_HANDLE; hSCManager: SC_HANDLE;
@ -43,11 +24,6 @@ function EnumServicesStatusEx(
pszGroupName: PWideChar): BOOL; stdcall; pszGroupName: PWideChar): BOOL; stdcall;
external advapi32 name 'EnumServicesStatusExW'; external advapi32 name 'EnumServicesStatusExW';
function ConvertStringSidToSid(
StringSid: PWideChar;
var Sid: PSID): BOOL; stdcall;
external advapi32 name 'ConvertStringSidToSidW';
type type
FILE_VERSION = record FILE_VERSION = record
Version: record case Boolean of Version: record case Boolean of
@ -83,7 +59,6 @@ const
TermService = 'TermService'; TermService = 'TermService';
var var
Installed: Boolean; Installed: Boolean;
Online: Boolean;
WrapPath: String; WrapPath: String;
Arch: Byte; Arch: Byte;
OldWow64RedirectionValue: LongBool; OldWow64RedirectionValue: LongBool;
@ -168,8 +143,7 @@ begin
end; end;
TermServiceHost := Reg.ReadString('ImagePath'); TermServiceHost := Reg.ReadString('ImagePath');
Reg.CloseKey; Reg.CloseKey;
if (Pos('svchost.exe', LowerCase(TermServiceHost)) = 0) if Pos('svchost.exe', LowerCase(TermServiceHost)) = 0 then
and (Pos('svchost -k', LowerCase(TermServiceHost)) = 0) then
begin begin
Reg.Free; Reg.Free;
Writeln('[-] TermService is hosted in a custom application (BeTwin, etc.) - unsupported.'); Writeln('[-] TermService is hosted in a custom application (BeTwin, etc.) - unsupported.');
@ -292,46 +266,33 @@ var
hSvc: THandle; hSvc: THandle;
Code: DWORD; Code: DWORD;
pch: PWideChar; pch: PWideChar;
procedure ExitError(Func: String; ErrorCode: DWORD);
begin
if hSC > 0 then
CloseServiceHandle(hSC);
if hSvc > 0 then
CloseServiceHandle(hSvc);
Writeln('[-] ', Func, ' error (code ', ErrorCode, ').');
end;
begin begin
hSC := 0;
hSvc := 0;
Writeln('[*] Starting ', SvcName, '...'); Writeln('[*] Starting ', SvcName, '...');
hSC := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); hSC := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
if hSC = 0 then if hSC = 0 then
begin begin
ExitError('OpenSCManager', GetLastError); Code := GetLastError;
Writeln('[-] OpenSCManager error (code ', Code, ').');
Exit; Exit;
end; end;
hSvc := OpenService(hSC, PWideChar(SvcName), SERVICE_START); hSvc := OpenService(hSC, PWideChar(SvcName), SERVICE_START);
if hSvc = 0 then if hSvc = 0 then
begin begin
ExitError('OpenService', GetLastError); CloseServiceHandle(hSC);
Code := GetLastError;
Writeln('[-] OpenService error (code ', Code, ').');
Exit; Exit;
end; end;
pch := nil; pch := nil;
if not StartService(hSvc, 0, pch) then begin if not StartService(hSvc, 0, pch) then begin
CloseServiceHandle(hSvc);
CloseServiceHandle(hSC);
Code := GetLastError; Code := GetLastError;
if Code = 1056 then begin // Service already started Writeln('[-] StartService error (code ', Code, ').');
Sleep(2000); // or SCM hasn't registered killed process
if not StartService(hSvc, 0, pch) then begin
ExitError('StartService', Code);
Exit; Exit;
end; end;
end else begin
ExitError('StartService', Code);
Exit;
end;
end;
CloseServiceHandle(hSvc); CloseServiceHandle(hSvc);
CloseServiceHandle(hSC); CloseServiceHandle(hSC);
end; end;
@ -357,8 +318,6 @@ begin
Halt(Code); Halt(Code);
end; end;
dwResumeHandle := 0;
SetLength(Svc, 1489); SetLength(Svc, 1489);
FillChar(Svc[0], sizeof(Svc[0])*Length(Svc), 0); FillChar(Svc[0], sizeof(Svc[0])*Length(Svc), 0);
if not EnumServicesStatusEx(hSC, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, if not EnumServicesStatusEx(hSC, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,
@ -598,196 +557,41 @@ begin
ResStream.Free; ResStream.Free;
end; end;
function ExtractResText(ResName: String): String;
var
ResStream: TResourceStream;
Str: TStringList;
begin
ResStream := TResourceStream.Create(HInstance, ResName, RT_RCDATA);
Str := TStringList.Create;
try
Str.LoadFromStream(ResStream);
except
end;
ResStream.Free;
Result := Str.Text;
Str.Free;
end;
function GitINIFile(var Content: String): Boolean;
const
URL = 'https://raw.githubusercontent.com/stascorp/rdpwrap/master/res/rdpwrap.ini';
var
NetHandle: HINTERNET;
UrlHandle: HINTERNET;
Str: String;
Buf: Array[0..1023] of Byte;
BytesRead: DWORD;
begin
Result := False;
Content := '';
NetHandle := InternetOpen('RDP Wrapper Update', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if not Assigned(NetHandle) then
Exit;
UrlHandle := InternetOpenUrl(NetHandle, PChar(URL), nil, 0, INTERNET_FLAG_RELOAD, 0);
if not Assigned(UrlHandle) then
begin
InternetCloseHandle(NetHandle);
Exit;
end;
repeat
InternetReadFile(UrlHandle, @Buf[0], SizeOf(Buf), BytesRead);
SetString(Str, PAnsiChar(@Buf[0]), BytesRead);
Content := Content + Str;
until BytesRead = 0;
InternetCloseHandle(UrlHandle);
InternetCloseHandle(NetHandle);
Result := True;
end;
procedure GrantSidFullAccess(Path, SID: String);
var
p_SID: PSID;
pDACL: PACL;
EA: EXPLICIT_ACCESS;
Code, Result: DWORD;
begin
p_SID := nil;
if not ConvertStringSidToSid(PChar(SID), p_SID) then
begin
Code := GetLastError;
Writeln('[-] ConvertStringSidToSid error (code ', Code, ').');
Exit;
end;
EA.grfAccessPermissions := GENERIC_ALL;
EA.grfAccessMode := GRANT_ACCESS;
EA.grfInheritance := SUB_CONTAINERS_AND_OBJECTS_INHERIT;
EA.Trustee.pMultipleTrustee := nil;
EA.Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
EA.Trustee.TrusteeForm := TRUSTEE_IS_SID;
EA.Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;
EA.Trustee.ptstrName := p_SID;
Result := SetEntriesInAcl(1, @EA, nil, pDACL);
if Result = ERROR_SUCCESS then
begin
if SetNamedSecurityInfo(pchar(Path), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, pDACL, nil) <> ERROR_SUCCESS then
begin
Code := GetLastError;
Writeln('[-] SetNamedSecurityInfo error (code ', Code, ').');
end;
LocalFree(Cardinal(pDACL));
end
else begin
Code := GetLastError;
Writeln('[-] SetEntriesInAcl error (code ', Code, ').');
end;
end;
procedure ExtractFiles; procedure ExtractFiles;
var
RDPClipRes, RfxvmtRes, S: String;
OnlineINI: TStringList;
begin begin
if not DirectoryExists(ExtractFilePath(ExpandPath(WrapPath))) then if not DirectoryExists(ExtractFilePath(ExpandPath(WrapPath))) then
if ForceDirectories(ExtractFilePath(ExpandPath(WrapPath))) then begin if ForceDirectories(ExtractFilePath(ExpandPath(WrapPath))) then
S := ExtractFilePath(ExpandPath(WrapPath)); Writeln('[+] Folder created: ', ExtractFilePath(ExpandPath(WrapPath)))
Writeln('[+] Folder created: ', S);
GrantSidFullAccess(S, 'S-1-5-18'); // Local System account
GrantSidFullAccess(S, 'S-1-5-6'); // Service group
end
else begin else begin
Writeln('[-] ForceDirectories error.'); Writeln('[-] ForceDirectories error.');
Writeln('[*] Path: ', ExtractFilePath(ExpandPath(WrapPath))); Writeln('[*] Path: ', ExtractFilePath(ExpandPath(WrapPath)));
Halt(0); Halt(0);
end; end;
if Online then
begin
Writeln('[*] Downloading latest INI file...');
OnlineINI := TStringList.Create;
if GitINIFile(S) then begin
OnlineINI.Text := S;
S := ExtractFilePath(ExpandPath(WrapPath)) + 'rdpwrap.ini';
OnlineINI.SaveToFile(S);
Writeln('[+] Latest INI file -> ', S);
end
else
begin
Writeln('[-] Failed to get online INI file, using built-in.');
Online := False;
end;
OnlineINI.Free;
end;
if not Online then
begin
S := ExtractFilePath(ParamStr(0)) + 'rdpwrap.ini';
if FileExists(S) then
begin
OnlineINI := TStringList.Create;
OnlineINI.LoadFromFile(S);
S := ExtractFilePath(ExpandPath(WrapPath)) + 'rdpwrap.ini';
OnlineINI.SaveToFile(S);
Writeln('[+] Current INI file -> ', S);
OnlineINI.Free;
end else
ExtractRes('config', ExtractFilePath(ExpandPath(WrapPath)) + 'rdpwrap.ini');
end;
RDPClipRes := '';
RfxvmtRes := '';
case Arch of case Arch of
32: begin 32: begin
ExtractRes('rdpw32', ExpandPath(WrapPath)); ExtractRes('rdpw32', ExpandPath(WrapPath));
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 0) then if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then
RDPClipRes := 'rdpclip6032'; ExtractRes('rdpclip32', ExpandPath('%SystemRoot%\System32\rdpclip.exe'));
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then
RDPClipRes := 'rdpclip6132';
if (FV.Version.w.Major = 10) and (FV.Version.w.Minor = 0) then
RfxvmtRes := 'rfxvmt32';
end; end;
64: begin 64: begin
ExtractRes('rdpw64', ExpandPath(WrapPath)); ExtractRes('rdpw64', ExpandPath(WrapPath));
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 0) then
RDPClipRes := 'rdpclip6064';
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then
RDPClipRes := 'rdpclip6164';
if (FV.Version.w.Major = 10) and (FV.Version.w.Minor = 0) then
RfxvmtRes := 'rfxvmt64';
end;
end;
if RDPClipRes <> '' then
if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then
ExtractRes(RDPClipRes, ExpandPath('%SystemRoot%\System32\rdpclip.exe')); ExtractRes('rdpclip64', ExpandPath('%SystemRoot%\System32\rdpclip.exe'));
if RfxvmtRes <> '' then end;
if not FileExists(ExpandPath('%SystemRoot%\System32\rfxvmt.dll')) then end;
ExtractRes(RfxvmtRes, ExpandPath('%SystemRoot%\System32\rfxvmt.dll'));
end; end;
procedure DeleteFiles; procedure DeleteFiles;
var var
Code: DWORD; Code: DWORD;
FullPath, Path: String;
begin begin
FullPath := ExpandPath(TermServicePath); if not DeleteFile(PWideChar(ExpandPath(TermServicePath))) then
Path := ExtractFilePath(FullPath);
if not DeleteFile(PWideChar(Path + 'rdpwrap.ini')) then
begin begin
Code := GetLastError; Code := GetLastError;
Writeln('[-] DeleteFile error (code ', Code, ').'); Writeln('[-] DeleteFile error (code ', Code, ').');
Exit; Exit;
end; end;
Writeln('[+] Removed file: ', Path + 'rdpwrap.ini'); Writeln('[+] Removed file: ', ExpandPath(TermServicePath));
if not DeleteFile(PWideChar(FullPath)) then
begin
Code := GetLastError;
Writeln('[-] DeleteFile error (code ', Code, ').');
Exit;
end;
Writeln('[+] Removed file: ', FullPath);
if not RemoveDirectory(PWideChar(ExtractFilePath(ExpandPath(TermServicePath)))) then if not RemoveDirectory(PWideChar(ExtractFilePath(ExpandPath(TermServicePath)))) then
begin begin
Code := GetLastError; Code := GetLastError;
@ -839,25 +643,17 @@ begin
FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE; FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE;
FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL; FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL;
FreeLibrary(hFile);
Result := True; Result := True;
end; end;
procedure CheckTermsrvVersion; procedure CheckTermsrvVersion;
var var
SuppLvl: Byte; SuppLvl: Byte;
VerTxt: String;
procedure UpdateMsg;
begin
Writeln('Try running "update.bat" or "RDPWInst -w" to download latest INI file.');
Writeln('If it doesn''t help, send your termsrv.dll to project developer for support.');
end;
begin begin
GetFileVersion(ExpandPath(TermServicePath), FV); GetFileVersion(ExpandPath(TermServicePath), FV);
VerTxt := Format('%d.%d.%d.%d', Writeln('[*] Terminal Services version: ',
[FV.Version.w.Major, FV.Version.w.Minor, FV.Release, FV.Build]); Format('%d.%d.%d.%d',
Writeln('[*] Terminal Services version: ', VerTxt); [FV.Version.w.Major, FV.Version.w.Minor, FV.Release, FV.Build]));
if (FV.Version.w.Major = 5) and (FV.Version.w.Minor = 1) then if (FV.Version.w.Major = 5) and (FV.Version.w.Minor = 1) then
begin begin
@ -886,20 +682,69 @@ begin
Writeln('[!] This version of Terminal Services may crash on logon attempt.'); Writeln('[!] This version of Terminal Services may crash on logon attempt.');
Writeln('It''s recommended to upgrade to Service Pack 1 or higher.'); Writeln('It''s recommended to upgrade to Service Pack 1 or higher.');
end; end;
end; if (FV.Release = 6000) and (FV.Build = 16386) then
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then
SuppLvl := 1;
if Pos('[' + VerTxt + ']', ExtractResText('config')) > 0 then
SuppLvl := 2; SuppLvl := 2;
if (FV.Release = 6001) and (FV.Build = 18000) then
SuppLvl := 2;
if (FV.Release = 6002) and (FV.Build = 18005) then
SuppLvl := 2;
if (FV.Release = 6002) and (FV.Build = 19214) then
SuppLvl := 2;
if (FV.Release = 6002) and (FV.Build = 23521) then
SuppLvl := 2;
end;
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then begin
SuppLvl := 1;
if (FV.Release = 7600) and (FV.Build = 16385) then
SuppLvl := 2;
if (FV.Release = 7601) and (FV.Build = 17514) then
SuppLvl := 2;
if (FV.Release = 7601) and (FV.Build = 18540) then
SuppLvl := 2;
if (FV.Release = 7601) and (FV.Build = 22750) then
SuppLvl := 2;
if (FV.Release = 7601) and (FV.Build = 18637) then
SuppLvl := 2;
if (FV.Release = 7601) and (FV.Build = 22843) then
SuppLvl := 2;
end;
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 2) then begin
if (FV.Release = 8102) and (FV.Build = 0) then
SuppLvl := 2;
if (FV.Release = 8250) and (FV.Build = 0) then
SuppLvl := 2;
if (FV.Release = 8400) and (FV.Build = 0) then
SuppLvl := 2;
if (FV.Release = 9200) and (FV.Build = 16384) then
SuppLvl := 2;
if (FV.Release = 9200) and (FV.Build = 17048) then
SuppLvl := 2;
if (FV.Release = 9200) and (FV.Build = 21166) then
SuppLvl := 2;
end;
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 3) then begin
if (FV.Release = 9431) and (FV.Build = 0) then
SuppLvl := 2;
if (FV.Release = 9600) and (FV.Build = 16384) then
SuppLvl := 2;
if (FV.Release = 9600) and (FV.Build = 17095) then
SuppLvl := 2;
end;
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 4) then begin
if (FV.Release = 9841) and (FV.Build = 0) then
SuppLvl := 2;
if (FV.Release = 9860) and (FV.Build = 0) then
SuppLvl := 2;
end;
case SuppLvl of case SuppLvl of
0: begin 0: begin
Writeln('[-] This version of Terminal Services is not supported.'); Writeln('[-] This version of Terminal Services is not supported.');
UpdateMsg; Writeln('Send your termsrv.dll to project developer for support.');
end; end;
1: begin 1: begin
Writeln('[!] This version of Terminal Services is supported partially.'); Writeln('[!] This version of Terminal Services is supported partially.');
Writeln('It means you may have some limitations such as only 2 concurrent sessions.'); Writeln('It means you may have some limitations such as only 2 concurrent sessions.');
UpdateMsg; Writeln('Send your termsrv.dll to project developer for adding full support.');
end; end;
2: begin 2: begin
Writeln('[+] This version of Terminal Services is fully supported.'); Writeln('[+] This version of Terminal Services is fully supported.');
@ -1028,148 +873,36 @@ end;
procedure TSConfigFirewall(Enable: Boolean); procedure TSConfigFirewall(Enable: Boolean);
begin begin
if Enable then if Enable then
begin ExecWait('netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=tcp localport=3389 profile=any action=allow')
ExecWait('netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=tcp localport=3389 profile=any action=allow'); else
ExecWait('netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=udp localport=3389 profile=any action=allow');
end else
ExecWait('netsh advfirewall firewall delete rule name="Remote Desktop"'); ExecWait('netsh advfirewall firewall delete rule name="Remote Desktop"');
end; end;
function CheckINIDate(Filename, Content: String; var Date: Integer): Boolean;
var
Str: TStringList;
I: Integer;
begin
Result := False;
Str := TStringList.Create;
if Filename <> '' then begin
try
Str.LoadFromFile(Filename);
except
Writeln('[-] Failed to read INI file.');
Exit;
end;
end else
Str.Text := Content;
for I := 0 to Str.Count - 1 do
if Pos('Updated=', Str[I]) = 1 then
Break;
if I >= Str.Count then begin
Writeln('[-] Failed to check INI date.');
Exit;
end;
Content := StringReplace(Str[I], 'Updated=', '', []);
Content := StringReplace(Content, '-', '', [rfReplaceAll]);
Str.Free;
try
Date := StrToInt(Content);
except
Writeln('[-] Wrong INI date format.');
Exit;
end;
Result := True;
end;
procedure CheckUpdate;
var
INIPath, S: String;
Str: TStringList;
I, OldDate, NewDate: Integer;
begin
INIPath := ExtractFilePath(ExpandPath(TermServicePath)) + 'rdpwrap.ini';
if not CheckINIDate(INIPath, '', OldDate) then
Halt(ERROR_ACCESS_DENIED);
Writeln('[*] Current update date: ',
Format('%d.%.2d.%.2d', [OldDate div 10000, OldDate div 100 mod 100, OldDate mod 100]));
if not GitINIFile(S) then begin
Writeln('[-] Failed to download latest INI from GitHub.');
Halt(ERROR_ACCESS_DENIED);
end;
if not CheckINIDate('', S, NewDate) then
Halt(ERROR_ACCESS_DENIED);
Writeln('[*] Latest update date: ',
Format('%d.%.2d.%.2d', [NewDate div 10000, NewDate div 100 mod 100, NewDate mod 100]));
if NewDate = OldDate then
Writeln('[*] Everything is up to date.')
else
if NewDate > OldDate then begin
Writeln('[+] New update is available, updating...');
CheckTermsrvProcess;
Writeln('[*] Terminating service...');
AddPrivilege('SeDebugPrivilege');
KillProcess(TermServicePID);
Sleep(1000);
if Length(ShareSvc) > 0 then
for I := 0 to Length(ShareSvc) - 1 do
SvcStart(ShareSvc[I]);
Sleep(500);
Str := TStringList.Create;
Str.Text := S;
try
Str.SaveToFile(INIPath);
except
Writeln('[-] Failed to write INI file.');
Halt(ERROR_ACCESS_DENIED);
end;
Str.Free;
SvcStart(TermService);
Writeln('[+] Update completed.');
end else
Writeln('[*] Your INI file is newer than public file. Are you a developer? :)');
end;
var var
I: Integer; I: Integer;
begin begin
Writeln('RDP Wrapper Library v1.6.2'); Writeln('RDP Wrapper Library v1.4');
Writeln('Installer v2.6'); Writeln('Installer v2.2');
Writeln('Copyright (C) Stas''M Corp. 2018'); Writeln('Copyright (C) Stas''M Corp. 2014');
Writeln(''); Writeln('');
if (ParamCount < 1) if (ParamCount < 1)
or ( or (
(ParamStr(1) <> '-l') (ParamStr(1) <> '-i')
and (ParamStr(1) <> '-i')
and (ParamStr(1) <> '-w')
and (ParamStr(1) <> '-u') and (ParamStr(1) <> '-u')
and (ParamStr(1) <> '-r') and (ParamStr(1) <> '-r')
) then ) then
begin begin
Writeln('USAGE:'); Writeln('USAGE:');
Writeln('RDPWInst.exe [-l|-i[-s][-o]|-w|-u[-k]|-r]'); Writeln('RDPWInst.exe [-i[-s]|-u|-r]');
Writeln(''); Writeln('');
Writeln('-l display the license agreement');
Writeln('-i install wrapper to Program Files folder (default)'); Writeln('-i install wrapper to Program Files folder (default)');
Writeln('-i -s install wrapper to System32 folder'); Writeln('-i -s install wrapper to System32 folder');
Writeln('-i -o online install mode (loads latest INI file)');
Writeln('-w get latest update for INI file');
Writeln('-u uninstall wrapper'); Writeln('-u uninstall wrapper');
Writeln('-u -k uninstall wrapper and keep settings');
Writeln('-r force restart Terminal Services'); Writeln('-r force restart Terminal Services');
Exit; Exit;
end; end;
if ParamStr(1) = '-l' then
begin
Writeln(ExtractResText('license'));
Exit;
end;
if not CheckWin32Version(6,0) then
begin
Writeln('[-] Unsupported Windows version:');
Writeln(' only >= 6.0 (Vista, Server 2008 and newer) are supported.');
Exit;
end;
if not SupportedArchitecture then if not SupportedArchitecture then
begin begin
Writeln('[-] Unsupported processor architecture.'); Writeln('[-] Unsupported processor architecture.');
@ -1185,13 +918,6 @@ begin
Writeln('[*] RDP Wrapper Library is already installed.'); Writeln('[*] RDP Wrapper Library is already installed.');
Halt(ERROR_INVALID_FUNCTION); Halt(ERROR_INVALID_FUNCTION);
end; end;
Writeln('[*] Notice to user:');
Writeln(' - By using all or any portion of this software, you are agreeing');
Writeln(' to be bound by all the terms and conditions of the license agreement.');
Writeln(' - To read the license agreement, run the installer with -l parameter.');
Writeln(' - If you do not agree to any terms of the license agreement,');
Writeln(' do not use the software.');
Writeln('[*] Installing...'); Writeln('[*] Installing...');
if ParamStr(2) = '-s' then if ParamStr(2) = '-s' then
WrapPath := '%SystemRoot%\system32\rdpwrap.dll' WrapPath := '%SystemRoot%\system32\rdpwrap.dll'
@ -1205,7 +931,6 @@ begin
CheckTermsrvProcess; CheckTermsrvProcess;
Writeln('[*] Extracting files...'); Writeln('[*] Extracting files...');
Online := (ParamStr(2) = '-o') or (ParamStr(3) = '-o');
ExtractFiles; ExtractFiles;
Writeln('[*] Configuring service library...'); Writeln('[*] Configuring service library...');
@ -1268,31 +993,16 @@ begin
SvcStart(TermService); SvcStart(TermService);
Sleep(500); Sleep(500);
if ParamStr(2) <> '-k' then
begin
Writeln('[*] Configuring registry...'); Writeln('[*] Configuring registry...');
TSConfigRegistry(False); TSConfigRegistry(False);
Writeln('[*] Configuring firewall...'); Writeln('[*] Configuring firewall...');
TSConfigFirewall(False); TSConfigFirewall(False);
end;
if Arch = 64 then if Arch = 64 then
RevertWowRedirection; RevertWowRedirection;
Writeln('[+] Successfully uninstalled.'); Writeln('[+] Successfully uninstalled.');
end; end;
if ParamStr(1) = '-w' then
begin
if not Installed then
begin
Writeln('[*] RDP Wrapper Library is not installed.');
Halt(ERROR_INVALID_FUNCTION);
end;
Writeln('[*] Checking for updates...');
CheckUpdate;
end;
if ParamStr(1) = '-r' then if ParamStr(1) = '-r' then
begin begin
Writeln('[*] Restarting...'); Writeln('[*] Restarting...');

View File

@ -20,9 +20,8 @@
<Base>true</Base> <Base>true</Base>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''"> <PropertyGroup Condition="'$(Base)'!=''">
<DCC_ExeOutput>..\bin\</DCC_ExeOutput>
<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias> <DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>
<DCC_DependencyCheckOutputName>..\bin\RDPWInst.exe</DCC_DependencyCheckOutputName> <DCC_DependencyCheckOutputName>RDPWInst.exe</DCC_DependencyCheckOutputName>
<DCC_ImageBase>00400000</DCC_ImageBase> <DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_Platform>x86</DCC_Platform> <DCC_Platform>x86</DCC_Platform>
</PropertyGroup> </PropertyGroup>
@ -42,14 +41,14 @@
<BuildConfiguration Include="Base"> <BuildConfiguration Include="Base">
<Key>Base</Key> <Key>Base</Key>
</BuildConfiguration> </BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>
</BuildConfiguration> </BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup> </ItemGroup>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<ProjectExtensions> <ProjectExtensions>
@ -61,7 +60,7 @@
<Parameters Name="UseLauncher">False</Parameters> <Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters> <Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters> <Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
<Parameters Name="RunParams">-w</Parameters> <Parameters Name="RunParams">-i</Parameters>
</Parameters> </Parameters>
<VersionInfo> <VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo> <VersionInfo Name="IncludeVerInfo">False</VersionInfo>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject>
<Transactions>
<Transaction>2013.12.07 17:17:05.152.dproj,C:\Users\user\Documents\RAD Studio\Projects\Project1.dproj=C:\Users\user\Documents\Delphi Projects (local)\RDPWrapInst\RDPInstall.dproj</Transaction>
<Transaction>2013.12.07 19:48:57.905.dproj,C:\Users\user\Documents\Delphi Projects (local)\RDPWrapInst\RDPInstall.dproj=C:\Users\user\Documents\Delphi Projects (local)\RDPWrapInst\RDPWInst.dproj</Transaction>
<Transaction>2013.12.08 01:45:08.501.dproj,C:\Users\user\Documents\Delphi Projects (local)\RDPWrapInst\RDPWInst.dproj=C:\Users\user\Documents\Delphi Projects (local)\RDPWrap\devel\installer2.0-binarymaster\RDPWInst.dproj</Transaction>
</Transactions>
</BorlandProject>

Binary file not shown.

View File

@ -0,0 +1,4 @@
rdpclip64 RCData "..\\rdpclip-x64.exe"
rdpclip32 RCData "..\\rdpclip-x86.exe"
rdpw32 RCData "..\\v1.2-x86-binarymaster\\rdpwrap.dll"
rdpw64 RCData "..\\v1.2-x86-x64-Fusix\\rdpw64.dll"

Binary file not shown.

BIN
src-rdpcheck/MainUnit.dcu Normal file

Binary file not shown.

View File

@ -1,19 +1,3 @@
{
Copyright 2015 Stas'M Corp.
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.
}
unit MainUnit; unit MainUnit;
interface interface
@ -44,12 +28,13 @@ implementation
procedure TFrm.FormCreate(Sender: TObject); procedure TFrm.FormCreate(Sender: TObject);
var var
Reg: TRegistry; Reg: TRegistry;
Port: Integer;
begin begin
RDP.DisconnectedText := 'Disconnected.'; RDP.DisconnectedText := 'Disconnected.';
RDP.ConnectingText := 'Connecting...'; RDP.ConnectingText := 'Connecting...';
RDP.ConnectedStatusText := 'Connected.'; RDP.ConnectedStatusText := 'Connected.';
RDP.UserName := ''; RDP.UserName := '';
RDP.Server := '127.0.0.2'; RDP.Server := '127.0.0.1';
Reg := TRegistry.Create; Reg := TRegistry.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.RootKey := HKEY_LOCAL_MACHINE;
@ -131,8 +116,8 @@ begin
$1707: ErrStr := 'Delegation of credentials to the target server is not allowed unless mutual authentication has been achieved.'; $1707: ErrStr := 'Delegation of credentials to the target server is not allowed unless mutual authentication has been achieved.';
$2207: ErrStr := 'The smart card is blocked.'; $2207: ErrStr := 'The smart card is blocked.';
$1C07: ErrStr := 'An incorrect PIN was presented to the smart card.'; $1C07: ErrStr := 'An incorrect PIN was presented to the smart card.';
$B09: ErrStr := 'Network Level Authentication is required, run RDPCheck as administrator.'; $B09: ErrStr := 'Network Level Authentication is required.';
$708: ErrStr := 'RDP is working, but the client doesn''t allow loopback connections. Try to connect to your PC from another device in the network.'; $708: ErrStr := 'The RDP seems to work, but your client doesn''t support loopback connections. Try to connect to your PC from another device in the network.';
else ErrStr := 'Unknown code 0x'+IntToHex(discReason, 1); else ErrStr := 'Unknown code 0x'+IntToHex(discReason, 1);
end; end;
if (discReason > 2) then if (discReason > 2) then

View File

@ -1,19 +1,3 @@
{
Copyright 2014 Stas'M Corp.
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.
}
program RDPCheck; program RDPCheck;
uses uses

View File

@ -20,9 +20,8 @@
<Base>true</Base> <Base>true</Base>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''"> <PropertyGroup Condition="'$(Base)'!=''">
<DCC_ExeOutput>..\bin\</DCC_ExeOutput>
<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias> <DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>
<DCC_DependencyCheckOutputName>..\bin\RDPCheck.exe</DCC_DependencyCheckOutputName> <DCC_DependencyCheckOutputName>RDPCheck.exe</DCC_DependencyCheckOutputName>
<DCC_ImageBase>00400000</DCC_ImageBase> <DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_Platform>x86</DCC_Platform> <DCC_Platform>x86</DCC_Platform>
</PropertyGroup> </PropertyGroup>
@ -45,14 +44,14 @@
<BuildConfiguration Include="Base"> <BuildConfiguration Include="Base">
<Key>Base</Key> <Key>Base</Key>
</BuildConfiguration> </BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>
</BuildConfiguration> </BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup> </ItemGroup>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<ProjectExtensions> <ProjectExtensions>
@ -69,7 +68,7 @@
<VersionInfo Name="IncludeVerInfo">True</VersionInfo> <VersionInfo Name="IncludeVerInfo">True</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo> <VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">2</VersionInfo> <VersionInfo Name="MajorVer">2</VersionInfo>
<VersionInfo Name="MinorVer">2</VersionInfo> <VersionInfo Name="MinorVer">1</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo> <VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo> <VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo> <VersionInfo Name="Debug">False</VersionInfo>
@ -83,13 +82,13 @@
<VersionInfoKeys> <VersionInfoKeys>
<VersionInfoKeys Name="CompanyName">Stas&apos;M Corp.</VersionInfoKeys> <VersionInfoKeys Name="CompanyName">Stas&apos;M Corp.</VersionInfoKeys>
<VersionInfoKeys Name="FileDescription">Local RDP Checker</VersionInfoKeys> <VersionInfoKeys Name="FileDescription">Local RDP Checker</VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">2.2.0.0</VersionInfoKeys> <VersionInfoKeys Name="FileVersion">2.1.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName">RDPCheck</VersionInfoKeys> <VersionInfoKeys Name="InternalName">RDPCheck</VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright">Copyright © Stas&apos;M Corp. 2015</VersionInfoKeys> <VersionInfoKeys Name="LegalCopyright">Copyright © Stas&apos;M Corp. 2014</VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks">Stas&apos;M Corp.</VersionInfoKeys> <VersionInfoKeys Name="LegalTrademarks">Stas&apos;M Corp.</VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename">RDPCheck.exe</VersionInfoKeys> <VersionInfoKeys Name="OriginalFilename">RDPCheck.exe</VersionInfoKeys>
<VersionInfoKeys Name="ProductName">RDP Host Support</VersionInfoKeys> <VersionInfoKeys Name="ProductName">RDP Host Support</VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.6.0.0</VersionInfoKeys> <VersionInfoKeys Name="ProductVersion">1.3.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments">http://stascorp.com</VersionInfoKeys> <VersionInfoKeys Name="Comments">http://stascorp.com</VersionInfoKeys>
</VersionInfoKeys> </VersionInfoKeys>
<Excluded_Packages> <Excluded_Packages>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject>
<Transactions>
<Transaction>2013.12.08 02:49:59.064.pas,C:\Users\user\Documents\RAD Studio\Projects\Unit2.pas=C:\Users\user\Documents\Delphi Projects (local)\RDPWrap\devel\rdpcheck-binarymaster\MainUnit.pas</Transaction>
<Transaction>2013.12.08 02:49:59.064.dfm,C:\Users\user\Documents\RAD Studio\Projects\Unit2.dfm=C:\Users\user\Documents\Delphi Projects (local)\RDPWrap\devel\rdpcheck-binarymaster\MainUnit.dfm</Transaction>
<Transaction>2013.12.08 02:50:08.464.dproj,C:\Users\user\Documents\RAD Studio\Projects\Project1.dproj=C:\Users\user\Documents\Delphi Projects (local)\RDPWrap\devel\rdpcheck-binarymaster\RDPCheck.dproj</Transaction>
</Transactions>
</BorlandProject>

Binary file not shown.

Binary file not shown.

View File

@ -1,47 +0,0 @@
object LicenseForm: TLicenseForm
Left = 0
Top = 0
BorderIcons = []
BorderStyle = bsDialog
Caption = 'License Agreement'
ClientHeight = 344
ClientWidth = 386
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poOwnerFormCenter
PixelsPerInch = 96
TextHeight = 13
object mText: TMemo
Left = 8
Top = 8
Width = 370
Height = 297
ReadOnly = True
ScrollBars = ssBoth
TabOrder = 0
WordWrap = False
end
object bAccept: TButton
Left = 115
Top = 311
Width = 75
Height = 25
Caption = '&Accept'
ModalResult = 1
TabOrder = 1
end
object bDecline: TButton
Left = 196
Top = 311
Width = 75
Height = 25
Caption = '&Decline'
ModalResult = 2
TabOrder = 2
end
end

View File

@ -1,43 +0,0 @@
{
Copyright 2014 Stas'M Corp.
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.
}
unit LicenseUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TLicenseForm = class(TForm)
mText: TMemo;
bAccept: TButton;
bDecline: TButton;
private
{ Private declarations }
public
{ Public declarations }
end;
var
LicenseForm: TLicenseForm;
implementation
{$R *.dfm}
end.

BIN
src-rdpconfig/MainUnit.dcu Normal file

Binary file not shown.

View File

@ -2,9 +2,9 @@ object MainForm: TMainForm
Left = 0 Left = 0
Top = 0 Top = 0
BorderStyle = bsDialog BorderStyle = bsDialog
Caption = 'RDP Wrapper Configuration' Caption = 'Remote Desktop Protocol Configuration'
ClientHeight = 314 ClientHeight = 245
ClientWidth = 404 ClientWidth = 326
Color = clBtnFace Color = clBtnFace
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText Font.Color = clWindowText
@ -15,227 +15,98 @@ object MainForm: TMainForm
Position = poDesktopCenter Position = poDesktopCenter
OnCloseQuery = FormCloseQuery OnCloseQuery = FormCloseQuery
OnCreate = FormCreate OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96 PixelsPerInch = 96
TextHeight = 13 TextHeight = 13
object lRDPPort: TLabel
Left = 203
Top = 22
Width = 47
Height = 13
Caption = 'RDP Port:'
end
object bOK: TButton object bOK: TButton
Left = 40 Left = 45
Top = 281 Top = 212
Width = 75 Width = 75
Height = 25 Height = 25
Caption = 'OK' Caption = 'OK'
ModalResult = 1 ModalResult = 1
TabOrder = 4 TabOrder = 0
OnClick = bOKClick OnClick = bOKClick
end end
object bCancel: TButton object bCancel: TButton
Left = 121 Left = 126
Top = 281 Top = 212
Width = 75 Width = 75
Height = 25 Height = 25
Caption = 'Cancel' Caption = 'Cancel'
ModalResult = 2 ModalResult = 2
TabOrder = 5 TabOrder = 1
OnClick = bCancelClick OnClick = bCancelClick
end end
object bApply: TButton object bApply: TButton
Left = 202 Left = 207
Top = 281 Top = 212
Width = 75 Width = 75
Height = 25 Height = 25
Caption = 'Apply' Caption = 'Apply'
Enabled = False Enabled = False
TabOrder = 6
OnClick = bApplyClick
end
object rgNLA: TRadioGroup
Left = 202
Top = 89
Width = 194
Height = 73
Caption = 'Authentication Mode'
Items.Strings = (
'GUI Authentication Only'
'Default RDP Authentication'
'Network Level Authentication')
TabOrder = 2 TabOrder = 2
OnClick = cbAllowTSConnectionsClick OnClick = bApplyClick
end
object rgShadow: TRadioGroup
Left = 202
Top = 168
Width = 194
Height = 105
Caption = 'Session Shadowing Mode'
Items.Strings = (
'Disable Shadowing'
'Full access with user'#39's permission'
'Full access without permission'
'View only with user'#39's permission'
'View only without permission')
TabOrder = 3
OnClick = cbAllowTSConnectionsClick
end
object bLicense: TButton
Left = 283
Top = 281
Width = 87
Height = 25
Caption = 'View license...'
TabOrder = 7
OnClick = bLicenseClick
end
object gbDiag: TGroupBox
Left = 8
Top = 6
Width = 388
Height = 77
Caption = 'Diagnostics'
TabOrder = 0
object lListener: TLabel
Left = 11
Top = 55
Width = 70
Height = 13
Caption = 'Listener state:'
end
object lService: TLabel
Left = 11
Top = 36
Width = 67
Height = 13
Caption = 'Service state:'
end
object lsListener: TLabel
Left = 91
Top = 55
Width = 44
Height = 13
Caption = 'Unknown'
end
object lsService: TLabel
Left = 91
Top = 36
Width = 44
Height = 13
Caption = 'Unknown'
end
object lsTSVer: TLabel
Left = 226
Top = 36
Width = 44
Height = 13
Caption = 'Unknown'
end
object lsWrapper: TLabel
Left = 91
Top = 17
Width = 44
Height = 13
Caption = 'Unknown'
end
object lsWrapVer: TLabel
Left = 226
Top = 17
Width = 44
Height = 13
Caption = 'Unknown'
end
object lTSVer: TLabel
Left = 202
Top = 36
Width = 20
Height = 13
Caption = 'ver.'
end
object lWrapper: TLabel
Left = 11
Top = 17
Width = 74
Height = 13
Caption = 'Wrapper state:'
end
object lWrapVer: TLabel
Left = 202
Top = 17
Width = 20
Height = 13
Caption = 'ver.'
end
object lsSuppVer: TLabel
Left = 202
Top = 55
Width = 70
Height = 13
Caption = '[support level]'
end
end
object gbGeneral: TGroupBox
Left = 8
Top = 89
Width = 188
Height = 184
Caption = 'General Settings'
TabOrder = 1
object lRDPPort: TLabel
Left = 8
Top = 44
Width = 47
Height = 13
Caption = 'RDP port:'
end
object cbAllowTSConnections: TCheckBox
Left = 8
Top = 18
Width = 132
Height = 17
Caption = 'Enable Remote Desktop'
TabOrder = 0
OnClick = cbAllowTSConnectionsClick
end end
object cbSingleSessionPerUser: TCheckBox object cbSingleSessionPerUser: TCheckBox
Left = 8 Left = 8
Top = 69 Top = 31
Width = 129 Width = 130
Height = 17 Height = 17
Caption = 'Single session per user' Caption = 'Single Session Per User'
TabOrder = 2
OnClick = cbAllowTSConnectionsClick
end
object cbHideUsers: TCheckBox
Left = 8
Top = 92
Width = 149
Height = 17
Caption = 'Hide users on logon screen'
TabOrder = 3 TabOrder = 3
OnClick = cbAllowTSConnectionsClick OnClick = cbAllowTSConnectionsClick
end end
object rgNLA: TRadioGroup
Left = 8
Top = 54
Width = 310
Height = 73
Caption = 'Security Mode'
Items.Strings = (
'Disable Security (not recommended)'
'Default Authentication (compatibility with older clients)'
'Network Level Authentication (best)')
TabOrder = 4
OnClick = cbAllowTSConnectionsClick
end
object cbAllowTSConnections: TCheckBox
Left = 8
Top = 8
Width = 174
Height = 17
Caption = 'Enable Remote Desktop Protocol'
TabOrder = 5
OnClick = cbAllowTSConnectionsClick
end
object rgShadow: TRadioGroup
Left = 8
Top = 133
Width = 310
Height = 73
Caption = 'Session Shadowing Mode'
Items.Strings = (
'Disable Shadowing'
'Shadowing will request user permission'
'Shadowing sessions immediately')
TabOrder = 6
OnClick = cbAllowTSConnectionsClick
end
object seRDPPort: TSpinEdit object seRDPPort: TSpinEdit
Left = 61 Left = 256
Top = 41 Top = 19
Width = 62 Width = 62
Height = 22 Height = 22
MaxValue = 65535 MaxValue = 65535
MinValue = 0 MinValue = 0
TabOrder = 1 TabOrder = 7
Value = 0 Value = 0
OnChange = seRDPPortChange OnChange = seRDPPortChange
end end
object cbCustomPrg: TCheckBox
Left = 8
Top = 115
Width = 169
Height = 17
Caption = 'Allow to start custom programs'
TabOrder = 4
OnClick = cbAllowTSConnectionsClick
end
end
object Timer: TTimer
Interval = 250
OnTimer = TimerTimer
Left = 352
Top = 27
end
end end

View File

@ -1,26 +1,10 @@
{
Copyright 2017 Stas'M Corp.
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.
}
unit MainUnit; unit MainUnit;
interface interface
uses uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin, ExtCtrls, Registry, WinSvc; Dialogs, StdCtrls, Spin, ExtCtrls, Registry;
type type
TMainForm = class(TForm) TMainForm = class(TForm)
@ -33,23 +17,6 @@ type
rgShadow: TRadioGroup; rgShadow: TRadioGroup;
seRDPPort: TSpinEdit; seRDPPort: TSpinEdit;
lRDPPort: TLabel; lRDPPort: TLabel;
lService: TLabel;
lListener: TLabel;
lWrapper: TLabel;
lsListener: TLabel;
lsService: TLabel;
lsWrapper: TLabel;
Timer: TTimer;
lTSVer: TLabel;
lsTSVer: TLabel;
lWrapVer: TLabel;
lsWrapVer: TLabel;
bLicense: TButton;
gbDiag: TGroupBox;
lsSuppVer: TLabel;
cbHideUsers: TCheckBox;
gbGeneral: TGroupBox;
cbCustomPrg: TCheckBox;
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure cbAllowTSConnectionsClick(Sender: TObject); procedure cbAllowTSConnectionsClick(Sender: TObject);
procedure seRDPPortChange(Sender: TObject); procedure seRDPPortChange(Sender: TObject);
@ -57,305 +24,22 @@ type
procedure bCancelClick(Sender: TObject); procedure bCancelClick(Sender: TObject);
procedure bOKClick(Sender: TObject); procedure bOKClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure bLicenseClick(Sender: TObject);
procedure TimerTimer(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private private
{ Private declarations } { Private declarations }
public public
{ Public declarations } { Public declarations }
function ExecWait(Cmdline: String): Boolean;
procedure ReadSettings; procedure ReadSettings;
procedure WriteSettings; procedure WriteSettings;
end; end;
FILE_VERSION = record
Version: record case Boolean of
True: (dw: DWORD);
False: (w: record
Minor, Major: Word;
end;)
end;
Release, Build: Word;
bDebug, bPrerelease, bPrivate, bSpecial: Boolean;
end;
WTS_SESSION_INFOW = record
SessionId: DWORD;
Name: packed array [0..33] of WideChar;
State: DWORD;
end;
WTS_SESSION = Array[0..0] of WTS_SESSION_INFOW;
PWTS_SESSION_INFOW = ^WTS_SESSION;
const
winstadll = 'winsta.dll';
var var
MainForm: TMainForm; MainForm: TMainForm;
Ready: Boolean = False; Ready: Boolean = False;
Arch: Byte;
OldWow64RedirectionValue: LongBool;
OldPort: Word;
INI: String;
function WinStationEnumerateW(hServer: THandle;
var ppSessionInfo: PWTS_SESSION_INFOW; var pCount: DWORD): BOOL; stdcall;
external winstadll name 'WinStationEnumerateW';
function WinStationFreeMemory(P: Pointer): BOOL; stdcall; external winstadll;
implementation implementation
{$R *.dfm} {$R *.dfm}
{$R resource.res} {$R manifest.res}
uses
LicenseUnit;
function ExpandPath(Path: String): String;
var
Str: Array[0..511] of Char;
begin
Result := '';
FillChar(Str, 512, 0);
if Arch = 64 then
Path := StringReplace(Path, '%ProgramFiles%', '%ProgramW6432%', [rfReplaceAll, rfIgnoreCase]);
if ExpandEnvironmentStrings(PWideChar(Path), Str, 512) > 0 then
Result := Str;
end;
function DisableWowRedirection: Boolean;
type
TFunc = function(var Wow64FsEnableRedirection: LongBool): LongBool; stdcall;
var
hModule: THandle;
Wow64DisableWow64FsRedirection: TFunc;
begin
Result := False;
hModule := GetModuleHandle(kernel32);
if hModule <> 0 then
Wow64DisableWow64FsRedirection := GetProcAddress(hModule, 'Wow64DisableWow64FsRedirection')
else
Exit;
if @Wow64DisableWow64FsRedirection <> nil then
Result := Wow64DisableWow64FsRedirection(OldWow64RedirectionValue);
end;
function RevertWowRedirection: Boolean;
type
TFunc = function(var Wow64RevertWow64FsRedirection: LongBool): LongBool; stdcall;
var
hModule: THandle;
Wow64RevertWow64FsRedirection: TFunc;
begin
Result := False;
hModule := GetModuleHandle(kernel32);
if hModule <> 0 then
Wow64RevertWow64FsRedirection := GetProcAddress(hModule, 'Wow64RevertWow64FsRedirection')
else
Exit;
if @Wow64RevertWow64FsRedirection <> nil then
Result := Wow64RevertWow64FsRedirection(OldWow64RedirectionValue);
end;
function GetFileVersion(const FileName: TFileName; var FileVersion: FILE_VERSION): Boolean;
type
VS_VERSIONINFO = record
wLength, wValueLength, wType: Word;
szKey: Array[1..16] of WideChar;
Padding1: Word;
Value: VS_FIXEDFILEINFO;
Padding2, Children: Word;
end;
PVS_VERSIONINFO = ^VS_VERSIONINFO;
const
VFF_DEBUG = 1;
VFF_PRERELEASE = 2;
VFF_PRIVATE = 8;
VFF_SPECIAL = 32;
var
hFile: HMODULE;
hResourceInfo: HRSRC;
VersionInfo: PVS_VERSIONINFO;
begin
Result := False;
hFile := LoadLibraryEx(PWideChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE);
if hFile = 0 then
Exit;
hResourceInfo := FindResource(hFile, PWideChar(1), PWideChar($10));
if hResourceInfo = 0 then
Exit;
VersionInfo := Pointer(LoadResource(hFile, hResourceInfo));
if VersionInfo = nil then
Exit;
FileVersion.Version.dw := VersionInfo.Value.dwFileVersionMS;
FileVersion.Release := Word(VersionInfo.Value.dwFileVersionLS shr 16);
FileVersion.Build := Word(VersionInfo.Value.dwFileVersionLS);
FileVersion.bDebug := (VersionInfo.Value.dwFileFlags and VFF_DEBUG) = VFF_DEBUG;
FileVersion.bPrerelease := (VersionInfo.Value.dwFileFlags and VFF_PRERELEASE) = VFF_PRERELEASE;
FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE;
FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL;
FreeLibrary(hFile);
Result := True;
end;
function IsWrapperInstalled(var WrapperPath: String): ShortInt;
var
TermServiceHost,
TermServicePath: String;
Reg: TRegistry;
begin
Result := -1;
WrapperPath := '';
Reg := TRegistry.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE;
if not Reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\TermService') then begin
Reg.Free;
Exit;
end;
TermServiceHost := Reg.ReadString('ImagePath');
Reg.CloseKey;
if Pos('svchost.exe', LowerCase(TermServiceHost)) = 0 then
begin
Result := 2;
Reg.Free;
Exit;
end;
if not Reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\TermService\Parameters') then
begin
Reg.Free;
Exit;
end;
TermServicePath := Reg.ReadString('ServiceDll');
Reg.CloseKey;
Reg.Free;
if (Pos('termsrv.dll', LowerCase(TermServicePath)) = 0)
and (Pos('rdpwrap.dll', LowerCase(TermServicePath)) = 0) then
begin
Result := 2;
Exit;
end;
if Pos('rdpwrap.dll', LowerCase(TermServicePath)) > 0 then begin
WrapperPath := TermServicePath;
Result := 1;
end else
Result := 0;
end;
function GetTermSrvState: ShortInt;
type
SERVICE_STATUS_PROCESS = record
dwServiceType,
dwCurrentState,
dwControlsAccepted,
dwWin32ExitCode,
dwServiceSpecificExitCode,
dwCheckPoint,
dwWaitHint,
dwProcessId,
dwServiceFlags: DWORD;
end;
PSERVICE_STATUS_PROCESS = ^SERVICE_STATUS_PROCESS;
const
SvcName = 'TermService';
var
hSC: SC_HANDLE;
hSvc: THandle;
lpServiceStatusProcess: PSERVICE_STATUS_PROCESS;
Buf: Pointer;
cbBufSize, pcbBytesNeeded: Cardinal;
begin
Result := -1;
hSC := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
if hSC = 0 then
Exit;
hSvc := OpenService(hSC, PWideChar(SvcName), SERVICE_QUERY_STATUS);
if hSvc = 0 then
begin
CloseServiceHandle(hSC);
Exit;
end;
if QueryServiceStatusEx(hSvc, SC_STATUS_PROCESS_INFO, nil, 0, pcbBytesNeeded) then
Exit;
cbBufSize := pcbBytesNeeded;
GetMem(Buf, cbBufSize);
if not QueryServiceStatusEx(hSvc, SC_STATUS_PROCESS_INFO, Buf, cbBufSize, pcbBytesNeeded) then begin
FreeMem(Buf, cbBufSize);
CloseServiceHandle(hSvc);
CloseServiceHandle(hSC);
Exit;
end else begin
lpServiceStatusProcess := Buf;
Result := ShortInt(lpServiceStatusProcess^.dwCurrentState);
end;
FreeMem(Buf, cbBufSize);
CloseServiceHandle(hSvc);
CloseServiceHandle(hSC);
end;
function IsListenerWorking: Boolean;
var
pCount: DWORD;
SessionInfo: PWTS_SESSION_INFOW;
I: Integer;
begin
Result := False;
if not WinStationEnumerateW(0, SessionInfo, pCount) then
Exit;
for I := 0 to pCount - 1 do
if SessionInfo^[I].Name = 'RDP-Tcp' then begin
Result := True;
Break;
end;
WinStationFreeMemory(SessionInfo);
end;
function ExtractResText(ResName: String): String;
var
ResStream: TResourceStream;
Str: TStringList;
begin
ResStream := TResourceStream.Create(HInstance, ResName, RT_RCDATA);
Str := TStringList.Create;
try
Str.LoadFromStream(ResStream);
except
end;
ResStream.Free;
Result := Str.Text;
Str.Free;
end;
function TMainForm.ExecWait(Cmdline: String): Boolean;
var
si: STARTUPINFO;
pi: PROCESS_INFORMATION;
begin
Result := False;
ZeroMemory(@si, sizeof(si));
si.cb := sizeof(si);
si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow := SW_HIDE;
UniqueString(Cmdline);
if not CreateProcess(nil, PWideChar(Cmdline), nil, nil, True, 0, nil, nil, si, pi) then begin
MessageBox(Handle,
PWideChar('CreateProcess error (code: ' + IntToStr(GetLastError) + ').'),
'Error', MB_ICONERROR or MB_OK);
Exit;
end;
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
Result := True;
end;
procedure TMainForm.ReadSettings; procedure TMainForm.ReadSettings;
var var
@ -374,11 +58,6 @@ begin
cbSingleSessionPerUser.Checked := Reg.ReadBool('fSingleSessionPerUser'); cbSingleSessionPerUser.Checked := Reg.ReadBool('fSingleSessionPerUser');
except except
end;
try
cbCustomPrg.Checked := Reg.ReadBool('HonorLegacySettings');
except
end; end;
Reg.CloseKey; Reg.CloseKey;
@ -389,7 +68,6 @@ begin
except except
end; end;
OldPort := seRDPPort.Value;
SecurityLayer := 0; SecurityLayer := 0;
UserAuthentication := 0; UserAuthentication := 0;
try try
@ -408,13 +86,6 @@ begin
rgShadow.ItemIndex := Reg.ReadInteger('Shadow'); rgShadow.ItemIndex := Reg.ReadInteger('Shadow');
except except
end;
Reg.CloseKey;
Reg.OpenKeyReadOnly('\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System');
try
cbHideUsers.Checked := Reg.ReadBool('dontdisplaylastusername');
except
end; end;
Reg.CloseKey; Reg.CloseKey;
Reg.Free; Reg.Free;
@ -437,11 +108,6 @@ begin
Reg.WriteBool('fSingleSessionPerUser', cbSingleSessionPerUser.Checked); Reg.WriteBool('fSingleSessionPerUser', cbSingleSessionPerUser.Checked);
except except
end;
try
Reg.WriteBool('HonorLegacySettings', cbCustomPrg.Checked);
except
end; end;
Reg.CloseKey; Reg.CloseKey;
@ -450,11 +116,6 @@ begin
Reg.WriteInteger('PortNumber', seRDPPort.Value); Reg.WriteInteger('PortNumber', seRDPPort.Value);
except except
end;
if OldPort <> seRDPPort.Value then
begin
OldPort := seRDPPort.Value;
ExecWait('netsh advfirewall firewall set rule name="Remote Desktop" new localport=' + IntToStr(OldPort));
end; end;
case rgNLA.ItemIndex of case rgNLA.ItemIndex of
0: begin 0: begin
@ -488,175 +149,11 @@ begin
except except
end; end;
end;
Reg.CloseKey;
Reg.OpenKey('\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services', True);
if rgShadow.ItemIndex >= 0 then begin
try
Reg.WriteInteger('Shadow', rgShadow.ItemIndex);
except
end;
end;
Reg.CloseKey;
Reg.OpenKey('\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System', True);
try
Reg.WriteBool('dontdisplaylastusername', cbHideUsers.Checked);
except
end; end;
Reg.CloseKey; Reg.CloseKey;
Reg.Free; Reg.Free;
end; end;
function CheckSupport(FV: FILE_VERSION): Byte;
var
VerTxt: String;
begin
Result := 0;
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 0) then
Result := 1;
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then
Result := 1;
VerTxt := Format('%d.%d.%d.%d',
[FV.Version.w.Major, FV.Version.w.Minor, FV.Release, FV.Build]);
if Pos('[' + VerTxt + ']', INI) > 0 then
Result := 2;
end;
procedure TMainForm.TimerTimer(Sender: TObject);
var
WrapperPath, INIPath: String;
FV: FILE_VERSION;
L: TStringList;
CheckSupp: Boolean;
begin
CheckSupp := False;
case IsWrapperInstalled(WrapperPath) of
-1: begin
lsWrapper.Caption := 'Unknown';
lsWrapper.Font.Color := clGrayText;
end;
0: begin
lsWrapper.Caption := 'Not installed';
lsWrapper.Font.Color := clGrayText;
end;
1: begin
lsWrapper.Caption := 'Installed';
lsWrapper.Font.Color := clGreen;
CheckSupp := True;
INIPath := ExtractFilePath(ExpandPath(WrapperPath)) + 'rdpwrap.ini';
if not FileExists(INIPath) then
CheckSupp := False;
end;
2: begin
lsWrapper.Caption := '3rd-party';
lsWrapper.Font.Color := clRed;
end;
end;
case GetTermSrvState of
-1, 0: begin
lsService.Caption := 'Unknown';
lsService.Font.Color := clGrayText;
end;
SERVICE_STOPPED: begin
lsService.Caption := 'Stopped';
lsService.Font.Color := clRed;
end;
SERVICE_START_PENDING: begin
lsService.Caption := 'Starting...';
lsService.Font.Color := clGrayText;
end;
SERVICE_STOP_PENDING: begin
lsService.Caption := 'Stopping...';
lsService.Font.Color := clGrayText;
end;
SERVICE_RUNNING: begin
lsService.Caption := 'Running';
lsService.Font.Color := clGreen;
end;
SERVICE_CONTINUE_PENDING: begin
lsService.Caption := 'Resuming...';
lsService.Font.Color := clGrayText;
end;
SERVICE_PAUSE_PENDING: begin
lsService.Caption := 'Suspending...';
lsService.Font.Color := clGrayText;
end;
SERVICE_PAUSED: begin
lsService.Caption := 'Suspended';
lsService.Font.Color := clWindowText;
end;
end;
if IsListenerWorking then begin
lsListener.Caption := 'Listening';
lsListener.Font.Color := clGreen;
end else begin
lsListener.Caption := 'Not listening';
lsListener.Font.Color := clRed;
end;
if WrapperPath = '' then begin
lsWrapVer.Caption := 'N/A';
lsWrapVer.Font.Color := clGrayText;
end else
if not GetFileVersion(ExpandPath(WrapperPath), FV) then begin
lsWrapVer.Caption := 'N/A';
lsWrapVer.Font.Color := clGrayText;
end else begin
lsWrapVer.Caption :=
IntToStr(FV.Version.w.Major)+'.'+
IntToStr(FV.Version.w.Minor)+'.'+
IntToStr(FV.Release)+'.'+
IntToStr(FV.Build);
lsWrapVer.Font.Color := clWindowText;
end;
if not GetFileVersion('termsrv.dll', FV) then begin
lsTSVer.Caption := 'N/A';
lsTSVer.Font.Color := clGrayText;
end else begin
lsTSVer.Caption :=
IntToStr(FV.Version.w.Major)+'.'+
IntToStr(FV.Version.w.Minor)+'.'+
IntToStr(FV.Release)+'.'+
IntToStr(FV.Build);
lsTSVer.Font.Color := clWindowText;
lsSuppVer.Visible := CheckSupp;
if CheckSupp then begin
if INI = '' then begin
L := TStringList.Create;
try
L.LoadFromFile(INIPath);
except
end;
INI := L.Text;
L.Free;
end;
case CheckSupport(FV) of
0: begin
lsSuppVer.Caption := '[not supported]';
lsSuppVer.Font.Color := clRed;
end;
1: begin
lsSuppVer.Caption := '[supported partially]';
lsSuppVer.Font.Color := clOlive;
end;
2: begin
lsSuppVer.Caption := '[fully supported]';
lsSuppVer.Font.Color := clGreen;
end;
end;
end;
end;
end;
procedure TMainForm.bLicenseClick(Sender: TObject);
begin
LicenseForm.mText.Text := ExtractResText('LICENSE');
if LicenseForm.ShowModal <> mrOk then
Halt(0);
end;
procedure TMainForm.cbAllowTSConnectionsClick(Sender: TObject); procedure TMainForm.cbAllowTSConnectionsClick(Sender: TObject);
begin begin
if Ready then if Ready then
@ -670,28 +167,11 @@ begin
end; end;
procedure TMainForm.FormCreate(Sender: TObject); procedure TMainForm.FormCreate(Sender: TObject);
var
SI: TSystemInfo;
begin begin
GetNativeSystemInfo(SI);
case SI.wProcessorArchitecture of
0: Arch := 32;
6: Arch := 64; // Itanium-based x64
9: Arch := 64; // Intel/AMD x64
else Arch := 0;
end;
if Arch = 64 then
DisableWowRedirection;
ReadSettings; ReadSettings;
Ready := True; Ready := True;
end; end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
if Arch = 64 then
RevertWowRedirection;
end;
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin begin
if bApply.Enabled then if bApply.Enabled then

View File

@ -1,25 +1,8 @@
{
Copyright 2014 Stas'M Corp.
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.
}
program RDPConf; program RDPConf;
uses uses
Forms, Forms,
MainUnit in 'MainUnit.pas' {MainForm}, MainUnit in 'MainUnit.pas' {MainForm};
LicenseUnit in 'LicenseUnit.pas' {LicenseForm};
{$R *.res} {$R *.res}
@ -28,6 +11,5 @@ begin
Application.MainFormOnTaskbar := True; Application.MainFormOnTaskbar := True;
Application.Title := 'Remote Desktop Protocol Configuration'; Application.Title := 'Remote Desktop Protocol Configuration';
Application.CreateForm(TMainForm, MainForm); Application.CreateForm(TMainForm, MainForm);
Application.CreateForm(TLicenseForm, LicenseForm);
Application.Run; Application.Run;
end. end.

View File

@ -20,9 +20,8 @@
<Base>true</Base> <Base>true</Base>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''"> <PropertyGroup Condition="'$(Base)'!=''">
<DCC_ExeOutput>..\bin\</DCC_ExeOutput>
<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias> <DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>
<DCC_DependencyCheckOutputName>..\bin\RDPConf.exe</DCC_DependencyCheckOutputName> <DCC_DependencyCheckOutputName>RDPConf.exe</DCC_DependencyCheckOutputName>
<DCC_ImageBase>00400000</DCC_ImageBase> <DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_Platform>x86</DCC_Platform> <DCC_Platform>x86</DCC_Platform>
</PropertyGroup> </PropertyGroup>
@ -42,20 +41,17 @@
<DCCReference Include="MainUnit.pas"> <DCCReference Include="MainUnit.pas">
<Form>MainForm</Form> <Form>MainForm</Form>
</DCCReference> </DCCReference>
<DCCReference Include="LicenseUnit.pas">
<Form>LicenseForm</Form>
</DCCReference>
<BuildConfiguration Include="Base"> <BuildConfiguration Include="Base">
<Key>Base</Key> <Key>Base</Key>
</BuildConfiguration> </BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>
</BuildConfiguration> </BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup> </ItemGroup>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<ProjectExtensions> <ProjectExtensions>

Binary file not shown.

BIN
src-rdpconfig/manifest.res Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,375 +0,0 @@
{
Copyright 2014 Stas'M Corp.
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.
}
unit LiteINI;
interface
uses
SysUtils;
type
SList = Array of String;
INIValue = record
Name: String;
Value: String;
end;
INISection = record
Name: String;
Values: Array of INIValue;
end;
INIFile = Array of INISection;
procedure SListClear(var List: SList);
function SListAppend(var List: SList; S: String): Integer;
function SListFind(List: SList; Value: String): Integer;
function INIFindSection(INI: INIFile; Section: String): Integer;
function INIFindValue(INI: INIFile; Section: Integer; Value: String): Integer;
function INIAddSection(var INI: INIFile; Section: String): Integer;
function INIAddValue(var INI: INIFile; Section: Integer; ValueName, Value: String): Integer;
procedure INIUnload(var INI: INIFile);
procedure INILoad(var INI: INIFile; FileName: String);
function INISectionExists(INI: INIFile; Section: String): Boolean;
function INIValueExists(INI: INIFile; Section: String; Value: String): Boolean;
function INIReadSectionLowAPI(INI: INIFile; Section: Integer; var List: SList): Boolean;
function INIReadSection(INI: INIFile; Section: String): SList;
function INIReadStringLowAPI(INI: INIFile; Section, Value: Integer; var Str: String): Boolean;
function INIReadString(INI: INIFile; Section, Value, Default: String): String;
function INIReadInt(INI: INIFile; Section, Value: String; Default: Integer): Integer;
function INIReadDWord(INI: INIFile; Section, Value: String; Default: Cardinal): Cardinal;
function INIReadIntHex(INI: INIFile; Section, Value: String; Default: Integer): Integer;
function INIReadDWordHex(INI: INIFile; Section, Value: String; Default: Cardinal): Cardinal;
function INIReadBool(INI: INIFile; Section, Value: String; Default: Boolean): Boolean;
function INIReadBytes(INI: INIFile; Section, Value: String): TBytes;
function INIReadBytesDef(INI: INIFile; Section, Value: String; Default: TBytes): TBytes;
implementation
procedure SListClear(var List: SList);
begin
SetLength(List, 0);
end;
function SListAppend(var List: SList; S: String): Integer;
begin
SetLength(List, Length(List) + 1);
List[Length(List) - 1] := S;
Result := Length(List) - 1;
end;
function SListFind(List: SList; Value: String): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to Length(List) - 1 do
if List[I] = Value then begin
Result := I;
Break;
end;
end;
function INIFindSection(INI: INIFile; Section: String): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to Length(INI) - 1 do
if INI[I].Name = Section then begin
Result := I;
Exit;
end;
end;
function INIFindValue(INI: INIFile; Section: Integer; Value: String): Integer;
var
I: Integer;
begin
Result := -1;
if (Section < 0) or (Section >= Length(INI)) then
Exit;
for I := 0 to Length(INI[Section].Values) - 1 do
if INI[Section].Values[I].Name = Value then begin
Result := I;
Exit;
end;
end;
function INIAddSection(var INI: INIFile; Section: String): Integer;
begin
Result := INIFindSection(INI, Section);
if Result >= 0 then
Exit;
Result := Length(INI);
SetLength(INI, Result + 1);
INI[Result].Name := Section;
SetLength(INI[Result].Values, 0);
end;
function INIAddValue(var INI: INIFile; Section: Integer; ValueName, Value: String): Integer;
var
I: Integer;
begin
Result := -1;
if (Section < 0) or (Section >= Length(INI)) then
Exit;
I := INIFindValue(INI, Section, ValueName);
if I = -1 then begin
Result := Length(INI[Section].Values);
SetLength(INI[Section].Values, Result + 1);
INI[Section].Values[Result].Name := ValueName;
INI[Section].Values[Result].Value := Value;
end else begin
INI[Section].Values[I].Value := Value;
Result := I;
end;
end;
procedure INIUnload(var INI: INIFile);
begin
SetLength(INI, 0);
end;
procedure INILoad(var INI: INIFile; FileName: String);
var
F: TextFile;
S, ValueName, Value: String;
INIList: SList;
I, Sect: Integer;
begin
INIUnload(INI);
if not FileExists(FileName) then
Exit;
AssignFile(F, FileName);
Reset(F);
// Read and filter lines
while not EOF(F) do begin
Readln(F, S);
if (Pos(';', S) <> 1)
and (Pos('#', S) <> 1)
and (
((Pos('[', S) > 0) and (Pos(']', S) > 0)) or
(Pos('=', S) > 0)
)
then
SListAppend(INIList, S);
end;
CloseFile(F);
// Parse 2 (parse format)
Sect := -1;
for I := 0 to Length(INIList) - 1 do begin
S := Trim(INIList[I]);
if Length(S) >= 2 then
if (S[1] = '[') and (S[Length(S)] = ']') then begin
S := Trim(Copy(S, 2, Length(S) - 2));
Sect := INIAddSection(INI, S);
Continue;
end;
S := INIList[I];
if Pos('=', S) > 0 then begin
ValueName := Trim(Copy(S, 1, Pos('=', S) - 1));
Value := Copy(S, Pos('=', S) + 1, Length(S) - Pos('=', S));
if Sect = -1 then
Sect := INIAddSection(INI, '');
INIAddValue(INI, Sect, ValueName, Value);
end;
end;
end;
function INISectionExists(INI: INIFile; Section: String): Boolean;
begin
Result := INIFindSection(INI, Section) > -1;
end;
function INIValueExists(INI: INIFile; Section: String; Value: String): Boolean;
var
Sect: Integer;
begin
Sect := INIFindSection(INI, Section);
Result := INIFindValue(INI, Sect, Value) > -1;
end;
function INIReadSectionLowAPI(INI: INIFile; Section: Integer; var List: SList): Boolean;
var
I: Integer;
begin
Result := False;
SetLength(List, 0);
if (Section < 0) or (Section >= Length(INI)) then
Exit;
for I := 0 to Length(INI[Section].Values) - 1 do
SListAppend(List, INI[Section].Values[I].Name);
Result := True;
end;
function INIReadSection(INI: INIFile; Section: String): SList;
var
Sect: Integer;
begin
Sect := INIFindSection(INI, Section);
INIReadSectionLowAPI(INI, Sect, Result);
end;
function INIReadStringLowAPI(INI: INIFile; Section, Value: Integer; var Str: String): Boolean;
begin
Result := False;
if (Section < 0) or (Section >= Length(INI)) then
Exit;
if (Value < 0) or (Value >= Length(INI[Section].Values)) then
Exit;
Str := INI[Section].Values[Value].Value;
Result := True;
end;
function INIReadString(INI: INIFile; Section, Value, Default: String): String;
var
Sect, Val: Integer;
begin
Sect := INIFindSection(INI, Section);
Val := INIFindValue(INI, Sect, Value);
if not INIReadStringLowAPI(INI, Sect, Val, Result) then
Result := Default;
end;
function INIReadInt(INI: INIFile; Section, Value: String; Default: Integer): Integer;
var
S: String;
E: Integer;
begin
S := INIReadString(INI, Section, Value, '');
Val(S, Result, E);
if E <> 0 then
Result := Default;
end;
function INIReadDWord(INI: INIFile; Section, Value: String; Default: Cardinal): Cardinal;
var
S: String;
E: Integer;
begin
S := INIReadString(INI, Section, Value, '');
Val(S, Result, E);
if E <> 0 then
Result := Default;
end;
function INIReadIntHex(INI: INIFile; Section, Value: String; Default: Integer): Integer;
var
S: String;
E: Integer;
begin
S := INIReadString(INI, Section, Value, '');
Val('$'+S, Result, E);
if E <> 0 then
Result := Default;
end;
function INIReadDWordHex(INI: INIFile; Section, Value: String; Default: Cardinal): Cardinal;
var
S: String;
E: Integer;
begin
S := INIReadString(INI, Section, Value, '');
Val('$'+S, Result, E);
if E <> 0 then
Result := Default;
end;
function INIReadBool(INI: INIFile; Section, Value: String; Default: Boolean): Boolean;
var
S: String;
I: Cardinal;
E: Integer;
begin
S := INIReadString(INI, Section, Value, '');
Val(S, I, E);
if E <> 0 then
Result := Default
else
Result := I > 0;
end;
function StringToBytes(S: String; var B: TBytes): Boolean;
var
I: Integer;
begin
Result := False;
if Odd(Length(S)) then
Exit;
SetLength(B, Length(S) div 2);
for I := 0 to Length(B) - 1 do begin
B[I] := 0;
case S[(I*2)+2] of
'0': ;
'1': B[I] := B[I] or $1;
'2': B[I] := B[I] or $2;
'3': B[I] := B[I] or $3;
'4': B[I] := B[I] or $4;
'5': B[I] := B[I] or $5;
'6': B[I] := B[I] or $6;
'7': B[I] := B[I] or $7;
'8': B[I] := B[I] or $8;
'9': B[I] := B[I] or $9;
'A','a': B[I] := B[I] or $A;
'B','b': B[I] := B[I] or $B;
'C','c': B[I] := B[I] or $C;
'D','d': B[I] := B[I] or $D;
'E','e': B[I] := B[I] or $E;
'F','f': B[I] := B[I] or $F;
else Exit;
end;
case S[(I*2)+1] of
'0': ;
'1': B[I] := B[I] or $10;
'2': B[I] := B[I] or $20;
'3': B[I] := B[I] or $30;
'4': B[I] := B[I] or $40;
'5': B[I] := B[I] or $50;
'6': B[I] := B[I] or $60;
'7': B[I] := B[I] or $70;
'8': B[I] := B[I] or $80;
'9': B[I] := B[I] or $90;
'A','a': B[I] := B[I] or $A0;
'B','b': B[I] := B[I] or $B0;
'C','c': B[I] := B[I] or $C0;
'D','d': B[I] := B[I] or $D0;
'E','e': B[I] := B[I] or $E0;
'F','f': B[I] := B[I] or $F0;
else Exit;
end;
end;
Result := True;
end;
function INIReadBytes(INI: INIFile; Section, Value: String): TBytes;
var
S: String;
begin
S := INIReadString(INI, Section, Value, '');
if not StringToBytes(S, Result) then
SetLength(Result, 0);
end;
function INIReadBytesDef(INI: INIFile; Section, Value: String; Default: TBytes): TBytes;
var
S: String;
begin
S := INIReadString(INI, Section, Value, '');
if not StringToBytes(S, Result) then
Result := Default;
end;
end.

Binary file not shown.

View File

@ -1,737 +0,0 @@
{
Copyright 2014 Stas'M Corp.
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.
}
library rdpwrap;
uses
SysUtils,
Windows,
TlHelp32,
LiteINI;
{$R rdpwrap.res}
// Hook core definitions
type
OldCode = packed record
One: DWORD;
two: Word;
end;
far_jmp = packed record
PushOp: Byte;
PushArg: Pointer;
RetOp: Byte;
end;
mov_far_jmp = packed record
MovOp: Byte;
MovArg: Byte;
PushOp: Byte;
PushArg: Pointer;
RetOp: Byte;
end;
TTHREADENTRY32 = packed record
dwSize: DWORD;
cntUsage: DWORD;
th32ThreadID: DWORD;
th32OwnerProcessID: DWORD;
tpBasePri: LongInt;
tpDeltaPri: LongInt;
dwFlags: DWORD;
end;
//IntArray = Array of Integer;
FILE_VERSION = record
Version: record case Boolean of
True: (dw: DWORD);
False: (w: record
Minor, Major: Word;
end;)
end;
Release, Build: Word;
bDebug, bPrerelease, bPrivate, bSpecial: Boolean;
end;
const
THREAD_SUSPEND_RESUME = 2;
TH32CS_SNAPTHREAD = 4;
var
INI: INIFile;
LogFile: String = '\rdpwrap.txt';
bw: {$if CompilerVersion>=16} NativeUInt {$else} DWORD {$endif};
IsHooked: Boolean = False;
// Unhooked import
function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL;
dwThreadId: DWORD): DWORD; stdcall; external kernel32;
function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): DWORD;
stdcall; external kernel32;
function Thread32First(hSnapshot: THandle; var lpte: TTHREADENTRY32): bool;
stdcall; external kernel32;
function Thread32Next(hSnapshot: THandle; var lpte: TTHREADENTRY32): bool;
stdcall; external kernel32;
// Wrapped import
var
TSMain: function(dwArgc: DWORD; lpszArgv: PWideChar): DWORD; stdcall;
TSGlobals: function(lpGlobalData: Pointer): DWORD; stdcall;
// Hooked import and vars
var
SLGetWindowsInformationDWORD: function(pwszValueName: PWideChar;
pdwValue: PDWORD): HRESULT; stdcall;
TermSrvBase: Pointer;
FV: FILE_VERSION;
var
Stub_SLGetWindowsInformationDWORD: far_jmp;
Old_SLGetWindowsInformationDWORD: OldCode;
// Main code
procedure WriteLog(S: AnsiString);
var
F: TextFile;
begin
if not FileExists(LogFile) then
Exit;
AssignFile(F, LogFile);
Append(F);
Write(F, S+#13#10);
CloseFile(F);
end;
function GetModuleHandleEx(dwFlags: DWORD; lpModuleName: PWideChar;
var phModule: HMODULE): BOOL; stdcall; external kernel32 name 'GetModuleHandleExW';
function GetCurrentModule: HMODULE;
const
GET_MODULE_HANDLE_EX_FLAG_PIN = 1;
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 2;
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS = 4;
begin
Result := 0;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, @GetCurrentModule, Result);
end;
function GetBinaryPath: String;
var
Buf: Array[0..511] of Byte;
begin
ZeroMemory(@Buf[0], Length(Buf));
GetModuleFileName(GetCurrentModule, PWideChar(@Buf[0]), Length(Buf));
Result := PWideChar(@Buf[0]);
end;
procedure StopThreads;
var
h, CurrTh, ThrHandle, CurrPr: DWORD;
Thread: TTHREADENTRY32;
begin
CurrTh := GetCurrentThreadId;
CurrPr := GetCurrentProcessId;
h := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if h <> INVALID_HANDLE_VALUE then
begin
Thread.dwSize := SizeOf(TTHREADENTRY32);
if Thread32First(h, Thread) then
repeat
if (Thread.th32ThreadID <> CurrTh) and
(Thread.th32OwnerProcessID = CurrPr) then
begin
ThrHandle := OpenThread(THREAD_SUSPEND_RESUME, false,
Thread.th32ThreadID);
if ThrHandle > 0 then
begin
SuspendThread(ThrHandle);
CloseHandle(ThrHandle);
end;
end;
until not Thread32Next(h, Thread);
CloseHandle(h);
end;
end;
procedure RunThreads;
var
h, CurrTh, ThrHandle, CurrPr: DWORD;
Thread: TTHREADENTRY32;
begin
CurrTh := GetCurrentThreadId;
CurrPr := GetCurrentProcessId;
h := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if h <> INVALID_HANDLE_VALUE then
begin
Thread.dwSize := SizeOf(TTHREADENTRY32);
if Thread32First(h, Thread) then
repeat
if (Thread.th32ThreadID <> CurrTh) and
(Thread.th32OwnerProcessID = CurrPr) then
begin
ThrHandle := OpenThread(THREAD_SUSPEND_RESUME, false,
Thread.th32ThreadID);
if ThrHandle > 0 then
begin
ResumeThread(ThrHandle);
CloseHandle(ThrHandle);
end;
end;
until not Thread32Next(h, Thread);
CloseHandle(h);
end;
end;
function GetModuleAddress(ModuleName: String; ProcessId: DWORD; var BaseAddr: Pointer; var BaseSize: DWORD): Boolean;
var
hSnap: THandle;
md: MODULEENTRY32;
begin
Result := False;
hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessId);
if hSnap = INVALID_HANDLE_VALUE Then
Exit;
md.dwSize := SizeOf(MODULEENTRY32);
if Module32First(hSnap, md) then
begin
if LowerCase(ExtractFileName(md.szExePath)) = LowerCase(ModuleName) then
begin
Result := True;
BaseAddr := Pointer(md.modBaseAddr);
BaseSize := md.modBaseSize;
CloseHandle(hSnap);
Exit;
end;
while Module32Next(hSnap, md) Do
begin
if LowerCase(ExtractFileName(md.szExePath)) = LowerCase(ModuleName) then
begin
Result := True;
BaseAddr := Pointer(md.modBaseAddr);
BaseSize := md.modBaseSize;
Break;
end;
end;
end;
CloseHandle(hSnap);
end;
{procedure FindMem(Mem: Pointer; MemSz: DWORD; Buf: Pointer; BufSz: DWORD;
From: DWORD; var A: IntArray);
var
I: Integer;
begin
SetLength(A, 0);
I:=From;
if From>0 then
Inc(PByte(Mem), From);
while I < MemSz - BufSz + 1 do
begin
if (not IsBadReadPtr(Mem, BufSz)) and (CompareMem(Mem, Buf, BufSz)) then
begin
SetLength(A, Length(A)+1);
A[Length(A)-1] := I;
end;
Inc(I);
Inc(PByte(Mem));
end;
end;}
function GetModuleVersion(const ModuleName: String; var FileVersion: FILE_VERSION): Boolean;
type
VS_VERSIONINFO = record
wLength, wValueLength, wType: Word;
szKey: Array[1..16] of WideChar;
Padding1: Word;
Value: VS_FIXEDFILEINFO;
Padding2, Children: Word;
end;
PVS_VERSIONINFO = ^VS_VERSIONINFO;
const
VFF_DEBUG = 1;
VFF_PRERELEASE = 2;
VFF_PRIVATE = 8;
VFF_SPECIAL = 32;
var
hMod: HMODULE;
hResourceInfo: HRSRC;
VersionInfo: PVS_VERSIONINFO;
begin
Result := False;
if ModuleName = '' then
hMod := GetModuleHandle(nil)
else
hMod := GetModuleHandle(PWideChar(ModuleName));
if hMod = 0 then
Exit;
hResourceInfo := FindResource(hMod, PWideChar(1), PWideChar($10));
if hResourceInfo = 0 then
Exit;
VersionInfo := Pointer(LoadResource(hMod, hResourceInfo));
if VersionInfo = nil then
Exit;
FileVersion.Version.dw := VersionInfo.Value.dwFileVersionMS;
FileVersion.Release := Word(VersionInfo.Value.dwFileVersionLS shr 16);
FileVersion.Build := Word(VersionInfo.Value.dwFileVersionLS);
FileVersion.bDebug := (VersionInfo.Value.dwFileFlags and VFF_DEBUG) = VFF_DEBUG;
FileVersion.bPrerelease := (VersionInfo.Value.dwFileFlags and VFF_PRERELEASE) = VFF_PRERELEASE;
FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE;
FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL;
Result := True;
end;
function GetFileVersion(const FileName: String; var FileVersion: FILE_VERSION): Boolean;
type
VS_VERSIONINFO = record
wLength, wValueLength, wType: Word;
szKey: Array[1..16] of WideChar;
Padding1: Word;
Value: VS_FIXEDFILEINFO;
Padding2, Children: Word;
end;
PVS_VERSIONINFO = ^VS_VERSIONINFO;
const
VFF_DEBUG = 1;
VFF_PRERELEASE = 2;
VFF_PRIVATE = 8;
VFF_SPECIAL = 32;
var
hFile: HMODULE;
hResourceInfo: HRSRC;
VersionInfo: PVS_VERSIONINFO;
begin
Result := False;
hFile := LoadLibraryEx(PWideChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE);
if hFile = 0 then
Exit;
hResourceInfo := FindResource(hFile, PWideChar(1), PWideChar($10));
if hResourceInfo = 0 then
Exit;
VersionInfo := Pointer(LoadResource(hFile, hResourceInfo));
if VersionInfo = nil then
Exit;
FileVersion.Version.dw := VersionInfo.Value.dwFileVersionMS;
FileVersion.Release := Word(VersionInfo.Value.dwFileVersionLS shr 16);
FileVersion.Build := Word(VersionInfo.Value.dwFileVersionLS);
FileVersion.bDebug := (VersionInfo.Value.dwFileFlags and VFF_DEBUG) = VFF_DEBUG;
FileVersion.bPrerelease := (VersionInfo.Value.dwFileFlags and VFF_PRERELEASE) = VFF_PRERELEASE;
FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE;
FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL;
Result := True;
end;
function OverrideSL(ValueName: String; var Value: DWORD): Boolean;
begin
Result := True;
if INIValueExists(INI, 'SLPolicy', ValueName) then begin
Value := INIReadDWord(INI, 'SLPolicy', ValueName, 0);
Exit;
end;
Result := False;
end;
function New_SLGetWindowsInformationDWORD(pwszValueName: PWideChar;
pdwValue: PDWORD): HRESULT; stdcall;
var
dw: DWORD;
begin
// wrapped SLGetWindowsInformationDWORD function
// termsrv.dll will call this function instead of original SLC.dll
// Override SL Policy
WriteLog('Policy query: ' + pwszValueName);
if OverrideSL(pwszValueName, dw) then begin
pdwValue^ := dw;
Result := S_OK;
WriteLog('Policy rewrite: ' + IntToStr(pdwValue^));
Exit;
end;
// If the requested value name is not defined above
// revert to original SL Policy function
WriteProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD,
@Old_SLGetWindowsInformationDWORD, SizeOf(OldCode), bw);
// get result
Result := SLGetWindowsInformationDWORD(pwszValueName, pdwValue);
if Result = S_OK then
WriteLog('Policy result: ' + IntToStr(pdwValue^))
else
WriteLog('Policy request failed');
// wrap it back
WriteProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD,
@Stub_SLGetWindowsInformationDWORD, SizeOf(far_jmp), bw);
end;
function New_Win8SL(pwszValueName: PWideChar; pdwValue: PDWORD): HRESULT; register;
var
dw: DWORD;
begin
// wrapped unexported function SLGetWindowsInformationDWORDWrapper in termsrv.dll
// for Windows 8 support
// Override SL Policy
WriteLog('Policy query: ' + pwszValueName);
if OverrideSL(pwszValueName, dw) then begin
pdwValue^ := dw;
Result := S_OK;
WriteLog('Policy rewrite: ' + IntToStr(pdwValue^));
Exit;
end;
// If the requested value name is not defined above
// use function from SLC.dll
Result := SLGetWindowsInformationDWORD(pwszValueName, pdwValue);
if Result = S_OK then
WriteLog('Policy result: ' + IntToStr(pdwValue^))
else
WriteLog('Policy request failed');
end;
function New_Win8SL_CP(eax: DWORD; pdwValue: PDWORD; ecx: DWORD; pwszValueName: PWideChar): HRESULT; register;
begin
// wrapped unexported function SLGetWindowsInformationDWORDWrapper in termsrv.dll
// for Windows 8 Consumer Preview support
Result := New_Win8SL(pwszValueName, pdwValue);
end;
function New_CSLQuery_Initialize: HRESULT; stdcall;
var
Sect: String;
bServerSku,
bRemoteConnAllowed,
bFUSEnabled,
bAppServerAllowed,
bMultimonAllowed,
lMaxUserSessions,
ulMaxDebugSessions,
bInitialized: PDWORD;
begin
bServerSku := nil;
bRemoteConnAllowed := nil;
bFUSEnabled := nil;
bAppServerAllowed := nil;
bMultimonAllowed := nil;
lMaxUserSessions := nil;
ulMaxDebugSessions := nil;
bInitialized := nil;
WriteLog('>>> CSLQuery::Initialize');
Sect := IntToStr(FV.Version.w.Major)+'.'+IntToStr(FV.Version.w.Minor)+'.'+
IntToStr(FV.Release)+'.'+IntToStr(FV.Build)+'-SLInit';
if INISectionExists(INI, Sect) then begin
bServerSku := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'bServerSku.x86', 0));
bRemoteConnAllowed := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'bRemoteConnAllowed.x86', 0));
bFUSEnabled := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'bFUSEnabled.x86', 0));
bAppServerAllowed := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'bAppServerAllowed.x86', 0));
bMultimonAllowed := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'bMultimonAllowed.x86', 0));
lMaxUserSessions := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'lMaxUserSessions.x86', 0));
ulMaxDebugSessions := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'ulMaxDebugSessions.x86', 0));
bInitialized := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'bInitialized.x86', 0));
end;
if bServerSku <> nil then begin
bServerSku^ := INIReadDWord(INI, 'SLInit', 'bServerSku', 1);
WriteLog('SLInit [0x'+IntToHex(DWORD(bServerSku), 1)+'] bServerSku = ' + IntToStr(bServerSku^));
end;
if bRemoteConnAllowed <> nil then begin
bRemoteConnAllowed^ := INIReadDWord(INI, 'SLInit', 'bRemoteConnAllowed', 1);
WriteLog('SLInit [0x'+IntToHex(DWORD(bRemoteConnAllowed), 1)+'] bRemoteConnAllowed = ' + IntToStr(bRemoteConnAllowed^));
end;
if bFUSEnabled <> nil then begin
bFUSEnabled^ := INIReadDWord(INI, 'SLInit', 'bFUSEnabled', 1);
WriteLog('SLInit [0x'+IntToHex(DWORD(bFUSEnabled), 1)+'] bFUSEnabled = ' + IntToStr(bFUSEnabled^));
end;
if bAppServerAllowed <> nil then begin
bAppServerAllowed^ := INIReadDWord(INI, 'SLInit', 'bAppServerAllowed', 1);
WriteLog('SLInit [0x'+IntToHex(DWORD(bAppServerAllowed), 1)+'] bAppServerAllowed = ' + IntToStr(bAppServerAllowed^));
end;
if bMultimonAllowed <> nil then begin
bMultimonAllowed^ := INIReadDWord(INI, 'SLInit', 'bMultimonAllowed', 1);
WriteLog('SLInit [0x'+IntToHex(DWORD(bMultimonAllowed), 1)+'] bMultimonAllowed = ' + IntToStr(bMultimonAllowed^));
end;
if lMaxUserSessions <> nil then begin
lMaxUserSessions^ := INIReadDWord(INI, 'SLInit', 'lMaxUserSessions', 0);
WriteLog('SLInit [0x'+IntToHex(DWORD(lMaxUserSessions), 1)+'] lMaxUserSessions = ' + IntToStr(lMaxUserSessions^));
end;
if ulMaxDebugSessions <> nil then begin
ulMaxDebugSessions^ := INIReadDWord(INI, 'SLInit', 'ulMaxDebugSessions', 0);
WriteLog('SLInit [0x'+IntToHex(DWORD(ulMaxDebugSessions), 1)+'] ulMaxDebugSessions = ' + IntToStr(ulMaxDebugSessions^));
end;
if bInitialized <> nil then begin
bInitialized^ := INIReadDWord(INI, 'SLInit', 'bInitialized', 1);
WriteLog('SLInit [0x'+IntToHex(DWORD(bInitialized), 1)+'] bInitialized = ' + IntToStr(bInitialized^));
end;
Result := S_OK;
WriteLog('<<< CSLQuery::Initialize');
end;
procedure HookFunctions;
var
ConfigFile, Sect, FuncName: String;
V: DWORD;
TS_Handle, SLC_Handle: THandle;
TermSrvSize: DWORD;
SignPtr: Pointer;
I: Integer;
PatchList: SList;
Patch: Array of TBytes;
Jump: far_jmp;
MovJump: mov_far_jmp;
begin
{ hook function ^^
(called once) }
IsHooked := True;
TSMain := nil;
TSGlobals := nil;
SLGetWindowsInformationDWORD := nil;
WriteLog('Loading configuration...');
ConfigFile := ExtractFilePath(GetBinaryPath) + 'rdpwrap.ini';
WriteLog('Configuration file: ' + ConfigFile);
INILoad(INI, ConfigFile);
if Length(INI) = 0 then begin
WriteLog('Error: Failed to load configuration');
Exit;
end;
LogFile := INIReadString(INI, 'Main', 'LogFile', ExtractFilePath(GetBinaryPath) + 'rdpwrap.txt');
WriteLog('Initializing RDP Wrapper...');
// load termsrv.dll and get functions
TS_Handle := LoadLibrary('termsrv.dll');
if TS_Handle = 0 then begin
WriteLog('Error: Failed to load Terminal Services library');
Exit;
end;
TSMain := GetProcAddress(TS_Handle, 'ServiceMain');
TSGlobals := GetProcAddress(TS_Handle, 'SvchostPushServiceGlobals');
WriteLog(
'Base addr: 0x' + IntToHex(TS_Handle, 8) + #13#10 +
'SvcMain: termsrv.dll+0x' + IntToHex(Cardinal(@TSMain) - TS_Handle, 1) + #13#10 +
'SvcGlobals: termsrv.dll+0x' + IntToHex(Cardinal(@TSGlobals) - TS_Handle, 1)
);
V := 0;
// check termsrv version
if GetModuleVersion('termsrv.dll', FV) then
V := Byte(FV.Version.w.Minor) or (Byte(FV.Version.w.Major) shl 8)
else begin
// check NT version
// V := GetVersion; // deprecated
// V := ((V and $FF) shl 8) or ((V and $FF00) shr 8);
end;
if V = 0 then begin
WriteLog('Error: Failed to detect Terminal Services version');
Exit;
end;
WriteLog('Version: '+
IntToStr(FV.Version.w.Major)+'.'+
IntToStr(FV.Version.w.Minor)+'.'+
IntToStr(FV.Release)+'.'+
IntToStr(FV.Build));
// temporarily freeze threads
WriteLog('Freezing threads...');
StopThreads();
WriteLog('Caching patch codes...');
PatchList := INIReadSection(INI, 'PatchCodes');
SetLength(Patch, Length(PatchList));
for I := 0 to Length(Patch) - 1 do begin
Patch[I] := INIReadBytes(INI, 'PatchCodes', PatchList[I]);
if Length(Patch[I]) > 16 then // for security reasons
SetLength(Patch[I], 16); // not more than 16 bytes
end;
if (V = $0600) and (INIReadBool(INI, 'Main', 'SLPolicyHookNT60', True)) then begin
// Windows Vista
// uses SL Policy API (slc.dll)
// load slc.dll and hook function
SLC_Handle := LoadLibrary('slc.dll');
SLGetWindowsInformationDWORD := GetProcAddress(SLC_Handle, 'SLGetWindowsInformationDWORD');
if @SLGetWindowsInformationDWORD <> nil then
begin
// rewrite original function to call our function (make hook)
WriteLog('Hook SLGetWindowsInformationDWORD');
Stub_SLGetWindowsInformationDWORD.PushOp := $68;
Stub_SLGetWindowsInformationDWORD.PushArg := @New_SLGetWindowsInformationDWORD;
Stub_SLGetWindowsInformationDWORD.RetOp := $C3;
ReadProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD,
@Old_SLGetWindowsInformationDWORD, SizeOf(OldCode), bw);
WriteProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD,
@Stub_SLGetWindowsInformationDWORD, SizeOf(far_jmp), bw);
end;
end;
if (V = $0601) and (INIReadBool(INI, 'Main', 'SLPolicyHookNT61', True)) then begin
// Windows 7
// uses SL Policy API (slc.dll)
// load slc.dll and hook function
SLC_Handle := LoadLibrary('slc.dll');
SLGetWindowsInformationDWORD := GetProcAddress(SLC_Handle, 'SLGetWindowsInformationDWORD');
if @SLGetWindowsInformationDWORD <> nil then
begin
// rewrite original function to call our function (make hook)
WriteLog('Hook SLGetWindowsInformationDWORD');
Stub_SLGetWindowsInformationDWORD.PushOp := $68;
Stub_SLGetWindowsInformationDWORD.PushArg := @New_SLGetWindowsInformationDWORD;
Stub_SLGetWindowsInformationDWORD.RetOp := $C3;
ReadProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD,
@Old_SLGetWindowsInformationDWORD, SizeOf(OldCode), bw);
WriteProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD,
@Stub_SLGetWindowsInformationDWORD, SizeOf(far_jmp), bw);
end;
end;
if V = $0602 then begin
// Windows 8
// uses SL Policy internal unexported function
// load slc.dll and get function
// (will be used on intercepting undefined values)
SLC_Handle := LoadLibrary('slc.dll');
SLGetWindowsInformationDWORD := GetProcAddress(SLC_Handle, 'SLGetWindowsInformationDWORD');
end;
if V = $0603 then begin
// Windows 8.1
// uses SL Policy internal inline code
end;
if V = $0604 then begin
// Windows 10
// uses SL Policy internal inline code
end;
Sect := IntToStr(FV.Version.w.Major)+'.'+IntToStr(FV.Version.w.Minor)+'.'+
IntToStr(FV.Release)+'.'+IntToStr(FV.Build);
if INISectionExists(INI, Sect) then
if GetModuleAddress('termsrv.dll', GetCurrentProcessId, TermSrvBase, TermSrvSize) then begin
if INIReadBool(INI, Sect, 'LocalOnlyPatch.x86', False) then begin
WriteLog('Patch CEnforcementCore::GetInstanceOfTSLicense');
SignPtr := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'LocalOnlyOffset.x86', 0));
I := SListFind(PatchList, INIReadString(INI, Sect, 'LocalOnlyCode.x86', ''));
if I >= 0 then
WriteProcessMemory(GetCurrentProcess, SignPtr, @Patch[I][0], Length(Patch[I]), bw);
end;
if INIReadBool(INI, Sect, 'SingleUserPatch.x86', False) then begin
WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled');
SignPtr := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'SingleUserOffset.x86', 0));
I := SListFind(PatchList, INIReadString(INI, Sect, 'SingleUserCode.x86', ''));
if I >= 0 then
WriteProcessMemory(GetCurrentProcess, SignPtr, @Patch[I][0], Length(Patch[I]), bw);
end;
if INIReadBool(INI, Sect, 'DefPolicyPatch.x86', False) then begin
WriteLog('Patch CDefPolicy::Query');
SignPtr := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'DefPolicyOffset.x86', 0));
I := SListFind(PatchList, INIReadString(INI, Sect, 'DefPolicyCode.x86', ''));
if I >= 0 then
WriteProcessMemory(GetCurrentProcess, SignPtr, @Patch[I][0], Length(Patch[I]), bw);
end;
if INIReadBool(INI, Sect, 'SLPolicyInternal.x86', False) then begin
WriteLog('Hook SLGetWindowsInformationDWORDWrapper');
SignPtr := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'SLPolicyOffset.x86', 0));
MovJump.MovOp := $89; // mov eax, ecx
MovJump.MovArg := $C8; // __msfastcall compatibility
MovJump.PushOp := $68;
MovJump.PushArg := @New_Win8SL;
MovJump.RetOp := $C3;
FuncName := INIReadString(INI, Sect, 'SLPolicyFunc.x86', 'New_Win8SL');
if FuncName = 'New_Win8SL' then
MovJump.PushArg := @New_Win8SL;
if FuncName = 'New_Win8SL_CP' then
MovJump.PushArg := @New_Win8SL_CP;
WriteProcessMemory(GetCurrentProcess, SignPtr,
@MovJump, SizeOf(mov_far_jmp), bw);
end;
if INIReadBool(INI, Sect, 'SLInitHook.x86', False) then begin
WriteLog('Hook CSLQuery::Initialize');
SignPtr := Pointer(Cardinal(TermSrvBase) + INIReadDWordHex(INI, Sect, 'SLInitOffset.x86', 0));
Jump.PushOp := $68;
Jump.PushArg := @New_CSLQuery_Initialize;
Jump.RetOp := $C3;
FuncName := INIReadString(INI, Sect, 'SLInitFunc.x86', 'New_CSLQuery_Initialize');
if FuncName = 'New_CSLQuery_Initialize' then
Jump.PushArg := @New_CSLQuery_Initialize;
WriteProcessMemory(GetCurrentProcess, SignPtr,
@Jump, SizeOf(far_jmp), bw);
end;
end;
// unfreeze threads
WriteLog('Resumimg threads...');
RunThreads();
end;
function TermServiceMain(dwArgc: DWORD; lpszArgv: PWideChar): DWORD; stdcall;
begin
// wrap ServiceMain function
WriteLog('>>> ServiceMain');
if not IsHooked then
HookFunctions;
Result := 0;
if @TSMain <> nil then
Result := TSMain(dwArgc, lpszArgv);
WriteLog('<<< ServiceMain');
end;
function TermServiceGlobals(lpGlobalData: Pointer): DWORD; stdcall;
begin
// wrap SvchostPushServiceGlobals function
WriteLog('>>> SvchostPushServiceGlobals');
if not IsHooked then
HookFunctions;
Result := 0;
if @TSGlobals <> nil then
Result := TSGlobals(lpGlobalData);
WriteLog('<<< SvchostPushServiceGlobals');
end;
// export section
exports
TermServiceMain index 1 name 'ServiceMain',
TermServiceGlobals index 2 name 'SvchostPushServiceGlobals';
begin
// DllMain procedure is not used
end.

File diff suppressed because it is too large Load Diff

View File

@ -42,14 +42,14 @@
<BuildConfiguration Include="Base"> <BuildConfiguration Include="Base">
<Key>Base</Key> <Key>Base</Key>
</BuildConfiguration> </BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>
</BuildConfiguration> </BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup> </ItemGroup>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<ProjectExtensions> <ProjectExtensions>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject/>

Binary file not shown.

View File

@ -1,562 +0,0 @@
/*
Copyright 2014 Stas'M Corp.
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 "stdafx.h"
#include <Windows.h>
#include <stdlib.h>
#include "IniFile.h"
INI_FILE::INI_FILE(wchar_t *FilePath)
{
DWORD Status = 0;
DWORD NumberOfBytesRead = 0;
HANDLE hFile = CreateFile(FilePath, GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return;
}
FileSize = GetFileSize(hFile, NULL);
if (FileSize == INVALID_FILE_SIZE)
{
return;
}
FileRaw = new char[FileSize];
Status = ReadFile(hFile, FileRaw, FileSize, &NumberOfBytesRead, NULL);
if (!Status)
{
return;
}
CreateStringsMap();
Parse();
}
INI_FILE::~INI_FILE()
{
for (DWORD i = 0; i < IniData.SectionCount; i++)
{
delete[] IniData.Section[i].Variables;
}
delete[] IniData.Section;
delete[] FileStringsMap;
delete FileRaw;
}
bool INI_FILE::CreateStringsMap()
{
DWORD StringsCount = 1;
for (DWORD i = 0; i < FileSize; i++)
{
if (FileRaw[i] == '\r' && FileRaw[i + 1] == '\n') StringsCount++;
}
FileStringsCount = StringsCount;
FileStringsMap = new DWORD[StringsCount];
FileStringsMap[0] = 0;
StringsCount = 1;
for (DWORD i = 0; i < FileSize; i++)
{
if (FileRaw[i] == '\r' && FileRaw[i + 1] == '\n')
{
FileStringsMap[StringsCount] = i + 2;
StringsCount++;
}
}
return true;
}
int INI_FILE::StrTrim(char* Str)
{
int i = 0, j;
while ((Str[i] == ' ') || (Str[i] == '\t'))
{
i++;
}
if (i>0)
{
for (j = 0; j < strlen(Str); j++)
{
Str[j] = Str[j + i];
}
Str[j] = '\0';
}
i = strlen(Str) - 1;
while ((Str[i] == ' ') || (Str[i] == '\t'))
{
i--;
}
if (i < (strlen(Str) - 1))
{
Str[i + 1] = '\0';
}
return 0;
}
DWORD INI_FILE::GetFileStringFromNum(DWORD StringNumber, char *RetString, DWORD Size)
{
DWORD CurrentStringNum = 0;
DWORD EndStringPos = 0;
DWORD StringSize = 0;
if (StringNumber > FileStringsCount) return 0;
for (DWORD i = FileStringsMap[StringNumber]; i < FileSize; i++)
{
if (i == (FileSize - 1))
{
EndStringPos = FileSize;
break;
}
if (FileRaw[i] == '\r' && FileRaw[i + 1] == '\n')
{
EndStringPos = i;
break;
}
}
StringSize = EndStringPos - FileStringsMap[StringNumber];
if (Size < StringSize) return 0;
memset(RetString, 0x00, Size);
memcpy(RetString, &(FileRaw[FileStringsMap[StringNumber]]), StringSize);
return StringSize;
}
bool INI_FILE::IsVariable(char *Str, DWORD StrSize)
{
bool Quotes = false;
for (DWORD i = 0; i < StrSize; i++)
{
if (Str[i] == '"' || Str[i] == '\'') Quotes = !Quotes;
if (Str[i] == '=' && !Quotes) return true;
}
return false;
}
bool INI_FILE::FillVariable(INI_SECTION_VARIABLE *Variable, char *Str, DWORD StrSize)
{
bool Quotes = false;
for (DWORD i = 0; i < StrSize; i++)
{
if (Str[i] == '"' || Str[i] == '\'') Quotes = !Quotes;
if (Str[i] == '=' && !Quotes)
{
memset(Variable->VariableName, 0, MAX_STRING_LEN);
memset(Variable->VariableValue, 0, MAX_STRING_LEN);
memcpy(Variable->VariableName, Str, i);
memcpy(Variable->VariableValue, &(Str[i + 1]), StrSize - (i - 1));
StrTrim(Variable->VariableName);
StrTrim(Variable->VariableValue);
break;
}
}
return true;
}
bool INI_FILE::Parse()
{
DWORD CurrentStringNum = 0;
char CurrentString[512];
DWORD CurrentStringSize = 0;
DWORD SectionsCount = 0;
DWORD VariablesCount = 0;
DWORD CurrentSectionNum = -1;
DWORD CurrentVariableNum = -1;
// Calculate sections count
for (DWORD CurrentStringNum = 0; CurrentStringNum < FileStringsCount; CurrentStringNum++)
{
CurrentStringSize = GetFileStringFromNum(CurrentStringNum, CurrentString, 512);
if (CurrentString[0] == ';') continue; // It's a comment
if (CurrentString[0] == '[' && CurrentString[CurrentStringSize - 1] == ']') // It's section declaration
{
SectionsCount++;
continue;
}
}
DWORD *SectionVariableCount = new DWORD[SectionsCount];
memset(SectionVariableCount, 0x00, sizeof(DWORD)*SectionsCount);
for (DWORD CurrentStringNum = 0; CurrentStringNum < FileStringsCount; CurrentStringNum++)
{
CurrentStringSize = GetFileStringFromNum(CurrentStringNum, CurrentString, 512);
if (CurrentString[0] == ';') continue; // It's a comment
if (CurrentString[0] == '[' && CurrentString[CurrentStringSize - 1] == ']') // It's section declaration
{
CurrentSectionNum++;
continue;
}
if (IsVariable(CurrentString, CurrentStringSize))
{
VariablesCount++;
SectionVariableCount[CurrentSectionNum]++;
continue;
}
}
IniData.SectionCount = SectionsCount;
IniData.Section = new INI_SECTION[SectionsCount];
memset(IniData.Section, 0x00, sizeof(PINI_SECTION)*SectionsCount);
for (DWORD i = 0; i < SectionsCount; i++)
{
IniData.Section[i].VariablesCount = SectionVariableCount[i];
IniData.Section[i].Variables = new INI_SECTION_VARIABLE[SectionVariableCount[i]];
memset(IniData.Section[i].Variables, 0x00, sizeof(INI_SECTION_VARIABLE)*SectionVariableCount[i]);
}
delete[] SectionVariableCount;
CurrentSectionNum = -1;
CurrentVariableNum = -1;
for (DWORD CurrentStringNum = 0; CurrentStringNum < FileStringsCount; CurrentStringNum++)
{
CurrentStringSize = GetFileStringFromNum(CurrentStringNum, CurrentString, 512);
if (CurrentString[0] == ';') // It's a comment
{
continue;
}
if (CurrentString[0] == '[' && CurrentString[CurrentStringSize - 1] == ']')
{
CurrentSectionNum++;
CurrentVariableNum = 0;
memset(IniData.Section[CurrentSectionNum].SectionName, 0, MAX_STRING_LEN);
memcpy(IniData.Section[CurrentSectionNum].SectionName, &(CurrentString[1]), (CurrentStringSize - 2));
continue;
}
if (IsVariable(CurrentString, CurrentStringSize))
{
FillVariable(&(IniData.Section[CurrentSectionNum].Variables[CurrentVariableNum]), CurrentString, CurrentStringSize);
CurrentVariableNum++;
continue;
}
}
return true;
}
PINI_SECTION INI_FILE::GetSection(char *SectionName)
{
for (DWORD i = 0; i < IniData.SectionCount; i++)
{
if (
(strlen(IniData.Section[i].SectionName) == strlen(SectionName)) &&
(memcmp(IniData.Section[i].SectionName, SectionName, strlen(SectionName)) == 0)
)
{
return &IniData.Section[i];
}
}
return NULL;
}
bool INI_FILE::SectionExists(char *SectionName)
{
if (GetSection(SectionName) == NULL) return false;
return true;
}
bool INI_FILE::VariableExists(char *SectionName, char *VariableName)
{
INI_SECTION_VARIABLE Variable = { 0 };
return GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
}
bool INI_FILE::GetVariableInSectionPrivate(char *SectionName, char *VariableName, INI_SECTION_VARIABLE *RetVariable)
{
INI_SECTION *Section = NULL;
INI_SECTION_VARIABLE *Variable = NULL;
// Find section
Section = GetSection(SectionName);
if (Section == NULL)
{
SetLastError(318); // This region is not found
return false;
}
// Find variable
for (DWORD i = 0; i < Section->VariablesCount; i++)
{
if (
(strlen(Section->Variables[i].VariableName) == strlen(VariableName)) &&
(memcmp(Section->Variables[i].VariableName, VariableName, strlen(VariableName)) == 0)
)
{
Variable = &(Section->Variables[i]);
break;
}
}
if (Variable == NULL)
{
SetLastError(1898); // Member of the group is not found
return false;
}
memset(RetVariable, 0x00, sizeof(*RetVariable));
memcpy(RetVariable, Variable, sizeof(*Variable));
return true;
}
bool INI_FILE::GetVariableInSection(char *SectionName, char *VariableName, INI_VAR_STRING *RetVariable)
{
bool Status = false;
INI_SECTION_VARIABLE Variable = {};
Status = GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
if (!Status) return Status;
memset(RetVariable, 0x00, sizeof(*RetVariable));
memcpy(RetVariable->Name, Variable.VariableName, strlen(Variable.VariableName));
memcpy(RetVariable->Value, Variable.VariableValue, strlen(Variable.VariableValue));
return true;
}
bool INI_FILE::GetVariableInSection(char *SectionName, char *VariableName, INI_VAR_DWORD *RetVariable)
{
bool Status = false;
INI_SECTION_VARIABLE Variable = {};
Status = GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
if (!Status) return Status;
memset(RetVariable, 0x00, sizeof(*RetVariable));
memcpy(RetVariable->Name, Variable.VariableName, strlen(Variable.VariableName));
#ifndef _WIN64
RetVariable->ValueDec = strtol(Variable.VariableValue, NULL, 10);
RetVariable->ValueHex = strtol(Variable.VariableValue, NULL, 16);
#else
RetVariable->ValueDec = _strtoi64(Variable.VariableValue, NULL, 10);
RetVariable->ValueHex = _strtoi64(Variable.VariableValue, NULL, 16);
#endif
return true;
}
bool INI_FILE::GetVariableInSection(char *SectionName, char *VariableName, INI_VAR_BYTEARRAY *RetVariable)
{
bool Status = false;
INI_SECTION_VARIABLE Variable = {};
Status = GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
if (!Status) return Status;
DWORD ValueLen = strlen(Variable.VariableValue);
if ((ValueLen % 2) != 0) return false;
// for security reasons not more than 16 bytes
if (ValueLen > 32) ValueLen = 32; // 32 hex digits
memset(RetVariable, 0x00, sizeof(*RetVariable));
memcpy(RetVariable->Name, Variable.VariableName, strlen(Variable.VariableName));
for (DWORD i = 0; i <= ValueLen; i++)
{
if ((i % 2) != 0) continue;
switch (Variable.VariableValue[i])
{
case '0': break;
case '1': RetVariable->Value[(i / 2)] += (1 << 4); break;
case '2': RetVariable->Value[(i / 2)] += (2 << 4); break;
case '3': RetVariable->Value[(i / 2)] += (3 << 4); break;
case '4': RetVariable->Value[(i / 2)] += (4 << 4); break;
case '5': RetVariable->Value[(i / 2)] += (5 << 4); break;
case '6': RetVariable->Value[(i / 2)] += (6 << 4); break;
case '7': RetVariable->Value[(i / 2)] += (7 << 4); break;
case '8': RetVariable->Value[(i / 2)] += (8 << 4); break;
case '9': RetVariable->Value[(i / 2)] += (9 << 4); break;
case 'A': RetVariable->Value[(i / 2)] += (10 << 4); break;
case 'B': RetVariable->Value[(i / 2)] += (11 << 4); break;
case 'C': RetVariable->Value[(i / 2)] += (12 << 4); break;
case 'D': RetVariable->Value[(i / 2)] += (13 << 4); break;
case 'E': RetVariable->Value[(i / 2)] += (14 << 4); break;
case 'F': RetVariable->Value[(i / 2)] += (15 << 4); break;
}
switch (Variable.VariableValue[i + 1])
{
case '0': break;
case '1': RetVariable->Value[(i / 2)] += 1; break;
case '2': RetVariable->Value[(i / 2)] += 2; break;
case '3': RetVariable->Value[(i / 2)] += 3; break;
case '4': RetVariable->Value[(i / 2)] += 4; break;
case '5': RetVariable->Value[(i / 2)] += 5; break;
case '6': RetVariable->Value[(i / 2)] += 6; break;
case '7': RetVariable->Value[(i / 2)] += 7; break;
case '8': RetVariable->Value[(i / 2)] += 8; break;
case '9': RetVariable->Value[(i / 2)] += 9; break;
case 'A': RetVariable->Value[(i / 2)] += 10; break;
case 'B': RetVariable->Value[(i / 2)] += 11; break;
case 'C': RetVariable->Value[(i / 2)] += 12; break;
case 'D': RetVariable->Value[(i / 2)] += 13; break;
case 'E': RetVariable->Value[(i / 2)] += 14; break;
case 'F': RetVariable->Value[(i / 2)] += 15; break;
}
}
RetVariable->ArraySize = ValueLen / 2;
return true;
}
bool INI_FILE::GetVariableInSection(char *SectionName, char *VariableName, bool *RetVariable)
{
bool Status = false;
INI_SECTION_VARIABLE Variable = {};
Status = GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
if (!Status) return Status;
*RetVariable = (bool)strtol(Variable.VariableValue, NULL, 10);
return true;
}
bool INI_FILE::GetSectionVariablesList(char *SectionName, INI_SECTION_VARLIST *VariablesList)
{
INI_SECTION *Section = NULL;
Section = GetSection(SectionName);
if (Section == NULL)
{
SetLastError(318); // This region is not found
return false;
}
VariablesList->EntriesCount = Section->VariablesCount;
VariablesList->NamesEntries = new INI_SECTION_VARLIST_ENTRY[VariablesList->EntriesCount];
memset(VariablesList->NamesEntries, 0x00, sizeof(INI_SECTION_VARLIST_ENTRY)*VariablesList->EntriesCount);
VariablesList->ValuesEntries = new INI_SECTION_VARLIST_ENTRY[VariablesList->EntriesCount];
memset(VariablesList->ValuesEntries, 0x00, sizeof(INI_SECTION_VARLIST_ENTRY)*VariablesList->EntriesCount);
for (DWORD i = 0; i < Section->VariablesCount; i++)
{
memcpy(VariablesList->NamesEntries[i].String, Section->Variables[i].VariableName,
strlen(Section->Variables[i].VariableName));
memcpy(VariablesList->ValuesEntries[i].String, Section->Variables[i].VariableValue,
strlen(Section->Variables[i].VariableValue));
}
return true;
}
// ---------------------------- WCHAR_T BLOCK ----------------------------------------------
bool INI_FILE::SectionExists(wchar_t *SectionName)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
return GetSection(cSectionName);
}
bool INI_FILE::VariableExists(wchar_t *SectionName, wchar_t *VariableName)
{
INI_SECTION_VARIABLE Variable = { 0 };
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSectionPrivate(cSectionName, cVariableName, &Variable);
}
bool INI_FILE::GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, INI_VAR_STRING *RetVariable)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSection(cSectionName, cVariableName, RetVariable);
}
bool INI_FILE::GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, INI_VAR_DWORD *RetVariable)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSection(cSectionName, cVariableName, RetVariable);
}
bool INI_FILE::GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, INI_VAR_BYTEARRAY *RetVariable)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSection(cSectionName, cVariableName, RetVariable);
}
bool INI_FILE::GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, bool *RetVariable)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSection(cSectionName, cVariableName, RetVariable);
}
bool INI_FILE::GetSectionVariablesList(wchar_t *SectionName, INI_SECTION_VARLIST *VariablesList)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
return GetSectionVariablesList(cSectionName, VariablesList);
}

View File

@ -1,126 +0,0 @@
/*
Copyright 2014 Stas'M Corp.
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 "stdafx.h"
#include <Windows.h>
#define MAX_STRING_LEN 255
// Out values struсts
typedef struct _INI_VAR_STRING
{
char Name[MAX_STRING_LEN];
char Value[MAX_STRING_LEN];
} INI_VAR_STRING, *PINI_VAR_STRING;
typedef struct _INI_VAR_DWORD
{
char Name[MAX_STRING_LEN];
#ifndef _WIN64
DWORD ValueDec;
DWORD ValueHex;
#else
DWORD64 ValueDec;
DWORD64 ValueHex;
#endif
} INI_VAR_DWORD, *PINI_VAR_DWORD;
typedef struct _INI_VAR_BYTEARRAY
{
char Name[MAX_STRING_LEN];
BYTE ArraySize;
char Value[MAX_STRING_LEN];
} INI_VAR_BYTEARRAY, *PINI_VAR_BYTEARRAY;
typedef struct _INI_SECTION_VARLIST_ENTRY
{
char String[MAX_STRING_LEN];
} INI_SECTION_VARLIST_ENTRY, *PINI_SECTION_VARLIST_ENTRY;
typedef struct _INI_SECTION_VARLIST
{
DWORD EntriesCount;
[length_is(EntriesCount)] INI_SECTION_VARLIST_ENTRY *NamesEntries;
[length_is(EntriesCount)] INI_SECTION_VARLIST_ENTRY *ValuesEntries;
} INI_SECTION_VARLIST, *PINI_SECTION_VARLIST;
// end
typedef struct _INI_SECTION_VARIABLE
{
char VariableName[MAX_STRING_LEN];
char VariableValue[MAX_STRING_LEN];
} INI_SECTION_VARIABLE, *PINI_SECTION_VARIABLE;
typedef struct _INI_SECTION
{
char SectionName[MAX_STRING_LEN];
DWORD VariablesCount;
[length_is(SectionCount)] INI_SECTION_VARIABLE *Variables;
} INI_SECTION, *PINI_SECTION;
typedef struct _INI_DATA
{
DWORD SectionCount;
[length_is(SectionCount)] INI_SECTION *Section;
} INI_DATA, *PINI_DATA;
class INI_FILE
{
public:
INI_FILE(wchar_t*);
~INI_FILE();
// char block
bool SectionExists(char *SectionName);
bool VariableExists(char *SectionName, char *VariableName);
bool GetVariableInSection(char *SectionName, char *VariableName, INI_VAR_STRING *Variable);
bool GetVariableInSection(char *SectionName, char *VariableName, INI_VAR_DWORD *Variable);
bool GetVariableInSection(char *SectionName, char *VariableName, bool *Variable);
bool GetVariableInSection(char *SectionName, char *VariableName, INI_VAR_BYTEARRAY *Variable);
bool GetSectionVariablesList(char *SectionName, INI_SECTION_VARLIST *VariablesList);
// wchar_t tramps
bool SectionExists(wchar_t *SectionName);
bool VariableExists(wchar_t *SectionName, wchar_t *VariableName);
bool GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, INI_VAR_STRING *Variable);
bool GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, INI_VAR_DWORD *Variable);
bool GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, bool *Variable);
bool GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, INI_VAR_BYTEARRAY *Variable);
bool GetSectionVariablesList(wchar_t *SectionName, INI_SECTION_VARLIST *VariablesList);
private:
DWORD FileSize; // Ini file size
char *FileRaw; // Ini file raw dump
DWORD FileStringsCount; // String-map length
DWORD *FileStringsMap; // String-map
INI_DATA IniData; // Parsed data
// Common service functions
int StrTrim(char* Str);
// Class service functions
bool CreateStringsMap(); // Create file string-map
bool Parse(); // Parse file to class structures
DWORD GetFileStringFromNum(DWORD StringNumber, char *RetString, DWORD Size); // Get string from string-map
bool IsVariable(char *Str, DWORD StrSize);
bool FillVariable(INI_SECTION_VARIABLE *Variable, char *Str, DWORD StrSize); // Fill INI_SECTION_VARIABLE struct (for Parse)
PINI_SECTION GetSection(char *SectionName);
bool GetVariableInSectionPrivate(char *SectionName, char *VariableName, INI_SECTION_VARIABLE *RetVariable);
};

View File

@ -1,869 +0,0 @@
/*
Copyright 2014 Stas'M Corp.
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 "stdafx.h"
#include "IniFile.h"
#include <stdlib.h>
typedef struct
{
union
{
struct
{
WORD Minor;
WORD Major;
} wVersion;
DWORD dwVersion;
};
WORD Release;
WORD Build;
} FILE_VERSION;
#ifdef _WIN64
typedef unsigned long long PLATFORM_DWORD;
struct FARJMP
{ // x64 far jump | opcode | assembly
BYTE MovOp; // 48 mov rax, ptr
BYTE MovRegArg; // B8
DWORD64 MovArg; // PTR
BYTE PushRaxOp; // 50 push rax
BYTE RetOp; // C3 retn
};
#else
typedef unsigned long PLATFORM_DWORD;
struct FARJMP
{ // x86 far jump | opcode | assembly
BYTE PushOp; // 68 push ptr
DWORD PushArg; // PTR
BYTE RetOp; // C3 retn
};
#endif
FARJMP Old_SLGetWindowsInformationDWORD, Stub_SLGetWindowsInformationDWORD;
SLGETWINDOWSINFORMATIONDWORD _SLGetWindowsInformationDWORD;
INI_FILE *IniFile;
wchar_t LogFile[256] = L"\\rdpwrap.txt\0";
HMODULE hTermSrv;
HMODULE hSLC;
PLATFORM_DWORD TermSrvBase;
FILE_VERSION FV;
SERVICEMAIN _ServiceMain;
SVCHOSTPUSHSERVICEGLOBALS _SvchostPushServiceGlobals;
bool AlreadyHooked = false;
DWORD INIReadDWordHex(INI_FILE *IniFile, char *Sect, char *VariableName, PLATFORM_DWORD Default)
{
INI_VAR_DWORD Variable;
if(IniFile->GetVariableInSection(Sect, VariableName, &Variable))
{
return Variable.ValueHex;
}
return Default;
}
void INIReadString(INI_FILE *IniFile, char *Sect, char *VariableName, char *Default, char *Ret, DWORD RetSize)
{
INI_VAR_STRING Variable;
memset(Ret, 0x00, RetSize);
if(!IniFile->GetVariableInSection(Sect, VariableName, &Variable))
{
strcpy_s(Ret, RetSize, Default);
return;
}
strcpy_s(Ret, RetSize, Variable.Value);
}
void WriteToLog(LPSTR Text)
{
DWORD dwBytesOfWritten;
HANDLE hFile = CreateFile(LogFile, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return;
SetFilePointer(hFile, 0, 0, FILE_END);
WriteFile(hFile, Text, strlen(Text), &dwBytesOfWritten, NULL);
CloseHandle(hFile);
}
HMODULE GetCurrentModule()
{
HMODULE hModule = NULL;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)GetCurrentModule, &hModule);
return hModule;
}
/*PLATFORM_DWORD SearchAddressBySignature(char *StartPosition, PLATFORM_DWORD Size, char *Signature, int SignatureSize)
{
PLATFORM_DWORD AddressReturn = -1;
for (PLATFORM_DWORD i = 0; i < Size; i++)
{
for (int j = 0; StartPosition[i+j] == Signature[j] && j < SignatureSize; j++)
{
if (j == SignatureSize-1) AddressReturn = (PLATFORM_DWORD)&StartPosition[i];
}
}
return AddressReturn;
}*/
bool GetModuleCodeSectionInfo(HMODULE hModule, PLATFORM_DWORD *BaseAddr, PLATFORM_DWORD *BaseSize)
{
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_FILE_HEADER pFileHeader;
PIMAGE_OPTIONAL_HEADER pOptionalHeader;
if (hModule == NULL) return false;
pDosHeader = (PIMAGE_DOS_HEADER)hModule;
pFileHeader = (PIMAGE_FILE_HEADER)(((PBYTE)hModule)+pDosHeader->e_lfanew+4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)(pFileHeader+1);
*BaseAddr = (PLATFORM_DWORD)hModule;
*BaseSize = (PLATFORM_DWORD)pOptionalHeader->SizeOfCode;
if (*BaseAddr <= 0 || *BaseSize <= 0) return false;
return true;
}
void SetThreadsState(bool Resume)
{
HANDLE h, hThread;
DWORD CurrTh, CurrPr;
THREADENTRY32 Thread;
CurrTh = GetCurrentThreadId();
CurrPr = GetCurrentProcessId();
h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (h != INVALID_HANDLE_VALUE)
{
Thread.dwSize = sizeof(THREADENTRY32);
Thread32First(h, &Thread);
do
{
if (Thread.th32ThreadID != CurrTh && Thread.th32OwnerProcessID == CurrPr)
{
hThread = OpenThread(THREAD_SUSPEND_RESUME, false, Thread.th32ThreadID);
if (hThread != INVALID_HANDLE_VALUE)
{
if (Resume) ResumeThread(hThread);
else SuspendThread(hThread);
CloseHandle(hThread);
}
}
} while (Thread32Next(h, &Thread));
CloseHandle(h);
}
}
BOOL __stdcall GetModuleVersion(LPCWSTR lptstrModuleName, FILE_VERSION *FileVersion)
{
typedef struct
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[16];
WORD Padding1;
VS_FIXEDFILEINFO Value;
WORD Padding2;
WORD Children;
} VS_VERSIONINFO;
HMODULE hMod = GetModuleHandle(lptstrModuleName);
if(!hMod)
{
return false;
}
HRSRC hResourceInfo = FindResourceW(hMod, (LPCWSTR)1, (LPCWSTR)0x10);
if(!hResourceInfo)
{
return false;
}
VS_VERSIONINFO *VersionInfo = (VS_VERSIONINFO*)LoadResource(hMod, hResourceInfo);
if(!VersionInfo)
{
return false;
}
FileVersion->dwVersion = VersionInfo->Value.dwFileVersionMS;
FileVersion->Release = (WORD)(VersionInfo->Value.dwFileVersionLS >> 16);
FileVersion->Build = (WORD)VersionInfo->Value.dwFileVersionLS;
return true;
}
BOOL __stdcall GetFileVersion(LPCWSTR lptstrFilename, FILE_VERSION *FileVersion)
{
typedef struct
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[16];
WORD Padding1;
VS_FIXEDFILEINFO Value;
WORD Padding2;
WORD Children;
} VS_VERSIONINFO;
HMODULE hFile = LoadLibraryExW(lptstrFilename, NULL, LOAD_LIBRARY_AS_DATAFILE);
if(!hFile)
{
return false;
}
HRSRC hResourceInfo = FindResourceW(hFile, (LPCWSTR)1, (LPCWSTR)0x10);
if(!hResourceInfo)
{
return false;
}
VS_VERSIONINFO *VersionInfo = (VS_VERSIONINFO*)LoadResource(hFile, hResourceInfo);
if(!VersionInfo)
{
return false;
}
FileVersion->dwVersion = VersionInfo->Value.dwFileVersionMS;
FileVersion->Release = (WORD)(VersionInfo->Value.dwFileVersionLS >> 16);
FileVersion->Build = (WORD)VersionInfo->Value.dwFileVersionLS;
return true;
}
bool OverrideSL(LPWSTR ValueName, DWORD *Value)
{
INI_VAR_DWORD Variable = {0};
if (IniFile->VariableExists(L"SLPolicy", ValueName))
{
if (!(IniFile->GetVariableInSection(L"SLPolicy", ValueName, &Variable))) *Value = 0;
else *Value = Variable.ValueDec;
return true;
}
return false;
}
HRESULT WINAPI New_SLGetWindowsInformationDWORD(PWSTR pwszValueName, DWORD *pdwValue)
{
// wrapped SLGetWindowsInformationDWORD function
// termsrv.dll will call this function instead of original SLC.dll
// Override SL Policy
extern FARJMP Old_SLGetWindowsInformationDWORD, Stub_SLGetWindowsInformationDWORD;
extern SLGETWINDOWSINFORMATIONDWORD _SLGetWindowsInformationDWORD;
char *Log;
DWORD dw;
SIZE_T bw;
HRESULT Result;
Log = new char[1024];
wsprintfA(Log, "Policy query: %S\r\n", pwszValueName);
WriteToLog(Log);
delete[] Log;
if (OverrideSL(pwszValueName, &dw))
{
*pdwValue = dw;
Log = new char[1024];
wsprintfA(Log, "Policy rewrite: %i\r\n", dw);
WriteToLog(Log);
delete[] Log;
return S_OK;
}
WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Old_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
Result = _SLGetWindowsInformationDWORD(pwszValueName, pdwValue);
if (Result == S_OK)
{
Log = new char[1024];
wsprintfA(Log, "Policy result: %i\r\n", dw);
WriteToLog(Log);
delete[] Log;
} else {
WriteToLog("Policy request failed\r\n");
}
WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Stub_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
return Result;
}
HRESULT __fastcall New_Win8SL(PWSTR pwszValueName, DWORD *pdwValue)
{
// wrapped unexported function SLGetWindowsInformationDWORDWrapper in termsrv.dll
// for Windows 8 support
// Override SL Policy
extern SLGETWINDOWSINFORMATIONDWORD _SLGetWindowsInformationDWORD;
char *Log;
DWORD dw;
HRESULT Result;
Log = new char[1024];
wsprintfA(Log, "Policy query: %S\r\n", pwszValueName);
WriteToLog(Log);
delete[] Log;
if (OverrideSL(pwszValueName, &dw))
{
*pdwValue = dw;
Log = new char[1024];
wsprintfA(Log, "Policy rewrite: %i\r\n", dw);
WriteToLog(Log);
delete[] Log;
return S_OK;
}
Result = _SLGetWindowsInformationDWORD(pwszValueName, pdwValue);
if (Result == S_OK)
{
Log = new char[1024];
wsprintfA(Log, "Policy result: %i\r\n", dw);
WriteToLog(Log);
delete[] Log;
} else {
WriteToLog("Policy request failed\r\n");
}
return Result;
}
#ifndef _WIN64
HRESULT __fastcall New_Win8SL_CP(DWORD arg1, DWORD *pdwValue, PWSTR pwszValueName, DWORD arg4)
{
// wrapped unexported function SLGetWindowsInformationDWORDWrapper in termsrv.dll
// for Windows 8 Consumer Preview support
return New_Win8SL(pwszValueName, pdwValue);
}
#endif
HRESULT WINAPI New_CSLQuery_Initialize()
{
extern PLATFORM_DWORD TermSrvBase;
extern FILE_VERSION FV;
char *Log;
DWORD *bServerSku = NULL;
DWORD *bRemoteConnAllowed = NULL;
DWORD *bFUSEnabled = NULL;
DWORD *bAppServerAllowed = NULL;
DWORD *bMultimonAllowed = NULL;
DWORD *lMaxUserSessions = NULL;
DWORD *ulMaxDebugSessions = NULL;
DWORD *bInitialized = NULL;
WriteToLog(">>> CSLQuery::Initialize\r\n");
char *Sect;
Sect = new char[256];
memset(Sect, 0x00, 256);
wsprintfA(Sect, "%d.%d.%d.%d-SLInit", FV.wVersion.Major, FV.wVersion.Minor, FV.Release, FV.Build);
if (IniFile->SectionExists(Sect))
{
#ifdef _WIN64
bServerSku = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bServerSku.x64", 0));
bRemoteConnAllowed = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bRemoteConnAllowed.x64", 0));
bFUSEnabled = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bFUSEnabled.x64", 0));
bAppServerAllowed = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bAppServerAllowed.x64", 0));
bMultimonAllowed = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bMultimonAllowed.x64", 0));
lMaxUserSessions = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "lMaxUserSessions.x64", 0));
ulMaxDebugSessions = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "ulMaxDebugSessions.x64", 0));
bInitialized = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bInitialized.x64", 0));
#else
bServerSku = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bServerSku.x86", 0));
bRemoteConnAllowed = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bRemoteConnAllowed.x86", 0));
bFUSEnabled = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bFUSEnabled.x86", 0));
bAppServerAllowed = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bAppServerAllowed.x86", 0));
bMultimonAllowed = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bMultimonAllowed.x86", 0));
lMaxUserSessions = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "lMaxUserSessions.x86", 0));
ulMaxDebugSessions = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "ulMaxDebugSessions.x86", 0));
bInitialized = (DWORD*)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "bInitialized.x86", 0));
#endif
}
delete[] Sect;
if (bServerSku)
{
*bServerSku = INIReadDWordHex(IniFile, "SLInit", "bServerSku", 1);
Log = new char[1024];
wsprintfA(Log, "SLInit [0x%p] bServerSku = %d\r\n", bServerSku, *bServerSku);
WriteToLog(Log);
delete[] Log;
}
if (bRemoteConnAllowed)
{
*bRemoteConnAllowed = INIReadDWordHex(IniFile, "SLInit", "bRemoteConnAllowed", 1);
Log = new char[1024];
wsprintfA(Log, "SLInit [0x%p] bRemoteConnAllowed = %d\r\n", bRemoteConnAllowed, *bRemoteConnAllowed);
WriteToLog(Log);
delete[] Log;
}
if (bFUSEnabled)
{
*bFUSEnabled = INIReadDWordHex(IniFile, "SLInit", "bFUSEnabled", 1);
Log = new char[1024];
wsprintfA(Log, "SLInit [0x%p] bFUSEnabled = %d\r\n", bFUSEnabled, *bFUSEnabled);
WriteToLog(Log);
delete[] Log;
}
if (bAppServerAllowed)
{
*bAppServerAllowed = INIReadDWordHex(IniFile, "SLInit", "bAppServerAllowed", 1);
Log = new char[1024];
wsprintfA(Log, "SLInit [0x%p] bAppServerAllowed = %d\r\n", bAppServerAllowed, *bAppServerAllowed);
WriteToLog(Log);
delete[] Log;
}
if (bMultimonAllowed)
{
*bMultimonAllowed = INIReadDWordHex(IniFile, "SLInit", "bMultimonAllowed", 1);
Log = new char[1024];
wsprintfA(Log, "SLInit [0x%p] bMultimonAllowed = %d\r\n", bMultimonAllowed, *bMultimonAllowed);
WriteToLog(Log);
delete[] Log;
}
if (lMaxUserSessions)
{
*lMaxUserSessions = INIReadDWordHex(IniFile, "SLInit", "lMaxUserSessions", 0);
Log = new char[1024];
wsprintfA(Log, "SLInit [0x%p] lMaxUserSessions = %d\r\n", lMaxUserSessions, *lMaxUserSessions);
WriteToLog(Log);
delete[] Log;
}
if (ulMaxDebugSessions)
{
*ulMaxDebugSessions = INIReadDWordHex(IniFile, "SLInit", "ulMaxDebugSessions", 0);
Log = new char[1024];
wsprintfA(Log, "SLInit [0x%p] ulMaxDebugSessions = %d\r\n", ulMaxDebugSessions, *ulMaxDebugSessions);
WriteToLog(Log);
delete[] Log;
}
if (bInitialized)
{
*bInitialized = INIReadDWordHex(IniFile, "SLInit", "bInitialized", 1);
Log = new char[1024];
wsprintfA(Log, "SLInit [0x%p] bInitialized = %d\r\n", bInitialized, *bInitialized);
WriteToLog(Log);
delete[] Log;
}
WriteToLog("<<< CSLQuery::Initialize\r\n");
return S_OK;
}
void Hook()
{
extern FARJMP Old_SLGetWindowsInformationDWORD, Stub_SLGetWindowsInformationDWORD;
extern SLGETWINDOWSINFORMATIONDWORD _SLGetWindowsInformationDWORD;
extern HMODULE hTermSrv;
extern HMODULE hSLC;
extern PLATFORM_DWORD TermSrvBase;
extern FILE_VERSION FV;
extern wchar_t LogFile[256];
AlreadyHooked = true;
char *Log;
wchar_t ConfigFile[256] = { 0x00 };
WriteToLog("Loading configuration...\r\n");
GetModuleFileName(GetCurrentModule(), ConfigFile, 255);
for (DWORD i = wcslen(ConfigFile); i > 0; i--)
{
if (ConfigFile[i] == '\\')
{
memset(&ConfigFile[i + 1], 0x00, ((256 - (i + 1))) * 2);
memcpy(&ConfigFile[i + 1], L"rdpwrap.ini", strlen("rdpwrap.ini") * 2);
break;
}
}
Log = new char[1024];
wsprintfA(Log, "Configuration file: %S\r\n", ConfigFile);
WriteToLog(Log);
delete[] Log;
IniFile = new INI_FILE(ConfigFile);
// TODO: implement this
if (IniFile == NULL)
{
WriteToLog("Error: Failed to load configuration\r\n");
return;
}
INI_VAR_STRING LogFileVar;
if(!(IniFile->GetVariableInSection("Main", "LogFile", &LogFileVar)))
{
GetModuleFileName(GetCurrentModule(), LogFile, 255);
for(DWORD i = wcslen(LogFile); i > 0; i--)
{
if(LogFile[i] == '\\')
{
memset(&LogFile[i+1], 0x00, ((256-(i+1)))*2);
memcpy(&LogFile[i+1], L"rdpwrap.txt", strlen("rdpwrap.txt")*2);
break;
}
}
}
else
{
// TODO: Change it before add UNICODE in IniFile
wchar_t wcLogFile[256];
memset(wcLogFile, 0x00, 256);
mbstowcs(wcLogFile, LogFileVar.Value, 255);
wcscpy(LogFile, wcLogFile);
}
SIZE_T bw;
WORD Ver = 0;
PLATFORM_DWORD TermSrvSize, SignPtr;
FARJMP Jump;
WriteToLog("Initializing RDP Wrapper...\r\n");
hTermSrv = LoadLibrary(L"termsrv.dll");
if (hTermSrv == 0)
{
WriteToLog("Error: Failed to load Terminal Services library\r\n");
return;
}
_ServiceMain = (SERVICEMAIN)GetProcAddress(hTermSrv, "ServiceMain");
_SvchostPushServiceGlobals = (SVCHOSTPUSHSERVICEGLOBALS)GetProcAddress(hTermSrv, "SvchostPushServiceGlobals");
Log = new char[4096];
wsprintfA(Log,
"Base addr: 0x%p\r\n"
"SvcMain: termsrv.dll+0x%p\r\n"
"SvcGlobals: termsrv.dll+0x%p\r\n",
hTermSrv,
(PLATFORM_DWORD)_ServiceMain - (PLATFORM_DWORD)hTermSrv,
(PLATFORM_DWORD)_SvchostPushServiceGlobals - (PLATFORM_DWORD)hTermSrv);
WriteToLog(Log);
delete[] Log;
// check termsrv version
if (GetModuleVersion(L"termsrv.dll", &FV))
{
Ver = (BYTE)FV.wVersion.Minor | ((BYTE)FV.wVersion.Major << 8);
} else {
// check NT version
// Ver = GetVersion(); // deprecated
// Ver = ((Ver & 0xFF) << 8) | ((Ver & 0xFF00) >> 8);
}
if (Ver == 0)
{
WriteToLog("Error: Failed to detect Terminal Services version\r\n");
return;
}
Log = new char[1024];
wsprintfA(Log, "Version: %d.%d.%d.%d\r\n", FV.wVersion.Major, FV.wVersion.Minor, FV.Release, FV.Build);
WriteToLog(Log);
delete[] Log;
// temporarily freeze threads
WriteToLog("Freezing threads...\r\n");
SetThreadsState(false);
bool Bool;
if (!(IniFile->GetVariableInSection("Main", "SLPolicyHookNT60", &Bool))) Bool = true;
if ((Ver == 0x0600) && Bool)
{
// Windows Vista
// uses SL Policy API (slc.dll)
// load slc.dll and hook function
hSLC = LoadLibrary(L"slc.dll");
_SLGetWindowsInformationDWORD = (SLGETWINDOWSINFORMATIONDWORD)GetProcAddress(hSLC, "SLGetWindowsInformationDWORD");
if (_SLGetWindowsInformationDWORD != INVALID_HANDLE_VALUE)
{
// rewrite original function to call our function (make hook)
WriteToLog("Hook SLGetWindowsInformationDWORD\r\n");
#ifdef _WIN64
Stub_SLGetWindowsInformationDWORD.MovOp = 0x48;
Stub_SLGetWindowsInformationDWORD.MovRegArg = 0xB8;
Stub_SLGetWindowsInformationDWORD.MovArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD;
Stub_SLGetWindowsInformationDWORD.PushRaxOp = 0x50;
Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3;
#else
Stub_SLGetWindowsInformationDWORD.PushOp = 0x68;
Stub_SLGetWindowsInformationDWORD.PushArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD;
Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3;
#endif
ReadProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Old_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Stub_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
}
}
if (!(IniFile->GetVariableInSection("Main", "SLPolicyHookNT61", &Bool))) Bool = true;
if ((Ver == 0x0601) && Bool)
{
// Windows 7
// uses SL Policy API (slc.dll)
// load slc.dll and hook function
hSLC = LoadLibrary(L"slc.dll");
_SLGetWindowsInformationDWORD = (SLGETWINDOWSINFORMATIONDWORD)GetProcAddress(hSLC, "SLGetWindowsInformationDWORD");
if (_SLGetWindowsInformationDWORD != INVALID_HANDLE_VALUE)
{
// rewrite original function to call our function (make hook)
WriteToLog("Hook SLGetWindowsInformationDWORD\r\n");
#ifdef _WIN64
Stub_SLGetWindowsInformationDWORD.MovOp = 0x48;
Stub_SLGetWindowsInformationDWORD.MovRegArg = 0xB8;
Stub_SLGetWindowsInformationDWORD.MovArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD;
Stub_SLGetWindowsInformationDWORD.PushRaxOp = 0x50;
Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3;
#else
Stub_SLGetWindowsInformationDWORD.PushOp = 0x68;
Stub_SLGetWindowsInformationDWORD.PushArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD;
Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3;
#endif
ReadProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Old_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Stub_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
}
}
if (Ver == 0x0602)
{
// Windows 8
// uses SL Policy internal unexported function
// load slc.dll and get function
// (will be used on intercepting undefined values)
hSLC = LoadLibrary(L"slc.dll");
_SLGetWindowsInformationDWORD = (SLGETWINDOWSINFORMATIONDWORD)GetProcAddress(hSLC, "SLGetWindowsInformationDWORD");
}
if (Ver == 0x0603)
{
// Windows 8.1
// uses SL Policy internal inline code
}
if (Ver == 0x0604)
{
// Windows 10
// uses SL Policy internal inline code
}
char *Sect;
INI_VAR_STRING PatchName;
INI_VAR_BYTEARRAY Patch;
Sect = new char[256];
memset(Sect, 0x00, 256);
wsprintfA(Sect, "%d.%d.%d.%d", FV.wVersion.Major, FV.wVersion.Minor, FV.Release, FV.Build);
if (IniFile->SectionExists(Sect))
{
if (GetModuleCodeSectionInfo(hTermSrv, &TermSrvBase, &TermSrvSize))
{
#ifdef _WIN64
if (!(IniFile->GetVariableInSection(Sect, "LocalOnlyPatch.x64", &Bool))) Bool = false;
#else
if (!(IniFile->GetVariableInSection(Sect, "LocalOnlyPatch.x86", &Bool))) Bool = false;
#endif
if (Bool)
{
WriteToLog("Patch CEnforcementCore::GetInstanceOfTSLicense\r\n");
Bool = false;
#ifdef _WIN64
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "LocalOnlyOffset.x64", 0));
Bool = IniFile->GetVariableInSection(Sect, "LocalOnlyCode.x64", &PatchName);
#else
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "LocalOnlyOffset.x86", 0));
Bool = IniFile->GetVariableInSection(Sect, "LocalOnlyCode.x86", &PatchName);
#endif
if (Bool) Bool = IniFile->GetVariableInSection("PatchCodes", PatchName.Value, &Patch);
if (Bool && (SignPtr > TermSrvBase)) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, Patch.Value, Patch.ArraySize, &bw);
}
#ifdef _WIN64
if (!(IniFile->GetVariableInSection(Sect, "SingleUserPatch.x64", &Bool))) Bool = false;
#else
if (!(IniFile->GetVariableInSection(Sect, "SingleUserPatch.x86", &Bool))) Bool = false;
#endif
if (Bool)
{
WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n");
Bool = false;
#ifdef _WIN64
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SingleUserOffset.x64", 0));
Bool = IniFile->GetVariableInSection(Sect, "SingleUserCode.x64", &PatchName);
#else
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SingleUserOffset.x86", 0));
Bool = IniFile->GetVariableInSection(Sect, "SingleUserCode.x86", &PatchName);
#endif
if (Bool) Bool = IniFile->GetVariableInSection("PatchCodes", PatchName.Value, &Patch);
if (Bool && (SignPtr > TermSrvBase)) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, Patch.Value, Patch.ArraySize, &bw);
}
#ifdef _WIN64
if (!(IniFile->GetVariableInSection(Sect, "DefPolicyPatch.x64", &Bool))) Bool = false;
#else
if (!(IniFile->GetVariableInSection(Sect, "DefPolicyPatch.x86", &Bool))) Bool = false;
#endif
if (Bool)
{
WriteToLog("Patch CDefPolicy::Query\r\n");
Bool = false;
#ifdef _WIN64
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "DefPolicyOffset.x64", 0));
Bool = IniFile->GetVariableInSection(Sect, "DefPolicyCode.x64", &PatchName);
#else
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "DefPolicyOffset.x86", 0));
Bool = IniFile->GetVariableInSection(Sect, "DefPolicyCode.x86", &PatchName);
#endif
if (Bool) Bool = IniFile->GetVariableInSection("PatchCodes", PatchName.Value, &Patch);
if (Bool && (SignPtr > TermSrvBase)) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, Patch.Value, Patch.ArraySize, &bw);
}
#ifdef _WIN64
if (!(IniFile->GetVariableInSection(Sect, "SLPolicyInternal.x64", &Bool))) Bool = false;
#else
if (!(IniFile->GetVariableInSection(Sect, "SLPolicyInternal.x86", &Bool))) Bool = false;
#endif
if (Bool)
{
WriteToLog("Hook SLGetWindowsInformationDWORDWrapper\r\n");
char *FuncName;
FuncName = new char[1024];
#ifdef _WIN64
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SLPolicyOffset.x64", 0));
Jump.MovOp = 0x48;
Jump.MovRegArg = 0xB8;
Jump.MovArg = (PLATFORM_DWORD)New_Win8SL;
Jump.PushRaxOp = 0x50;
Jump.RetOp = 0xC3;
INIReadString(IniFile, Sect, "SLPolicyFunc.x64", "New_Win8SL", FuncName, 1024);
if (strcmp(FuncName, "New_Win8SL"))
{
Jump.MovArg = (PLATFORM_DWORD)New_Win8SL;
}
#else
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SLPolicyOffset.x86", 0));
Jump.PushOp = 0x68;
Jump.PushArg = (PLATFORM_DWORD)New_Win8SL;
Jump.RetOp = 0xC3;
INIReadString(IniFile, Sect, "SLPolicyFunc.x86", "New_Win8SL", FuncName, 1024);
if (strcmp(FuncName, "New_Win8SL"))
{
Jump.PushArg = (PLATFORM_DWORD)New_Win8SL;
}
if (strcmp(FuncName, "New_Win8SL_CP"))
{
Jump.PushArg = (PLATFORM_DWORD)New_Win8SL_CP;
}
#endif
delete[] FuncName;
if (SignPtr > TermSrvBase) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw);
}
#ifdef _WIN64
if (!(IniFile->GetVariableInSection(Sect, "SLInitHook.x64", &Bool))) Bool = false;
#else
if (!(IniFile->GetVariableInSection(Sect, "SLInitHook.x86", &Bool))) Bool = false;
#endif
if (Bool)
{
WriteToLog("Hook CSLQuery::Initialize\r\n");
char *FuncName;
FuncName = new char[1024];
#ifdef _WIN64
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SLInitOffset.x64", 0));
Jump.MovOp = 0x48;
Jump.MovRegArg = 0xB8;
Jump.MovArg = (PLATFORM_DWORD)New_CSLQuery_Initialize;
Jump.PushRaxOp = 0x50;
Jump.RetOp = 0xC3;
INIReadString(IniFile, Sect, "SLInitFunc.x64", "New_CSLQuery_Initialize", FuncName, 1024);
if (strcmp(FuncName, "New_CSLQuery_Initialize"))
{
Jump.MovArg = (PLATFORM_DWORD)New_CSLQuery_Initialize;
}
#else
SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SLInitOffset.x86", 0));
Jump.PushOp = 0x68;
Jump.PushArg = (PLATFORM_DWORD)New_CSLQuery_Initialize;
Jump.RetOp = 0xC3;
INIReadString(IniFile, Sect, "SLInitFunc.x86", "New_CSLQuery_Initialize", FuncName, 1024);
if (strcmp(FuncName, "New_CSLQuery_Initialize"))
{
Jump.PushArg = (PLATFORM_DWORD)New_CSLQuery_Initialize;
}
#endif
delete[] FuncName;
if (SignPtr > TermSrvBase) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw);
}
}
}
delete[] Sect;
WriteToLog("Resumimg threads...\r\n");
SetThreadsState(true);
return;
}
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
WriteToLog(">>> ServiceMain\r\n");
if (!AlreadyHooked) Hook();
if (_ServiceMain != NULL) _ServiceMain(dwArgc, lpszArgv);
WriteToLog("<<< ServiceMain\r\n");
}
void WINAPI SvchostPushServiceGlobals(void *lpGlobalData)
{
WriteToLog(">>> SvchostPushServiceGlobals\r\n");
if (!AlreadyHooked) Hook();
if (_SvchostPushServiceGlobals != NULL) _SvchostPushServiceGlobals(lpGlobalData);
WriteToLog("<<< SvchostPushServiceGlobals\r\n");
}

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -27,26 +27,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -160,7 +160,6 @@
<Text Include="ReadMe.txt" /> <Text Include="ReadMe.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="IniFile.h" />
<ClInclude Include="stdafx.h" /> <ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" /> <ClInclude Include="targetver.h" />
</ItemGroup> </ItemGroup>
@ -179,7 +178,6 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeader> </PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="IniFile.cpp" />
<ClCompile Include="RDPWrap.cpp" /> <ClCompile Include="RDPWrap.cpp" />
<ClCompile Include="stdafx.cpp"> <ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>

View File

@ -24,9 +24,6 @@
<ClInclude Include="targetver.h"> <ClInclude Include="targetver.h">
<Filter>Заголовочные файлы</Filter> <Filter>Заголовочные файлы</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="IniFile.h">
<Filter>Заголовочные файлы</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="stdafx.cpp"> <ClCompile Include="stdafx.cpp">
@ -38,9 +35,6 @@
<ClCompile Include="dllmain.cpp"> <ClCompile Include="dllmain.cpp">
<Filter>Файлы исходного кода</Filter> <Filter>Файлы исходного кода</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="IniFile.cpp">
<Filter>Файлы исходного кода</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Export.def"> <None Include="Export.def">

Binary file not shown.

View File

@ -1,561 +0,0 @@
RDP Wrapper Library project by Stas'M
Terminal Services supported versions
6.0.X.X (Windows Vista, any) [policy hook only]
6.0.6000.16386 (Windows Vista) [policy hook + extended patch]
6.0.6000.20723 (Windows Vista with KB944917) [todo]
6.0.6001.18000 (Windows Vista SP1) [policy hook + extended patch]
6.0.6001.22286 (Windows Vista SP1 with KB958612) [todo]
6.0.6001.22357 (Windows Vista SP1 with KB958612 v2) [todo]
6.0.6001.22323 (Windows Vista SP1 with KB960742) [todo]
6.0.6001.22392 (Windows Vista SP1 with KB968680) [todo]
6.0.6001.22565 (Windows Vista SP1 with KB977541) [todo]
6.0.6001.22635 (Windows Vista SP1 with KB970911) [todo]
6.0.6001.22801 (Windows Vista SP1 with KB2381675) [todo]
6.0.6002.18005 (Windows Vista SP2) [policy hook + extended patch]
6.0.6002.22269 (Windows Vista SP2 with KB977541) [todo]
6.0.6002.22340 (Windows Vista SP2 with KB970911) [todo]
6.0.6002.22515 (Windows Vista SP2 with KB2381675) [todo]
6.0.6002.22641 (Windows Vista SP2 with KB2523307) [todo]
6.0.6002.22790 (Windows Vista SP2 with KB2672601) [todo]
6.0.6002.19214 (Windows Vista SP2 with KB3003743 GDR) [policy hook + extended patch]
6.0.6002.23521 (Windows Vista SP2 with KB3003743 LDR) [policy hook + extended patch]
6.1.X.X (Windows 7, any) [policy hook only]
6.1.7100.0 (Windows 7 Release Candidate) [todo]
6.1.7600.16385 (Windows 7) [policy hook + extended patch]
6.1.7600.20661 (Windows 7 with KB951422) [todo]
6.1.7600.21085 (Windows 7 with KB951422 v2) [todo]
6.1.7600.20621 (Windows 7 with KB979470) [todo]
6.1.7600.20890 (Windows 7 with KB2479710) [policy hook + extended patch]
6.1.7600.21316 (Windows 7 with KB2750090) [policy hook + extended patch]
6.1.7600.21420 (Windows 7 with KB2800789) [todo]
6.1.7601.17514 (Windows 7 SP1) [policy hook + extended patch]
6.1.7601.21855 (Windows 7 SP1 with KB951422 v2) [todo]
6.1.7601.21650 (Windows 7 SP1 with KB2479710) [policy hook + extended patch]
6.1.7601.21866 (Windows 7 SP1 with KB2647409) [policy hook + extended patch]
6.1.7601.22104 (Windows 7 SP1 with KB2750090) [policy hook + extended patch]
6.1.7601.22213 (Windows 7 SP1 with KB2800789) [todo]
6.1.7601.22476 (Windows 7 SP1 with KB2870165) [todo]
6.1.7601.22435 (Windows 7 SP1 with KB2878424) [todo]
6.1.7601.22477 (Windows 7 SP1 with KB2896256) [todo]
6.1.7601.18540 (Windows 7 SP1 with KB2984972 GDR) [policy hook + extended patch]
6.1.7601.22750 (Windows 7 SP1 with KB2984972 LDR) [policy hook + extended patch]
6.1.7601.18637 (Windows 7 SP1 with KB3003743 GDR) [policy hook + extended patch]
6.1.7601.22843 (Windows 7 SP1 with KB3003743 LDR) [policy hook + extended patch]
6.1.7601.23403 (Windows 7 SP1 with KB3125574) [policy hook + extended patch]
6.1.7601.24234 (Windows 7 SP1 with KB4462923) [policy hook + extended patch]
6.2.8102.0 (Windows 8 Developer Preview) [policy hook + extended patch]
6.2.8250.0 (Windows 8 Consumer Preview) [policy hook + extended patch]
6.2.8400.0 (Windows 8 Release Preview) [policy hook + extended patch]
6.2.9200.16384 (Windows 8) [policy hook + extended patch]
6.2.9200.17048 (Windows 8 with KB2973501 GDR) [policy hook + extended patch]
6.2.9200.21166 (Windows 8 with KB2973501 LDR) [policy hook + extended patch]
6.3.9431.0 (Windows 8.1 Preview) [init hook + extended patch]
6.3.9600.16384 (Windows 8.1) [init hook + extended patch]
6.3.9600.17095 (Windows 8.1 with KB2959626) [init hook + extended patch]
6.3.9600.17415 (Windows 8.1 with KB3000850) [init hook + extended patch]
6.3.9600.18692 (Windows 8.1 with KB4022720) [init hook + extended patch]
6.3.9600.18708 (Windows 8.1 with KB4025335) [init hook + extended patch]
6.3.9600.18928 (Windows 8.1 with KB4088876) [init hook + extended patch]
6.3.9600.19093 (Windows 8.1 with KB4343891) [init hook + extended patch]
6.4.9841.0 (Windows 10 Technical Preview) [init hook + extended patch]
6.4.9860.0 (Windows 10 Technical Preview UP1) [init hook + extended patch]
6.4.9879.0 (Windows 10 Technical Preview UP2) [init hook + extended patch]
10.0.9926.0 (Windows 10 Pro Technical Preview) [init hook + extended patch]
10.0.10041.0 (Windows 10 Pro Technical Preview UP1) [init hook + extended patch]
10.0.10049.0 (Windows 10 Pro Technical Preview UP2) [todo]
10.0.10061.0 (Windows 10 Pro Technical Preview UP3) [todo]
10.0.10240.16384 (Windows 10 RTM) [init hook + extended patch]
10.0.10525.0 (Windows 10 th2_release.150812-1658) [todo]
10.0.10532.0 (Windows 10 th2_release.150822-1406) [todo]
10.0.10547.0 (Windows 10 th2_release.150913-1511) [todo]
10.0.10586.0 (Windows 10 th2_release.151029-1700) [init hook + extended patch]
10.0.10586.589 (Windows 10 th2_release.160906-1759) [init hook + extended patch]
10.0.11082.1000 (Windows 10 rs1_release.151210-2021) [init hook + extended patch]
10.0.11102.1000 (Windows 10 rs1_release.160113-1800) [init hook + extended patch]
10.0.14251.1000 (Windows 10 rs1_release.160124-1059) [init hook + extended patch]
10.0.14271.1000 (Windows 10 rs1_release.160218-2310) [init hook + extended patch]
10.0.14279.1000 (Windows 10 rs1_release.160229-1700) [init hook + extended patch]
10.0.14295.1000 (Windows 10 rs1_release.160318-1628) [init hook + extended patch]
10.0.14300.1000 (Windows Server 2016 Technical Preview 5) [init hook + extended patch]
10.0.14316.1000 (Windows 10 rs1_release.160402-2227) [init hook + extended patch]
10.0.14328.1000 (Windows 10 rs1_release.160418-1609) [init hook + extended patch]
10.0.14332.1001 (Windows 10 rs1_release.160422-1940) [init hook + extended patch]
10.0.14342.1000 (Windows 10 rs1_release.160506-1708) [init hook + extended patch]
10.0.14352.1002 (Windows 10 rs1_release.160522-1930) [init hook + extended patch]
10.0.14366.0 (Windows 10 rs1_release.160610-1700) [init hook + extended patch]
10.0.14367.0 (Windows 10 rs1_release.160613-1700) [init hook + extended patch]
10.0.14372.0 (Windows 10 rs1_release.160620-2342) [init hook + extended patch]
10.0.14379.0 (Windows 10 rs1_release.160627-1607) [init hook + extended patch]
10.0.14383.0 (Windows 10 rs1_release.160701-1839) [init hook + extended patch]
10.0.14385.0 (Windows 10 rs1_release.160706-1700) [init hook + extended patch]
10.0.14388.0 (Windows 10 rs1_release.160709-1635) [init hook + extended patch]
10.0.14393.0 (Windows 10 rs1_release.160715-1616) [init hook + extended patch]
10.0.14393.1198 (Windows 10 rs1_release_sec.170427-1353) [init hook + extended patch]
10.0.14393.1737 (Windows 10 rs1_release_inmarket.170914-1249) [init hook + extended patch]
10.0.14393.2457 (Windows 10 rs1_release_inmarket.180822-1743) [init hook + extended patch]
10.0.14901.1000 (Windows 10 rs_prerelease.160805-1700) [init hook + extended patch]
10.0.14905.1000 (Windows 10 rs_prerelease.160811-1739) [init hook + extended patch]
10.0.14915.1000 (Windows 10 rs_prerelease.160826-1902) [init hook + extended patch]
10.0.14926.1000 (Windows 10 rs_prerelease.160910-1529) [init hook + extended patch]
10.0.14931.1000 (Windows 10 rs_prerelease.160916-1700) [init hook + extended patch]
10.0.14936.1000 (Windows 10 rs_prerelease.160923-1700) [init hook + extended patch]
10.0.14942.1000 (Windows 10 rs_prerelease.161003-1929) [init hook + extended patch]
10.0.14946.1000 (Windows 10 rs_prerelease.161007-1700) [init hook + extended patch]
10.0.14951.1000 (Windows 10 rs_prerelease.161014-1700) [init hook + extended patch]
10.0.14955.1000 (Windows 10 rs_prerelease.161020-1700) [init hook + extended patch]
10.0.14959.1000 (Windows 10 rs_prerelease.161026-1700) [init hook + extended patch]
10.0.14965.1001 (Windows 10 rs_prerelease.161104-1700) [init hook + extended patch]
10.0.14971.1000 (Windows 10 rs_prerelease.161111-1700) [init hook + extended patch]
10.0.14986.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.14997.1001 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15002.1001 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15007.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15014.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15019.1000 (Windows 10 rs_prerelease.170121-1513) [init hook + extended patch]
10.0.15025.1000 (Windows 10 rs_prerelease.170127-1750) [init hook + extended patch]
10.0.15031.0 (Windows 10 rs2_release.170204-1546) [init hook + extended patch]
10.0.15042.0 (Windows 10 rs2_release.170219-2329) [init hook + extended patch]
10.0.15046.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15048.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15055.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15058.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15061.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15063.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15063.296 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15063.994 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.15063.1155 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16179.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16184.1001 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16199.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16215.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16232.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16237.1001 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16241.1001 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16251.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16251.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16257.1 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16257.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16273.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16275.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16278.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16281.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16288.1 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16291.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16294.1 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16296.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16299.0 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16299.15 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16353.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.16362.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17004.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17017.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17025.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17035.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17040.1000 (Windows 10 WinBuild.160101.0800) [todo]
10.0.17046.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17063.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17074.1002 (Windows 10 WinBuild.160101.0800) [todo]
10.0.17083.1000 (Windows 10 WinBuild.160101.0800) [todo]
10.0.17115.1 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17128.1 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17133.1 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17134.1 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17723.1000 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
10.0.17763.1 (Windows 10 WinBuild.160101.0800) [init hook + extended patch]
Source code changelog (rdpwrap library):
2018.10.10 :
- added support for termsrv.dll 6.1.7601.24234 x86
2018.10.04 :
- added support for termsrv.dll 10.0.14393.2457 x86
2018.10.03 :
- added support for termsrv.dll 6.1.7601.24234 x64
- added support for termsrv.dll 10.0.15063.994 x64
- added support for termsrv.dll 10.0.17723.1000 x64
- added support for termsrv.dll 10.0.17763.1
2018.09.10 :
- added support for termsrv.dll 6.1.7600.20890
- added support for termsrv.dll 6.1.7600.21316
- added support for termsrv.dll 6.1.7601.21650
- added support for termsrv.dll 6.1.7601.21866
- added support for termsrv.dll 6.1.7601.22104
- added support for termsrv.dll 6.3.9600.19093
- added support for termsrv.dll 10.0.14393.2457 x64
- added support for termsrv.dll 10.0.15063.1155 x64
2018.05.16 :
- added support for termsrv.dll 10.0.17115.1
- added support for termsrv.dll 10.0.17128.1
- added support for termsrv.dll 10.0.17133.1
- added support for termsrv.dll 10.0.17134.1
2018.03.26 :
- added support for termsrv.dll 6.3.9600.18928 by 1nd1g0
2017.12.27 :
- added support for termsrv.dll 10.0.17017.1000
- added support for termsrv.dll 10.0.17025.1000
- added support for termsrv.dll 10.0.17035.1000
- added support for termsrv.dll 10.0.17046.1000
- added support for termsrv.dll 10.0.17063.1000
2017.10.13 :
- added support for termsrv.dll 10.0.14393.1737
- added support for termsrv.dll 10.0.16299.0
- added support for termsrv.dll 10.0.16299.15
- added support for termsrv.dll 10.0.17004.1000
2017.09.24 :
- added support for termsrv.dll 10.0.16291.0
- added support for termsrv.dll 10.0.16294.1
- added support for termsrv.dll 10.0.16296.0
- added support for termsrv.dll 10.0.16362.1000
2017.09.15 :
- added support for termsrv.dll 10.0.16288.1
2017.09.06 :
- added support for termsrv.dll 10.0.16273.1000
- added support for termsrv.dll 10.0.16275.1000
- added support for termsrv.dll 10.0.16278.1000
- added support for termsrv.dll 10.0.16281.1000
- added support for termsrv.dll 10.0.16353.1000
2017.08.04 :
- added support for termsrv.dll 10.0.16257.1
- added support for termsrv.dll 10.0.16257.1000
2017.07.30 :
- added support for termsrv.dll 6.3.9600.18708
- added support for termsrv.dll 10.0.16232.1000
- added support for termsrv.dll 10.0.16237.1001
- added support for termsrv.dll 10.0.16241.1001
- added support for termsrv.dll 10.0.16251.0
- added support for termsrv.dll 10.0.16251.1000
2017.06.29 :
- added support for termsrv.dll 6.3.9600.18692
2017.06.10 :
- added support for termsrv.dll 10.0.15063.296
- added support for termsrv.dll 10.0.16215.1000
2017.05.29 :
- added support for termsrv.dll 10.0.16199.1000
2017.05.17 :
- added support for termsrv.dll 10.0.14997.1001 x64
2017.05.12 :
- added support for termsrv.dll 10.0.14393.1198 x86
2017.05.03 :
- added support for termsrv.dll 10.0.16179.1000
- added support for termsrv.dll 10.0.16184.1001
2017.03.22 :
- added support for termsrv.dll 10.0.15063.0
2017.03.21 :
- added support for termsrv.dll 10.0.15061.0
2017.03.16 :
- added support for termsrv.dll 10.0.15058.0
2017.03.14 :
- added support for termsrv.dll 10.0.15055.0
2017.03.05 :
- added support for termsrv.dll 10.0.15048.0
2017.03.02 :
- added support for termsrv.dll 10.0.15046.0
2017.03.01 :
- added support for termsrv.dll 10.0.15031.0
- added support for termsrv.dll 10.0.15042.0
2017.02.03 :
- added support for termsrv.dll 10.0.15025.1000 x64
2017.01.28 :
- added support for termsrv.dll 10.0.15019.1000
2017.01.21 :
- added support for termsrv.dll 10.0.15014.1000
2017.01.15 :
- added support for termsrv.dll 10.0.15007.1000
2017.01.12 :
- added support for termsrv.dll 10.0.15002.1001
2016.12.23 :
- added support for termsrv.dll 10.0.14986.1000
2016.11.19 :
- added support for termsrv.dll 10.0.14959.1000
- added support for termsrv.dll 10.0.14965.1001
- added support for termsrv.dll 10.0.14971.1000
2016.10.28 :
- added support for termsrv.dll 10.0.14955.1000
2016.10.21 :
- added support for termsrv.dll 10.0.14951.1000
2016.10.19 :
- added support for termsrv.dll 10.0.14946.1000
2016.10.08 :
- added support for termsrv.dll 10.0.14942.1000
2016.09.30 :
- added support for termsrv.dll 10.0.14936.1000
2016.09.27 :
- added support for termsrv.dll 10.0.14931.1000
2016.09.15 :
- added support for termsrv.dll 10.0.14926.1000
2016.09.14 :
- added support for termsrv.dll 10.0.10586.589
2016.09.03 :
- added support for termsrv.dll 10.0.14915.1000
2016.08.28 :
- added support for termsrv.dll 6.1.7601.23403
- added support for termsrv.dll 10.0.14901.1000
- added support for termsrv.dll 10.0.14905.1000
2016.08.12 :
- added support for termsrv.dll 10.0.14385.0
2016.08.01 :
- preparing the release
2016.07.23 :
- added online install mode to installer
- added feature to keep settings on uninstall
- fixed update firewall rule on port change in config tool
- added feature to hide users on logon
2016.07.22 :
- added support for termsrv.dll 10.0.14393.0
2016.07.15 :
- added support for termsrv.dll 10.0.14383.0
- added support for termsrv.dll 10.0.14388.0
2016.07.06 :
- added support for termsrv.dll 10.0.14379.0
2016.06.27 :
- added support for termsrv.dll 10.0.14372.0 x86
2016.06.26 :
- added support for termsrv.dll 10.0.14372.0 x64 by kbmorris
2016.06.17 :
- fixed issue with termsrv.dll 10.0.14352.1002
- added support for termsrv.dll 10.0.14366.0
- added support for termsrv.dll 10.0.14367.0
2016.05.30 :
- added support for termsrv.dll 10.0.14352.1002
2016.05.14 :
- added support for termsrv.dll 10.0.14342.1000
2016.05.08 :
- added support for termsrv.dll 10.0.14300.1000 x64
- added support for termsrv.dll 10.0.14328.1000
2016.04.29 :
- added support for termsrv.dll 10.0.14332.1001 by maxpiva
2016.04.14 :
- added support for termsrv.dll 10.0.14316.1000
2016.04.06 :
- added support for termsrv.dll 10.0.14295.1000
2016.03.07 :
- added experimental codes for ARMv7 architecture (see rdpwrap-arm-kb.ini)
- Windows RT / termsrv.dll 6.2.9200.16384
- Windows RT 8.1 / termsrv.dll 6.3.9600.16384
- Windows RT 8.1 / termsrv.dll 6.3.9600.17095
2016.03.06 :
- added support for termsrv.dll 10.0.14279.1000
2016.02.29 :
- added support for termsrv.dll 10.0.14271.1000
2016.01.28 :
- added support for termsrv.dll 10.0.14251.1000
2016.01.26 :
- added support for termsrv.dll 10.0.11102.1000
2016.01.15 :
- updated messages in the installer
- added support for termsrv.dll 10.0.11082.1000
2015.11.14 :
- added support for termsrv.dll 10.0.10586.0
2015.08.11 :
- embed new rdpclip versions in the installer (for NT 6.0 and 6.1)
- preparing the release
2015.08.07 :
- added INI update feature to installer
2015.07.30 :
- fixed issue with Windows 10 Home x86 (wrong LocalOnly offset was specified in INI file)
2015.07.17 :
- added support for termsrv.dll 10.0.10240.16384
- added HOW TO hints to KB (so other reverse engineers can do this hard work more easier)
2015.07.16 :
- moved all comments from INI file to Knowledge Base text file
- now INI file have smaller size
- updated RDP checker: changed IP Address to 127.0.0.2 (sometimes client doesn't want to connect .1), updated text message
- updated RDP config: list all possible shadowing modes, also write group policy
- updated installer: added workaround for 1056 error
- updated copyright years in source code
- obtained files from build 10.0.10240.16384
- researching Windows 10 RTM
2015.03.23 :
- researching Windows 10 Pro Technical Preview UP1
- added support for termsrv.dll 10.0.10041.0
2015.03.20 :
- new build 10.0.10041.0 was released, obtaining files...
2015.01.26 :
- researching Windows 10 Pro Technical Preview (10.0.9926.0 x86)
- added support for termsrv.dll 10.0.9926.0 (x86)
2015.01.22 :
- v-yadli contributed offsets for version 10.0.9926.0 (x64)
2014.12.13 :
- added more policy values to INI file
2014.12.10 :
- C++ version seems to work well now!
- added support for termsrv.dll 6.4.9879.0
- preparing the new release
2014.12.09 :
- many bug fixes in C++ version, you can track it in the git history :)
- it can be compiled now :D
- we are getting closer to the finish line!
2014.12.03 :
- added INI reader by Fusix for C++ version
- asulwer also helped with the development
2014.11.25 :
- corrected some typos in INI file
- added EasyPrint policy value
2014.11.24 :
- added support for termsrv.dll 6.3.9600.17415
2014.11.21 :
- new LiteINI module to read INI files
- added support to store patch settings in INI file
- version support can be extended without recompilation
- C++ version needs to be updated
2014.11.20 :
- improved comments
- researching KB3000850
- found required files
- improving RDPWrap...
- placing signatures, offsets, values, etc in separate config file
- working with code
2014.11.13 :
- researching KB3003743
- added support for version 6.0.6002.19214
- added support for version 6.0.6002.23521
- added support for version 6.1.7601.18637
- added support for version 6.1.7601.22843
2014.11.02 :
- researching termsrv.dll 6.4.9860.0
- done
2014.10.19 :
- added support for version 6.0.6000.16386 (x64)
- added support for version 6.0.6001.18000 (x64)
- added support for version 6.1.7600.16385
2014.10.18 :
- corrected some typos in source
- simplified signature constants
- added support for version 6.0.6000.16386 (x86)
- added support for version 6.0.6001.18000 (x86)
- added support for version 6.0.6002.18005
- added support for version 6.1.7601.17514
- added support for version 6.1.7601.18540
- added support for version 6.1.7601.22750
- added support for version 6.2.9200.17048
- added support for version 6.2.9200.21166
2014.10.17 :
- collecting information about all versions of Terminal Services beginning from Vista
- added [todo] to the versions list
2014.10.16 :
- got new updates: KB2984972 for Win 7 (still works with 2 concurrent users) and KB2973501 for Win 8 (doesn't work)
2014.10.02 :
- researching Windows 10 TP Remote Desktop
- done! even without debugging symbols ^^)
2014.07.20 :
- added support for Windows 8 Release Preview
- added support for Windows 8 Consumer Preview
- added support for Windows 8 Developer Preview
2014.07.19 :
- improved patching of Windows 8
- added policy patches
- will patch CDefPolicy::Query
- will patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled
2014.07.18 :
- researched patched files from MDL forum
- CSLQuery::GetMaxSessions requires no patching
- it's better to change the default policy, so...
- will patch CDefPolicy::Query
- will patch CEnforcementCore::GetInstanceOfTSLicense
- will patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled
- the function CSLQuery::Initialize is hooked correctly
2014.07.17 :
- will hook only CSLQuery::Initialize function
- CSLQuery::GetMaxSessions will be patched
- added x86 signatures for 6.3.9431.0 (Windows 8.1 Preview)
2014.07.16 :
- changing asm opcodes is bad, will hook CSL functions
2014.07.15 :
- added x86 signatures for 6.3.9600.16384 (Windows 8.1)
2014.07.15 :
- added x86 signatures for 6.3.9600.17095 (Windows 8.1 with KB2959626)