Compare commits
98 Commits
Author | SHA1 | Date | |
---|---|---|---|
5553d07206 | |||
216255b3b4 | |||
e11b3c7354 | |||
f534a1c8fc | |||
d4d5111711 | |||
4bf2866b49 | |||
7c52a27ba5 | |||
e6686b3b35 | |||
1f8e2b9e65 | |||
946bd7f8a6 | |||
b9149eef02 | |||
80387dcc31 | |||
8ac3396165 | |||
8be10a125b | |||
7baa979752 | |||
425fc02fec | |||
659ba3dbcf | |||
efe2872a26 | |||
ca71d4ace4 | |||
a42b740946 | |||
fca45f61e7 | |||
5062ff6c75 | |||
9a7c501ca9 | |||
adabe322c3 | |||
eca971de03 | |||
6f23a18a24 | |||
09bfc748f4 | |||
97d0b92054 | |||
867c271cb3 | |||
fd56533897 | |||
782dc346a9 | |||
ca36e9f49f | |||
513a7a1ebf | |||
657ee646d5 | |||
5a37f663bc | |||
33e3e3664c | |||
c75ff99bd3 | |||
d6c1110ff6 | |||
742fd143ea | |||
43c7e7fb57 | |||
bca5e184ad | |||
f0d5f3a6de | |||
6c2747a08f | |||
f8de2d5297 | |||
1febb524bc | |||
cf53e9c984 | |||
6059197036 | |||
939a884f20 | |||
239cd5fe3f | |||
ac5cb9e480 | |||
b5b5806177 | |||
31cce7a873 | |||
4054ef493b | |||
d7d00ae309 | |||
60027d5e02 | |||
190dd74a65 | |||
ddb15f8cf5 | |||
539bdbfc52 | |||
39b8c6fade | |||
e2968a43de | |||
e3ce360ec9 | |||
12e04325dc | |||
a449d04619 | |||
87887259b2 | |||
b5e4350d0b | |||
7d5f17edf6 | |||
32185c9c12 | |||
06eb0a325e | |||
e1b4b10006 | |||
c79a7bc152 | |||
7873abd48c | |||
a0576b6ffb | |||
03bbf7d7a8 | |||
faf2bdc905 | |||
9033bd91f1 | |||
8b85f43605 | |||
e2e4a33954 | |||
436c1e2c75 | |||
4d89fc245a | |||
17102ec1cd | |||
bc84ee3ac4 | |||
d2449ccdd6 | |||
81baa4522f | |||
2136d2c358 | |||
61f6adf1f2 | |||
edbff7bedd | |||
2c7e0279e0 | |||
1d35b31d6e | |||
c47495acc5 | |||
95b6719cbc | |||
0e322ede13 | |||
1a9d9e7fea | |||
136f4c7de8 | |||
74e5708a17 | |||
dd92b47812 | |||
64b3bf8bc1 | |||
6b4dadcde5 | |||
88d60769a2 |
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Delphi local files (user-specific info)
|
||||||
|
*.local
|
||||||
|
*.identcache
|
||||||
|
|
||||||
|
# Delphi history and backups
|
||||||
|
__history/
|
||||||
|
*.~*
|
||||||
|
|
||||||
|
# Compiled binaries
|
||||||
|
*.dcu
|
||||||
|
*.exe
|
||||||
|
*.dll
|
217
LICENSE
217
LICENSE
@ -1,25 +1,202 @@
|
|||||||
This is free and unencumbered software released into the public domain.
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
distribute this software, either in source code form or as a compiled
|
|
||||||
binary, for any purpose, commercial or non-commercial, and by any
|
|
||||||
means.
|
|
||||||
|
|
||||||
In jurisdictions that recognize copyright laws, the author or authors
|
1. Definitions.
|
||||||
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.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
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.
|
|
||||||
|
|
||||||
For more information, please refer to <http://unlicense.org>
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"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.
|
||||||
|
|
||||||
|
73
README.md
73
README.md
@ -17,6 +17,8 @@ Screenshots:<br>
|
|||||||
<a href="http://stascorp.com/images/rdpwrap/Win81P.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin81P.jpg"></a>
|
<a href="http://stascorp.com/images/rdpwrap/Win81P.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin81P.jpg"></a>
|
||||||
<a href="http://stascorp.com/images/rdpwrap/Win81.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin81.jpg"></a>
|
<a href="http://stascorp.com/images/rdpwrap/Win81.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin81.jpg"></a>
|
||||||
<a href="http://stascorp.com/images/rdpwrap/Win10TP.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin10TP.jpg"></a>
|
<a href="http://stascorp.com/images/rdpwrap/Win10TP.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin10TP.jpg"></a>
|
||||||
|
<a href="http://stascorp.com/images/rdpwrap/Win10PTP.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin10PTP.jpg"></a>
|
||||||
|
<a href="http://stascorp.com/images/rdpwrap/Win10.png" target="_blank"><img src="http://stascorp.com/images/rdpwrap/pWin10.jpg"></a>
|
||||||
</div><br>
|
</div><br>
|
||||||
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>
|
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>
|
||||||
- binarymaster<br>
|
- binarymaster<br>
|
||||||
@ -35,6 +37,10 @@ Porting to other platforms:<br>
|
|||||||
• <b>ARM</b> for Windows RT (see links below)<br>
|
• <b>ARM</b> for Windows RT (see links below)<br>
|
||||||
• <b>IA-64</b> for Itanium-based Windows Server? <i>Well, I have no idea</i> :)<br>
|
• <b>IA-64</b> for Itanium-based Windows Server? <i>Well, I have no idea</i> :)<br>
|
||||||
<br>
|
<br>
|
||||||
|
Building the binaries:<br>
|
||||||
|
• <b>x86 Delphi version</b> can be built with <i>Embarcadero RAD Studio 2010</i><br>
|
||||||
|
• <b>x86/x64 C++ version</b> can be built with <i>Microsoft Visual Studio 2013</i><br>
|
||||||
|
<br>
|
||||||
<b>Links:</b><br>
|
<b>Links:</b><br>
|
||||||
• Official GitHub repository:<br>
|
• Official GitHub repository:<br>
|
||||||
<a href="https://github.com/binarymaster/rdpwrap/" target="_blank">https://github.com/binarymaster/rdpwrap/</a><br>
|
<a href="https://github.com/binarymaster/rdpwrap/" target="_blank">https://github.com/binarymaster/rdpwrap/</a><br>
|
||||||
@ -47,18 +53,50 @@ Porting to other platforms:<br>
|
|||||||
• Adding «Remote Desktop Users» group:<br>
|
• Adding «Remote Desktop Users» group:<br>
|
||||||
<a href="http://superuser.com/questions/680572/" target="_blank">http://superuser.com/questions/680572/</a><br>
|
<a href="http://superuser.com/questions/680572/" target="_blank">http://superuser.com/questions/680572/</a><br>
|
||||||
<br>
|
<br>
|
||||||
|
<b>Tutorial videos:</b><br>
|
||||||
|
• <a href="http://www.youtube.com/watch?v=W9BpbEt1yJw" target="_blank">Updating RDP Wrapper INI file manually</a><br>
|
||||||
|
• <a href="http://www.youtube.com/watch?v=FiD86tmRBtk" target="_blank">How to find offsets for new termsrv.dll versions</a><br>
|
||||||
|
<br>
|
||||||
Files description:<br>
|
Files description:<br>
|
||||||
<br>
|
<br>
|
||||||
<table style="border-collapse: collapse; width: 100%; border: 1px solid black;" width="" align="">
|
<table style="border-collapse: collapse; width: 100%; border: 1px solid black;" width="" align="">
|
||||||
<tbody>
|
<tbody>
|
||||||
<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>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>
|
<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>
|
||||||
|
<tr><td style="border: 1px solid black;"><b>RDPConf.exe</b></td><td style="border: 1px solid black;">RDP Wrapper Configuration</td></tr>
|
||||||
<tr><td style="border: 1px solid black;"><b>install.bat</b></td><td style="border: 1px solid black;">Quick install batch file</td></tr>
|
<tr><td style="border: 1px solid black;"><b>install.bat</b></td><td style="border: 1px solid black;">Quick install batch file</td></tr>
|
||||||
<tr><td style="border: 1px solid black;"><b>uninstall.bat</b></td><td style="border: 1px solid black;">Quick uninstall batch file</td></tr>
|
<tr><td style="border: 1px solid black;"><b>uninstall.bat</b></td><td style="border: 1px solid black;">Quick uninstall batch file</td></tr>
|
||||||
|
<tr><td style="border: 1px solid black;"><b>update.bat</b></td><td style="border: 1px solid black;">Quick update batch file</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table><br>
|
</table><br>
|
||||||
Change log:<br>
|
Change log:<br>
|
||||||
<br>
|
<br>
|
||||||
|
<b><u>2015.08.12</u></b><br>
|
||||||
|
• Version 1.6<br>
|
||||||
|
• Added support for Windows 10<br>
|
||||||
|
• INI file has smaller size now - all comments are moved to KB file<br>
|
||||||
|
• Installer updated<br>
|
||||||
|
• Added workaround for 1056 error (although it isn't an error)<br>
|
||||||
|
• Added update support to installer<br>
|
||||||
|
• Newest RDPClip versions are included with installer<br>
|
||||||
|
• RDP Checker updated<br>
|
||||||
|
• Changed connect IP to 127.0.0.2<br>
|
||||||
|
• Updated some text messages<br>
|
||||||
|
• RDP Config updated<br>
|
||||||
|
• Added all possible shadowing modes<br>
|
||||||
|
• Also it will write settings to the group policy<br>
|
||||||
|
<br>
|
||||||
|
<b><u>2014.12.11</u></b><br>
|
||||||
|
• Version 1.5<br>
|
||||||
|
• Added INI config support<br>
|
||||||
|
• Configuration is stored in INI file now<br>
|
||||||
|
• We can extend version support without building new binaries<br>
|
||||||
|
• Added support for Windows 8.1 with KB3000850<br>
|
||||||
|
• Added support for Windows 10 Technical Preview Update 2<br>
|
||||||
|
• Installer updated<br>
|
||||||
|
• RDP Config updated<br>
|
||||||
|
• Diagnostics feature added to RDP Config<br>
|
||||||
|
<br>
|
||||||
<b><u>2014.11.14</u></b><br>
|
<b><u>2014.11.14</u></b><br>
|
||||||
• Version 1.4<br>
|
• Version 1.4<br>
|
||||||
• Added support for Windows 10 Technical Preview Update 1<br>
|
• Added support for Windows 10 Technical Preview Update 1<br>
|
||||||
@ -141,16 +179,21 @@ Change log:<br>
|
|||||||
• <u>6.3.9431.0</u> (Windows 8.1 Preview)<br>
|
• <u>6.3.9431.0</u> (Windows 8.1 Preview)<br>
|
||||||
• <u>6.3.9600.16384</u> (Windows 8.1 / Server 2012 R2)<br>
|
• <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>
|
• <u>6.3.9600.17095</u> (Windows 8.1 with KB2959626)<br>
|
||||||
|
• <u>6.3.9600.17415</u> (Windows 8.1 with KB3000850)<br>
|
||||||
• <u>6.4.9841.0</u> (Windows 10 Technical Preview)<br>
|
• <u>6.4.9841.0</u> (Windows 10 Technical Preview)<br>
|
||||||
• <u>6.4.9860.0</u> (Windows 10 Technical Preview Update 1)<br>
|
• <u>6.4.9860.0</u> (Windows 10 Technical Preview Update 1)<br>
|
||||||
|
• <u>6.4.9879.0</u> (Windows 10 Technical Preview Update 2)<br>
|
||||||
|
• <u>10.0.9926.0</u> (Windows 10 Pro Technical Preview)<br>
|
||||||
|
• <u>10.0.10041.0</u> (Windows 10 Pro Technical Preview Update 1)<br>
|
||||||
|
• <u>10.0.10240.16384</u> (Windows 10 RTM)<br>
|
||||||
<br>
|
<br>
|
||||||
<b>Confirmed working on:</b><br>
|
<b>Confirmed working on:</b><br>
|
||||||
• Windows Vista Starter (x86 - Service Pack 1 and higher)<br>
|
• Windows Vista Starter (x86 - Service Pack 1 and higher)<br>
|
||||||
• Windows Vista Home Basic (x86 - Service Pack 1 and higher)<br>
|
• Windows Vista Home Basic<br>
|
||||||
• Windows Vista Home Premium (x86 - Service Pack 1 and higher)<br>
|
• Windows Vista Home Premium<br>
|
||||||
• Windows Vista Business (x86 - Service Pack 1 and higher)<br>
|
• Windows Vista Business<br>
|
||||||
• Windows Vista Enterprise (x86 - Service Pack 1 and higher)<br>
|
• Windows Vista Enterprise<br>
|
||||||
• Windows Vista Ultimate (x86 - Service Pack 1 and higher)<br>
|
• Windows Vista Ultimate<br>
|
||||||
• Windows 7 Starter<br>
|
• Windows 7 Starter<br>
|
||||||
• Windows 7 Home Basic<br>
|
• Windows 7 Home Basic<br>
|
||||||
• Windows 7 Home Premium<br>
|
• Windows 7 Home Premium<br>
|
||||||
@ -166,23 +209,33 @@ Change log:<br>
|
|||||||
• Windows 8 Enterprise<br>
|
• Windows 8 Enterprise<br>
|
||||||
• Windows 8.1 Preview<br>
|
• Windows 8.1 Preview<br>
|
||||||
• Windows 8.1<br>
|
• Windows 8.1<br>
|
||||||
|
• Windows 8.1 Connected (with Bing)<br>
|
||||||
• Windows 8.1 Single Language<br>
|
• Windows 8.1 Single Language<br>
|
||||||
|
• Windows 8.1 Connected Single Language (with Bing)<br>
|
||||||
• Windows 8.1 Pro<br>
|
• Windows 8.1 Pro<br>
|
||||||
• Windows 8.1 Enterprise<br>
|
• Windows 8.1 Enterprise<br>
|
||||||
• Windows 10 Technical Preview<br>
|
• Windows 10 Technical Preview<br>
|
||||||
|
• Windows 10 Pro Technical Preview<br>
|
||||||
|
• Windows 10 Home<br>
|
||||||
|
• Windows 10 Pro<br>
|
||||||
|
• Windows 10 Enterprise<br>
|
||||||
<br>
|
<br>
|
||||||
<b>Working partially:</b><br>
|
<b>Known issues:</b><br>
|
||||||
• Windows Vista Starter RTM x86 (termsrv.dll 6.0.6000.16386 : RDP works, but termsrv.dll crashes on logon attempt)<br>
|
• Beginning with Windows 8 (non-server editions) you can't connect to existing sessions (they will be logged out by system)<br>
|
||||||
|
• RDP works, but termsrv.dll crashes on logon attempt - Windows Vista Starter RTM x86 (termsrv.dll 6.0.6000.16386)<br>
|
||||||
|
• If Terminal Services hangs at startup, try to add <b>rdpwrap.dll</b> to antivirus exclusions. Also try to isolate RDP Wrapper from other shared services by the command:<br>
|
||||||
|
<tt>sc config TermService type= own</tt><br>
|
||||||
|
• RDP Wrapper Installer can be removed by AVG Free Antivirus after reboot - add it to exclusions.<br>
|
||||||
<br>
|
<br>
|
||||||
<u>Installation instructions:</u><br>
|
<u>Installation instructions:</u><br>
|
||||||
1. Download and unpack files<br>
|
1. Download latest release binaries and unpack files<br>
|
||||||
2. Run <b>Command Prompt (cmd)</b> as administrator<br>
|
2. Run <b>Command Prompt (cmd)</b> as administrator<br>
|
||||||
3. Change directory to <b>/bin</b> (where binaries and batch files are placed)<br>
|
3. Change directory to where you extracted the files<br>
|
||||||
4. Type <b>install.bat</b> and press Enter<br>
|
4. Type <b>install.bat</b> and press Enter<br>
|
||||||
5. See command output for details<br>
|
5. See command output for details<br>
|
||||||
<br>
|
<br>
|
||||||
<u>To uninstall:</u><br>
|
<u>To uninstall:</u><br>
|
||||||
1. Run <b>Command Prompt</b> as administrator<br>
|
1. Run <b>Command Prompt</b> as administrator<br>
|
||||||
2. Change directory to <b>/bin</b><br>
|
2. Change directory to where you extracted the files<br>
|
||||||
3. Type <b>uninstall.bat</b> and press Enter<br>
|
3. Type <b>uninstall.bat</b> and press Enter<br>
|
||||||
4. See command output for details<br>
|
4. See command output for details<br>
|
||||||
|
BIN
bin/RDPCheck.exe
BIN
bin/RDPCheck.exe
Binary file not shown.
BIN
bin/RDPConf.exe
BIN
bin/RDPConf.exe
Binary file not shown.
BIN
bin/RDPWInst.exe
BIN
bin/RDPWInst.exe
Binary file not shown.
@ -1,8 +1,14 @@
|
|||||||
@echo off
|
@echo off
|
||||||
RDPWInst -i
|
if not exist "%~dp0RDPWInst.exe" goto :error
|
||||||
|
"%~dp0RDPWInst" -i
|
||||||
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
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
@echo off
|
@echo off
|
||||||
RDPWInst -u
|
if not exist "%~dp0RDPWInst.exe" goto :error
|
||||||
|
"%~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
|
||||||
|
10
bin/update.bat
Normal file
10
bin/update.bat
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@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
|
Binary file not shown.
Binary file not shown.
1652
res/rdpwrap-ini-kb.txt
Normal file
1652
res/rdpwrap-ini-kb.txt
Normal file
File diff suppressed because it is too large
Load Diff
770
res/rdpwrap.ini
Normal file
770
res/rdpwrap.ini
Normal file
@ -0,0 +1,770 @@
|
|||||||
|
; RDP Wrapper Library configuration
|
||||||
|
; Do not modify without special knowledge
|
||||||
|
|
||||||
|
[Main]
|
||||||
|
Updated=2015-07-30
|
||||||
|
LogFile=\rdpwrap.txt
|
||||||
|
SLPolicyHookNT60=1
|
||||||
|
SLPolicyHookNT61=1
|
||||||
|
|
||||||
|
[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]
|
||||||
|
nop=90
|
||||||
|
Zero=00
|
||||||
|
jmpshort=EB
|
||||||
|
nopjmp=90E9
|
||||||
|
CDefPolicy_Query_edx_ecx=BA000100008991200300005E90
|
||||||
|
CDefPolicy_Query_eax_rcx_jmp=B80001000089813806000090EB
|
||||||
|
CDefPolicy_Query_eax_esi=B80001000089862003000090
|
||||||
|
CDefPolicy_Query_eax_rdi=B80001000089873806000090
|
||||||
|
CDefPolicy_Query_eax_ecx=B80001000089812003000090
|
||||||
|
CDefPolicy_Query_eax_rcx=B80001000089813806000090
|
||||||
|
|
||||||
|
[6.0.6000.16386]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=160BF
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=65E3E
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=15CD8
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_edx_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=5C88F
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx_jmp
|
||||||
|
|
||||||
|
[6.0.6001.18000]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=185E4
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=70DBA
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=17FD8
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_edx_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=65BD7
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx_jmp
|
||||||
|
|
||||||
|
[6.0.6002.18005]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=17FA8
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=70FF6
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=179C0
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_edx_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=65E83
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx_jmp
|
||||||
|
|
||||||
|
[6.0.6002.19214]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=17FC4
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=712AA
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=179B8
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_edx_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=65FF7
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx_jmp
|
||||||
|
|
||||||
|
[6.0.6002.23521]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=17FB4
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=71EAA
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=179CC
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_edx_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=669CB
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx_jmp
|
||||||
|
|
||||||
|
[6.1.7600.16385]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=19E25
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=17D96
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=196F3
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=17AD2
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
|
||||||
|
[6.1.7601.17514]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=1A49D
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=180E2
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=19D53
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=17D8A
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
|
||||||
|
[6.1.7601.18540]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=1A4E5
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=18006
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=19D9F
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=17C82
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
|
||||||
|
[6.1.7601.22750]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=1A655
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=17E8E
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=19E21
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=17C92
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
|
||||||
|
[6.1.7601.18637]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=1A4DD
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=180FA
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=19DBB
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=17DC6
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
|
||||||
|
[6.1.7601.22843]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=1A655
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=17F96
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=19E25
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=17D6E
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
|
||||||
|
[6.2.8102.0]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=F7E9
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=D840
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=E47C
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=D3E6
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
SLPolicyInternal.x86=1
|
||||||
|
SLPolicyOffset.x86=1B909
|
||||||
|
SLPolicyFunc.x86=New_Win8SL
|
||||||
|
SLPolicyInternal.x64=1
|
||||||
|
SLPolicyOffset.x64=1A484
|
||||||
|
SLPolicyFunc.x64=New_Win8SL
|
||||||
|
|
||||||
|
[6.2.8250.0]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=159C9
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=11E74
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=13520
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=1187A
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
SLPolicyInternal.x86=1
|
||||||
|
SLPolicyOffset.x86=1A0A9
|
||||||
|
SLPolicyFunc.x86=New_Win8SL_CP
|
||||||
|
SLPolicyInternal.x64=1
|
||||||
|
SLPolicyOffset.x64=18FAC
|
||||||
|
SLPolicyFunc.x64=New_Win8SL
|
||||||
|
|
||||||
|
[6.2.8400.0]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=15482
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=20824
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=13E48
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=1F102
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
SLPolicyInternal.x86=1
|
||||||
|
SLPolicyOffset.x86=19629
|
||||||
|
SLPolicyFunc.x86=New_Win8SL
|
||||||
|
SLPolicyInternal.x64=1
|
||||||
|
SLPolicyOffset.x64=2492C
|
||||||
|
SLPolicyFunc.x64=New_Win8SL
|
||||||
|
|
||||||
|
[6.2.9200.16384]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=15552
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=2BAA8
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=13F08
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=2A31A
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
SLPolicyInternal.x86=1
|
||||||
|
SLPolicyOffset.x86=19559
|
||||||
|
SLPolicyFunc.x86=New_Win8SL
|
||||||
|
SLPolicyInternal.x64=1
|
||||||
|
SLPolicyOffset.x64=21FA8
|
||||||
|
SLPolicyFunc.x64=New_Win8SL
|
||||||
|
|
||||||
|
[6.2.9200.17048]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=20592
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=20948
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=1F408
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=1F206
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
SLPolicyInternal.x86=1
|
||||||
|
SLPolicyOffset.x86=17059
|
||||||
|
SLPolicyFunc.x86=New_Win8SL
|
||||||
|
SLPolicyInternal.x64=1
|
||||||
|
SLPolicyOffset.x64=24570
|
||||||
|
SLPolicyFunc.x64=New_Win8SL
|
||||||
|
|
||||||
|
[6.2.9200.21166]
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=1557A
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=2BAF8
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=13F30
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_esi
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=2A3B6
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rdi
|
||||||
|
SLPolicyInternal.x86=1
|
||||||
|
SLPolicyOffset.x86=19581
|
||||||
|
SLPolicyFunc.x86=New_Win8SL
|
||||||
|
SLPolicyInternal.x64=1
|
||||||
|
SLPolicyOffset.x64=21FD0
|
||||||
|
SLPolicyFunc.x64=New_Win8SL
|
||||||
|
|
||||||
|
[6.3.9431.0]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=8A611
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=9F721
|
||||||
|
LocalOnlyCode.x64=jmpshort
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=306A8
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=367F9
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=2EA25
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=350FD
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=196B0
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=2F9C0
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[6.3.9600.16384]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=A2729
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=81824
|
||||||
|
LocalOnlyCode.x64=nopjmp
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=18028
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=20241
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=16115
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=57829
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=1CEB0
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=554C0
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[6.3.9600.17095]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=A36D1
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=B9159
|
||||||
|
LocalOnlyCode.x64=jmpshort
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=36BA9
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=21829
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=37529
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=1F6A1
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=117F1
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=3B110
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[6.3.9600.17415]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=B33F8
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=8B2D9
|
||||||
|
LocalOnlyCode.x64=nopjmp
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=37115
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=33CE9
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=3CFF9
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=45825
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=18478
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=5DBC0
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[6.4.9841.0]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=956A8
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=81141
|
||||||
|
LocalOnlyCode.x64=jmpshort
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=30125
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=12159
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=3B989
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=C125
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=46A68
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=1EA50
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[6.4.9860.0]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=962C8
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=81091
|
||||||
|
LocalOnlyCode.x64=jmpshort
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=30845
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=11AA9
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=3BEC9
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=B9F5
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=46F18
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=1EB00
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[6.4.9879.0]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=A9CC8
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=95611
|
||||||
|
LocalOnlyCode.x64=jmpshort
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=30C55
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=16A34
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=2DAB9
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=1BDC5
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=41132
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=24750
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[10.0.9926.0]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=A8C28
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=31725
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=3CF99
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=3F140
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=95FF1
|
||||||
|
LocalOnlyCode.x64=jmpshort
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=12A34
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=BE05
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=24EC0
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[10.0.10041.0]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=A9D88
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=97141
|
||||||
|
LocalOnlyCode.x64=jmpshort
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=32215
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=15C64
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=2DFC9
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=B795
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=46960
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=22E40
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[10.0.10240.16384]
|
||||||
|
LocalOnlyPatch.x86=1
|
||||||
|
LocalOnlyOffset.x86=A7D38
|
||||||
|
LocalOnlyCode.x86=jmpshort
|
||||||
|
LocalOnlyPatch.x64=1
|
||||||
|
LocalOnlyOffset.x64=96901
|
||||||
|
LocalOnlyCode.x64=jmpshort
|
||||||
|
SingleUserPatch.x86=1
|
||||||
|
SingleUserOffset.x86=32A95
|
||||||
|
SingleUserCode.x86=nop
|
||||||
|
SingleUserPatch.x64=1
|
||||||
|
SingleUserOffset.x64=18F74
|
||||||
|
SingleUserCode.x64=Zero
|
||||||
|
DefPolicyPatch.x86=1
|
||||||
|
DefPolicyOffset.x86=2F5B9
|
||||||
|
DefPolicyCode.x86=CDefPolicy_Query_eax_ecx
|
||||||
|
DefPolicyPatch.x64=1
|
||||||
|
DefPolicyOffset.x64=22865
|
||||||
|
DefPolicyCode.x64=CDefPolicy_Query_eax_rcx
|
||||||
|
SLInitHook.x86=1
|
||||||
|
SLInitOffset.x86=46581
|
||||||
|
SLInitFunc.x86=New_CSLQuery_Initialize
|
||||||
|
SLInitHook.x64=1
|
||||||
|
SLInitOffset.x64=250F0
|
||||||
|
SLInitFunc.x64=New_CSLQuery_Initialize
|
||||||
|
|
||||||
|
[SLInit]
|
||||||
|
bServerSku=1
|
||||||
|
bRemoteConnAllowed=1
|
||||||
|
bFUSEnabled=1
|
||||||
|
bAppServerAllowed=1
|
||||||
|
bMultimonAllowed=1
|
||||||
|
lMaxUserSessions=0
|
||||||
|
ulMaxDebugSessions=0
|
||||||
|
bInitialized=1
|
||||||
|
|
||||||
|
[6.3.9431.0-SLInit]
|
||||||
|
bFUSEnabled.x86 =A22A8
|
||||||
|
lMaxUserSessions.x86 =A22AC
|
||||||
|
bAppServerAllowed.x86 =A22B0
|
||||||
|
bInitialized.x86 =A22B4
|
||||||
|
bMultimonAllowed.x86 =A22B8
|
||||||
|
bServerSku.x86 =A22BC
|
||||||
|
ulMaxDebugSessions.x86=A22C0
|
||||||
|
bRemoteConnAllowed.x86=A22C4
|
||||||
|
|
||||||
|
bFUSEnabled.x64 =C4490
|
||||||
|
lMaxUserSessions.x64 =C4494
|
||||||
|
bAppServerAllowed.x64 =C4498
|
||||||
|
bInitialized.x64 =C449C
|
||||||
|
bMultimonAllowed.x64 =C44A0
|
||||||
|
bServerSku.x64 =C44A4
|
||||||
|
ulMaxDebugSessions.x64=C44A8
|
||||||
|
bRemoteConnAllowed.x64=C44AC
|
||||||
|
|
||||||
|
[6.3.9600.16384-SLInit]
|
||||||
|
bFUSEnabled.x86 =C02A8
|
||||||
|
lMaxUserSessions.x86 =C02AC
|
||||||
|
bAppServerAllowed.x86 =C02B0
|
||||||
|
bInitialized.x86 =C02B4
|
||||||
|
bMultimonAllowed.x86 =C02B8
|
||||||
|
bServerSku.x86 =C02BC
|
||||||
|
ulMaxDebugSessions.x86=C02C0
|
||||||
|
bRemoteConnAllowed.x86=C02C4
|
||||||
|
|
||||||
|
bServerSku.x64 =E6494
|
||||||
|
ulMaxDebugSessions.x64=E6498
|
||||||
|
bRemoteConnAllowed.x64=E649C
|
||||||
|
bFUSEnabled.x64 =E64A0
|
||||||
|
lMaxUserSessions.x64 =E64A4
|
||||||
|
bAppServerAllowed.x64 =E64A8
|
||||||
|
bInitialized.x64 =E64AC
|
||||||
|
bMultimonAllowed.x64 =E64B0
|
||||||
|
|
||||||
|
[6.3.9600.17095-SLInit]
|
||||||
|
bFUSEnabled.x86 =C12A8
|
||||||
|
lMaxUserSessions.x86 =C12AC
|
||||||
|
bAppServerAllowed.x86 =C12B0
|
||||||
|
bInitialized.x86 =C12B4
|
||||||
|
bMultimonAllowed.x86 =C12B8
|
||||||
|
bServerSku.x86 =C12BC
|
||||||
|
ulMaxDebugSessions.x86=C12C0
|
||||||
|
bRemoteConnAllowed.x86=C12C4
|
||||||
|
|
||||||
|
bServerSku.x64 =E4494
|
||||||
|
ulMaxDebugSessions.x64=E4498
|
||||||
|
bRemoteConnAllowed.x64=E449C
|
||||||
|
bFUSEnabled.x64 =E44A0
|
||||||
|
lMaxUserSessions.x64 =E44A4
|
||||||
|
bAppServerAllowed.x64 =E44A8
|
||||||
|
bInitialized.x64 =E44AC
|
||||||
|
bMultimonAllowed.x64 =E44B0
|
||||||
|
|
||||||
|
[6.3.9600.17415-SLInit]
|
||||||
|
bFUSEnabled.x86 =D3068
|
||||||
|
lMaxUserSessions.x86 =D306C
|
||||||
|
bAppServerAllowed.x86 =D3070
|
||||||
|
bInitialized.x86 =D3074
|
||||||
|
bMultimonAllowed.x86 =D3078
|
||||||
|
bServerSku.x86 =D307C
|
||||||
|
ulMaxDebugSessions.x86=D3080
|
||||||
|
bRemoteConnAllowed.x86=D3084
|
||||||
|
|
||||||
|
bFUSEnabled.x64 =F9054
|
||||||
|
lMaxUserSessions.x64 =F9058
|
||||||
|
bAppServerAllowed.x64 =F905C
|
||||||
|
bInitialized.x64 =F9060
|
||||||
|
bMultimonAllowed.x64 =F9064
|
||||||
|
bServerSku.x64 =F9068
|
||||||
|
ulMaxDebugSessions.x64=F906C
|
||||||
|
bRemoteConnAllowed.x64=F9070
|
||||||
|
|
||||||
|
[6.4.9841.0-SLInit]
|
||||||
|
bFUSEnabled.x86 =BF9F0
|
||||||
|
lMaxUserSessions.x86 =BF9F4
|
||||||
|
bAppServerAllowed.x86 =BF9F8
|
||||||
|
bInitialized.x86 =BF9FC
|
||||||
|
bMultimonAllowed.x86 =BFA00
|
||||||
|
bServerSku.x86 =BFA04
|
||||||
|
ulMaxDebugSessions.x86=BFA08
|
||||||
|
bRemoteConnAllowed.x86=BFA0C
|
||||||
|
|
||||||
|
bFUSEnabled.x64 =ECFF8
|
||||||
|
lMaxUserSessions.x64 =ECFFC
|
||||||
|
bAppServerAllowed.x64 =ED000
|
||||||
|
bInitialized.x64 =ED004
|
||||||
|
bMultimonAllowed.x64 =ED008
|
||||||
|
bServerSku.x64 =ED00C
|
||||||
|
ulMaxDebugSessions.x64=ED010
|
||||||
|
bRemoteConnAllowed.x64=ED014
|
||||||
|
|
||||||
|
[6.4.9860.0-SLInit]
|
||||||
|
bFUSEnabled.x86 =BF7E0
|
||||||
|
lMaxUserSessions.x86 =BF7E4
|
||||||
|
bAppServerAllowed.x86 =BF7E8
|
||||||
|
bInitialized.x86 =BF7EC
|
||||||
|
bMultimonAllowed.x86 =BF7F0
|
||||||
|
bServerSku.x86 =BF7F4
|
||||||
|
ulMaxDebugSessions.x86=BF7F8
|
||||||
|
bRemoteConnAllowed.x86=BF7FC
|
||||||
|
|
||||||
|
bFUSEnabled.x64 =ECBD8
|
||||||
|
lMaxUserSessions.x64 =ECBDC
|
||||||
|
bAppServerAllowed.x64 =ECBE0
|
||||||
|
bInitialized.x64 =ECBE4
|
||||||
|
bMultimonAllowed.x64 =ECBE8
|
||||||
|
bServerSku.x64 =ECBEC
|
||||||
|
ulMaxDebugSessions.x64=ECBF0
|
||||||
|
bRemoteConnAllowed.x64=ECBF4
|
||||||
|
|
||||||
|
[6.4.9879.0-SLInit]
|
||||||
|
bFUSEnabled.x86 =C27D8
|
||||||
|
lMaxUserSessions.x86 =C27DC
|
||||||
|
bAppServerAllowed.x86 =C27E0
|
||||||
|
bInitialized.x86 =C27E4
|
||||||
|
bMultimonAllowed.x86 =C27E8
|
||||||
|
bServerSku.x86 =C27EC
|
||||||
|
ulMaxDebugSessions.x86=C27F0
|
||||||
|
bRemoteConnAllowed.x86=C27F4
|
||||||
|
|
||||||
|
bFUSEnabled.x64 =EDBF0
|
||||||
|
lMaxUserSessions.x64 =EDBF4
|
||||||
|
bAppServerAllowed.x64 =EDBF8
|
||||||
|
bInitialized.x64 =EDBFC
|
||||||
|
bMultimonAllowed.x64 =EDC00
|
||||||
|
bServerSku.x64 =EDC04
|
||||||
|
ulMaxDebugSessions.x64=EDC08
|
||||||
|
bRemoteConnAllowed.x64=EDC0C
|
||||||
|
|
||||||
|
[10.0.9926.0-SLInit]
|
||||||
|
bFUSEnabled.x86 =C17D8
|
||||||
|
lMaxUserSessions.x86 =C17DC
|
||||||
|
bAppServerAllowed.x86 =C17E0
|
||||||
|
bInitialized.x86 =C17E4
|
||||||
|
bMultimonAllowed.x86 =C17E8
|
||||||
|
bServerSku.x86 =C17EC
|
||||||
|
ulMaxDebugSessions.x86=C17F0
|
||||||
|
bRemoteConnAllowed.x86=C17F4
|
||||||
|
|
||||||
|
bFUSEnabled.x64 =EEBF0
|
||||||
|
lMaxUserSessions.x64 =EEBF4
|
||||||
|
bAppServerAllowed.x64 =EEBF8
|
||||||
|
bInitialized.x64 =EEBFC
|
||||||
|
bMultimonAllowed.x64 =EEC00
|
||||||
|
bServerSku.x64 =EEC04
|
||||||
|
ulMaxDebugSessions.x64=EEC08
|
||||||
|
bRemoteConnAllowed.x64=EEC0C
|
||||||
|
|
||||||
|
[10.0.10041.0-SLInit]
|
||||||
|
bFUSEnabled.x86 =C5F60
|
||||||
|
lMaxUserSessions.x86 =C5F64
|
||||||
|
bAppServerAllowed.x86 =C5F68
|
||||||
|
bInitialized.x86 =C5F6C
|
||||||
|
bMultimonAllowed.x86 =C5F70
|
||||||
|
bServerSku.x86 =C5F74
|
||||||
|
ulMaxDebugSessions.x86=C5F78
|
||||||
|
bRemoteConnAllowed.x86=C5F7C
|
||||||
|
|
||||||
|
bFUSEnabled.x64 =F3448
|
||||||
|
lMaxUserSessions.x64 =F344C
|
||||||
|
bAppServerAllowed.x64 =F3450
|
||||||
|
bInitialized.x64 =F3454
|
||||||
|
bMultimonAllowed.x64 =F3458
|
||||||
|
bServerSku.x64 =F345C
|
||||||
|
ulMaxDebugSessions.x64=F3460
|
||||||
|
bRemoteConnAllowed.x64=F3464
|
||||||
|
|
||||||
|
[10.0.10240.16384-SLInit]
|
||||||
|
bFUSEnabled.x86 =C3F60
|
||||||
|
lMaxUserSessions.x86 =C3F64
|
||||||
|
bAppServerAllowed.x86 =C3F68
|
||||||
|
bInitialized.x86 =C3F6C
|
||||||
|
bMultimonAllowed.x86 =C3F70
|
||||||
|
bServerSku.x86 =C3F74
|
||||||
|
ulMaxDebugSessions.x86=C3F78
|
||||||
|
bRemoteConnAllowed.x86=C3F7C
|
||||||
|
|
||||||
|
lMaxUserSessions.x64 =F23B0
|
||||||
|
bAppServerAllowed.x64 =F23B4
|
||||||
|
bServerSku.x64 =F23B8
|
||||||
|
bFUSEnabled.x64 =F3460
|
||||||
|
bInitialized.x64 =F3464
|
||||||
|
bMultimonAllowed.x64 =F3468
|
||||||
|
ulMaxDebugSessions.x64=F346C
|
||||||
|
bRemoteConnAllowed.x64=F3470
|
@ -1,3 +1,19 @@
|
|||||||
|
{
|
||||||
|
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.
|
||||||
|
}
|
||||||
|
|
||||||
program RDPWInst;
|
program RDPWInst;
|
||||||
|
|
||||||
{$APPTYPE CONSOLE}
|
{$APPTYPE CONSOLE}
|
||||||
@ -9,7 +25,8 @@ uses
|
|||||||
Windows,
|
Windows,
|
||||||
Classes,
|
Classes,
|
||||||
WinSvc,
|
WinSvc,
|
||||||
Registry;
|
Registry,
|
||||||
|
WinInet;
|
||||||
|
|
||||||
function EnumServicesStatusEx(
|
function EnumServicesStatusEx(
|
||||||
hSCManager: SC_HANDLE;
|
hSCManager: SC_HANDLE;
|
||||||
@ -143,7 +160,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
TermServiceHost := Reg.ReadString('ImagePath');
|
TermServiceHost := Reg.ReadString('ImagePath');
|
||||||
Reg.CloseKey;
|
Reg.CloseKey;
|
||||||
if Pos('svchost.exe', LowerCase(TermServiceHost)) = 0 then
|
if (Pos('svchost.exe', LowerCase(TermServiceHost)) = 0)
|
||||||
|
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.');
|
||||||
@ -266,33 +284,46 @@ 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
|
||||||
Code := GetLastError;
|
ExitError('OpenSCManager', 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
|
||||||
CloseServiceHandle(hSC);
|
ExitError('OpenService', GetLastError);
|
||||||
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;
|
||||||
Writeln('[-] StartService error (code ', Code, ').');
|
if Code = 1056 then begin // Service already started
|
||||||
|
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;
|
||||||
@ -557,7 +588,26 @@ 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;
|
||||||
|
|
||||||
procedure ExtractFiles;
|
procedure ExtractFiles;
|
||||||
|
var
|
||||||
|
RDPClipRes: String;
|
||||||
begin
|
begin
|
||||||
if not DirectoryExists(ExtractFilePath(ExpandPath(WrapPath))) then
|
if not DirectoryExists(ExtractFilePath(ExpandPath(WrapPath))) then
|
||||||
if ForceDirectories(ExtractFilePath(ExpandPath(WrapPath))) then
|
if ForceDirectories(ExtractFilePath(ExpandPath(WrapPath))) then
|
||||||
@ -567,31 +617,53 @@ begin
|
|||||||
Writeln('[*] Path: ', ExtractFilePath(ExpandPath(WrapPath)));
|
Writeln('[*] Path: ', ExtractFilePath(ExpandPath(WrapPath)));
|
||||||
Halt(0);
|
Halt(0);
|
||||||
end;
|
end;
|
||||||
|
ExtractRes('config', ExtractFilePath(ExpandPath(WrapPath)) + 'rdpwrap.ini');
|
||||||
|
RDPClipRes := '';
|
||||||
case Arch of
|
case Arch of
|
||||||
32: begin
|
32: begin
|
||||||
ExtractRes('rdpw32', ExpandPath(WrapPath));
|
ExtractRes('rdpw32', ExpandPath(WrapPath));
|
||||||
if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then
|
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 0) then
|
||||||
ExtractRes('rdpclip32', ExpandPath('%SystemRoot%\System32\rdpclip.exe'));
|
RDPClipRes := 'rdpclip6032';
|
||||||
|
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then
|
||||||
|
RDPClipRes := 'rdpclip6132';
|
||||||
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';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if RDPClipRes <> '' then
|
||||||
if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then
|
if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then
|
||||||
ExtractRes('rdpclip64', ExpandPath('%SystemRoot%\System32\rdpclip.exe'));
|
ExtractRes(RDPClipRes, ExpandPath('%SystemRoot%\System32\rdpclip.exe'));
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DeleteFiles;
|
procedure DeleteFiles;
|
||||||
var
|
var
|
||||||
Code: DWORD;
|
Code: DWORD;
|
||||||
|
FullPath, Path: String;
|
||||||
begin
|
begin
|
||||||
if not DeleteFile(PWideChar(ExpandPath(TermServicePath))) then
|
FullPath := ExpandPath(TermServicePath);
|
||||||
|
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: ', ExpandPath(TermServicePath));
|
Writeln('[+] Removed file: ', Path + 'rdpwrap.ini');
|
||||||
|
|
||||||
|
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;
|
||||||
@ -643,17 +715,19 @@ 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;
|
||||||
begin
|
begin
|
||||||
GetFileVersion(ExpandPath(TermServicePath), FV);
|
GetFileVersion(ExpandPath(TermServicePath), FV);
|
||||||
Writeln('[*] Terminal Services version: ',
|
VerTxt := Format('%d.%d.%d.%d',
|
||||||
Format('%d.%d.%d.%d',
|
[FV.Version.w.Major, FV.Version.w.Minor, FV.Release, FV.Build]);
|
||||||
[FV.Version.w.Major, FV.Version.w.Minor, FV.Release, FV.Build]));
|
Writeln('[*] Terminal Services version: ', VerTxt);
|
||||||
|
|
||||||
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
|
||||||
@ -682,60 +756,11 @@ 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;
|
||||||
if (FV.Release = 6000) and (FV.Build = 16386) then
|
|
||||||
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;
|
end;
|
||||||
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then begin
|
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then
|
||||||
SuppLvl := 1;
|
SuppLvl := 1;
|
||||||
if (FV.Release = 7600) and (FV.Build = 16385) then
|
if Pos('[' + VerTxt + ']', ExtractResText('config')) > 0 then
|
||||||
SuppLvl := 2;
|
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.');
|
||||||
@ -878,31 +903,163 @@ begin
|
|||||||
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;
|
||||||
|
|
||||||
|
function GitINIFile(var Content: String): Boolean;
|
||||||
|
const
|
||||||
|
URL = 'https://raw.githubusercontent.com/binarymaster/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 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.4');
|
Writeln('RDP Wrapper Library v1.5');
|
||||||
Writeln('Installer v2.2');
|
Writeln('Installer v2.2');
|
||||||
Writeln('Copyright (C) Stas''M Corp. 2014');
|
Writeln('Copyright (C) Stas''M Corp. 2015');
|
||||||
Writeln('');
|
Writeln('');
|
||||||
|
|
||||||
if (ParamCount < 1)
|
if (ParamCount < 1)
|
||||||
or (
|
or (
|
||||||
(ParamStr(1) <> '-i')
|
(ParamStr(1) <> '-l')
|
||||||
|
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 [-i[-s]|-u|-r]');
|
Writeln('RDPWInst.exe [-l|-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('-w get latest update for INI file');
|
||||||
Writeln('-u uninstall wrapper');
|
Writeln('-u uninstall wrapper');
|
||||||
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 SupportedArchitecture then
|
if not SupportedArchitecture then
|
||||||
begin
|
begin
|
||||||
Writeln('[-] Unsupported processor architecture.');
|
Writeln('[-] Unsupported processor architecture.');
|
||||||
@ -918,6 +1075,13 @@ 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'
|
||||||
@ -1003,6 +1167,18 @@ begin
|
|||||||
|
|
||||||
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...');
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
<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>RDPWInst.exe</DCC_DependencyCheckOutputName>
|
<DCC_DependencyCheckOutputName>..\bin\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>
|
||||||
@ -41,14 +42,14 @@
|
|||||||
<BuildConfiguration Include="Base">
|
<BuildConfiguration Include="Base">
|
||||||
<Key>Base</Key>
|
<Key>Base</Key>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
<BuildConfiguration Include="Debug">
|
|
||||||
<Key>Cfg_2</Key>
|
|
||||||
<CfgParent>Base</CfgParent>
|
|
||||||
</BuildConfiguration>
|
|
||||||
<BuildConfiguration Include="Release">
|
<BuildConfiguration Include="Release">
|
||||||
<Key>Cfg_1</Key>
|
<Key>Cfg_1</Key>
|
||||||
<CfgParent>Base</CfgParent>
|
<CfgParent>Base</CfgParent>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
|
<BuildConfiguration Include="Debug">
|
||||||
|
<Key>Cfg_2</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>
|
||||||
@ -60,7 +61,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">-i</Parameters>
|
<Parameters Name="RunParams">-w</Parameters>
|
||||||
</Parameters>
|
</Parameters>
|
||||||
<VersionInfo>
|
<VersionInfo>
|
||||||
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
|
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
<?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.
@ -1,4 +0,0 @@
|
|||||||
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.
Binary file not shown.
@ -1,3 +1,19 @@
|
|||||||
|
{
|
||||||
|
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
|
||||||
@ -28,13 +44,12 @@ 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.1';
|
RDP.Server := '127.0.0.2';
|
||||||
Reg := TRegistry.Create;
|
Reg := TRegistry.Create;
|
||||||
Reg.RootKey := HKEY_LOCAL_MACHINE;
|
Reg.RootKey := HKEY_LOCAL_MACHINE;
|
||||||
|
|
||||||
@ -116,8 +131,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.';
|
$B09: ErrStr := 'Network Level Authentication is required, run RDPCheck as administrator.';
|
||||||
$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.';
|
$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.';
|
||||||
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
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
{
|
||||||
|
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
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
<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>RDPCheck.exe</DCC_DependencyCheckOutputName>
|
<DCC_DependencyCheckOutputName>..\bin\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>
|
||||||
@ -44,14 +45,14 @@
|
|||||||
<BuildConfiguration Include="Base">
|
<BuildConfiguration Include="Base">
|
||||||
<Key>Base</Key>
|
<Key>Base</Key>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
<BuildConfiguration Include="Debug">
|
|
||||||
<Key>Cfg_2</Key>
|
|
||||||
<CfgParent>Base</CfgParent>
|
|
||||||
</BuildConfiguration>
|
|
||||||
<BuildConfiguration Include="Release">
|
<BuildConfiguration Include="Release">
|
||||||
<Key>Cfg_1</Key>
|
<Key>Cfg_1</Key>
|
||||||
<CfgParent>Base</CfgParent>
|
<CfgParent>Base</CfgParent>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
|
<BuildConfiguration Include="Debug">
|
||||||
|
<Key>Cfg_2</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>
|
||||||
@ -68,7 +69,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">1</VersionInfo>
|
<VersionInfo Name="MinorVer">2</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>
|
||||||
@ -82,13 +83,13 @@
|
|||||||
<VersionInfoKeys>
|
<VersionInfoKeys>
|
||||||
<VersionInfoKeys Name="CompanyName">Stas'M Corp.</VersionInfoKeys>
|
<VersionInfoKeys Name="CompanyName">Stas'M Corp.</VersionInfoKeys>
|
||||||
<VersionInfoKeys Name="FileDescription">Local RDP Checker</VersionInfoKeys>
|
<VersionInfoKeys Name="FileDescription">Local RDP Checker</VersionInfoKeys>
|
||||||
<VersionInfoKeys Name="FileVersion">2.1.0.0</VersionInfoKeys>
|
<VersionInfoKeys Name="FileVersion">2.2.0.0</VersionInfoKeys>
|
||||||
<VersionInfoKeys Name="InternalName">RDPCheck</VersionInfoKeys>
|
<VersionInfoKeys Name="InternalName">RDPCheck</VersionInfoKeys>
|
||||||
<VersionInfoKeys Name="LegalCopyright">Copyright © Stas'M Corp. 2014</VersionInfoKeys>
|
<VersionInfoKeys Name="LegalCopyright">Copyright © Stas'M Corp. 2015</VersionInfoKeys>
|
||||||
<VersionInfoKeys Name="LegalTrademarks">Stas'M Corp.</VersionInfoKeys>
|
<VersionInfoKeys Name="LegalTrademarks">Stas'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.3.0.0</VersionInfoKeys>
|
<VersionInfoKeys Name="ProductVersion">1.6.0.0</VersionInfoKeys>
|
||||||
<VersionInfoKeys Name="Comments">http://stascorp.com</VersionInfoKeys>
|
<VersionInfoKeys Name="Comments">http://stascorp.com</VersionInfoKeys>
|
||||||
</VersionInfoKeys>
|
</VersionInfoKeys>
|
||||||
<Excluded_Packages>
|
<Excluded_Packages>
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
<?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.
47
src-rdpconfig/LicenseUnit.dfm
Normal file
47
src-rdpconfig/LicenseUnit.dfm
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
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
|
43
src-rdpconfig/LicenseUnit.pas
Normal file
43
src-rdpconfig/LicenseUnit.pas
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
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.
|
Binary file not shown.
@ -2,9 +2,9 @@ object MainForm: TMainForm
|
|||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
BorderStyle = bsDialog
|
BorderStyle = bsDialog
|
||||||
Caption = 'Remote Desktop Protocol Configuration'
|
Caption = 'RDP Wrapper Configuration'
|
||||||
ClientHeight = 245
|
ClientHeight = 352
|
||||||
ClientWidth = 326
|
ClientWidth = 351
|
||||||
Color = clBtnFace
|
Color = clBtnFace
|
||||||
Font.Charset = DEFAULT_CHARSET
|
Font.Charset = DEFAULT_CHARSET
|
||||||
Font.Color = clWindowText
|
Font.Color = clWindowText
|
||||||
@ -15,18 +15,19 @@ 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
|
object lRDPPort: TLabel
|
||||||
Left = 203
|
Left = 225
|
||||||
Top = 22
|
Top = 103
|
||||||
Width = 47
|
Width = 47
|
||||||
Height = 13
|
Height = 13
|
||||||
Caption = 'RDP Port:'
|
Caption = 'RDP Port:'
|
||||||
end
|
end
|
||||||
object bOK: TButton
|
object bOK: TButton
|
||||||
Left = 45
|
Left = 10
|
||||||
Top = 212
|
Top = 319
|
||||||
Width = 75
|
Width = 75
|
||||||
Height = 25
|
Height = 25
|
||||||
Caption = 'OK'
|
Caption = 'OK'
|
||||||
@ -35,8 +36,8 @@ object MainForm: TMainForm
|
|||||||
OnClick = bOKClick
|
OnClick = bOKClick
|
||||||
end
|
end
|
||||||
object bCancel: TButton
|
object bCancel: TButton
|
||||||
Left = 126
|
Left = 91
|
||||||
Top = 212
|
Top = 319
|
||||||
Width = 75
|
Width = 75
|
||||||
Height = 25
|
Height = 25
|
||||||
Caption = 'Cancel'
|
Caption = 'Cancel'
|
||||||
@ -45,8 +46,8 @@ object MainForm: TMainForm
|
|||||||
OnClick = bCancelClick
|
OnClick = bCancelClick
|
||||||
end
|
end
|
||||||
object bApply: TButton
|
object bApply: TButton
|
||||||
Left = 207
|
Left = 172
|
||||||
Top = 212
|
Top = 319
|
||||||
Width = 75
|
Width = 75
|
||||||
Height = 25
|
Height = 25
|
||||||
Caption = 'Apply'
|
Caption = 'Apply'
|
||||||
@ -56,7 +57,7 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object cbSingleSessionPerUser: TCheckBox
|
object cbSingleSessionPerUser: TCheckBox
|
||||||
Left = 8
|
Left = 8
|
||||||
Top = 31
|
Top = 112
|
||||||
Width = 130
|
Width = 130
|
||||||
Height = 17
|
Height = 17
|
||||||
Caption = 'Single Session Per User'
|
Caption = 'Single Session Per User'
|
||||||
@ -65,8 +66,8 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object rgNLA: TRadioGroup
|
object rgNLA: TRadioGroup
|
||||||
Left = 8
|
Left = 8
|
||||||
Top = 54
|
Top = 132
|
||||||
Width = 310
|
Width = 335
|
||||||
Height = 73
|
Height = 73
|
||||||
Caption = 'Security Mode'
|
Caption = 'Security Mode'
|
||||||
Items.Strings = (
|
Items.Strings = (
|
||||||
@ -78,7 +79,7 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object cbAllowTSConnections: TCheckBox
|
object cbAllowTSConnections: TCheckBox
|
||||||
Left = 8
|
Left = 8
|
||||||
Top = 8
|
Top = 89
|
||||||
Width = 174
|
Width = 174
|
||||||
Height = 17
|
Height = 17
|
||||||
Caption = 'Enable Remote Desktop Protocol'
|
Caption = 'Enable Remote Desktop Protocol'
|
||||||
@ -87,20 +88,22 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object rgShadow: TRadioGroup
|
object rgShadow: TRadioGroup
|
||||||
Left = 8
|
Left = 8
|
||||||
Top = 133
|
Top = 208
|
||||||
Width = 310
|
Width = 335
|
||||||
Height = 73
|
Height = 105
|
||||||
Caption = 'Session Shadowing Mode'
|
Caption = 'Session Shadowing Mode'
|
||||||
Items.Strings = (
|
Items.Strings = (
|
||||||
'Disable Shadowing'
|
'Disable Shadowing'
|
||||||
'Shadowing will request user permission'
|
'Full access with user'#39's permission'
|
||||||
'Shadowing sessions immediately')
|
'Full access without permission'
|
||||||
|
'View only with user'#39's permission'
|
||||||
|
'View only without permission')
|
||||||
TabOrder = 6
|
TabOrder = 6
|
||||||
OnClick = cbAllowTSConnectionsClick
|
OnClick = cbAllowTSConnectionsClick
|
||||||
end
|
end
|
||||||
object seRDPPort: TSpinEdit
|
object seRDPPort: TSpinEdit
|
||||||
Left = 256
|
Left = 278
|
||||||
Top = 19
|
Top = 100
|
||||||
Width = 62
|
Width = 62
|
||||||
Height = 22
|
Height = 22
|
||||||
MaxValue = 65535
|
MaxValue = 65535
|
||||||
@ -109,4 +112,104 @@ object MainForm: TMainForm
|
|||||||
Value = 0
|
Value = 0
|
||||||
OnChange = seRDPPortChange
|
OnChange = seRDPPortChange
|
||||||
end
|
end
|
||||||
|
object bLicense: TButton
|
||||||
|
Left = 253
|
||||||
|
Top = 319
|
||||||
|
Width = 87
|
||||||
|
Height = 25
|
||||||
|
Caption = 'View license...'
|
||||||
|
TabOrder = 8
|
||||||
|
OnClick = bLicenseClick
|
||||||
|
end
|
||||||
|
object gbDiag: TGroupBox
|
||||||
|
Left = 8
|
||||||
|
Top = 6
|
||||||
|
Width = 335
|
||||||
|
Height = 77
|
||||||
|
Caption = 'Diagnostics'
|
||||||
|
TabOrder = 9
|
||||||
|
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 = 206
|
||||||
|
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 = 206
|
||||||
|
Top = 17
|
||||||
|
Width = 44
|
||||||
|
Height = 13
|
||||||
|
Caption = 'Unknown'
|
||||||
|
end
|
||||||
|
object lTSVer: TLabel
|
||||||
|
Left = 182
|
||||||
|
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 = 182
|
||||||
|
Top = 17
|
||||||
|
Width = 20
|
||||||
|
Height = 13
|
||||||
|
Caption = 'ver.'
|
||||||
|
end
|
||||||
|
object lsSuppVer: TLabel
|
||||||
|
Left = 182
|
||||||
|
Top = 55
|
||||||
|
Width = 70
|
||||||
|
Height = 13
|
||||||
|
Caption = '[support level]'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object Timer: TTimer
|
||||||
|
Interval = 250
|
||||||
|
OnTimer = TimerTimer
|
||||||
|
Left = 280
|
||||||
|
Top = 19
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,10 +1,26 @@
|
|||||||
|
{
|
||||||
|
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
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
||||||
Dialogs, StdCtrls, Spin, ExtCtrls, Registry;
|
Dialogs, StdCtrls, Spin, ExtCtrls, Registry, WinSvc;
|
||||||
|
|
||||||
type
|
type
|
||||||
TMainForm = class(TForm)
|
TMainForm = class(TForm)
|
||||||
@ -17,6 +33,20 @@ 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;
|
||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
procedure cbAllowTSConnectionsClick(Sender: TObject);
|
procedure cbAllowTSConnectionsClick(Sender: TObject);
|
||||||
procedure seRDPPortChange(Sender: TObject);
|
procedure seRDPPortChange(Sender: TObject);
|
||||||
@ -24,6 +54,9 @@ 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
|
||||||
@ -31,15 +64,270 @@ type
|
|||||||
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;
|
||||||
|
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 manifest.res}
|
{$R resource.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;
|
||||||
|
|
||||||
procedure TMainForm.ReadSettings;
|
procedure TMainForm.ReadSettings;
|
||||||
var
|
var
|
||||||
@ -151,9 +439,166 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Reg.CloseKey;
|
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.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
|
||||||
@ -167,11 +612,28 @@ 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
|
||||||
|
@ -1,8 +1,25 @@
|
|||||||
|
{
|
||||||
|
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}
|
||||||
|
|
||||||
@ -11,5 +28,6 @@ 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.
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
<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>RDPConf.exe</DCC_DependencyCheckOutputName>
|
<DCC_DependencyCheckOutputName>..\bin\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>
|
||||||
@ -41,17 +42,20 @@
|
|||||||
<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="Debug">
|
|
||||||
<Key>Cfg_2</Key>
|
|
||||||
<CfgParent>Base</CfgParent>
|
|
||||||
</BuildConfiguration>
|
|
||||||
<BuildConfiguration Include="Release">
|
<BuildConfiguration Include="Release">
|
||||||
<Key>Cfg_1</Key>
|
<Key>Cfg_1</Key>
|
||||||
<CfgParent>Base</CfgParent>
|
<CfgParent>Base</CfgParent>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
|
<BuildConfiguration Include="Debug">
|
||||||
|
<Key>Cfg_2</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.
Binary file not shown.
BIN
src-rdpconfig/resource.res
Normal file
BIN
src-rdpconfig/resource.res
Normal file
Binary file not shown.
375
src-x86-binarymaster/LiteINI.pas
Normal file
375
src-x86-binarymaster/LiteINI.pas
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
{
|
||||||
|
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.
737
src-x86-binarymaster/rdpwrap.dpr
Normal file
737
src-x86-binarymaster/rdpwrap.dpr
Normal file
@ -0,0 +1,737 @@
|
|||||||
|
{
|
||||||
|
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: DWORD;
|
||||||
|
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.
|
@ -42,14 +42,14 @@
|
|||||||
<BuildConfiguration Include="Base">
|
<BuildConfiguration Include="Base">
|
||||||
<Key>Base</Key>
|
<Key>Base</Key>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
<BuildConfiguration Include="Debug">
|
|
||||||
<Key>Cfg_2</Key>
|
|
||||||
<CfgParent>Base</CfgParent>
|
|
||||||
</BuildConfiguration>
|
|
||||||
<BuildConfiguration Include="Release">
|
<BuildConfiguration Include="Release">
|
||||||
<Key>Cfg_1</Key>
|
<Key>Cfg_1</Key>
|
||||||
<CfgParent>Base</CfgParent>
|
<CfgParent>Base</CfgParent>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
|
<BuildConfiguration Include="Debug">
|
||||||
|
<Key>Cfg_2</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>
|
File diff suppressed because it is too large
Load Diff
@ -1,2 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<BorlandProject/>
|
|
Binary file not shown.
557
src-x86-x64-Fusix/IniFile.cpp
Normal file
557
src-x86-x64-Fusix/IniFile.cpp
Normal file
@ -0,0 +1,557 @@
|
|||||||
|
/*
|
||||||
|
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 ((FileRaw[i] == '\r' && FileRaw[i + 1] == '\n') || i == (FileSize - 1))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
126
src-x86-x64-Fusix/IniFile.h
Normal file
126
src-x86-x64-Fusix/IniFile.h
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
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);
|
||||||
|
};
|
869
src-x86-x64-Fusix/RDPWrap.cpp
Normal file
869
src-x86-x64-Fusix/RDPWrap.cpp
Normal file
@ -0,0 +1,869 @@
|
|||||||
|
/*
|
||||||
|
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");
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="12.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>v110</PlatformToolset>
|
<PlatformToolset>v120</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>v110</PlatformToolset>
|
<PlatformToolset>v120</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>v110</PlatformToolset>
|
<PlatformToolset>v120</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>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -160,6 +160,7 @@
|
|||||||
<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>
|
||||||
@ -178,6 +179,7 @@
|
|||||||
<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>
|
@ -24,6 +24,9 @@
|
|||||||
<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">
|
||||||
@ -35,6 +38,9 @@
|
|||||||
<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.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
215
technical.txt
Normal file
215
technical.txt
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
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) [todo]
|
||||||
|
6.1.7600.21316 (Windows 7 with KB2750090) [todo]
|
||||||
|
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) [todo]
|
||||||
|
6.1.7601.21866 (Windows 7 SP1 with KB2647409) [todo]
|
||||||
|
6.1.7601.22104 (Windows 7 SP1 with KB2750090) [todo]
|
||||||
|
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.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.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]
|
||||||
|
|
||||||
|
Known failures
|
||||||
|
6.0.6000.16386 (Windows Vista RTM x86, crashes on logon attempt)
|
||||||
|
|
||||||
|
Source code changelog (rdpwrap library):
|
||||||
|
|
||||||
|
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)
|
Reference in New Issue
Block a user