Compare commits

...

226 Commits
v1.4 ... master

Author SHA1 Message Date
Kevin Smyth a5c64a4331 IniFile: don't lose last character if the file doesn't end with \r\n 2018-12-20 18:50:35 +03:00
Stas'M 326551985f
INI: Add support for new builds (fix #586)
- 6.1.7601.24234 x86
2018-10-10 15:57:37 +03:00
Stas'M 2eef50f254
INI: Add support for new builds (#542)
10.0.14393.2457 x86
2018-10-05 01:45:44 +03:00
Stas'M dc3b07f1fe
README: Add Telegram chat link 2018-10-04 15:31:04 +03:00
Stas'M 0c76513a27
INI: Add support for new builds
- 6.1.7601.24234 (fix #572)
- 10.0.15063.994 (fix #455)
- 10.0.17723.1000 (fix #537)
- 10.0.17763.1 (fix #578)
2018-10-03 23:59:34 +03:00
NULL b3e1c77321 INI: Add support for new builds (#568)
- 6.1.7600.20890 (fix #563)
- 6.1.7600.21316 (fix #564)
- 6.1.7601.21650 (fix #565)
- 6.1.7601.21866 (fix #566)
- 6.1.7601.22104 (fix #567)
- 6.3.9600.19093 (fix #549)
- 10.0.14393.2457 (fix #542)
- 10.0.15063.1155 (fix #506)
2018-10-03 21:47:48 +03:00
Stas'M 65b19543f4 INI: Add support for new builds
10.0.17115.1 (fix #424)
2018-05-16 19:26:57 +03:00
Stas'M 9b2a50bfb8 INI: Fix bug in DefPolicy patch (fix #486) 2018-05-16 18:55:16 +03:00
Stas'M 2df3a74958 Installer: Grant access to system and services (fix #391) 2018-05-16 17:14:17 +03:00
Stas'M 560c5a7b45 INI: Add support for new builds
10.0.17128.1
10.0.17133.1 (fix #442)
10.0.17134.1 (fix #456)
2018-05-16 12:40:21 +03:00
1nd1g0 7dc8817de9 INI: Add support for new builds
6.3.9600.18928 (fix #418)
2018-05-16 09:59:55 +03:00
Jim Yang 56915ccf5b Allow UDP 3389 at firewall configuration 2018-04-15 13:54:26 +03:00
Stanislav Motylkov a3cd8ca630
README: Update changelog for v1.6.2 2017-12-28 00:04:36 +03:00
Stas'M ba75e65dac MSI: Move WiX script to res directory and update it 2017-12-27 23:30:30 +03:00
Stas'M 5ad550638e Config: Update version and copyright year 2017-12-27 21:31:48 +03:00
Stas'M 63bf27f0a9 Config: Add HonorLegacySettings option 2017-12-27 21:28:44 +03:00
Stas'M 1459036d05 Installer: Update version 2017-12-27 20:20:28 +03:00
Stas'M 1223417ca1 Installer: Extract rfxvmt.dll if missing (#194) 2017-12-27 20:17:28 +03:00
Stas'M 180f41197a Installer: Allow to install INI from current directory (fix #300) 2017-12-27 17:12:28 +03:00
Stas'M 51b3421a65 INI: Add support for new builds
10.0.17017.1000 (fix #323)
10.0.17025.1000 (fix #339)
10.0.17035.1000 (fix #348)
10.0.17046.1000 (fix #357)
10.0.17063.1000 (fix #375)
2017-12-27 16:34:10 +03:00
Stas'M ebdd795d17 INI: Add support for new builds
- 10.0.14393.1737 x86/x64 (fix #322)
- 10.0.16299.0 x86/x64
- 10.0.16299.15 x86/x64 (fix #316)
- 10.0.17004.1000 x86/x64
2017-10-13 18:25:29 +03:00
Stas'M 96fdc27be5 README: Addendum for previous commit 2017-10-07 15:25:08 +03:00
Stas'M 60eb9a6bc4 README: Add link to the workaround for the Creators Update
Merge pull request #321 from markyi370/patch-1
2017-10-07 15:19:56 +03:00
Mark Yisri 476e277ad3 Update README.md with workaround
Add link to discussion about workaround for the Creators Update.
2017-10-07 08:16:14 -04:00
binarymaster 8ace817d8d INI: Add support for new builds
- 10.0.16291.0 x86/x64 (fix #312)
- 10.0.16294.1 x86/x64 (fix #313)
- 10.0.16296.0 x86/x64
- 10.0.16362.1000 x86/x64 (fix #311)
2017-09-24 22:08:01 +03:00
binarymaster 073c1282db INI: Add support for new builds (fix #309)
10.0.16288.1 x86/x64
2017-09-15 17:43:15 +03:00
binarymaster b50f2dec59 INI: Add support for new builds (fix #307)
10.0.16273.1000 x86/x64
10.0.16275.1000 x86/x64
10.0.16278.1000 x86/x64
10.0.16281.1000 x86/x64
10.0.16353.1000 x86/x64
2017-09-06 21:21:10 +03:00
binarymaster 1c5b9c9e71 INI: Add support for new builds
10.0.16257.1000 x86/x64
2017-08-04 23:01:57 +03:00
binarymaster 37d1872aa7 INI: Add support for new builds (fix #292)
10.0.16257.1 x86/x64
2017-08-04 22:46:48 +03:00
binarymaster 13fca00206 INI: Add support for new builds
10.0.16241.1001 x86/x64
2017-07-30 22:55:55 +03:00
binarymaster 72f3d6ea07 INI: Add support for new builds (fix #275)
10.0.16232.1000 x86/x64
2017-07-30 22:55:55 +03:00
binarymaster 8a3a20c6cb INI: Add support for new builds (fix #279)
10.0.16237.1001 x86/x64
2017-07-30 22:55:55 +03:00
binarymaster 733ed36f70 INI: Add support for new builds
10.0.16251.1000 x86/x64
2017-07-30 22:55:55 +03:00
binarymaster 3e7c0ebfd2 INI: Add support for new builds (fix #286)
10.0.16251.0 x86/x64
2017-07-30 22:55:54 +03:00
binarymaster 2ba5baa34f INI: Add support for new builds (fix #285)
6.3.9600.18708 x86/x64
2017-07-30 22:55:54 +03:00
Stas'M dc9ff8910b Merge pull request #263 from galeksandrp/install
Add WiX Toolset script for MSI installation package
2017-07-10 09:53:42 +03:00
binarymaster f26edcb6f8 INI: Add support for new builds (fix #269)
6.3.9600.18692 x86/x64
2017-06-29 23:44:44 +03:00
Alexander Georgievskiy 7ef04f27c2 Create RDPWInst.wxs 2017-06-13 23:46:19 +03:00
binarymaster 7b809a887d INI: Add support for new builds (fix #261)
10.0.16215.1000 x86/x64
2017-06-10 18:16:01 +03:00
binarymaster f71684aa26 INI: Add support for new builds (fix #258)
10.0.15063.296 x86/x64
2017-06-10 15:42:35 +03:00
Alexander Georgievskiy f0e21b8802 Add MSI installer fixes #14 2017-06-01 12:14:28 +03:00
binarymaster 49c9cbf379 INI: Add support for new builds (fix #254)
10.0.16199.1000 x86/x64
2017-05-29 13:30:07 +03:00
binarymaster 85f2b39568 INI: Add support for new builds (relates to #194)
10.0.14997.1001 (x64 only)
2017-05-17 15:01:07 +03:00
binarymaster 890006de99 INI: Add support for new builds (fix #245)
10.0.14393.1198 (x86 only)
2017-05-12 21:10:38 +03:00
binarymaster 8b2e24cecf INI: Add support for new builds
- 10.0.16179.1000 (x86/x64)
- 10.0.16184.1001 (x86/x64)
2017-05-03 23:27:12 +03:00
binarymaster 49770e6bb8 INI: Add support for new builds (fix #224)
10.0.15063.0 x86/x64
2017-03-22 20:38:58 +03:00
binarymaster baddaab28e INI: Add support for new builds (fix #222)
10.0.15061.0 x86/x64
2017-03-21 21:08:12 +03:00
Stas'M ea1c0dd97d README: Add known issue (fix #215) 2017-03-20 11:48:40 +03:00
Stas'M 2ea06e79e7 README: Move known issues higher 2017-03-20 11:25:19 +03:00
Stas'M 4f85c52a45 README: Add RemoteFX known issue 2017-03-20 11:22:56 +03:00
Stas'M 51dd6cd440 README: Fix badge image link 2017-03-20 11:08:23 +03:00
binarymaster df2b23e2c0 INI: Add support for new builds (fix #219)
10.0.15058.0 x86/x64
2017-03-16 20:18:44 +03:00
binarymaster 7d31342dcf INI: Add support for new builds (fix #218)
10.0.15055.0 x86/x64
2017-03-14 23:41:47 +03:00
binarymaster fe3a61fa24 INI: Add support for new builds (fix #212)
10.0.15048.0 x86/x64
2017-03-05 00:39:53 +03:00
binarymaster ee1fa16bf5 INI: Add support for new builds (fix #211)
10.0.15046.0 x86/x64
2017-03-02 20:36:12 +03:00
binarymaster acaf2b2f72 INI: Add support for new builds (fix #207)
10.0.15031.0 x86/x64
10.0.15042.0 x86/x64
2017-03-01 21:21:49 +03:00
binarymaster 1e93d3ca20 INI: Add support for new builds (fix #204)
10.0.15025.1000 (x64 only)
2017-02-03 01:53:42 +03:00
binarymaster 0f0fbeb71f INI: Add support for new builds (fix #203)
10.0.15019.1000 x86/x64
2017-01-28 21:17:03 +03:00
Stas'M 9b666a3961 README: Web archive link for Andrew Block 2017-01-25 15:15:39 +03:00
binarymaster 9699e08d1a INI: Add support for new builds (fix #199)
10.0.15014.1000 x86/x64
2017-01-21 19:32:23 +03:00
binarymaster 5814e3fcf1 INI: Add support for new builds (fix #195)
10.0.15007.1000 x86/x64
2017-01-15 18:33:49 +03:00
binarymaster 091a0b8e92 Update README (fix #192) 2017-01-12 22:00:53 +03:00
binarymaster 7412f7a732 Update README (fix #163) 2017-01-12 21:57:44 +03:00
binarymaster e1f1d7c123 Update README (fix #191) 2017-01-12 21:30:57 +03:00
binarymaster fe535fd34b INI: Add support for new builds (fix #193)
10.0.15002.1001 x86/x64
2017-01-12 21:30:57 +03:00
Stas'M e9ad5e709f Update README.md - Add badges 2017-01-10 16:49:33 +03:00
binarymaster e69261a495 INI: Add support for new builds (fix #189)
10.0.14986.1000 x86/x64
2016-12-23 21:26:18 +03:00
binarymaster 3cb1ed5944 INI: Add support for new builds (fix #181)
10.0.14959.1000 x86/x64
10.0.14965.1001 x86/x64
10.0.14971.1000 x86/x64
2016-11-19 23:33:26 +03:00
binarymaster 47830889eb INI: Add support for new builds (fix #177)
10.0.14955.1000 x86/x64
2016-10-28 20:51:09 +03:00
binarymaster 0175a08fd1 INI: Add support for new builds (fix #175)
10.0.14951.1000 x86/x64
2016-10-21 22:12:56 +03:00
binarymaster fe43b60f5c INI: Add support for new builds (fix #173)
10.0.14946.1000 x86/x64
2016-10-19 20:52:05 +03:00
binarymaster 59a3a5b305 INI: Add support for new builds (fix #172)
10.0.14942.1000 x86/x64
2016-10-08 23:47:40 +03:00
binarymaster ae54efba8e INI: Add support for new builds (fix #168)
10.0.14936.1000 x86/x64
2016-09-30 01:32:31 +03:00
binarymaster 1bbeee751b INI: Add support for new builds (fix #167)
10.0.14931.1000 x86/x64
2016-09-27 18:07:45 +03:00
binarymaster 73c2583a46 INI: Add support for new builds (fix #160)
10.0.14926.1000 x86/x64
2016-09-15 23:58:24 +03:00
binarymaster 743b53ca16 INI: Add support for new builds (fix #157)
10.0.10586.589 x86/x64
2016-09-14 23:09:20 +03:00
Stas'M 4de59e9ff8 Merge pull request #155 from cher-nov/master
Installer: Add check for supported Windows version
2016-09-10 13:23:49 +03:00
cher-nov 121f893c0c Installer: Add check for supported Windows version 2016-09-10 19:47:50 +10:00
binarymaster 59b1924af9 INI: Add support for new builds (fix #150)
10.0.14915.1000 x86/x64
2016-09-03 14:36:22 +03:00
binarymaster d556f4373f INI: Add support for new builds (fix #140)
10.0.14901.1000 x86/x64
10.0.14905.1000 x86/x64
2016-08-28 16:58:49 +03:00
binarymaster a60c7f4351 INI: Add support for new builds (fix #141)
6.1.7601.23403 x86/x64
2016-08-28 16:32:09 +03:00
binarymaster af6a3c7194 README: FAQ about RDPCheck (fix #139) 2016-08-14 03:04:17 +03:00
binarymaster 13c0932252 INI: Add support for new builds (fix #137)
10.0.14385.0 x86/x64
2016-08-12 11:57:41 +03:00
binarymaster ef2561fe79 Update README (fix #132) 2016-08-02 14:20:16 +03:00
binarymaster e45fde37c2 Pre-release updates 2016-08-01 16:32:00 +03:00
Stas'M 1254ac3b3b README: Quick fixes 2016-07-24 01:21:30 +03:00
Stas'M 0e9385490b README: Replace HTML with Markdown 2016-07-24 01:11:25 +03:00
binarymaster 3edd0e5300 RDPConf: Add feature to hide users on logon 2016-07-23 22:08:44 +03:00
binarymaster 2d482b29be RDPConf: Update firewall rule on port change (fix #86) 2016-07-23 19:56:58 +03:00
binarymaster 11be8c6833 Installer: Allow to keep settings on uninstall (fix #106) 2016-07-23 19:33:35 +03:00
binarymaster 64e0987053 Installer: Add online install mode 2016-07-23 19:27:33 +03:00
binarymaster 558925a865 INI: Add support for new builds (fix #130)
10.0.14393.0 x86/x64
2016-07-22 21:15:53 +03:00
binarymaster 1395ea22bb INI: Add support for new builds (fix #128)
10.0.14383.0 x86/x64
10.0.14388.0 x86/x64
2016-07-15 21:55:02 +03:00
binarymaster 92bc50b6db INI: Add support for new builds (fix #126)
10.0.14379.0 x86/x64
2016-07-06 21:26:53 +03:00
binarymaster f6b125331e INI: Add support for new builds
10.0.14372.0 x86/x64
2016-06-27 09:44:49 +03:00
Stas'M 87e6e00b1b Merge pull request #125 from kbmorris/patch-1
Add support for new x64 architecture builds
2016-06-26 23:49:35 +03:00
kbmorris 533c3978a6 Add support for new x64 architecture builds
Add support for 10.0.14372.0 x64 architecture.
2016-06-26 14:36:12 -04:00
binarymaster cabb00fc78 INI: Add support for new builds (fix #123)
10.0.14366.0 x86/x64
10.0.14367.0 x86/x64
2016-06-17 22:11:05 +03:00
binarymaster 078e5cd1cb Correct offsets for 14352 (fix #121) 2016-06-17 22:09:18 +03:00
binarymaster d19a8cf733 INI: Add support for new builds (fix #119)
10.0.14352.1002 x86/x64
2016-05-30 17:40:06 +03:00
binarymaster bb6d905b8d INI: Add support for new builds
10.0.14342.1000 x86/x64
2016-05-14 20:41:16 +03:00
binarymaster 53897b40c7 INI: Add support for new builds
10.0.14300.1000 x64
10.0.14328.1000 x86/x64
2016-05-08 18:39:11 +03:00
Stas'M d3de408f7e Merge pull request #113 from maxpiva/master
INI: Add support for 10.0.14332.1001
2016-04-29 14:07:52 +03:00
Maximo Piva 69f46c6caf INI: Add support for 10.0.14332.1001 2016-04-29 01:34:19 -03:00
Stas'M 89a03ccba9 Merge pull request #111 from Chocobo1/inst_update
Update immediately after install
2016-04-23 22:17:56 +03:00
Chocobo1 d02238218c Update immediately after install 2016-04-23 23:07:44 +08:00
binarymaster 37bcdd6414 INI: Add support for 10.0.14316.1000 2016-04-14 19:28:00 +03:00
binarymaster 6c58b69306 INI: Add support for 10.0.14295.1000 2016-04-06 14:12:47 +03:00
binarymaster a7d7972ca4 INI: Experimental codes for ARMv7 2016-03-07 21:15:52 +03:00
binarymaster fc58cf13c8 INI: Add support for 10.0.14279.1000 2016-03-06 14:19:32 +03:00
binarymaster 50e7459421 Repository: Update links 2016-03-06 05:58:29 +03:00
binarymaster 2c007fbb1d INI: Add support for 10.0.14271.1000 2016-02-29 14:37:49 +03:00
binarymaster ff3df89647 INI: Add support for 10.0.14251.1000 2016-01-28 20:52:46 +03:00
binarymaster 103a687689 INI: Add support for 10.0.11102.1000 2016-01-26 18:38:13 +03:00
Stas'M def243e15f Merge pull request #84 from fig2k4/master
Support for Delphi XE2 and above
2016-01-16 00:51:21 +03:00
fig2k4 9c6a8f4914 Support for Delphi XE2 and above 2016-01-15 21:17:20 +00:00
binarymaster fdfbf0e1aa Support: Add termsrv 10.0.11082.1000 2016-01-15 22:59:48 +03:00
binarymaster 669c2bd20f Repository: Add .gitattributes 2016-01-15 22:57:51 +03:00
binarymaster c881f80f60 Installer: Update messages 2016-01-15 19:22:39 +03:00
Stas'M 2fe23a1b4f Merge pull request #82 from fig2k4/master
dwResumeHandle initialized before calling EnumServicesStatusEx()
2016-01-15 19:06:32 +03:00
fig2k4 b0c471660b dwResumeHandle initialized before calling EnumServicesStatusEx() 2016-01-15 16:00:36 +00:00
binarymaster b4a0fe1a7a Update README 2015-11-14 17:25:15 +03:00
binarymaster 741527eccd Support for build 10.0.10586.0 2015-11-14 16:44:08 +03:00
binarymaster 3d1f7c9e66 Tech update 2015-11-14 15:59:55 +03:00
binarymaster 733e617a1f Forgot about version 2015-08-12 22:01:19 +03:00
binarymaster 0c89dc564f More info 2015-08-12 20:13:24 +03:00
binarymaster 00e4c3bf19 Update links 2015-08-12 20:06:31 +03:00
binarymaster eadebe921b Update instructions 2015-08-12 19:48:13 +03:00
binarymaster 5553d07206 v1.6 release notes 2015-08-12 19:39:06 +03:00
binarymaster 216255b3b4 Pre-release updates 2015-08-11 05:32:35 +03:00
binarymaster e11b3c7354 Implement simple update routine 2015-08-07 04:33:37 +03:00
Stas'M f534a1c8fc Merge pull request #44 from WisdomWolf/master
Fix for INI File (CR-LF and last line)
2015-08-01 15:36:16 +03:00
WisdomWolf d4d5111711 maybe underscore? 2015-07-31 23:42:14 -04:00
WisdomWolf 4bf2866b49 added period to last line to preserve CR-LF when viewed on GitHub 2015-07-31 23:40:53 -04:00
WisdomWolf 7c52a27ba5 Merge branch 'master' of github.com:WisdomWolf/rdpwrap 2015-07-31 23:39:41 -04:00
WisdomWolf e6686b3b35 corrected CR-LF at end of ini file 2015-07-31 23:39:10 -04:00
WisdomWolf 1f8e2b9e65 corrected CR-LF at end of ini file 2015-07-31 23:37:41 -04:00
binarymaster 946bd7f8a6 Update technical 2015-07-30 01:15:55 +03:00
binarymaster b9149eef02 Fix wrong LocalOnly x86 offset 2015-07-30 01:09:12 +03:00
binarymaster 80387dcc31 Fix installer: check ImagePath without extension 2015-07-17 21:59:20 +03:00
binarymaster 8ac3396165 Small readme fix 2015-07-17 19:06:57 +03:00
binarymaster 8be10a125b Update readme 2015-07-17 18:50:40 +03:00
binarymaster 7baa979752 Update readme 2015-07-17 03:45:22 +03:00
binarymaster 425fc02fec New batch scripts 2015-07-17 02:39:09 +03:00
binarymaster 659ba3dbcf RDPCheck: update text 2015-07-17 02:35:05 +03:00
binarymaster efe2872a26 Update INI modification date 2015-07-17 02:29:20 +03:00
binarymaster ca71d4ace4 Small fix 2015-07-17 02:21:51 +03:00
binarymaster a42b740946 More tech details 2015-07-17 02:19:07 +03:00
binarymaster fca45f61e7 Update tech log 2015-07-17 02:06:27 +03:00
binarymaster 5062ff6c75 Update INI
- Added support for build 10.0.10240.16384
- Added HOW TO hints to KB
2015-07-17 01:28:23 +03:00
binarymaster 9a7c501ca9 Fix readme 2015-07-16 23:32:16 +03:00
binarymaster adabe322c3 Update apps 2015-07-16 23:17:41 +03:00
binarymaster eca971de03 Fix previous commit 2015-07-16 22:15:14 +03:00
binarymaster 6f23a18a24 Update INI
Move comments to KB file
Actual INI now have smaller size
2015-07-16 22:07:21 +03:00
binarymaster 09bfc748f4 Update readme 2015-07-16 21:48:52 +03:00
binarymaster 97d0b92054 Update tech log 2015-07-16 21:43:08 +03:00
binarymaster 867c271cb3 Readme: Update issues section 2015-06-23 20:03:14 +03:00
binarymaster fd56533897 Add support for 10.0.10041.0 2015-03-23 18:13:24 +03:00
binarymaster 782dc346a9 New build has been discovered, obtaining files 2015-03-23 15:28:50 +03:00
binarymaster ca36e9f49f Support for 10.0.9926.0 (x86) 2015-01-27 14:25:29 +03:00
binarymaster 513a7a1ebf 10.0.9926.0 x64 contributed by v-yadli 2015-01-24 20:36:45 +03:00
binarymaster 657ee646d5 Config: update policy values 2014-12-13 14:39:58 +03:00
binarymaster 5a37f663bc Updates discovered 2014-12-11 22:44:05 +03:00
binarymaster 33e3e3664c Update README.md 2014-12-11 01:52:25 +03:00
binarymaster c75ff99bd3 Update README.md
For new release
2014-12-11 01:42:25 +03:00
binarymaster d6c1110ff6 Configurator updated 2014-12-11 01:18:05 +03:00
binarymaster 742fd143ea Delete old binaries
New binaries will be in releases
2014-12-11 00:45:50 +03:00
binarymaster 43c7e7fb57 Update resource 2014-12-10 23:25:01 +03:00
binarymaster bca5e184ad More pre-release fixes 2014-12-10 23:19:31 +03:00
binarymaster f0d5f3a6de Pre-release fixes 2014-12-10 22:09:07 +03:00
binarymaster 6c2747a08f Preparing for release 2014-12-10 21:25:57 +03:00
binarymaster f8de2d5297 Delete old files 2014-12-10 19:58:45 +03:00
binarymaster 1febb524bc Logging improved 2014-12-10 19:55:53 +03:00
binarymaster cf53e9c984 Improvements 2014-12-10 19:38:01 +03:00
binarymaster 6059197036 Perfect look 2014-12-10 19:28:31 +03:00
binarymaster 939a884f20 That epic commit
Seems to work well 👍
2014-12-10 19:11:36 +03:00
binarymaster 239cd5fe3f More bug fixes 2014-12-10 02:59:13 +03:00
binarymaster ac5cb9e480 Bug fixes 2014-12-10 02:17:24 +03:00
binarymaster b5b5806177 Some fixes 2014-12-10 01:39:32 +03:00
binarymaster 31cce7a873 Some updates 2014-12-10 01:00:20 +03:00
binarymaster 4054ef493b Update 2014-12-09 16:09:54 +03:00
Stas'M d7d00ae309 Merge pull request #12 from FusixGit/patch-4
New IniFile class
2014-12-09 16:06:24 +03:00
FusixGit 60027d5e02 New IniFile class 2014-12-09 16:00:11 +03:00
binarymaster 190dd74a65 Small fix 2014-12-09 14:39:46 +03:00
binarymaster ddb15f8cf5 Minor fixes 2014-12-09 13:22:36 +03:00
binarymaster 539bdbfc52 Weekly tech update 2014-12-09 03:34:35 +03:00
binarymaster 39b8c6fade Mega bug fixes! 2014-12-09 03:15:58 +03:00
binarymaster e2968a43de Do not forget about security 2014-12-09 02:00:43 +03:00
binarymaster e3ce360ec9 OMG there are bugs 2014-12-09 01:51:29 +03:00
binarymaster 12e04325dc Moar conditions 2014-12-09 01:41:55 +03:00
binarymaster a449d04619 Some fixes and comments
The final is near, it already compiles :)
2014-12-09 00:59:47 +03:00
Stas'M 87887259b2 Merge pull request #10 from FusixGit/patch-2
Compiled
2014-12-09 00:08:25 +03:00
FusixGit b5e4350d0b Compiled 2014-12-08 22:18:28 +03:00
binarymaster 7d5f17edf6 Fix 2014-12-07 20:34:04 +03:00
Stas'M 32185c9c12 Merge pull request #9 from FusixGit/patch-1
Update RDPWrap.cpp
2014-12-07 20:15:06 +03:00
FusixGit 06eb0a325e Update RDPWrap.cpp 2014-12-07 15:33:23 +03:00
binarymaster e1b4b10006 Bug fix 2014-12-04 23:12:59 +03:00
Stas'M c79a7bc152 Merge pull request #8 from FusixGit/patch-5
Update IniFile.cpp
2014-12-04 23:08:19 +03:00
Stas'M 7873abd48c Merge pull request #7 from FusixGit/patch-4
Update IniFile.h
2014-12-04 23:08:07 +03:00
Stas'M a0576b6ffb Merge pull request #6 from FusixGit/patch-3
Update RDPWrap.cpp
2014-12-04 23:07:47 +03:00
FusixGit 03bbf7d7a8 Update IniFile.cpp 2014-12-04 23:01:30 +03:00
FusixGit faf2bdc905 Update IniFile.h 2014-12-04 23:00:44 +03:00
FusixGit 9033bd91f1 Update RDPWrap.cpp 2014-12-04 22:59:52 +03:00
binarymaster 8b85f43605 Fix typos 2014-12-04 21:22:57 +03:00
Stas'M e2e4a33954 Merge pull request #5 from FusixGit/patch-2
Update IniFile.h // needs typo correction
2014-12-04 21:08:47 +03:00
Stas'M 436c1e2c75 Merge pull request #4 from FusixGit/patch-1
Update IniFile.cpp // needs typo correction
2014-12-04 21:08:22 +03:00
FusixGit 4d89fc245a Update IniFile.h 2014-12-04 17:48:31 +03:00
FusixGit 17102ec1cd Update IniFile.cpp 2014-12-04 17:47:37 +03:00
binarymaster bc84ee3ac4 Linking with new module (incomplete) 2014-12-04 01:23:10 +03:00
binarymaster d2449ccdd6 Fix some typos 2014-12-03 22:51:56 +03:00
binarymaster 81baa4522f Tech updates
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-12-03 22:07:26 +03:00
binarymaster 2136d2c358 INI reader added
Added INI reader by Fusix for C++ version
with additional help from asulwer
2014-12-03 21:58:56 +03:00
binarymaster 61f6adf1f2 Code improvements
Fixed memory leak in the installer
Added diagnostics info to configuration app
2014-11-22 21:17:39 +03:00
binarymaster edbff7bedd Better structure 2014-11-21 16:42:39 +03:00
binarymaster 2c7e0279e0 Code updates
C++ code still needs to be processed
2014-11-21 16:38:07 +03:00
binarymaster 1d35b31d6e Resource sorrection 2014-11-21 14:46:04 +03:00
binarymaster c47495acc5 Tech update 2014-11-21 05:50:42 +03:00
binarymaster 95b6719cbc Great improvements
Added support to store patch settings in INI file, so the code is more
readable now.
Library version support now can be extended without recompilation of the
project, but C++ version needs to be updated.
2014-11-21 05:47:25 +03:00
binarymaster 0e322ede13 Tech updates 2014-11-20 23:17:09 +03:00
binarymaster 1a9d9e7fea Bug fix
Wrong offset was specified (typo)
Not affected on release, because Delphi version is used for x86 platform
2014-11-20 22:31:59 +03:00
binarymaster 136f4c7de8 Technical info
Now it will be in separate file
2014-11-20 18:02:07 +03:00
binarymaster 74e5708a17 Improved comments 2014-11-20 17:54:20 +03:00
binarymaster dd92b47812 Small cleanup
Deleted unnecessary files and added .gitignore file
2014-11-20 16:45:16 +03:00
binarymaster 64b3bf8bc1 Added license info
Now license can be viewed in applications
2014-11-20 16:36:04 +03:00
binarymaster 6b4dadcde5 License changed to Apache 2.0 2014-11-20 15:21:23 +03:00
binarymaster 88d60769a2 Building info
Added information for building the binaries
2014-11-20 15:02:46 +03:00
67 changed files with 16726 additions and 4665 deletions

6
.gitattributes vendored Normal file
View File

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

17
.gitignore vendored Normal file
View File

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

217
LICENSE
View File

@ -1,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.

651
README.md
View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

@ -1,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
View 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

49
res/RDPWInst.wxs Normal file
View File

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

3
res/build_wxs.bat Normal file
View File

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

View File

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

Binary file not shown.

Binary file not shown.

172
res/rdpwrap-arm-kb.ini Normal file
View File

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

6289
res/rdpwrap-ini-kb.txt Normal file

File diff suppressed because it is too large Load Diff

4998
res/rdpwrap.ini Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,19 @@
{
Copyright 2018 Stas'M Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
}
program RDPWInst; program RDPWInst;
{$APPTYPE CONSOLE} {$APPTYPE CONSOLE}
@ -9,7 +25,10 @@ uses
Windows, Windows,
Classes, Classes,
WinSvc, WinSvc,
Registry; Registry,
WinInet,
AccCtrl,
AclAPI;
function EnumServicesStatusEx( function EnumServicesStatusEx(
hSCManager: SC_HANDLE; hSCManager: SC_HANDLE;
@ -24,6 +43,11 @@ function EnumServicesStatusEx(
pszGroupName: PWideChar): BOOL; stdcall; pszGroupName: PWideChar): BOOL; stdcall;
external advapi32 name 'EnumServicesStatusExW'; external advapi32 name 'EnumServicesStatusExW';
function ConvertStringSidToSid(
StringSid: PWideChar;
var Sid: PSID): BOOL; stdcall;
external advapi32 name 'ConvertStringSidToSidW';
type type
FILE_VERSION = record FILE_VERSION = record
Version: record case Boolean of Version: record case Boolean of
@ -59,6 +83,7 @@ const
TermService = 'TermService'; TermService = 'TermService';
var var
Installed: Boolean; Installed: Boolean;
Online: Boolean;
WrapPath: String; WrapPath: String;
Arch: Byte; Arch: Byte;
OldWow64RedirectionValue: LongBool; OldWow64RedirectionValue: LongBool;
@ -143,7 +168,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,32 +292,45 @@ 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
Exit; Sleep(2000); // or SCM hasn't registered killed process
if not StartService(hSvc, 0, pch) then begin
ExitError('StartService', Code);
Exit;
end;
end else begin
ExitError('StartService', Code);
Exit;
end;
end; end;
CloseServiceHandle(hSvc); CloseServiceHandle(hSvc);
CloseServiceHandle(hSC); CloseServiceHandle(hSC);
@ -318,6 +357,8 @@ begin
Halt(Code); Halt(Code);
end; end;
dwResumeHandle := 0;
SetLength(Svc, 1489); SetLength(Svc, 1489);
FillChar(Svc[0], sizeof(Svc[0])*Length(Svc), 0); FillChar(Svc[0], sizeof(Svc[0])*Length(Svc), 0);
if not EnumServicesStatusEx(hSC, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, if not EnumServicesStatusEx(hSC, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,
@ -557,41 +598,196 @@ begin
ResStream.Free; ResStream.Free;
end; end;
function ExtractResText(ResName: String): String;
var
ResStream: TResourceStream;
Str: TStringList;
begin
ResStream := TResourceStream.Create(HInstance, ResName, RT_RCDATA);
Str := TStringList.Create;
try
Str.LoadFromStream(ResStream);
except
end;
ResStream.Free;
Result := Str.Text;
Str.Free;
end;
function GitINIFile(var Content: String): Boolean;
const
URL = 'https://raw.githubusercontent.com/stascorp/rdpwrap/master/res/rdpwrap.ini';
var
NetHandle: HINTERNET;
UrlHandle: HINTERNET;
Str: String;
Buf: Array[0..1023] of Byte;
BytesRead: DWORD;
begin
Result := False;
Content := '';
NetHandle := InternetOpen('RDP Wrapper Update', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if not Assigned(NetHandle) then
Exit;
UrlHandle := InternetOpenUrl(NetHandle, PChar(URL), nil, 0, INTERNET_FLAG_RELOAD, 0);
if not Assigned(UrlHandle) then
begin
InternetCloseHandle(NetHandle);
Exit;
end;
repeat
InternetReadFile(UrlHandle, @Buf[0], SizeOf(Buf), BytesRead);
SetString(Str, PAnsiChar(@Buf[0]), BytesRead);
Content := Content + Str;
until BytesRead = 0;
InternetCloseHandle(UrlHandle);
InternetCloseHandle(NetHandle);
Result := True;
end;
procedure GrantSidFullAccess(Path, SID: String);
var
p_SID: PSID;
pDACL: PACL;
EA: EXPLICIT_ACCESS;
Code, Result: DWORD;
begin
p_SID := nil;
if not ConvertStringSidToSid(PChar(SID), p_SID) then
begin
Code := GetLastError;
Writeln('[-] ConvertStringSidToSid error (code ', Code, ').');
Exit;
end;
EA.grfAccessPermissions := GENERIC_ALL;
EA.grfAccessMode := GRANT_ACCESS;
EA.grfInheritance := SUB_CONTAINERS_AND_OBJECTS_INHERIT;
EA.Trustee.pMultipleTrustee := nil;
EA.Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
EA.Trustee.TrusteeForm := TRUSTEE_IS_SID;
EA.Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;
EA.Trustee.ptstrName := p_SID;
Result := SetEntriesInAcl(1, @EA, nil, pDACL);
if Result = ERROR_SUCCESS then
begin
if SetNamedSecurityInfo(pchar(Path), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, pDACL, nil) <> ERROR_SUCCESS then
begin
Code := GetLastError;
Writeln('[-] SetNamedSecurityInfo error (code ', Code, ').');
end;
LocalFree(Cardinal(pDACL));
end
else begin
Code := GetLastError;
Writeln('[-] SetEntriesInAcl error (code ', Code, ').');
end;
end;
procedure ExtractFiles; procedure ExtractFiles;
var
RDPClipRes, RfxvmtRes, S: String;
OnlineINI: TStringList;
begin begin
if not DirectoryExists(ExtractFilePath(ExpandPath(WrapPath))) then if not DirectoryExists(ExtractFilePath(ExpandPath(WrapPath))) then
if ForceDirectories(ExtractFilePath(ExpandPath(WrapPath))) then if ForceDirectories(ExtractFilePath(ExpandPath(WrapPath))) then begin
Writeln('[+] Folder created: ', ExtractFilePath(ExpandPath(WrapPath))) S := ExtractFilePath(ExpandPath(WrapPath));
Writeln('[+] Folder created: ', S);
GrantSidFullAccess(S, 'S-1-5-18'); // Local System account
GrantSidFullAccess(S, 'S-1-5-6'); // Service group
end
else begin else begin
Writeln('[-] ForceDirectories error.'); Writeln('[-] ForceDirectories error.');
Writeln('[*] Path: ', ExtractFilePath(ExpandPath(WrapPath))); Writeln('[*] Path: ', ExtractFilePath(ExpandPath(WrapPath)));
Halt(0); Halt(0);
end; end;
if Online then
begin
Writeln('[*] Downloading latest INI file...');
OnlineINI := TStringList.Create;
if GitINIFile(S) then begin
OnlineINI.Text := S;
S := ExtractFilePath(ExpandPath(WrapPath)) + 'rdpwrap.ini';
OnlineINI.SaveToFile(S);
Writeln('[+] Latest INI file -> ', S);
end
else
begin
Writeln('[-] Failed to get online INI file, using built-in.');
Online := False;
end;
OnlineINI.Free;
end;
if not Online then
begin
S := ExtractFilePath(ParamStr(0)) + 'rdpwrap.ini';
if FileExists(S) then
begin
OnlineINI := TStringList.Create;
OnlineINI.LoadFromFile(S);
S := ExtractFilePath(ExpandPath(WrapPath)) + 'rdpwrap.ini';
OnlineINI.SaveToFile(S);
Writeln('[+] Current INI file -> ', S);
OnlineINI.Free;
end else
ExtractRes('config', ExtractFilePath(ExpandPath(WrapPath)) + 'rdpwrap.ini');
end;
RDPClipRes := '';
RfxvmtRes := '';
case Arch of case Arch of
32: begin 32: begin
ExtractRes('rdpw32', ExpandPath(WrapPath)); ExtractRes('rdpw32', ExpandPath(WrapPath));
if 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';
if (FV.Version.w.Major = 10) and (FV.Version.w.Minor = 0) then
RfxvmtRes := 'rfxvmt32';
end; end;
64: begin 64: begin
ExtractRes('rdpw64', ExpandPath(WrapPath)); ExtractRes('rdpw64', ExpandPath(WrapPath));
if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 0) then
ExtractRes('rdpclip64', ExpandPath('%SystemRoot%\System32\rdpclip.exe')); RDPClipRes := 'rdpclip6064';
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then
RDPClipRes := 'rdpclip6164';
if (FV.Version.w.Major = 10) and (FV.Version.w.Minor = 0) then
RfxvmtRes := 'rfxvmt64';
end; end;
end; end;
if RDPClipRes <> '' then
if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then
ExtractRes(RDPClipRes, ExpandPath('%SystemRoot%\System32\rdpclip.exe'));
if RfxvmtRes <> '' then
if not FileExists(ExpandPath('%SystemRoot%\System32\rfxvmt.dll')) then
ExtractRes(RfxvmtRes, ExpandPath('%SystemRoot%\System32\rfxvmt.dll'));
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 +839,25 @@ begin
FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE; FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE;
FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL; FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL;
FreeLibrary(hFile);
Result := True; Result := True;
end; end;
procedure CheckTermsrvVersion; procedure CheckTermsrvVersion;
var var
SuppLvl: Byte; SuppLvl: Byte;
VerTxt: String;
procedure UpdateMsg;
begin
Writeln('Try running "update.bat" or "RDPWInst -w" to download latest INI file.');
Writeln('If it doesn''t help, send your termsrv.dll to project developer for support.');
end;
begin begin
GetFileVersion(ExpandPath(TermServicePath), FV); GetFileVersion(ExpandPath(TermServicePath), FV);
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,69 +886,20 @@ 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.');
Writeln('Send your termsrv.dll to project developer for support.'); UpdateMsg;
end; end;
1: begin 1: begin
Writeln('[!] This version of Terminal Services is supported partially.'); Writeln('[!] This version of Terminal Services is supported partially.');
Writeln('It means you may have some limitations such as only 2 concurrent sessions.'); Writeln('It means you may have some limitations such as only 2 concurrent sessions.');
Writeln('Send your termsrv.dll to project developer for adding full support.'); UpdateMsg;
end; end;
2: begin 2: begin
Writeln('[+] This version of Terminal Services is fully supported.'); Writeln('[+] This version of Terminal Services is fully supported.');
@ -873,36 +1028,148 @@ end;
procedure TSConfigFirewall(Enable: Boolean); procedure TSConfigFirewall(Enable: Boolean);
begin begin
if Enable then if Enable then
ExecWait('netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=tcp localport=3389 profile=any action=allow') begin
else ExecWait('netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=tcp localport=3389 profile=any action=allow');
ExecWait('netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=udp localport=3389 profile=any action=allow');
end else
ExecWait('netsh advfirewall firewall delete rule name="Remote Desktop"'); ExecWait('netsh advfirewall firewall delete rule name="Remote Desktop"');
end; end;
function CheckINIDate(Filename, Content: String; var Date: Integer): Boolean;
var
Str: TStringList;
I: Integer;
begin
Result := False;
Str := TStringList.Create;
if Filename <> '' then begin
try
Str.LoadFromFile(Filename);
except
Writeln('[-] Failed to read INI file.');
Exit;
end;
end else
Str.Text := Content;
for I := 0 to Str.Count - 1 do
if Pos('Updated=', Str[I]) = 1 then
Break;
if I >= Str.Count then begin
Writeln('[-] Failed to check INI date.');
Exit;
end;
Content := StringReplace(Str[I], 'Updated=', '', []);
Content := StringReplace(Content, '-', '', [rfReplaceAll]);
Str.Free;
try
Date := StrToInt(Content);
except
Writeln('[-] Wrong INI date format.');
Exit;
end;
Result := True;
end;
procedure CheckUpdate;
var
INIPath, S: String;
Str: TStringList;
I, OldDate, NewDate: Integer;
begin
INIPath := ExtractFilePath(ExpandPath(TermServicePath)) + 'rdpwrap.ini';
if not CheckINIDate(INIPath, '', OldDate) then
Halt(ERROR_ACCESS_DENIED);
Writeln('[*] Current update date: ',
Format('%d.%.2d.%.2d', [OldDate div 10000, OldDate div 100 mod 100, OldDate mod 100]));
if not GitINIFile(S) then begin
Writeln('[-] Failed to download latest INI from GitHub.');
Halt(ERROR_ACCESS_DENIED);
end;
if not CheckINIDate('', S, NewDate) then
Halt(ERROR_ACCESS_DENIED);
Writeln('[*] Latest update date: ',
Format('%d.%.2d.%.2d', [NewDate div 10000, NewDate div 100 mod 100, NewDate mod 100]));
if NewDate = OldDate then
Writeln('[*] Everything is up to date.')
else
if NewDate > OldDate then begin
Writeln('[+] New update is available, updating...');
CheckTermsrvProcess;
Writeln('[*] Terminating service...');
AddPrivilege('SeDebugPrivilege');
KillProcess(TermServicePID);
Sleep(1000);
if Length(ShareSvc) > 0 then
for I := 0 to Length(ShareSvc) - 1 do
SvcStart(ShareSvc[I]);
Sleep(500);
Str := TStringList.Create;
Str.Text := S;
try
Str.SaveToFile(INIPath);
except
Writeln('[-] Failed to write INI file.');
Halt(ERROR_ACCESS_DENIED);
end;
Str.Free;
SvcStart(TermService);
Writeln('[+] Update completed.');
end else
Writeln('[*] Your INI file is newer than public file. Are you a developer? :)');
end;
var var
I: Integer; I: Integer;
begin begin
Writeln('RDP Wrapper Library v1.4'); Writeln('RDP Wrapper Library v1.6.2');
Writeln('Installer v2.2'); Writeln('Installer v2.6');
Writeln('Copyright (C) Stas''M Corp. 2014'); Writeln('Copyright (C) Stas''M Corp. 2018');
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][-o]|-w|-u[-k]|-r]');
Writeln(''); Writeln('');
Writeln('-l display the license agreement');
Writeln('-i install wrapper to Program Files folder (default)'); Writeln('-i install wrapper to Program Files folder (default)');
Writeln('-i -s install wrapper to System32 folder'); Writeln('-i -s install wrapper to System32 folder');
Writeln('-i -o online install mode (loads latest INI file)');
Writeln('-w get latest update for INI file');
Writeln('-u uninstall wrapper'); Writeln('-u uninstall wrapper');
Writeln('-u -k uninstall wrapper and keep settings');
Writeln('-r force restart Terminal Services'); Writeln('-r force restart Terminal Services');
Exit; Exit;
end; end;
if ParamStr(1) = '-l' then
begin
Writeln(ExtractResText('license'));
Exit;
end;
if not CheckWin32Version(6,0) then
begin
Writeln('[-] Unsupported Windows version:');
Writeln(' only >= 6.0 (Vista, Server 2008 and newer) are supported.');
Exit;
end;
if not SupportedArchitecture then if not SupportedArchitecture then
begin begin
Writeln('[-] Unsupported processor architecture.'); Writeln('[-] Unsupported processor architecture.');
@ -918,6 +1185,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'
@ -931,6 +1205,7 @@ begin
CheckTermsrvProcess; CheckTermsrvProcess;
Writeln('[*] Extracting files...'); Writeln('[*] Extracting files...');
Online := (ParamStr(2) = '-o') or (ParamStr(3) = '-o');
ExtractFiles; ExtractFiles;
Writeln('[*] Configuring service library...'); Writeln('[*] Configuring service library...');
@ -993,16 +1268,31 @@ begin
SvcStart(TermService); SvcStart(TermService);
Sleep(500); Sleep(500);
Writeln('[*] Configuring registry...'); if ParamStr(2) <> '-k' then
TSConfigRegistry(False); begin
Writeln('[*] Configuring firewall...'); Writeln('[*] Configuring registry...');
TSConfigFirewall(False); TSConfigRegistry(False);
Writeln('[*] Configuring firewall...');
TSConfigFirewall(False);
end;
if Arch = 64 then if Arch = 64 then
RevertWowRedirection; RevertWowRedirection;
Writeln('[+] Successfully uninstalled.'); Writeln('[+] Successfully uninstalled.');
end; end;
if ParamStr(1) = '-w' then
begin
if not Installed then
begin
Writeln('[*] RDP Wrapper Library is not installed.');
Halt(ERROR_INVALID_FUNCTION);
end;
Writeln('[*] Checking for updates...');
CheckUpdate;
end;
if ParamStr(1) = '-r' then if ParamStr(1) = '-r' then
begin begin
Writeln('[*] Restarting...'); Writeln('[*] Restarting...');

View File

@ -20,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>

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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&apos;M Corp.</VersionInfoKeys> <VersionInfoKeys Name="CompanyName">Stas&apos;M Corp.</VersionInfoKeys>
<VersionInfoKeys Name="FileDescription">Local RDP Checker</VersionInfoKeys> <VersionInfoKeys Name="FileDescription">Local RDP Checker</VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">2.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&apos;M Corp. 2014</VersionInfoKeys> <VersionInfoKeys Name="LegalCopyright">Copyright © Stas&apos;M Corp. 2015</VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks">Stas&apos;M Corp.</VersionInfoKeys> <VersionInfoKeys Name="LegalTrademarks">Stas&apos;M Corp.</VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename">RDPCheck.exe</VersionInfoKeys> <VersionInfoKeys Name="OriginalFilename">RDPCheck.exe</VersionInfoKeys>
<VersionInfoKeys Name="ProductName">RDP Host Support</VersionInfoKeys> <VersionInfoKeys Name="ProductName">RDP Host Support</VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.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>

View File

@ -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.

View 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

View 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.

View File

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

View File

@ -1,10 +1,26 @@
{
Copyright 2017 Stas'M Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
}
unit MainUnit; unit MainUnit;
interface interface
uses uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin, ExtCtrls, Registry; Dialogs, StdCtrls, Spin, ExtCtrls, Registry, WinSvc;
type type
TMainForm = class(TForm) TMainForm = class(TForm)
@ -17,6 +33,23 @@ type
rgShadow: TRadioGroup; rgShadow: TRadioGroup;
seRDPPort: TSpinEdit; seRDPPort: TSpinEdit;
lRDPPort: TLabel; lRDPPort: TLabel;
lService: TLabel;
lListener: TLabel;
lWrapper: TLabel;
lsListener: TLabel;
lsService: TLabel;
lsWrapper: TLabel;
Timer: TTimer;
lTSVer: TLabel;
lsTSVer: TLabel;
lWrapVer: TLabel;
lsWrapVer: TLabel;
bLicense: TButton;
gbDiag: TGroupBox;
lsSuppVer: TLabel;
cbHideUsers: TCheckBox;
gbGeneral: TGroupBox;
cbCustomPrg: TCheckBox;
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure cbAllowTSConnectionsClick(Sender: TObject); procedure cbAllowTSConnectionsClick(Sender: TObject);
procedure seRDPPortChange(Sender: TObject); procedure seRDPPortChange(Sender: TObject);
@ -24,22 +57,305 @@ type
procedure bCancelClick(Sender: TObject); procedure bCancelClick(Sender: TObject);
procedure bOKClick(Sender: TObject); procedure bOKClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure bLicenseClick(Sender: TObject);
procedure TimerTimer(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private private
{ Private declarations } { Private declarations }
public public
{ Public declarations } { Public declarations }
function ExecWait(Cmdline: String): Boolean;
procedure ReadSettings; procedure ReadSettings;
procedure WriteSettings; procedure WriteSettings;
end; end;
FILE_VERSION = record
Version: record case Boolean of
True: (dw: DWORD);
False: (w: record
Minor, Major: Word;
end;)
end;
Release, Build: Word;
bDebug, bPrerelease, bPrivate, bSpecial: Boolean;
end;
WTS_SESSION_INFOW = record
SessionId: DWORD;
Name: packed array [0..33] of WideChar;
State: DWORD;
end;
WTS_SESSION = Array[0..0] of WTS_SESSION_INFOW;
PWTS_SESSION_INFOW = ^WTS_SESSION;
const
winstadll = 'winsta.dll';
var var
MainForm: TMainForm; MainForm: TMainForm;
Ready: Boolean = False; Ready: Boolean = False;
Arch: Byte;
OldWow64RedirectionValue: LongBool;
OldPort: Word;
INI: String;
function WinStationEnumerateW(hServer: THandle;
var ppSessionInfo: PWTS_SESSION_INFOW; var pCount: DWORD): BOOL; stdcall;
external winstadll name 'WinStationEnumerateW';
function WinStationFreeMemory(P: Pointer): BOOL; stdcall; external winstadll;
implementation implementation
{$R *.dfm} {$R *.dfm}
{$R 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;
function TMainForm.ExecWait(Cmdline: String): Boolean;
var
si: STARTUPINFO;
pi: PROCESS_INFORMATION;
begin
Result := False;
ZeroMemory(@si, sizeof(si));
si.cb := sizeof(si);
si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow := SW_HIDE;
UniqueString(Cmdline);
if not CreateProcess(nil, PWideChar(Cmdline), nil, nil, True, 0, nil, nil, si, pi) then begin
MessageBox(Handle,
PWideChar('CreateProcess error (code: ' + IntToStr(GetLastError) + ').'),
'Error', MB_ICONERROR or MB_OK);
Exit;
end;
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
Result := True;
end;
procedure TMainForm.ReadSettings; procedure TMainForm.ReadSettings;
var var
@ -58,6 +374,11 @@ begin
cbSingleSessionPerUser.Checked := Reg.ReadBool('fSingleSessionPerUser'); cbSingleSessionPerUser.Checked := Reg.ReadBool('fSingleSessionPerUser');
except except
end;
try
cbCustomPrg.Checked := Reg.ReadBool('HonorLegacySettings');
except
end; end;
Reg.CloseKey; Reg.CloseKey;
@ -68,6 +389,7 @@ begin
except except
end; end;
OldPort := seRDPPort.Value;
SecurityLayer := 0; SecurityLayer := 0;
UserAuthentication := 0; UserAuthentication := 0;
try try
@ -86,6 +408,13 @@ begin
rgShadow.ItemIndex := Reg.ReadInteger('Shadow'); rgShadow.ItemIndex := Reg.ReadInteger('Shadow');
except except
end;
Reg.CloseKey;
Reg.OpenKeyReadOnly('\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System');
try
cbHideUsers.Checked := Reg.ReadBool('dontdisplaylastusername');
except
end; end;
Reg.CloseKey; Reg.CloseKey;
Reg.Free; Reg.Free;
@ -108,6 +437,11 @@ begin
Reg.WriteBool('fSingleSessionPerUser', cbSingleSessionPerUser.Checked); Reg.WriteBool('fSingleSessionPerUser', cbSingleSessionPerUser.Checked);
except except
end;
try
Reg.WriteBool('HonorLegacySettings', cbCustomPrg.Checked);
except
end; end;
Reg.CloseKey; Reg.CloseKey;
@ -116,6 +450,11 @@ begin
Reg.WriteInteger('PortNumber', seRDPPort.Value); Reg.WriteInteger('PortNumber', seRDPPort.Value);
except except
end;
if OldPort <> seRDPPort.Value then
begin
OldPort := seRDPPort.Value;
ExecWait('netsh advfirewall firewall set rule name="Remote Desktop" new localport=' + IntToStr(OldPort));
end; end;
case rgNLA.ItemIndex of case rgNLA.ItemIndex of
0: begin 0: begin
@ -149,11 +488,175 @@ begin
except except
end; end;
end;
Reg.CloseKey;
Reg.OpenKey('\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services', True);
if rgShadow.ItemIndex >= 0 then begin
try
Reg.WriteInteger('Shadow', rgShadow.ItemIndex);
except
end;
end;
Reg.CloseKey;
Reg.OpenKey('\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System', True);
try
Reg.WriteBool('dontdisplaylastusername', cbHideUsers.Checked);
except
end; end;
Reg.CloseKey; Reg.CloseKey;
Reg.Free; Reg.Free;
end; end;
function CheckSupport(FV: FILE_VERSION): Byte;
var
VerTxt: String;
begin
Result := 0;
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 0) then
Result := 1;
if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then
Result := 1;
VerTxt := Format('%d.%d.%d.%d',
[FV.Version.w.Major, FV.Version.w.Minor, FV.Release, FV.Build]);
if Pos('[' + VerTxt + ']', INI) > 0 then
Result := 2;
end;
procedure TMainForm.TimerTimer(Sender: TObject);
var
WrapperPath, INIPath: String;
FV: FILE_VERSION;
L: TStringList;
CheckSupp: Boolean;
begin
CheckSupp := False;
case IsWrapperInstalled(WrapperPath) of
-1: begin
lsWrapper.Caption := 'Unknown';
lsWrapper.Font.Color := clGrayText;
end;
0: begin
lsWrapper.Caption := 'Not installed';
lsWrapper.Font.Color := clGrayText;
end;
1: begin
lsWrapper.Caption := 'Installed';
lsWrapper.Font.Color := clGreen;
CheckSupp := True;
INIPath := ExtractFilePath(ExpandPath(WrapperPath)) + 'rdpwrap.ini';
if not FileExists(INIPath) then
CheckSupp := False;
end;
2: begin
lsWrapper.Caption := '3rd-party';
lsWrapper.Font.Color := clRed;
end;
end;
case GetTermSrvState of
-1, 0: begin
lsService.Caption := 'Unknown';
lsService.Font.Color := clGrayText;
end;
SERVICE_STOPPED: begin
lsService.Caption := 'Stopped';
lsService.Font.Color := clRed;
end;
SERVICE_START_PENDING: begin
lsService.Caption := 'Starting...';
lsService.Font.Color := clGrayText;
end;
SERVICE_STOP_PENDING: begin
lsService.Caption := 'Stopping...';
lsService.Font.Color := clGrayText;
end;
SERVICE_RUNNING: begin
lsService.Caption := 'Running';
lsService.Font.Color := clGreen;
end;
SERVICE_CONTINUE_PENDING: begin
lsService.Caption := 'Resuming...';
lsService.Font.Color := clGrayText;
end;
SERVICE_PAUSE_PENDING: begin
lsService.Caption := 'Suspending...';
lsService.Font.Color := clGrayText;
end;
SERVICE_PAUSED: begin
lsService.Caption := 'Suspended';
lsService.Font.Color := clWindowText;
end;
end;
if IsListenerWorking then begin
lsListener.Caption := 'Listening';
lsListener.Font.Color := clGreen;
end else begin
lsListener.Caption := 'Not listening';
lsListener.Font.Color := clRed;
end;
if WrapperPath = '' then begin
lsWrapVer.Caption := 'N/A';
lsWrapVer.Font.Color := clGrayText;
end else
if not GetFileVersion(ExpandPath(WrapperPath), FV) then begin
lsWrapVer.Caption := 'N/A';
lsWrapVer.Font.Color := clGrayText;
end else begin
lsWrapVer.Caption :=
IntToStr(FV.Version.w.Major)+'.'+
IntToStr(FV.Version.w.Minor)+'.'+
IntToStr(FV.Release)+'.'+
IntToStr(FV.Build);
lsWrapVer.Font.Color := clWindowText;
end;
if not GetFileVersion('termsrv.dll', FV) then begin
lsTSVer.Caption := 'N/A';
lsTSVer.Font.Color := clGrayText;
end else begin
lsTSVer.Caption :=
IntToStr(FV.Version.w.Major)+'.'+
IntToStr(FV.Version.w.Minor)+'.'+
IntToStr(FV.Release)+'.'+
IntToStr(FV.Build);
lsTSVer.Font.Color := clWindowText;
lsSuppVer.Visible := CheckSupp;
if CheckSupp then begin
if INI = '' then begin
L := TStringList.Create;
try
L.LoadFromFile(INIPath);
except
end;
INI := L.Text;
L.Free;
end;
case CheckSupport(FV) of
0: begin
lsSuppVer.Caption := '[not supported]';
lsSuppVer.Font.Color := clRed;
end;
1: begin
lsSuppVer.Caption := '[supported partially]';
lsSuppVer.Font.Color := clOlive;
end;
2: begin
lsSuppVer.Caption := '[fully supported]';
lsSuppVer.Font.Color := clGreen;
end;
end;
end;
end;
end;
procedure TMainForm.bLicenseClick(Sender: TObject);
begin
LicenseForm.mText.Text := ExtractResText('LICENSE');
if LicenseForm.ShowModal <> mrOk then
Halt(0);
end;
procedure TMainForm.cbAllowTSConnectionsClick(Sender: TObject); procedure TMainForm.cbAllowTSConnectionsClick(Sender: TObject);
begin begin
if Ready then if Ready then
@ -167,11 +670,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

View File

@ -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.

View File

@ -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

Binary file not shown.

View 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.

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

View File

@ -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

View File

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

View File

@ -0,0 +1,562 @@
/*
Copyright 2014 Stas'M Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
#include <Windows.h>
#include <stdlib.h>
#include "IniFile.h"
INI_FILE::INI_FILE(wchar_t *FilePath)
{
DWORD Status = 0;
DWORD NumberOfBytesRead = 0;
HANDLE hFile = CreateFile(FilePath, GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return;
}
FileSize = GetFileSize(hFile, NULL);
if (FileSize == INVALID_FILE_SIZE)
{
return;
}
FileRaw = new char[FileSize];
Status = ReadFile(hFile, FileRaw, FileSize, &NumberOfBytesRead, NULL);
if (!Status)
{
return;
}
CreateStringsMap();
Parse();
}
INI_FILE::~INI_FILE()
{
for (DWORD i = 0; i < IniData.SectionCount; i++)
{
delete[] IniData.Section[i].Variables;
}
delete[] IniData.Section;
delete[] FileStringsMap;
delete FileRaw;
}
bool INI_FILE::CreateStringsMap()
{
DWORD StringsCount = 1;
for (DWORD i = 0; i < FileSize; i++)
{
if (FileRaw[i] == '\r' && FileRaw[i + 1] == '\n') StringsCount++;
}
FileStringsCount = StringsCount;
FileStringsMap = new DWORD[StringsCount];
FileStringsMap[0] = 0;
StringsCount = 1;
for (DWORD i = 0; i < FileSize; i++)
{
if (FileRaw[i] == '\r' && FileRaw[i + 1] == '\n')
{
FileStringsMap[StringsCount] = i + 2;
StringsCount++;
}
}
return true;
}
int INI_FILE::StrTrim(char* Str)
{
int i = 0, j;
while ((Str[i] == ' ') || (Str[i] == '\t'))
{
i++;
}
if (i>0)
{
for (j = 0; j < strlen(Str); j++)
{
Str[j] = Str[j + i];
}
Str[j] = '\0';
}
i = strlen(Str) - 1;
while ((Str[i] == ' ') || (Str[i] == '\t'))
{
i--;
}
if (i < (strlen(Str) - 1))
{
Str[i + 1] = '\0';
}
return 0;
}
DWORD INI_FILE::GetFileStringFromNum(DWORD StringNumber, char *RetString, DWORD Size)
{
DWORD CurrentStringNum = 0;
DWORD EndStringPos = 0;
DWORD StringSize = 0;
if (StringNumber > FileStringsCount) return 0;
for (DWORD i = FileStringsMap[StringNumber]; i < FileSize; i++)
{
if (i == (FileSize - 1))
{
EndStringPos = FileSize;
break;
}
if (FileRaw[i] == '\r' && FileRaw[i + 1] == '\n')
{
EndStringPos = i;
break;
}
}
StringSize = EndStringPos - FileStringsMap[StringNumber];
if (Size < StringSize) return 0;
memset(RetString, 0x00, Size);
memcpy(RetString, &(FileRaw[FileStringsMap[StringNumber]]), StringSize);
return StringSize;
}
bool INI_FILE::IsVariable(char *Str, DWORD StrSize)
{
bool Quotes = false;
for (DWORD i = 0; i < StrSize; i++)
{
if (Str[i] == '"' || Str[i] == '\'') Quotes = !Quotes;
if (Str[i] == '=' && !Quotes) return true;
}
return false;
}
bool INI_FILE::FillVariable(INI_SECTION_VARIABLE *Variable, char *Str, DWORD StrSize)
{
bool Quotes = false;
for (DWORD i = 0; i < StrSize; i++)
{
if (Str[i] == '"' || Str[i] == '\'') Quotes = !Quotes;
if (Str[i] == '=' && !Quotes)
{
memset(Variable->VariableName, 0, MAX_STRING_LEN);
memset(Variable->VariableValue, 0, MAX_STRING_LEN);
memcpy(Variable->VariableName, Str, i);
memcpy(Variable->VariableValue, &(Str[i + 1]), StrSize - (i - 1));
StrTrim(Variable->VariableName);
StrTrim(Variable->VariableValue);
break;
}
}
return true;
}
bool INI_FILE::Parse()
{
DWORD CurrentStringNum = 0;
char CurrentString[512];
DWORD CurrentStringSize = 0;
DWORD SectionsCount = 0;
DWORD VariablesCount = 0;
DWORD CurrentSectionNum = -1;
DWORD CurrentVariableNum = -1;
// Calculate sections count
for (DWORD CurrentStringNum = 0; CurrentStringNum < FileStringsCount; CurrentStringNum++)
{
CurrentStringSize = GetFileStringFromNum(CurrentStringNum, CurrentString, 512);
if (CurrentString[0] == ';') continue; // It's a comment
if (CurrentString[0] == '[' && CurrentString[CurrentStringSize - 1] == ']') // It's section declaration
{
SectionsCount++;
continue;
}
}
DWORD *SectionVariableCount = new DWORD[SectionsCount];
memset(SectionVariableCount, 0x00, sizeof(DWORD)*SectionsCount);
for (DWORD CurrentStringNum = 0; CurrentStringNum < FileStringsCount; CurrentStringNum++)
{
CurrentStringSize = GetFileStringFromNum(CurrentStringNum, CurrentString, 512);
if (CurrentString[0] == ';') continue; // It's a comment
if (CurrentString[0] == '[' && CurrentString[CurrentStringSize - 1] == ']') // It's section declaration
{
CurrentSectionNum++;
continue;
}
if (IsVariable(CurrentString, CurrentStringSize))
{
VariablesCount++;
SectionVariableCount[CurrentSectionNum]++;
continue;
}
}
IniData.SectionCount = SectionsCount;
IniData.Section = new INI_SECTION[SectionsCount];
memset(IniData.Section, 0x00, sizeof(PINI_SECTION)*SectionsCount);
for (DWORD i = 0; i < SectionsCount; i++)
{
IniData.Section[i].VariablesCount = SectionVariableCount[i];
IniData.Section[i].Variables = new INI_SECTION_VARIABLE[SectionVariableCount[i]];
memset(IniData.Section[i].Variables, 0x00, sizeof(INI_SECTION_VARIABLE)*SectionVariableCount[i]);
}
delete[] SectionVariableCount;
CurrentSectionNum = -1;
CurrentVariableNum = -1;
for (DWORD CurrentStringNum = 0; CurrentStringNum < FileStringsCount; CurrentStringNum++)
{
CurrentStringSize = GetFileStringFromNum(CurrentStringNum, CurrentString, 512);
if (CurrentString[0] == ';') // It's a comment
{
continue;
}
if (CurrentString[0] == '[' && CurrentString[CurrentStringSize - 1] == ']')
{
CurrentSectionNum++;
CurrentVariableNum = 0;
memset(IniData.Section[CurrentSectionNum].SectionName, 0, MAX_STRING_LEN);
memcpy(IniData.Section[CurrentSectionNum].SectionName, &(CurrentString[1]), (CurrentStringSize - 2));
continue;
}
if (IsVariable(CurrentString, CurrentStringSize))
{
FillVariable(&(IniData.Section[CurrentSectionNum].Variables[CurrentVariableNum]), CurrentString, CurrentStringSize);
CurrentVariableNum++;
continue;
}
}
return true;
}
PINI_SECTION INI_FILE::GetSection(char *SectionName)
{
for (DWORD i = 0; i < IniData.SectionCount; i++)
{
if (
(strlen(IniData.Section[i].SectionName) == strlen(SectionName)) &&
(memcmp(IniData.Section[i].SectionName, SectionName, strlen(SectionName)) == 0)
)
{
return &IniData.Section[i];
}
}
return NULL;
}
bool INI_FILE::SectionExists(char *SectionName)
{
if (GetSection(SectionName) == NULL) return false;
return true;
}
bool INI_FILE::VariableExists(char *SectionName, char *VariableName)
{
INI_SECTION_VARIABLE Variable = { 0 };
return GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
}
bool INI_FILE::GetVariableInSectionPrivate(char *SectionName, char *VariableName, INI_SECTION_VARIABLE *RetVariable)
{
INI_SECTION *Section = NULL;
INI_SECTION_VARIABLE *Variable = NULL;
// Find section
Section = GetSection(SectionName);
if (Section == NULL)
{
SetLastError(318); // This region is not found
return false;
}
// Find variable
for (DWORD i = 0; i < Section->VariablesCount; i++)
{
if (
(strlen(Section->Variables[i].VariableName) == strlen(VariableName)) &&
(memcmp(Section->Variables[i].VariableName, VariableName, strlen(VariableName)) == 0)
)
{
Variable = &(Section->Variables[i]);
break;
}
}
if (Variable == NULL)
{
SetLastError(1898); // Member of the group is not found
return false;
}
memset(RetVariable, 0x00, sizeof(*RetVariable));
memcpy(RetVariable, Variable, sizeof(*Variable));
return true;
}
bool INI_FILE::GetVariableInSection(char *SectionName, char *VariableName, INI_VAR_STRING *RetVariable)
{
bool Status = false;
INI_SECTION_VARIABLE Variable = {};
Status = GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
if (!Status) return Status;
memset(RetVariable, 0x00, sizeof(*RetVariable));
memcpy(RetVariable->Name, Variable.VariableName, strlen(Variable.VariableName));
memcpy(RetVariable->Value, Variable.VariableValue, strlen(Variable.VariableValue));
return true;
}
bool INI_FILE::GetVariableInSection(char *SectionName, char *VariableName, INI_VAR_DWORD *RetVariable)
{
bool Status = false;
INI_SECTION_VARIABLE Variable = {};
Status = GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
if (!Status) return Status;
memset(RetVariable, 0x00, sizeof(*RetVariable));
memcpy(RetVariable->Name, Variable.VariableName, strlen(Variable.VariableName));
#ifndef _WIN64
RetVariable->ValueDec = strtol(Variable.VariableValue, NULL, 10);
RetVariable->ValueHex = strtol(Variable.VariableValue, NULL, 16);
#else
RetVariable->ValueDec = _strtoi64(Variable.VariableValue, NULL, 10);
RetVariable->ValueHex = _strtoi64(Variable.VariableValue, NULL, 16);
#endif
return true;
}
bool INI_FILE::GetVariableInSection(char *SectionName, char *VariableName, INI_VAR_BYTEARRAY *RetVariable)
{
bool Status = false;
INI_SECTION_VARIABLE Variable = {};
Status = GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
if (!Status) return Status;
DWORD ValueLen = strlen(Variable.VariableValue);
if ((ValueLen % 2) != 0) return false;
// for security reasons not more than 16 bytes
if (ValueLen > 32) ValueLen = 32; // 32 hex digits
memset(RetVariable, 0x00, sizeof(*RetVariable));
memcpy(RetVariable->Name, Variable.VariableName, strlen(Variable.VariableName));
for (DWORD i = 0; i <= ValueLen; i++)
{
if ((i % 2) != 0) continue;
switch (Variable.VariableValue[i])
{
case '0': break;
case '1': RetVariable->Value[(i / 2)] += (1 << 4); break;
case '2': RetVariable->Value[(i / 2)] += (2 << 4); break;
case '3': RetVariable->Value[(i / 2)] += (3 << 4); break;
case '4': RetVariable->Value[(i / 2)] += (4 << 4); break;
case '5': RetVariable->Value[(i / 2)] += (5 << 4); break;
case '6': RetVariable->Value[(i / 2)] += (6 << 4); break;
case '7': RetVariable->Value[(i / 2)] += (7 << 4); break;
case '8': RetVariable->Value[(i / 2)] += (8 << 4); break;
case '9': RetVariable->Value[(i / 2)] += (9 << 4); break;
case 'A': RetVariable->Value[(i / 2)] += (10 << 4); break;
case 'B': RetVariable->Value[(i / 2)] += (11 << 4); break;
case 'C': RetVariable->Value[(i / 2)] += (12 << 4); break;
case 'D': RetVariable->Value[(i / 2)] += (13 << 4); break;
case 'E': RetVariable->Value[(i / 2)] += (14 << 4); break;
case 'F': RetVariable->Value[(i / 2)] += (15 << 4); break;
}
switch (Variable.VariableValue[i + 1])
{
case '0': break;
case '1': RetVariable->Value[(i / 2)] += 1; break;
case '2': RetVariable->Value[(i / 2)] += 2; break;
case '3': RetVariable->Value[(i / 2)] += 3; break;
case '4': RetVariable->Value[(i / 2)] += 4; break;
case '5': RetVariable->Value[(i / 2)] += 5; break;
case '6': RetVariable->Value[(i / 2)] += 6; break;
case '7': RetVariable->Value[(i / 2)] += 7; break;
case '8': RetVariable->Value[(i / 2)] += 8; break;
case '9': RetVariable->Value[(i / 2)] += 9; break;
case 'A': RetVariable->Value[(i / 2)] += 10; break;
case 'B': RetVariable->Value[(i / 2)] += 11; break;
case 'C': RetVariable->Value[(i / 2)] += 12; break;
case 'D': RetVariable->Value[(i / 2)] += 13; break;
case 'E': RetVariable->Value[(i / 2)] += 14; break;
case 'F': RetVariable->Value[(i / 2)] += 15; break;
}
}
RetVariable->ArraySize = ValueLen / 2;
return true;
}
bool INI_FILE::GetVariableInSection(char *SectionName, char *VariableName, bool *RetVariable)
{
bool Status = false;
INI_SECTION_VARIABLE Variable = {};
Status = GetVariableInSectionPrivate(SectionName, VariableName, &Variable);
if (!Status) return Status;
*RetVariable = (bool)strtol(Variable.VariableValue, NULL, 10);
return true;
}
bool INI_FILE::GetSectionVariablesList(char *SectionName, INI_SECTION_VARLIST *VariablesList)
{
INI_SECTION *Section = NULL;
Section = GetSection(SectionName);
if (Section == NULL)
{
SetLastError(318); // This region is not found
return false;
}
VariablesList->EntriesCount = Section->VariablesCount;
VariablesList->NamesEntries = new INI_SECTION_VARLIST_ENTRY[VariablesList->EntriesCount];
memset(VariablesList->NamesEntries, 0x00, sizeof(INI_SECTION_VARLIST_ENTRY)*VariablesList->EntriesCount);
VariablesList->ValuesEntries = new INI_SECTION_VARLIST_ENTRY[VariablesList->EntriesCount];
memset(VariablesList->ValuesEntries, 0x00, sizeof(INI_SECTION_VARLIST_ENTRY)*VariablesList->EntriesCount);
for (DWORD i = 0; i < Section->VariablesCount; i++)
{
memcpy(VariablesList->NamesEntries[i].String, Section->Variables[i].VariableName,
strlen(Section->Variables[i].VariableName));
memcpy(VariablesList->ValuesEntries[i].String, Section->Variables[i].VariableValue,
strlen(Section->Variables[i].VariableValue));
}
return true;
}
// ---------------------------- WCHAR_T BLOCK ----------------------------------------------
bool INI_FILE::SectionExists(wchar_t *SectionName)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
return GetSection(cSectionName);
}
bool INI_FILE::VariableExists(wchar_t *SectionName, wchar_t *VariableName)
{
INI_SECTION_VARIABLE Variable = { 0 };
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSectionPrivate(cSectionName, cVariableName, &Variable);
}
bool INI_FILE::GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, INI_VAR_STRING *RetVariable)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSection(cSectionName, cVariableName, RetVariable);
}
bool INI_FILE::GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, INI_VAR_DWORD *RetVariable)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSection(cSectionName, cVariableName, RetVariable);
}
bool INI_FILE::GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, INI_VAR_BYTEARRAY *RetVariable)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSection(cSectionName, cVariableName, RetVariable);
}
bool INI_FILE::GetVariableInSection(wchar_t *SectionName, wchar_t *VariableName, bool *RetVariable)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
char cVariableName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
wcstombs(cVariableName, VariableName, MAX_STRING_LEN);
return GetVariableInSection(cSectionName, cVariableName, RetVariable);
}
bool INI_FILE::GetSectionVariablesList(wchar_t *SectionName, INI_SECTION_VARLIST *VariablesList)
{
char cSectionName[MAX_STRING_LEN] = { 0x00 };
wcstombs(cSectionName, SectionName, MAX_STRING_LEN);
return GetSectionVariablesList(cSectionName, VariablesList);
}

126
src-x86-x64-Fusix/IniFile.h Normal file
View 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);
};

View 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");
}

View File

@ -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>

View File

@ -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.

561
technical.txt Normal file
View File

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