├── .gitignore ├── LICENSE ├── README.md ├── UlteriusScreenShare.sln ├── UlteriusScreenShare ├── Desktop │ └── Capture.cs ├── Properties │ └── AssemblyInfo.cs ├── ScreenShareSErver.cs ├── Security │ ├── Rsa.cs │ ├── StringUtils.cs │ └── Uaes.cs ├── UlteriusScreenShare.csproj ├── Websocket │ ├── AuthClient.cs │ ├── Server │ │ ├── AuthenticationHandler.cs │ │ ├── CommandHandler.cs │ │ ├── ConnectionHandler.cs │ │ └── MessageHandler.cs │ └── WebSocketEventListener.cs ├── Win32Api │ ├── Gdi.cs │ ├── Win32.cs │ └── packages.config └── packages.config └── UlteriusScreenShareExample ├── App.config ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── UlteriusScreenShareExample.csproj └── packages.config /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | *.userprefs 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Rr]elease/ 20 | x64/ 21 | *_i.c 22 | *_p.c 23 | *.ilk 24 | *.meta 25 | *.obj 26 | *.pch 27 | *.pdb 28 | *.pgc 29 | *.pgd 30 | *.rsp 31 | *.sbr 32 | *.tlb 33 | *.tli 34 | *.tlh 35 | *.tmp 36 | *.log 37 | *.vspscc 38 | *.vssscc 39 | .builds 40 | 41 | # Visual C++ cache files 42 | ipch/ 43 | *.aps 44 | *.ncb 45 | *.opensdf 46 | *.sdf 47 | 48 | # Visual Studio profiler 49 | *.psess 50 | *.vsp 51 | *.vspx 52 | 53 | # Guidance Automation Toolkit 54 | *.gpState 55 | 56 | # ReSharper is a .NET coding add-in 57 | _ReSharper* 58 | 59 | # NCrunch 60 | *.ncrunch* 61 | .*crunch*.local.xml 62 | 63 | # Installshield output folder 64 | [Ee]xpress 65 | 66 | # DocProject is a documentation generator add-in 67 | DocProject/buildhelp/ 68 | DocProject/Help/*.HxT 69 | DocProject/Help/*.HxC 70 | DocProject/Help/*.hhc 71 | DocProject/Help/*.hhk 72 | DocProject/Help/*.hhp 73 | DocProject/Help/Html2 74 | DocProject/Help/html 75 | 76 | # Click-Once directory 77 | publish 78 | 79 | # Publish Web Output 80 | *.Publish.xml 81 | 82 | # NuGet Packages Directory 83 | packages 84 | 85 | # Windows Azure Build Output 86 | csx 87 | *.build.csdef 88 | 89 | # Windows Store app package directory 90 | AppPackages/ 91 | 92 | # Others 93 | [Bb]in 94 | [Oo]bj 95 | sql 96 | TestResults 97 | [Tt]est[Rr]esult* 98 | *.Cache 99 | ClientBin 100 | [Ss]tyle[Cc]op.* 101 | ~$* 102 | *.dbmdl 103 | Generated_Code #added for RIA/Silverlight projects 104 | 105 | # Backup & report files from converting an old project file to a newer 106 | # Visual Studio version. Backup files are not needed, because we have git ;-) 107 | _UpgradeReport_Files/ 108 | Backup*/ 109 | UpgradeLog*.XML 110 | 111 | Installer/*setup.exe 112 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### screen-share 2 | Remote desktop powered by C# and websockets. 3 | 4 | ### TODO 5 | 6 | - [x] Compression 7 | - [ ] Partial Frame Updating 8 | - [x] Keyboard input 9 | - [x] Fix Mouse Events 10 | - [x] Increase peformance 11 | - [ ] Screen Selection 12 | - [x] AES Encryption 13 | - [x] Password Authentication -------------------------------------------------------------------------------- /UlteriusScreenShare.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UlteriusScreenShare", "UlteriusScreenShare\UlteriusScreenShare.csproj", "{D91B9FDB-9412-4658-98E6-476576A16265}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UlteriusScreenShareExample", "UlteriusScreenShareExample\UlteriusScreenShareExample.csproj", "{EA65F94D-D15B-401A-AAF2-BC0298FB0637}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UlteriusScreenShareClient", "UlteriusScreenShareClient\UlteriusScreenShareClient.csproj", "{6412E095-8813-4719-8064-CE1E034E6B0A}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {D91B9FDB-9412-4658-98E6-476576A16265}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {D91B9FDB-9412-4658-98E6-476576A16265}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {D91B9FDB-9412-4658-98E6-476576A16265}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {D91B9FDB-9412-4658-98E6-476576A16265}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {EA65F94D-D15B-401A-AAF2-BC0298FB0637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {EA65F94D-D15B-401A-AAF2-BC0298FB0637}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {EA65F94D-D15B-401A-AAF2-BC0298FB0637}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {EA65F94D-D15B-401A-AAF2-BC0298FB0637}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {6412E095-8813-4719-8064-CE1E034E6B0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {6412E095-8813-4719-8064-CE1E034E6B0A}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {6412E095-8813-4719-8064-CE1E034E6B0A}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {6412E095-8813-4719-8064-CE1E034E6B0A}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /UlteriusScreenShare/Desktop/Capture.cs: -------------------------------------------------------------------------------- 1 | #region 2 | 3 | using System; 4 | using System.Drawing; 5 | using System.Drawing.Imaging; 6 | using System.Runtime.InteropServices; 7 | using UlteriusScreenShare.Win32Api; 8 | #endregion 9 | 10 | namespace UlteriusScreenShare.Desktop 11 | { 12 | internal class Capture 13 | { 14 | public static Bitmap CaptureDesktop() 15 | { 16 | Bitmap bmp = null; 17 | { 18 | var hDc = IntPtr.Zero; 19 | try 20 | { 21 | SIZE size; 22 | hDc = Win32.GetDC(Win32.GetDesktopWindow()); 23 | var hMemDc = Gdi.CreateCompatibleDC(hDc); 24 | 25 | size.Cx = Win32.GetSystemMetrics 26 | (Win32.SmCxscreen); 27 | 28 | size.Cy = Win32.GetSystemMetrics 29 | (Win32.SmCyscreen); 30 | 31 | var hBitmap = Gdi.CreateCompatibleBitmap(hDc, size.Cx, size.Cy); 32 | 33 | if (hBitmap != IntPtr.Zero) 34 | { 35 | var hOld = Gdi.SelectObject 36 | (hMemDc, hBitmap); 37 | 38 | Gdi.BitBlt(hMemDc, 0, 0, size.Cx, size.Cy, hDc, 39 | 0, 0, Gdi.Srccopy); 40 | 41 | Gdi.SelectObject(hMemDc, hOld); 42 | Gdi.DeleteDC(hMemDc); 43 | bmp = Image.FromHbitmap(hBitmap); 44 | Gdi.DeleteObject(hBitmap); 45 | // GC.Collect(); 46 | } 47 | } 48 | finally 49 | { 50 | if (hDc != IntPtr.Zero) 51 | { 52 | Win32.ReleaseDC(Win32.GetDesktopWindow(), hDc); 53 | } 54 | } 55 | } 56 | return bmp; 57 | } 58 | 59 | 60 | public struct SIZE 61 | { 62 | public int Cx; 63 | public int Cy; 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UlteriusScreenShare")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("UlteriusScreenShare")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("d91b9fdb-9412-4658-98e6-476576a16265")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /UlteriusScreenShare/ScreenShareSErver.cs: -------------------------------------------------------------------------------- 1 | #region 2 | 3 | using System; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Net.NetworkInformation; 7 | using System.Security; 8 | using System.Threading; 9 | using UlteriusScreenShare.Websocket; 10 | using UlteriusScreenShare.Websocket.Server; 11 | using vtortola.WebSockets; 12 | 13 | #endregion 14 | 15 | namespace UlteriusScreenShare 16 | { 17 | public class ScreenShareServer 18 | { 19 | private readonly ConnectionHandler _connectionHandler; 20 | private readonly SecureString _password; 21 | private readonly int _port; 22 | private readonly WebSocketEventListener _server; 23 | private readonly string _serverName; 24 | 25 | public ScreenShareServer(string serverName, SecureString password, IPAddress address, int port) 26 | { 27 | _port = port; 28 | _serverName = serverName; 29 | _password = password; 30 | 31 | var cancellation = new CancellationTokenSource(); 32 | var endpoint = new IPEndPoint(address, _port); 33 | _server = new WebSocketEventListener(endpoint, new WebSocketListenerOptions 34 | { 35 | PingTimeout = TimeSpan.FromSeconds(15), 36 | NegotiationTimeout = TimeSpan.FromSeconds(15), 37 | WebSocketSendTimeout = TimeSpan.FromSeconds(15), 38 | WebSocketReceiveTimeout = TimeSpan.FromSeconds(15), 39 | ParallelNegotiations = Environment.ProcessorCount*2, 40 | NegotiationQueueCapacity = 256, 41 | TcpBacklog = 1000 42 | }); 43 | _connectionHandler = new ConnectionHandler(_serverName, _password, _server); 44 | } 45 | 46 | public bool PortAvailable() 47 | { 48 | var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties(); 49 | var tcpConnInfoArray = ipGlobalProperties.GetActiveTcpListeners(); 50 | return tcpConnInfoArray.All(endpoint => endpoint.Port != _port); 51 | } 52 | 53 | public bool Start() 54 | { 55 | try 56 | { 57 | if (PortAvailable()) 58 | { 59 | _server.Start(); 60 | return true; 61 | } 62 | return false; 63 | } 64 | catch (Exception) 65 | { 66 | return false; 67 | } 68 | } 69 | 70 | public bool Stop() 71 | { 72 | try 73 | { 74 | if (!PortAvailable()) 75 | { 76 | _server.Stop(); 77 | return true; 78 | } 79 | return false; 80 | } 81 | catch (Exception) 82 | { 83 | return false; 84 | } 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Security/Rsa.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Security; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Org.BouncyCastle.Crypto; 10 | using Org.BouncyCastle.Crypto.Encodings; 11 | using Org.BouncyCastle.Crypto.Engines; 12 | using Org.BouncyCastle.Crypto.Generators; 13 | using Org.BouncyCastle.Crypto.Parameters; 14 | using Org.BouncyCastle.Crypto.Prng; 15 | using Org.BouncyCastle.OpenSsl; 16 | using Org.BouncyCastle.Security; 17 | 18 | namespace UlteriusScreenShare.Security 19 | { 20 | internal class Rsa 21 | { 22 | public SecureString PrivateKey; 23 | public SecureString PublicKey; 24 | 25 | public static AsymmetricCipherKeyPair GetKeyPair() 26 | { 27 | var randomGenerator = new CryptoApiRandomGenerator(); 28 | var secureRandom = new SecureRandom(randomGenerator); 29 | var keyGenerationParameters = new KeyGenerationParameters(secureRandom, 2048); 30 | 31 | var keyPairGenerator = new RsaKeyPairGenerator(); 32 | keyPairGenerator.Init(keyGenerationParameters); 33 | return keyPairGenerator.GenerateKeyPair(); 34 | } 35 | 36 | public static SecureString StringToSecureString(string input) 37 | { 38 | var output = new SecureString(); 39 | var l = input.Length; 40 | var s = input.ToCharArray(0, l); 41 | foreach (var c in s) 42 | { 43 | output.AppendChar(c); 44 | } 45 | return output; 46 | } 47 | 48 | public static string SecureStringToString(SecureString value) 49 | { 50 | var valuePtr = IntPtr.Zero; 51 | try 52 | { 53 | valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value); 54 | return Marshal.PtrToStringUni(valuePtr); 55 | } 56 | finally 57 | { 58 | Marshal.ZeroFreeGlobalAllocUnicode(valuePtr); 59 | } 60 | } 61 | 62 | 63 | public static string Base64Encode(string plainText) 64 | { 65 | var plainTextBytes = Encoding.UTF8.GetBytes(plainText); 66 | return Convert.ToBase64String(plainTextBytes); 67 | } 68 | 69 | public static SecureString Decryption(SecureString clientPrivateKey, string encryptedData) 70 | { 71 | var data = Convert.FromBase64String(SecureStringToString(clientPrivateKey)); 72 | var decodedPrivateKey = Encoding.UTF8.GetString(data); 73 | var bytesToDecrypt = Convert.FromBase64String(encryptedData); 74 | var decryptEngine = new Pkcs1Encoding(new RsaEngine()); 75 | 76 | using (var txtreader = new StringReader(decodedPrivateKey)) 77 | { 78 | var keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject(); 79 | 80 | decryptEngine.Init(false, keyPair.Private); 81 | } 82 | return 83 | StringToSecureString( 84 | Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length))); 85 | } 86 | 87 | 88 | public void GenerateKeyPairs() 89 | { 90 | var keyPair = GetKeyPair(); 91 | var publicKey = (RsaKeyParameters)keyPair.Public; 92 | var privateKey = (RsaKeyParameters)keyPair.Private; 93 | 94 | 95 | var publicWriter = new StringWriter(); 96 | var pemWriter = new PemWriter(publicWriter); 97 | pemWriter.WriteObject(publicKey); 98 | pemWriter.Writer.Flush(); 99 | PublicKey = StringToSecureString(Base64Encode(publicWriter.ToString())); 100 | publicWriter.Close(); 101 | 102 | var privateWriter = new StringWriter(); 103 | var pemWriterP = new PemWriter(privateWriter); 104 | pemWriterP.WriteObject(privateKey); 105 | pemWriterP.Writer.Flush(); 106 | PrivateKey = StringToSecureString(Base64Encode(privateWriter.ToString())); 107 | privateWriter.Close(); 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Security/StringUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Security; 6 | using System.Text; 7 | using System.Text.RegularExpressions; 8 | using System.Threading.Tasks; 9 | 10 | namespace UlteriusScreenShare.Security 11 | { 12 | public static class StringUtils 13 | { 14 | public static bool IsBase64String(this string s) 15 | { 16 | s = s.Trim(); 17 | return (s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None); 18 | } 19 | public static string ConvertToUnsecureString(this SecureString securePassword) 20 | { 21 | if (securePassword == null) 22 | throw new ArgumentNullException("securePassword"); 23 | 24 | IntPtr unmanagedString = IntPtr.Zero; 25 | try 26 | { 27 | unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(securePassword); 28 | return Marshal.PtrToStringUni(unmanagedString); 29 | } 30 | finally 31 | { 32 | Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /UlteriusScreenShare/Security/Uaes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Security.Cryptography; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace UlteriusScreenShare.Security 10 | { 11 | internal class UAes 12 | { 13 | 14 | public static byte[] Encrypt(string plainText, byte[] key, byte[] iv) 15 | { 16 | // Check arguments. 17 | if (plainText == null || plainText.Length <= 0) 18 | { 19 | throw new ArgumentNullException("plainText"); 20 | } 21 | if (key == null || key.Length <= 0) 22 | { 23 | throw new ArgumentNullException("key"); 24 | } 25 | if (iv == null || iv.Length <= 0) 26 | { 27 | throw new ArgumentNullException("key"); 28 | } 29 | byte[] encrypted; 30 | // Create a RijndaelManaged object 31 | // with the specified key and IV. 32 | using (var rijAlg = new RijndaelManaged()) 33 | { 34 | rijAlg.Mode = CipherMode.CBC; 35 | rijAlg.Padding = PaddingMode.PKCS7; 36 | rijAlg.FeedbackSize = 128; 37 | 38 | rijAlg.Key = key; 39 | rijAlg.IV = iv; 40 | 41 | // Create a decrytor to perform the stream transform. 42 | var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV); 43 | 44 | // Create the streams used for encryption. 45 | using (var msEncrypt = new MemoryStream()) 46 | { 47 | using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 48 | { 49 | using (var swEncrypt = new StreamWriter(csEncrypt)) 50 | { 51 | //Write all data to the stream. 52 | swEncrypt.Write(plainText); 53 | } 54 | encrypted = msEncrypt.ToArray(); 55 | } 56 | } 57 | } 58 | // Return the encrypted bytes from the memory stream. 59 | return encrypted; 60 | } 61 | 62 | public static byte[] EncryptB(byte[] data, byte[] key, byte[] iv) 63 | { 64 | // Check arguments. 65 | if (data == null || data.Length <= 0) 66 | { 67 | throw new ArgumentNullException("data"); 68 | } 69 | if (key == null || key.Length <= 0) 70 | { 71 | throw new ArgumentNullException("key"); 72 | } 73 | if (iv == null || iv.Length <= 0) 74 | { 75 | throw new ArgumentNullException("key"); 76 | } 77 | byte[] encrypted; 78 | // Create a RijndaelManaged object 79 | // with the specified key and IV. 80 | using (var rijAlg = new RijndaelManaged()) 81 | { 82 | rijAlg.Mode = CipherMode.CBC; 83 | rijAlg.Padding = PaddingMode.PKCS7; 84 | rijAlg.FeedbackSize = 128; 85 | 86 | rijAlg.Key = key; 87 | rijAlg.IV = iv; 88 | 89 | // Create a decrytor to perform the stream transform. 90 | var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV); 91 | 92 | // Create the streams used for encryption. 93 | using (var msEncrypt = new MemoryStream()) 94 | { 95 | using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 96 | { 97 | using (var swEncrypt = new StreamWriter(csEncrypt)) 98 | { 99 | //Write all data to the stream. 100 | swEncrypt.Write(data); 101 | } 102 | encrypted = msEncrypt.ToArray(); 103 | } 104 | } 105 | } 106 | // Return the encrypted bytes from the memory stream. 107 | return encrypted; 108 | } 109 | 110 | public static string Decrypt(byte[] cipherText, byte[] key, byte[] iv) 111 | { 112 | // Check arguments. 113 | if (cipherText == null || cipherText.Length <= 0) 114 | { 115 | throw new ArgumentNullException("cipherText"); 116 | } 117 | if (key == null || key.Length <= 0) 118 | { 119 | throw new ArgumentNullException("key"); 120 | } 121 | if (iv == null || iv.Length <= 0) 122 | { 123 | throw new ArgumentNullException("key"); 124 | } 125 | 126 | // Declare the string used to hold 127 | // the decrypted text. 128 | string plaintext = null; 129 | 130 | // Create an RijndaelManaged object 131 | // with the specified key and IV. 132 | using (var rijAlg = new RijndaelManaged()) 133 | { 134 | //Settings 135 | rijAlg.Mode = CipherMode.CBC; 136 | rijAlg.Padding = PaddingMode.PKCS7; 137 | rijAlg.FeedbackSize = 128; 138 | rijAlg.Key = key; 139 | rijAlg.IV = iv; 140 | 141 | // Create a decrytor to perform the stream transform. 142 | var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV); 143 | 144 | try 145 | { 146 | // Create the streams used for decryption. 147 | using (var msDecrypt = new MemoryStream(cipherText)) 148 | { 149 | using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 150 | { 151 | using (var srDecrypt = new StreamReader(csDecrypt)) 152 | { 153 | // Read the decrypted bytes from the decrypting stream 154 | // and place them in a string. 155 | plaintext = srDecrypt.ReadToEnd(); 156 | } 157 | } 158 | } 159 | } 160 | catch 161 | { 162 | plaintext = "keyError"; 163 | } 164 | } 165 | 166 | return plaintext; 167 | } 168 | } 169 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/UlteriusScreenShare.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D91B9FDB-9412-4658-98E6-476576A16265} 8 | Library 9 | Properties 10 | UlteriusScreenShare 11 | UlteriusScreenShare 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | true 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | true 35 | 36 | 37 | 38 | ..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll 39 | True 40 | 41 | 42 | ..\packages\DotNetZip.1.9.8\lib\net20\Ionic.Zip.dll 43 | True 44 | 45 | 46 | ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll 47 | True 48 | 49 | 50 | 51 | 52 | 53 | 54 | ..\packages\Microsoft.Tpl.Dataflow.4.5.24\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll 55 | True 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | ..\packages\vtortola.WebSocketListener.2.2.0.3\lib\net45\vtortola.WebSockets.dll 67 | True 68 | 69 | 70 | ..\packages\vtortola.WebSocketListener.2.2.0.3\lib\net45\vtortola.WebSockets.Deflate.dll 71 | True 72 | 73 | 74 | ..\packages\vtortola.WebSocketListener.2.2.0.3\lib\net45\vtortola.WebSockets.Rfc6455.dll 75 | True 76 | 77 | 78 | 79 | ..\packages\InputSimulator.1.0.4.0\lib\net20\WindowsInput.dll 80 | True 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 112 | -------------------------------------------------------------------------------- /UlteriusScreenShare/Websocket/AuthClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using vtortola.WebSockets; 8 | 9 | namespace UlteriusScreenShare.Websocket 10 | { 11 | internal class AuthClient 12 | { 13 | public AuthClient(WebSocket client) 14 | { 15 | Client = client; 16 | Started = DateTime.Now; 17 | Authenticated = false; 18 | AesShook = false; 19 | } 20 | 21 | public WebSocket Client { get; set; } 22 | public DateTime Started { get; set; } 23 | public bool Authenticated { get; set; } 24 | public SecureString PrivateKey { get; set; } 25 | public SecureString PublicKey { get; set; } 26 | public SecureString AesKey { get; set; } 27 | public SecureString AesIv { get; set; } 28 | public bool AesShook { get; set; } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /UlteriusScreenShare/Websocket/Server/AuthenticationHandler.cs: -------------------------------------------------------------------------------- 1 | #region 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using Newtonsoft.Json.Linq; 6 | using UlteriusScreenShare.Security; 7 | 8 | #endregion 9 | 10 | namespace UlteriusScreenShare.Websocket.Server 11 | { 12 | internal class AuthenticationHandler 13 | { 14 | public static void Authenticate(string password, string packetData, AuthClient authClient) 15 | { 16 | try 17 | { 18 | if (!packetData.IsBase64String()) 19 | { 20 | throw new InvalidOperationException("Packet must be base64 encoded if encrypted."); 21 | } 22 | 23 | if (authClient != null) 24 | { 25 | packetData = MessageHandler.DecryptMessage(packetData, authClient); 26 | if (packetData == null) 27 | { 28 | throw new Exception("Packet is null"); 29 | } 30 | var args = new List(); 31 | var deserializedPacket = JObject.Parse(packetData); 32 | args.AddRange(JArray.Parse(deserializedPacket["args"].ToString())); 33 | var authKey = authClient.Client.GetHashCode().ToString(); 34 | var inputPass = args[0].ToString(); 35 | if (inputPass.Equals(password)) 36 | { 37 | authClient.Authenticated = true; 38 | ConnectionHandler.Clients[authKey] = authClient; 39 | var login = new 40 | { 41 | message = "Login Valid!", 42 | loggedIn = true 43 | }; 44 | MessageHandler.SendMessage("login", login, authClient); 45 | } 46 | else 47 | { 48 | var login = new 49 | { 50 | message = "Login Invalid!", 51 | loggedIn = false 52 | }; 53 | MessageHandler.SendMessage("login", login, authClient); 54 | } 55 | } 56 | } 57 | catch (Exception e) 58 | { 59 | var login = new 60 | { 61 | message = "Login Failed!", 62 | reason = e.Message, 63 | loggedIn = false 64 | }; 65 | MessageHandler.SendMessage("login", login, authClient); 66 | } 67 | } 68 | 69 | public static void AesHandshake(string packet, AuthClient authClient) 70 | { 71 | try 72 | { 73 | var args = new List(); 74 | var deserializedPacket = JObject.Parse(packet); 75 | args.AddRange(JArray.Parse(deserializedPacket["args"].ToString())); 76 | if (authClient != null) 77 | { 78 | var authKey = authClient.Client.GetHashCode().ToString(); 79 | var privateKey = authClient.PrivateKey; 80 | var encryptedKey = args[0].ToString(); 81 | var encryptedIv = args[1].ToString(); 82 | authClient.AesKey = Rsa.Decryption(privateKey, encryptedKey); 83 | authClient.AesIv = Rsa.Decryption(privateKey, encryptedIv); 84 | authClient.AesShook = true; 85 | ConnectionHandler.Clients[authKey] = authClient; 86 | var handshake = new 87 | { 88 | message = "Handshake Accepted", 89 | shook = true 90 | }; 91 | MessageHandler.SendMessage("aeshandshake", handshake, authClient); 92 | } 93 | } 94 | catch (Exception e) 95 | { 96 | if (authClient != null) 97 | { 98 | var handshake = new 99 | { 100 | message = "Handshake Failed", 101 | reason = e.Message, 102 | shook = false 103 | }; 104 | MessageHandler.SendMessage("aeshandshake", handshake, authClient); 105 | } 106 | } 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Websocket/Server/CommandHandler.cs: -------------------------------------------------------------------------------- 1 | #region 2 | 3 | using System; 4 | using System.Drawing; 5 | using System.Drawing.Imaging; 6 | using System.Globalization; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Windows.Forms; 10 | using WindowsInput; 11 | using WindowsInput.Native; 12 | using Ionic.Zlib; 13 | using Newtonsoft.Json.Linq; 14 | using UlteriusScreenShare.Desktop; 15 | using vtortola.WebSockets; 16 | 17 | #endregion 18 | 19 | namespace UlteriusScreenShare.Websocket.Server 20 | { 21 | internal class CommandHandler 22 | { 23 | private readonly ConnectionHandler _connectionHandler; 24 | private readonly Screen[] _screens = Screen.AllScreens; 25 | private readonly InputSimulator _simulator = new InputSimulator(); 26 | 27 | public CommandHandler(ConnectionHandler connectionHandler) 28 | { 29 | _connectionHandler = connectionHandler; 30 | } 31 | 32 | public void ProcessCommand(WebSocket client, string message) 33 | { 34 | var packet = JObject.Parse(message); 35 | var eventType = (string) packet["EventType"]; 36 | var eventAction = (string) packet["Action"]; 37 | if (eventType.Equals("Mouse")) 38 | { 39 | switch (eventAction) 40 | { 41 | case "Move": 42 | MoveMouse(packet); 43 | break; 44 | case "Down": 45 | HandleMouseDown(); 46 | break; 47 | case "Scroll": 48 | HandleScroll(packet); 49 | break; 50 | case "Up": 51 | HandleMouseUp(); 52 | break; 53 | case "LeftClick": 54 | HandleLeftClick(); 55 | break; 56 | case "LeftDblClick": 57 | HandleDoubleClick(); 58 | break; 59 | case "RightClick": 60 | HandleRightClick(); 61 | break; 62 | } 63 | } 64 | else if (eventType.Equals("Keyboard")) 65 | { 66 | switch (eventAction) 67 | { 68 | case "KeyDown": 69 | HandleKeyDown(packet); 70 | break; 71 | } 72 | } 73 | else if (eventType.Equals("Frame")) 74 | { 75 | switch (eventAction) 76 | { 77 | case "Full": 78 | 79 | HandleFullFrame(client); 80 | break; 81 | } 82 | } 83 | } 84 | 85 | private void HandleScroll(JObject packet) 86 | { 87 | var delta = (int) packet["delta"]; 88 | delta = ~delta; 89 | 90 | _simulator.Mouse.VerticalScroll(delta); 91 | } 92 | 93 | private string ToHex(int value) 94 | { 95 | return $"0x{value:X}"; 96 | } 97 | 98 | private void HandleKeyDown(JObject packet) 99 | { 100 | var keyCodes = packet["KeyCodes"]; 101 | var codes = 102 | keyCodes.Select(code => ToHex(int.Parse(code.ToString()))) 103 | .Select(hexString => Convert.ToInt32(hexString, 16)) 104 | .ToList(); 105 | 106 | if (codes.Count >= 2) 107 | { 108 | foreach (var code in codes) 109 | { 110 | var virtualKey = (VirtualKeyCode) code; 111 | _simulator.Keyboard.KeyDown(virtualKey); 112 | } 113 | //fuck.gif 114 | foreach (var code in codes) 115 | { 116 | var virtualKey = (VirtualKeyCode) code; 117 | _simulator.Keyboard.KeyUp(virtualKey); 118 | } 119 | } 120 | else 121 | { 122 | var virtualKey = (VirtualKeyCode) codes[0]; 123 | _simulator.Keyboard.KeyPress(virtualKey); 124 | } 125 | } 126 | 127 | private void HandleFullFrame(WebSocket client) 128 | { 129 | using (var jpegStream = new MemoryStream()) 130 | { 131 | var screenGrab = Capture.CaptureDesktop(); 132 | if (screenGrab == null) 133 | { 134 | return; 135 | } 136 | screenGrab.Save(jpegStream, ImageFormat.Jpeg); 137 | var compressed = ZlibStream.CompressBuffer(jpegStream.ToArray()); 138 | SendFrameData(client, compressed); 139 | } 140 | } 141 | 142 | private void SendFrameData(WebSocket client, byte[] compressed) 143 | { 144 | var encryptedData = MessageHandler.EncryptBuffer(compressed, client); 145 | if (encryptedData != null && client.IsConnected) 146 | { 147 | try 148 | { 149 | using (var messageWriter = client.CreateMessageWriter(WebSocketMessageType.Binary)) 150 | { 151 | using (var stream = new MemoryStream(encryptedData)) 152 | { 153 | stream.CopyTo(messageWriter); 154 | } 155 | } 156 | } 157 | catch (Exception e) 158 | { 159 | Console.WriteLine(e.Message); 160 | } 161 | } 162 | } 163 | 164 | private void HandleDoubleClick() 165 | { 166 | Console.WriteLine("Double click fired"); 167 | _simulator.Mouse.LeftButtonClick(); 168 | } 169 | 170 | private void HandleMouseDown() 171 | { 172 | Console.WriteLine("Mouse down"); 173 | _simulator.Mouse.LeftButtonDown(); 174 | } 175 | 176 | private void HandleMouseUp() 177 | { 178 | Console.WriteLine("Mouse up"); 179 | _simulator.Mouse.LeftButtonUp(); 180 | } 181 | 182 | private void HandleRightClick() 183 | { 184 | Console.WriteLine("Right click"); 185 | _simulator.Mouse.RightButtonClick(); 186 | } 187 | 188 | private void HandleLeftClick() 189 | { 190 | Console.WriteLine("Left click"); 191 | // _simulator.Mouse.LeftButtonClick(); 192 | } 193 | 194 | private void MoveMouse(JObject packet) 195 | { 196 | try 197 | { 198 | int y = Convert.ToInt16(packet["PointerY"], CultureInfo.InvariantCulture); 199 | int x = Convert.ToInt16(packet["PointerX"], CultureInfo.InvariantCulture); 200 | var device = _screens[0]; 201 | if (x < 0 || x >= device.Bounds.Width || y < 0 || y >= device.Bounds.Height) 202 | { 203 | return; 204 | } 205 | Cursor.Position = new Point(x, y); 206 | } 207 | catch 208 | { 209 | Console.WriteLine("Error moving mouse"); 210 | } 211 | } 212 | } 213 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Websocket/Server/ConnectionHandler.cs: -------------------------------------------------------------------------------- 1 | #region 2 | 3 | using System; 4 | using System.Collections.Concurrent; 5 | using System.Security; 6 | using UlteriusScreenShare.Security; 7 | using vtortola.WebSockets; 8 | 9 | #endregion 10 | 11 | namespace UlteriusScreenShare.Websocket.Server 12 | { 13 | internal class ConnectionHandler 14 | { 15 | public static ConcurrentDictionary Clients; 16 | private readonly CommandHandler _commandHandler; 17 | private readonly WebSocketEventListener _server; 18 | private readonly SecureString _password; 19 | private string _serverName; 20 | 21 | public ConnectionHandler(string serverName, SecureString password, WebSocketEventListener server) 22 | { 23 | _serverName = serverName; 24 | _password = password; 25 | Clients = new ConcurrentDictionary(); 26 | _commandHandler = new CommandHandler(this); 27 | _server = server; 28 | _server.OnConnect += HandleConnect; 29 | _server.OnDisconnect += HandleDisconnect; 30 | _server.OnMessage += HandleMessage; 31 | _server.OnError += HandleError; 32 | } 33 | 34 | 35 | private void HandleError(WebSocket websocket, Exception error) 36 | { 37 | Console.WriteLine($"Error occured on {websocket.GetHashCode()}: {error.Message}"); 38 | } 39 | 40 | private void HandleMessage(WebSocket websocket, string message) 41 | { 42 | AuthClient client; 43 | 44 | if (Clients.TryRemove(websocket.GetHashCode().ToString(), out client)) 45 | { 46 | if (!client.AesShook) 47 | { 48 | AuthenticationHandler.AesHandshake(message, client); 49 | } 50 | else if (!client.Authenticated && client.AesShook) 51 | { 52 | AuthenticationHandler.Authenticate(_password.ConvertToUnsecureString(), message, client); 53 | } 54 | else if (client.Authenticated && client.AesShook) 55 | { 56 | try 57 | { 58 | _commandHandler.ProcessCommand(websocket, MessageHandler.DecryptMessage(message, client)); 59 | } 60 | catch (Exception) 61 | { 62 | 63 | Console.WriteLine("Failed to decrypt packet on command."); 64 | } 65 | } 66 | } 67 | } 68 | 69 | private void HandleDisconnect(WebSocket websocket) 70 | { 71 | AuthClient client; 72 | if (Clients.TryRemove(websocket.GetHashCode().ToString(), out client)) 73 | { 74 | Console.WriteLine("Client removed"); 75 | } 76 | } 77 | 78 | public void Handshake(AuthClient authClient) 79 | { 80 | var handshake = new 81 | { 82 | message = "Handshake established", 83 | publicKey = Rsa.SecureStringToString(authClient.PublicKey) 84 | }; 85 | MessageHandler.SendMessage("connectedToScreenShare", handshake, authClient); 86 | } 87 | 88 | private void HandleConnect(WebSocket websocket) 89 | { 90 | var authClient = new AuthClient(websocket); 91 | var rsa = new Rsa(); 92 | rsa.GenerateKeyPairs(); 93 | authClient.PublicKey = rsa.PublicKey; 94 | authClient.PrivateKey = rsa.PrivateKey; 95 | if (Clients.TryAdd(websocket.GetHashCode().ToString(), authClient)) 96 | { 97 | Handshake(authClient); 98 | Console.WriteLine("New Client Connected"); 99 | } 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Websocket/Server/MessageHandler.cs: -------------------------------------------------------------------------------- 1 | #region 2 | 3 | using System; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Web.Script.Serialization; 7 | using UlteriusScreenShare.Security; 8 | using vtortola.WebSockets; 9 | 10 | #endregion 11 | 12 | namespace UlteriusScreenShare.Websocket.Server 13 | { 14 | internal class MessageHandler 15 | { 16 | public static string DecryptMessage(string message, AuthClient client) 17 | { 18 | if (!message.IsBase64String()) 19 | { 20 | throw new InvalidOperationException("Packet must be base64 encoded if encrypted."); 21 | } 22 | if (client != null) 23 | { 24 | var keybytes = Encoding.UTF8.GetBytes(Rsa.SecureStringToString(client.AesKey)); 25 | var iv = Encoding.UTF8.GetBytes(Rsa.SecureStringToString(client.AesIv)); 26 | var packet = Convert.FromBase64String(message); 27 | return UAes.Decrypt(packet, keybytes, iv); 28 | } 29 | return null; 30 | } 31 | 32 | public static byte[] EncryptBuffer(byte[] data, WebSocket client) 33 | { 34 | try 35 | { 36 | AuthClient authClient; 37 | if (ConnectionHandler.Clients.TryGetValue(client.GetHashCode().ToString(), out authClient)) 38 | { 39 | var keybytes = Encoding.UTF8.GetBytes(Rsa.SecureStringToString(authClient.AesKey)); 40 | var iv = Encoding.UTF8.GetBytes(Rsa.SecureStringToString(authClient.AesIv)); 41 | return UAes.EncryptB(data, keybytes, iv); 42 | } 43 | return null; 44 | } 45 | catch (Exception e) 46 | { 47 | Console.WriteLine("Could not encrypt buffer: " + e.Message); 48 | return null; 49 | } 50 | } 51 | 52 | public static void SendMessage(string endpoint, object data, AuthClient authClient) 53 | { 54 | var serializer = new JavaScriptSerializer {MaxJsonLength = int.MaxValue}; 55 | var json = serializer.Serialize(new 56 | { 57 | endpoint, 58 | results = data 59 | }); 60 | try 61 | { 62 | if (authClient != null) 63 | { 64 | if (authClient.AesShook) 65 | { 66 | var keyBytes = Encoding.UTF8.GetBytes(Rsa.SecureStringToString(authClient.AesKey)); 67 | var keyIv = Encoding.UTF8.GetBytes(Rsa.SecureStringToString(authClient.AesIv)); 68 | var encryptedData = UAes.Encrypt(json, keyBytes, keyIv); 69 | json = Convert.ToBase64String(encryptedData); 70 | Console.WriteLine("Message Encrypted"); 71 | } 72 | } 73 | } 74 | catch (Exception) 75 | { 76 | //TODO Handle 77 | } 78 | Push(authClient.Client, json); 79 | } 80 | 81 | private static void Push(WebSocket client, string json) 82 | { 83 | try 84 | { 85 | client.WriteStringAsync(json, CancellationToken.None); 86 | } 87 | catch (Exception e) 88 | { 89 | Console.WriteLine(e.Message); 90 | } 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Websocket/WebSocketEventListener.cs: -------------------------------------------------------------------------------- 1 | #region 2 | 3 | using System; 4 | using System.Net; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using vtortola.WebSockets; 8 | using vtortola.WebSockets.Rfc6455; 9 | 10 | #endregion 11 | 12 | namespace UlteriusScreenShare.Websocket 13 | { 14 | public delegate void WebSocketEventListenerOnConnect(WebSocket webSocket); 15 | 16 | public delegate void WebSocketEventListenerOnDisconnect(WebSocket webSocket); 17 | 18 | public delegate void WebSocketEventListenerOnMessage(WebSocket webSocket, string message); 19 | 20 | public delegate void WebSocketEventListenerOnError(WebSocket webSocket, Exception error); 21 | 22 | internal class WebSocketEventListener : IDisposable 23 | { 24 | private readonly WebSocketListener _listener; 25 | 26 | public WebSocketEventListener(IPEndPoint endpoint) 27 | : this(endpoint, new WebSocketListenerOptions()) 28 | { 29 | } 30 | 31 | public WebSocketEventListener(IPEndPoint endpoint, WebSocketListenerOptions options) 32 | { 33 | _listener = new WebSocketListener(endpoint, options); 34 | _listener.Standards.RegisterStandard(new WebSocketFactoryRfc6455(_listener)); 35 | } 36 | 37 | public void Dispose() 38 | { 39 | _listener.Dispose(); 40 | } 41 | 42 | public event WebSocketEventListenerOnConnect OnConnect; 43 | public event WebSocketEventListenerOnDisconnect OnDisconnect; 44 | public event WebSocketEventListenerOnMessage OnMessage; 45 | public event WebSocketEventListenerOnError OnError; 46 | 47 | public void Start() 48 | { 49 | _listener.Start(); 50 | Task.Run(ListenAsync); 51 | 52 | } 53 | 54 | public void Stop() 55 | { 56 | _listener.Stop(); 57 | 58 | } 59 | 60 | private async Task ListenAsync() 61 | { 62 | while (_listener.IsStarted) 63 | { 64 | 65 | try 66 | { 67 | var websocket = await _listener.AcceptWebSocketAsync(CancellationToken.None) 68 | .ConfigureAwait(false); 69 | if (websocket != null) 70 | Task.Run(() => HandleWebSocketAsync(websocket)); 71 | } 72 | catch (Exception ex) 73 | { 74 | OnError?.Invoke(null, ex); 75 | } 76 | } 77 | } 78 | 79 | private async Task HandleWebSocketAsync(WebSocket websocket) 80 | { 81 | try 82 | { 83 | OnConnect?.Invoke(websocket); 84 | 85 | while (websocket.IsConnected) 86 | { 87 | var message = await websocket.ReadStringAsync(CancellationToken.None) 88 | .ConfigureAwait(false); 89 | if (message != null) 90 | OnMessage?.Invoke(websocket, message); 91 | } 92 | 93 | OnDisconnect?.Invoke(websocket); 94 | } 95 | catch (Exception ex) 96 | { 97 | OnError?.Invoke(websocket, ex); 98 | } 99 | finally 100 | { 101 | websocket.Dispose(); 102 | } 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Win32Api/Gdi.cs: -------------------------------------------------------------------------------- 1 | #region 2 | 3 | using System; 4 | using System.Runtime.InteropServices; 5 | 6 | #endregion 7 | 8 | namespace UlteriusScreenShare.Win32Api 9 | { 10 | internal class Gdi 11 | { 12 | public const int Srccopy = 13369376; 13 | 14 | #region Class Functions 15 | 16 | [DllImport("gdi32.dll", EntryPoint = "CreateDC")] 17 | public static extern IntPtr CreateDC(IntPtr lpszDriver, string lpszDevice, IntPtr lpszOutput, IntPtr lpInitData); 18 | 19 | [DllImport("gdi32.dll", EntryPoint = "DeleteDC")] 20 | public static extern IntPtr DeleteDC(IntPtr hDc); 21 | 22 | [DllImport("gdi32.dll", EntryPoint = "DeleteObject")] 23 | public static extern IntPtr DeleteObject(IntPtr hDc); 24 | 25 | [DllImport("gdi32.dll", EntryPoint = "BitBlt")] 26 | public static extern bool BitBlt(IntPtr hdcDest, int xDest, 27 | int yDest, int wDest, 28 | int hDest, IntPtr hdcSource, 29 | int xSrc, int ySrc, int rasterOp); 30 | 31 | [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")] 32 | public static extern IntPtr CreateCompatibleBitmap 33 | (IntPtr hdc, int nWidth, int nHeight); 34 | 35 | [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")] 36 | public static extern IntPtr CreateCompatibleDC(IntPtr hdc); 37 | 38 | [DllImport("gdi32.dll", EntryPoint = "SelectObject")] 39 | public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp); 40 | 41 | [DllImport("gdi32.dll")] 42 | public static extern int StretchBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, int dwRop); 43 | 44 | [DllImport("gdi32.dll")] 45 | public static extern int SetStretchBltMode(IntPtr hdc, int iStretchMode); 46 | 47 | 48 | [DllImport("gdi32.dll")] 49 | public static extern IntPtr CreateDIBSection(IntPtr hdc, [In] ref Win32.Bitmapinfo pbmi, uint pila, out IntPtr ppvBits, IntPtr hSection, uint dwOffset); 50 | 51 | #endregion 52 | } 53 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Win32Api/Win32.cs: -------------------------------------------------------------------------------- 1 | #region 2 | 3 | using System; 4 | using System.Runtime.InteropServices; 5 | using WindowsInput.Native; 6 | 7 | #endregion 8 | 9 | namespace UlteriusScreenShare.Win32Api 10 | { 11 | internal class Win32 12 | { 13 | [Flags] 14 | public enum MouseEventFlags : uint 15 | { 16 | MouseeventfMove = 0x0001, 17 | MouseeventfLeftdown = 0x0002, 18 | MouseeventfLeftup = 0x0004, 19 | MouseeventfRightdown = 0x0008, 20 | MouseeventfRightup = 0x0010, 21 | MouseeventfMiddledown = 0x0020, 22 | MouseeventfMiddleup = 0x0040, 23 | MouseeventfXdown = 0x0080, 24 | MouseeventfXup = 0x0100, 25 | MouseeventfWheel = 0x0800, 26 | MouseeventfVirtualdesk = 0x4000, 27 | MouseeventfAbsolute = 0x8000 28 | } 29 | 30 | public enum SendInputEventType 31 | { 32 | InputMouse, 33 | InputKeyboard, 34 | InputHardware 35 | } 36 | 37 | public const int SmCxscreen = 0; 38 | public const int SmCyscreen = 1; 39 | 40 | public const int CursorShowing = 0x00000001; 41 | public static readonly int Srccopy = 0x00CC0020; 42 | public static readonly int Srcpaint = 0x00EE0086; 43 | public static readonly int Captureblt = 0x40000000; 44 | public static readonly int StretchHalftone = 0x04; 45 | public static readonly uint PmNoremove = 0x00; 46 | 47 | public static readonly uint DibRgbColors = 0; /* color table in RGBs */ 48 | public static readonly uint DibPalColors = 1; /* color table in palette indices */ 49 | public static readonly uint BiRgb = 0; 50 | public static readonly uint BiRle8 = 1; 51 | public static readonly uint BiRle4 = 2; 52 | public static readonly uint BiBitfields = 3; 53 | 54 | [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")] 55 | public static extern IntPtr GetDesktopWindow(); 56 | 57 | [DllImport("user32.dll", EntryPoint = "GetDC")] 58 | public static extern IntPtr GetDC(IntPtr ptr); 59 | 60 | [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")] 61 | public static extern int GetSystemMetrics(int abc); 62 | 63 | [DllImport("user32.dll", EntryPoint = "GetWindowDC")] 64 | public static extern IntPtr GetWindowDC(int ptr); 65 | 66 | [DllImport("user32.dll", EntryPoint = "ReleaseDC")] 67 | public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc); 68 | 69 | [DllImport("user32.dll")] 70 | public static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect); 71 | 72 | [DllImport("user32.dll", EntryPoint = "GetCursorInfo")] 73 | public static extern bool GetCursorInfo(out Cursorinfo pci); 74 | 75 | [DllImport("user32.dll", EntryPoint = "CopyIcon")] 76 | public static extern IntPtr CopyIcon(IntPtr hIcon); 77 | 78 | [DllImport("user32.dll", EntryPoint = "GetIconInfo")] 79 | public static extern bool GetIconInfo(IntPtr hIcon, out Iconinfo piconinfo); 80 | 81 | [DllImport("user32.dll", EntryPoint = "DestroyIcon")] 82 | public static extern bool DestroyIcon(IntPtr hIcon); 83 | 84 | [DllImport("user32.dll")] 85 | public static extern bool ClientToScreen(IntPtr hWnd, ref Point point); 86 | 87 | 88 | [DllImport("user32.dll")] 89 | public static extern long SetCursorPos(int x, int y); 90 | 91 | [DllImport("user32.dll")] 92 | private static extern int GetSystemMetrics(SystemMetric smIndex); 93 | 94 | [DllImport("user32.dll", SetLastError = true)] 95 | private static extern uint SendInput(uint nInputs, ref Input pInputs, int cbSize); 96 | 97 | public static int CalculateAbsoluteCoordinateX(int x) 98 | { 99 | return x*65536/GetSystemMetrics(SystemMetric.SM_CXSCREEN); 100 | } 101 | 102 | public static int CalculateAbsoluteCoordinateY(int y) 103 | { 104 | return y*65536/GetSystemMetrics(SystemMetric.SM_CXSCREEN); 105 | } 106 | 107 | public static void LeftMouseButton(MouseEventFlags mouseEventFlags, int x, int y) 108 | { 109 | var mouseInput = new Input {type = SendInputEventType.InputMouse}; 110 | mouseInput.mkhi.mi.Dx = CalculateAbsoluteCoordinateX(x); 111 | mouseInput.mkhi.mi.Dy = CalculateAbsoluteCoordinateY(y); 112 | mouseInput.mkhi.mi.MouseData = 0; 113 | 114 | mouseInput.mkhi.mi.DwFlags = MouseEventFlags.MouseeventfMove | MouseEventFlags.MouseeventfAbsolute; 115 | SendInput(1, ref mouseInput, Marshal.SizeOf(new Input())); 116 | 117 | mouseInput.mkhi.mi.DwFlags = mouseEventFlags; 118 | SendInput(1, ref mouseInput, Marshal.SizeOf(new Input())); 119 | } 120 | 121 | public static void ClickRightMouseButton(int x, int y) 122 | { 123 | var mouseInput = new Input {type = SendInputEventType.InputMouse}; 124 | mouseInput.mkhi.mi.Dx = CalculateAbsoluteCoordinateX(x); 125 | mouseInput.mkhi.mi.Dy = CalculateAbsoluteCoordinateY(y); 126 | mouseInput.mkhi.mi.MouseData = 0; 127 | 128 | mouseInput.mkhi.mi.DwFlags = MouseEventFlags.MouseeventfMove | MouseEventFlags.MouseeventfAbsolute; 129 | SendInput(1, ref mouseInput, Marshal.SizeOf(new Input())); 130 | 131 | mouseInput.mkhi.mi.DwFlags = MouseEventFlags.MouseeventfRightdown; 132 | SendInput(1, ref mouseInput, Marshal.SizeOf(new Input())); 133 | 134 | mouseInput.mkhi.mi.DwFlags = MouseEventFlags.MouseeventfRightup; 135 | SendInput(1, ref mouseInput, Marshal.SizeOf(new Input())); 136 | } 137 | /// 138 | /// Retrieves the cursor's position, in screen coordinates. 139 | /// 140 | /// See MSDN documentation for further information. 141 | [DllImport("user32.dll")] 142 | public static extern bool GetCursorPos(out Point lpPoint); 143 | 144 | public static Point GetCursorPosition() 145 | { 146 | Point lpPoint; 147 | GetCursorPos(out lpPoint); 148 | //bool success = User32.GetCursorPos(out lpPoint); 149 | // if (!success) 150 | 151 | return lpPoint; 152 | } 153 | public static void MoveMouse(int x, int y) 154 | { 155 | var mouseInput = new Input {type = SendInputEventType.InputMouse}; 156 | mouseInput.mkhi.mi.Dx = CalculateAbsoluteCoordinateX(x); 157 | mouseInput.mkhi.mi.Dy = CalculateAbsoluteCoordinateY(y); 158 | mouseInput.mkhi.mi.MouseData = 0; 159 | 160 | mouseInput.mkhi.mi.DwFlags = MouseEventFlags.MouseeventfMove | MouseEventFlags.MouseeventfAbsolute; 161 | SendInput(1, ref mouseInput, Marshal.SizeOf(new Input())); 162 | } 163 | 164 | 165 | [StructLayout(LayoutKind.Sequential)] 166 | public struct Bitmapinfoheader 167 | { 168 | public uint biSize; 169 | public int biWidth; 170 | public int biHeight; 171 | public ushort biPlanes; 172 | public ushort biBitCount; 173 | public uint biCompression; 174 | public uint biSizeImage; 175 | public int biXPelsPerMeter; 176 | public int biYPelsPerMeter; 177 | public uint biClrUsed; 178 | public uint biClrImportant; 179 | } 180 | 181 | [StructLayout(LayoutKind.Sequential)] 182 | public struct Rect 183 | { 184 | public int left; 185 | public int top; 186 | public int right; 187 | public int bottom; 188 | } 189 | 190 | [StructLayout(LayoutKind.Sequential)] 191 | public struct Rgbquad 192 | { 193 | public byte rgbBlue; 194 | public byte rgbGreen; 195 | public byte rgbRed; 196 | public byte rgbReserved; 197 | } 198 | 199 | [StructLayout(LayoutKind.Sequential)] 200 | public struct Bitmapinfo 201 | { 202 | public Bitmapinfoheader bmiHeader; 203 | public Rgbquad bmiColors_1; 204 | } 205 | 206 | [StructLayout(LayoutKind.Sequential)] 207 | public struct Bitmap 208 | { 209 | public int bmType; 210 | public int bmWidth; 211 | public int bmHeight; 212 | public int bmWidthBytes; 213 | public byte bmPlanes; 214 | public byte bmBitsPixel; 215 | public IntPtr bmBits; 216 | } 217 | 218 | [StructLayout(LayoutKind.Sequential)] 219 | public struct Iconinfo 220 | { 221 | public bool fIcon; 222 | // Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies 223 | 224 | public int xHotspot; 225 | // Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot 226 | 227 | public int yHotspot; 228 | // Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot 229 | 230 | public IntPtr hbmMask; 231 | // (HBITMAP) Specifies the icon bitmask bitmap. If this structure defines a black and white icon, 232 | 233 | public IntPtr hbmColor; // (HBITMAP) Handle to the icon color bitmap. This member can be optional if this 234 | } 235 | 236 | [StructLayout(LayoutKind.Sequential)] 237 | public struct Point 238 | { 239 | public int x; 240 | public int y; 241 | } 242 | 243 | [StructLayout(LayoutKind.Sequential)] 244 | public struct Cursorinfo 245 | { 246 | public int cbSize; // Specifies the size, in bytes, of the structure. 247 | public int flags; // Specifies the cursor state. This parameter can be one of the following values: 248 | public IntPtr hCursor; // Handle to the cursor. 249 | public Point ptScreenPos; // A POINT structure that receives the screen coordinates of the cursor. 250 | } 251 | 252 | private enum SystemMetric 253 | { 254 | SM_CXSCREEN = 0, 255 | SM_CYSCREEN = 1 256 | } 257 | 258 | [StructLayout(LayoutKind.Sequential)] 259 | public struct Hardwareinput 260 | { 261 | public int uMsg; 262 | public short wParamL; 263 | public short wParamH; 264 | } 265 | 266 | [StructLayout(LayoutKind.Sequential)] 267 | public struct Keybdinput 268 | { 269 | public ushort wVk; 270 | public ushort wScan; 271 | public uint dwFlags; 272 | public uint time; 273 | public IntPtr dwExtraInfo; 274 | } 275 | 276 | [StructLayout(LayoutKind.Explicit)] 277 | public struct MouseKeybdhardwareInputUnion 278 | { 279 | [FieldOffset(0)] public MouseInputData mi; 280 | 281 | [FieldOffset(0)] public Keybdinput ki; 282 | 283 | [FieldOffset(0)] public Hardwareinput hi; 284 | } 285 | 286 | [StructLayout(LayoutKind.Sequential)] 287 | public struct Input 288 | { 289 | public SendInputEventType type; 290 | public MouseKeybdhardwareInputUnion mkhi; 291 | } 292 | 293 | public struct MouseInputData 294 | { 295 | public int Dx; 296 | public int Dy; 297 | public uint MouseData; 298 | public MouseEventFlags DwFlags; 299 | public uint Time; 300 | public IntPtr DwExtraInfo; 301 | } 302 | } 303 | } -------------------------------------------------------------------------------- /UlteriusScreenShare/Win32Api/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /UlteriusScreenShare/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /UlteriusScreenShareExample/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /UlteriusScreenShareExample/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using UlteriusScreenShare; 8 | 9 | namespace UlteriusScreenShareExample 10 | { 11 | class Program 12 | { 13 | static void Main(string[] args) 14 | { 15 | var server = new Server(IPAddress.Any, 5555); 16 | server.Start(); 17 | Console.Read(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /UlteriusScreenShareExample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UlteriusScreenShareExample")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("UlteriusScreenShareExample")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("ea65f94d-d15b-401a-aaf2-bc0298fb0637")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /UlteriusScreenShareExample/UlteriusScreenShareExample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EA65F94D-D15B-401A-AAF2-BC0298FB0637} 8 | Exe 9 | Properties 10 | UlteriusScreenShareExample 11 | UlteriusScreenShareExample 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | ..\packages\Microsoft.Tpl.Dataflow.4.5.24\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll 40 | True 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | ..\packages\vtortola.WebSocketListener.2.2.0.3\lib\net45\vtortola.WebSockets.dll 50 | True 51 | 52 | 53 | ..\packages\vtortola.WebSocketListener.2.2.0.3\lib\net45\vtortola.WebSockets.Deflate.dll 54 | True 55 | 56 | 57 | ..\packages\vtortola.WebSocketListener.2.2.0.3\lib\net45\vtortola.WebSockets.Rfc6455.dll 58 | True 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | {d91b9fdb-9412-4658-98e6-476576a16265} 72 | UlteriusScreenShare 73 | 74 | 75 | 76 | 83 | -------------------------------------------------------------------------------- /UlteriusScreenShareExample/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | --------------------------------------------------------------------------------