@@ -52,18 +52,14 @@ Add-Type -Assembly System.Windows.Forms
52
52
Add-Type - Assembly System.Drawing
53
53
Add-Type - MemberDefinition ' [DllImport("User32.dll")] public static extern bool SetProcessDPIAware();[DllImport("User32.dll")] public static extern int LoadCursorA(int hInstance, int lpCursorName);[DllImport("User32.dll")] public static extern bool GetCursorInfo(IntPtr pci);' - Name User32 - Namespace W;
54
54
55
- $global :PowerRemoteDesktopVersion = " 1.0.5.beta. 6"
55
+ $global :PowerRemoteDesktopVersion = " 1.0.6"
56
56
57
57
$global :HostSyncHash = [HashTable ]::Synchronized(@ {
58
58
host = $host
59
59
ClipboardText = (Get-Clipboard - Raw)
60
+ RunningSession = $false
60
61
})
61
62
62
- enum TransportMode {
63
- Raw = 1
64
- Base64 = 2
65
- }
66
-
67
63
enum ClipboardMode {
68
64
Disabled = 1
69
65
Receive = 2
@@ -600,14 +596,12 @@ class ClientIO {
600
596
[System.IO.StreamWriter ] $Writer = $null
601
597
[System.IO.StreamReader ] $Reader = $null
602
598
[System.Net.Security.SslStream ] $SSLStream = $null
603
- [TransportMode ] $TransportMode
604
599
605
600
606
601
ClientIO(
607
602
[System.Net.Sockets.TcpClient ] $Client ,
608
603
[System.Security.Cryptography.X509Certificates.X509Certificate2 ] $Certificate ,
609
- [bool ] $TLSv1_3 ,
610
- [TransportMode ] $TransportMode
604
+ [bool ] $TLSv1_3
611
605
) {
612
606
<#
613
607
. SYNOPSIS
@@ -621,9 +615,6 @@ class ClientIO {
621
615
622
616
. PARAMETER TLSv1_3
623
617
Define whether or not SSL/TLS v1.3 must be used.
624
-
625
- . PARAMETER TransportMode
626
- Define transport method for streams (Base64 or Raw)
627
618
#>
628
619
629
620
if ((-not $Client ) -or (-not $Certificate ))
@@ -632,7 +623,6 @@ class ClientIO {
632
623
}
633
624
634
625
$this.Client = $Client
635
- $this.TransportMode = $TransportMode
636
626
637
627
Write-Verbose " Create new SSL Stream..."
638
628
@@ -783,7 +773,6 @@ class ClientIO {
783
773
784
774
$sessionInformation = Get-LocalMachineInformation
785
775
786
- $sessionInformation | Add-Member - MemberType NoteProperty - Name " TransportMode" - Value $this.TransportMode
787
776
$sessionInformation | Add-Member - MemberType NoteProperty - Name " SessionId" - Value $session.Id
788
777
$sessionInformation | Add-Member - MemberType NoteProperty - Name " Version" - Value $global :PowerRemoteDesktopVersion
789
778
$sessionInformation | Add-Member - MemberType NoteProperty - Name " ViewOnly" - Value $ViewOnly
@@ -854,7 +843,6 @@ class ServerIO {
854
843
[string ] $ListenAddress = " 127.0.0.1"
855
844
[int ] $ListenPort = 2801
856
845
[bool ] $TLSv1_3 = $false
857
- [TransportMode ] $TransportMode
858
846
[string ] $Password
859
847
[bool ] $ViewOnly = $false
860
848
@@ -888,17 +876,13 @@ class ServerIO {
888
876
. PARAMETER TLSv1_3
889
877
Define if TLS v1.3 must be used.
890
878
891
- . PARAMETER TransportMode
892
- Define stream transport method.
893
-
894
879
. PARAMETER ViewOnly
895
880
Define if mouse / keyboard is authorized.
896
881
#>
897
882
898
883
[string ] $ListenAddress ,
899
884
[int ] $ListenPort ,
900
885
[string ] $Password ,
901
- [TransportMode ] $TransportMode ,
902
886
[System.Security.Cryptography.X509Certificates.X509Certificate2 ] $Certificate ,
903
887
[bool ] $TLSv1_3 ,
904
888
[bool ] $ViewOnly
@@ -913,7 +897,6 @@ class ServerIO {
913
897
$this.ListenPort = $ListenPort
914
898
$this.TLSv1_3 = $TLSv1_3
915
899
$this.Password = $Password
916
- $this.TransportMode = $TransportMode
917
900
$this.ViewOnly = $ViewOnly
918
901
919
902
if (-not $Certificate )
@@ -997,8 +980,7 @@ class ServerIO {
997
980
$client = [ClientIO ]::New(
998
981
$socket ,
999
982
$this.Certificate ,
1000
- $this.TLSv1_3 ,
1001
- $this.TransportMode
983
+ $this.TLSv1_3
1002
984
)
1003
985
try
1004
986
{
@@ -1059,11 +1041,6 @@ class ServerIO {
1059
1041
1060
1042
$global :DesktopStreamScriptBlock = {
1061
1043
1062
- enum TransportMode {
1063
- Raw = 1
1064
- Base64 = 2
1065
- }
1066
-
1067
1044
function Get-DesktopImage {
1068
1045
<#
1069
1046
. SYNOPSIS
@@ -1093,11 +1070,16 @@ $global:DesktopStreamScriptBlock = {
1093
1070
$Screen.Bounds.Location.Y
1094
1071
)
1095
1072
1096
- $bitmap = New-Object System.Drawing.Bitmap($size.Width , $size.Height )
1073
+ $bitmap = New-Object System.Drawing.Bitmap(
1074
+ $size.Width ,
1075
+ $size.Height ,
1076
+ [System.Drawing.Imaging.PixelFormat ]::Format24bppRgb
1077
+ )
1078
+
1097
1079
$graphics = [System.Drawing.Graphics ]::FromImage($bitmap )
1098
1080
1099
1081
$graphics.CopyFromScreen ($location , [System.Drawing.Point ]::Empty, $size )
1100
-
1082
+
1101
1083
return $bitmap
1102
1084
}
1103
1085
catch
@@ -1130,13 +1112,13 @@ $global:DesktopStreamScriptBlock = {
1130
1112
$encoderParameters = New-Object System.Drawing.Imaging.EncoderParameters(1 )
1131
1113
$encoderParameters.Param [0 ] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder ]::Quality, $imageQuality )
1132
1114
1133
- $packetSize = 4096
1134
-
1135
- while ($true )
1136
- {
1115
+ $packetSize = 9216 # 9KiB
1116
+
1117
+ while ($global :HostSyncHash .RunningSession )
1118
+ {
1137
1119
try
1138
1120
{
1139
- $desktopImage = Get-DesktopImage - Screen $Param.Screen
1121
+ $desktopImage = Get-DesktopImage - Screen $Param.Screen
1140
1122
1141
1123
$imageStream = New-Object System.IO.MemoryStream
1142
1124
@@ -1163,50 +1145,20 @@ $global:DesktopStreamScriptBlock = {
1163
1145
{
1164
1146
$imageStream.position = 0
1165
1147
try
1166
- {
1167
- switch ([TransportMode ] $Param.Client.TransportMode )
1168
- {
1169
- ([TransportMode ]::Raw)
1170
- {
1171
- $Param.Client.SSLStream.Write ([BitConverter ]::GetBytes([int32 ] $imageStream.Length ) , 0 , 4 ) # SizeOf(Int32)
1172
-
1173
- $totalBytesSent = 0
1174
-
1175
- $buffer = New-Object - TypeName byte[] - ArgumentList $packetSize
1176
- do
1177
- {
1178
- $bufferSize = ($imageStream.Length - $totalBytesSent )
1179
- if ($bufferSize -gt $packetSize )
1180
- {
1181
- $bufferSize = $packetSize
1182
- }
1183
- else
1184
- {
1185
- # Save some memory operations for creating objects.
1186
- # Usually, bellow code is call when last chunk is being sent.
1187
- $buffer = New-Object - TypeName byte[] - ArgumentList $bufferSize
1188
- }
1189
-
1190
- # (OPTIMIZATION IDEA): Try with BinaryStream to save the need of "byte[]"" buffer.
1191
- $null = $imageStream.Read ($buffer , 0 , $buffer.Length )
1192
-
1193
- $Param.Client.SSLStream.Write ($buffer , 0 , $buffer.Length )
1194
-
1195
- $totalBytesSent += $bufferSize
1196
- } until ($totalBytesSent -eq $imageStream.Length )
1197
-
1198
- break
1199
- }
1200
-
1201
- ([TransportMode ]::Base64)
1202
- {
1203
- $Param.Client.Writer.WriteLine (
1204
- [System.Convert ]::ToBase64String($imageStream.ToArray ())
1205
- )
1148
+ {
1149
+ $Param.Client.SSLStream.Write ([BitConverter ]::GetBytes([int32 ] $imageStream.Length ) , 0 , 4 ) # SizeOf(Int32)
1150
+
1151
+ $binaryReader = New-Object System.IO.BinaryReader($imageStream )
1152
+ do
1153
+ {
1154
+ $bufferSize = ($imageStream.Length - $imageStream.Position )
1155
+ if ($bufferSize -gt $packetSize )
1156
+ {
1157
+ $bufferSize = $packetSize
1158
+ }
1206
1159
1207
- break
1208
- }
1209
- }
1160
+ $Param.Client.SSLStream.Write ($binaryReader.ReadBytes ($bufferSize ), 0 , $bufferSize )
1161
+ } until ($imageStream.Position -eq $imageStream.Length )
1210
1162
}
1211
1163
catch
1212
1164
{ break }
@@ -1323,7 +1275,7 @@ $global:IngressEventScriptBlock = {
1323
1275
1324
1276
$keyboardSim = [KeyboardSim ]::New()
1325
1277
1326
- while ($true )
1278
+ while ($global :HostSyncHash .RunningSession )
1327
1279
{
1328
1280
try
1329
1281
{
@@ -1626,7 +1578,7 @@ $global:EgressEventScriptBlock = {
1626
1578
1627
1579
$stopWatch = [System.Diagnostics.Stopwatch ]::StartNew()
1628
1580
1629
- while ($true )
1581
+ while ($global :HostSyncHash .RunningSession )
1630
1582
{
1631
1583
# Events that occurs every seconds needs to be placed bellow.
1632
1584
# If no event has occured during this second we send a Keep-Alive signal to
@@ -1792,10 +1744,6 @@ function Invoke-RemoteDesktopServer
1792
1744
. PARAMETER EncodedCertificate
1793
1745
A valid X509 Certificate (With Private Key) encoded as a Base64 String.
1794
1746
1795
- . PARAMETER TransportMode
1796
- Tell server how to send desktop image to remote viewer. Best method is Raw Bytes but I decided to keep
1797
- the Base64 transport method as an alternative.
1798
-
1799
1747
. PARAMETER TLSv1_3
1800
1748
Define whether or not TLS v1.3 must be used for communication with Viewer.
1801
1749
@@ -1828,7 +1776,6 @@ function Invoke-RemoteDesktopServer
1828
1776
# Or
1829
1777
[string ] $EncodedCertificate = " " , # 2
1830
1778
1831
- [TransportMode ] $TransportMode = [TransportMode ]::Raw,
1832
1779
[switch ] $TLSv1_3 ,
1833
1780
[switch ] $DisableVerbosity ,
1834
1781
[int ] $ImageQuality = 100 ,
@@ -1911,13 +1858,11 @@ function Invoke-RemoteDesktopServer
1911
1858
}
1912
1859
}
1913
1860
1914
- Write-Verbose $TransportMode
1915
1861
# Create new server and listen
1916
1862
$server = [ServerIO ]::New(
1917
1863
$ListenAddress ,
1918
1864
$ListenPort ,
1919
1865
$Password ,
1920
- $TransportMode ,
1921
1866
$Certificate ,
1922
1867
$TLSv1_3 ,
1923
1868
$ViewOnly
@@ -1929,6 +1874,8 @@ function Invoke-RemoteDesktopServer
1929
1874
{
1930
1875
try
1931
1876
{
1877
+ $global :HostSyncHash.RunningSession = $false
1878
+
1932
1879
Write-Verbose " Server waiting for new incomming session..."
1933
1880
1934
1881
# Establish a new Remote Desktop Session.
@@ -1939,7 +1886,9 @@ function Invoke-RemoteDesktopServer
1939
1886
# Otherwise a Timeout Exception will be raised.
1940
1887
# Actually, if someone else decide to connect in the mean time it will interrupt the whole session,
1941
1888
# Remote Viewer will then need to establish a new session from scratch.
1942
- $clientEvents = $server.PullClient (10 * 1000 );
1889
+ $clientEvents = $server.PullClient (10 * 1000 );
1890
+
1891
+ $global :HostSyncHash.RunningSession = $true
1943
1892
1944
1893
# Grab desired screen to capture
1945
1894
$screen = [System.Windows.Forms.Screen ]::AllScreens | Where-Object - FilterScript { $_.DeviceName -eq $server.Session.Screen }
@@ -1983,16 +1932,19 @@ function Invoke-RemoteDesktopServer
1983
1932
# Waiting for Runspaces to finish their jobs.
1984
1933
while ($true )
1985
1934
{
1986
- $completed = $true
1935
+ $completed = $true
1987
1936
1988
1937
# Probe each existing runspaces
1989
1938
foreach ($runspace in $runspaces )
1990
1939
{
1991
1940
if (-not $runspace.AsyncResult.IsCompleted )
1992
1941
{
1993
- $completed = $false
1994
-
1995
- break
1942
+ $completed = $false
1943
+ }
1944
+ elseif ($global :HostSyncHash.RunningSession )
1945
+ {
1946
+ # Notifying other runspaces that a session integrity was lost
1947
+ $global :HostSyncHash.RunningSession = $false
1996
1948
}
1997
1949
}
1998
1950
0 commit comments