diff --git a/hyperv-passthrough/App.config b/hyperv-passthrough/App.config
index 1243f4282..6525f5822 100644
--- a/hyperv-passthrough/App.config
+++ b/hyperv-passthrough/App.config
@@ -3,22 +3,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hyperv-passthrough/DisplayAssignableDevices.Designer.cs b/hyperv-passthrough/DisplayAssignableDevices.Designer.cs
new file mode 100644
index 000000000..cd3f91329
--- /dev/null
+++ b/hyperv-passthrough/DisplayAssignableDevices.Designer.cs
@@ -0,0 +1,88 @@
+namespace HyperVPassthoughDevice
+{
+ partial class DisplayAssignableDevices
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DisplayAssignableDevices));
+ this.CloseButton = new System.Windows.Forms.Button();
+ this.start = new System.Windows.Forms.Button();
+ this.richTextBox1 = new System.Windows.Forms.RichTextBox();
+ this.SuspendLayout();
+ //
+ // CloseButton
+ //
+ this.CloseButton.Location = new System.Drawing.Point(505, 346);
+ this.CloseButton.Name = "CloseButton";
+ this.CloseButton.Size = new System.Drawing.Size(75, 23);
+ this.CloseButton.TabIndex = 0;
+ this.CloseButton.Text = "Close";
+ this.CloseButton.UseVisualStyleBackColor = true;
+ this.CloseButton.Click += new System.EventHandler(this.CloseDiaglog);
+ //
+ // start
+ //
+ this.start.Location = new System.Drawing.Point(397, 346);
+ this.start.Name = "start";
+ this.start.Size = new System.Drawing.Size(102, 23);
+ this.start.TabIndex = 3;
+ this.start.Text = "Start Checking";
+ this.start.UseVisualStyleBackColor = true;
+ this.start.Click += new System.EventHandler(this.StartChecking);
+ //
+ // richTextBox1
+ //
+ this.richTextBox1.Location = new System.Drawing.Point(12, 12);
+ this.richTextBox1.Name = "richTextBox1";
+ this.richTextBox1.Size = new System.Drawing.Size(568, 328);
+ this.richTextBox1.TabIndex = 1;
+ this.richTextBox1.Text = "";
+ this.richTextBox1.WordWrap = false;
+ //
+ // DisplayAssignableDevices
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(592, 381);
+ this.Controls.Add(this.start);
+ this.Controls.Add(this.richTextBox1);
+ this.Controls.Add(this.CloseButton);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.Name = "DisplayAssignableDevices";
+ this.Text = "Display Assignable Devices";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button CloseButton;
+ private System.Windows.Forms.Button start;
+ private System.Windows.Forms.RichTextBox richTextBox1;
+ }
+}
\ No newline at end of file
diff --git a/hyperv-passthrough/DisplayAssignableDevices.cs b/hyperv-passthrough/DisplayAssignableDevices.cs
new file mode 100644
index 000000000..51613ae44
--- /dev/null
+++ b/hyperv-passthrough/DisplayAssignableDevices.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Management.Automation;
+using System.Text;
+using System.Windows.Forms;
+
+namespace HyperVPassthoughDevice
+{
+ public partial class DisplayAssignableDevices : Form
+ {
+ public DisplayAssignableDevices()
+ {
+ InitializeComponent();
+ ShowDialog();
+ }
+
+ private void CloseDiaglog(object sender, EventArgs e)
+ {
+ Close();
+ }
+
+ private void StartChecking(object sender, EventArgs e)
+ {
+ richTextBox1.Clear(); //Clear textbox
+
+ string script = "#\r\n# These variables are device properties. For people who are very\r\n# curious about this, you can download the Windows Driver Kit headers and\r\n# look for pciprop.h. All of these are contained in that file.\r\n#\r\n$devpkey_PciDevice_DeviceType = \"{3AB22E31-8264-4b4e-9AF5-A8D2D8E33E62} 1\"\r\n$devpkey_PciDevice_BaseClass = \"{3AB22E31-8264-4b4e-9AF5-A8D2D8E33E62} 3\"\r\n$devpkey_PciDevice_RequiresReservedMemoryRegion = \"{3AB22E31-8264-4b4e-9AF5-A8D2D8E33E62} 34\"\r\n$devpkey_PciDevice_AcsCompatibleUpHierarchy = \"{3AB22E31-8264-4b4e-9AF5-A8D2D8E33E62} 31\"\r\n\r\n$devprop_PciDevice_DeviceType_PciConventional = 0\r\n$devprop_PciDevice_DeviceType_PciX = 1\r\n$devprop_PciDevice_DeviceType_PciExpressEndpoint = 2\r\n$devprop_PciDevice_DeviceType_PciExpressLegacyEndpoint = 3\r\n$devprop_PciDevice_DeviceType_PciExpressRootComplexIntegratedEndpoint= 4\r\n$devprop_PciDevice_DeviceType_PciExpressTreatedAsPci = 5\r\n$devprop_PciDevice_BridgeType_PciConventional = 6\r\n$devprop_PciDevice_BridgeType_PciX = 7\r\n$devprop_PciDevice_BridgeType_PciExpressRootPort = 8\r\n$devprop_PciDevice_BridgeType_PciExpressUpstreamSwitchPort = 9\r\n$devprop_PciDevice_BridgeType_PciExpressDownstreamSwitchPort = 10\r\n$devprop_PciDevice_BridgeType_PciExpressToPciXBridge = 11\r\n$devprop_PciDevice_BridgeType_PciXToExpressBridge = 12\r\n$devprop_PciDevice_BridgeType_PciExpressTreatedAsPci = 13\r\n$devprop_PciDevice_BridgeType_PciExpressEventCollector = 14\r\n\r\n$devprop_PciDevice_AcsCompatibleUpHierarchy_NotSupported = 0\r\n$devprop_PciDevice_AcsCompatibleUpHierarchy_SingleFunctionSupported = 1\r\n$devprop_PciDevice_AcsCompatibleUpHierarchy_NoP2PSupported = 2\r\n$devprop_PciDevice_AcsCompatibleUpHierarchy_Supported = 3\r\n\r\n#\r\n# These values are defined in the PCI spec, and are also published in wdm.h\r\n# of the Windows Driver Kit headers.\r\n#\r\n$devprop_PciDevice_BaseClass_DisplayCtlr = 3\r\n\r\nWrite-Host \"Executing SurveyDDA.ps1, revision 1\"\r\n\r\nwrite-host \"Generating a list of PCI Express endpoint devices\"\r\n$pnpdevs = Get-PnpDevice -PresentOnly\r\n$pcidevs = $pnpdevs | Where-Object {$_.InstanceId -like \"PCI*\"}\r\n\r\nforeach ($pcidev in $pcidevs) {\r\n $rmrr = ($pcidev | Get-PnpDeviceProperty $devpkey_PciDevice_RequiresReservedMemoryRegion).Data\r\n if ($rmrr -ne 0) {\r\n write-host -ForegroundColor Red -BackgroundColor Black \"BIOS requires that this device remain attached to BIOS-owned memory. Not assignable.\"\r\n continue\r\n }\r\n\r\n $acsUp = ($pcidev | Get-PnpDeviceProperty $devpkey_PciDevice_AcsCompatibleUpHierarchy).Data\r\n if ($acsUp -eq $devprop_PciDevice_AcsCompatibleUpHierarchy_NotSupported) {\r\n write-host -ForegroundColor Red -BackgroundColor Black \"Traffic from this device may be redirected to other devices in the system. Not assignable.\"\r\n continue\r\n }\r\n\r\n $devtype = ($pcidev | Get-PnpDeviceProperty $devpkey_PciDevice_DeviceType).Data\r\n if ($devtype -eq $devprop_PciDevice_DeviceType_PciExpressEndpoint) {\r\n Write-Host \"Express Endpoint -- more secure.\"\r\n } else {\r\n if ($devtype -eq $devprop_PciDevice_DeviceType_PciExpressRootComplexIntegratedEndpoint) {\r\n Write-Host \"Embedded Endpoint -- less secure.\"\r\n } elseif ($devtype -eq $devprop_PciDevice_DeviceType_PciExpressLegacyEndpoint) {\r\n $devBaseClass = ($pcidev | Get-PnpDeviceProperty $devpkey_PciDevice_BaseClass).Data\r\n\r\n if ($devBaseClass -eq $devprop_PciDevice_BaseClass_DisplayCtlr) {\r\n Write-Host \"Legacy Express Endpoint -- graphics controller.\"\r\n } else {\r\n Write-Host -ForegroundColor Red -BackgroundColor Black \"Legacy, non-VGA PCI device. Not assignable.\"\r\n continue\r\n }\r\n } else {\r\n if ($devtype -eq $devprop_PciDevice_DeviceType_PciExpressTreatedAsPci) {\r\n Write-Host -ForegroundColor Red -BackgroundColor Black \"BIOS kept control of PCI Express for this device. Not assignable.\"\r\n } else {\r\n Write-Host -ForegroundColor Red -BackgroundColor Black \"Old-style PCI device, switch port, etc. Not assignable.\"\r\n }\r\n continue\r\n }\r\n }\r\n\r\n $locationpath = ($pcidev | get-pnpdeviceproperty DEVPKEY_Device_LocationPaths).data[0]\r\n\r\n #\r\n # If the device is disabled, we can't check the resources, report a warning and continue on.\r\n #\r\n #\r\n if ($pcidev.ConfigManagerErrorCode -eq \"CM_PROB_DISABLED\")\r\n {\r\n Write-Host -ForegroundColor Yellow -BackgroundColor Black \"Device is Disabled, unable to check resource requirements, it may be assignable.\"\r\n Write-Host -ForegroundColor Yellow -BackgroundColor Black \"Enable the device and rerun this script to confirm.\"\r\n $locationpath\r\n continue\r\n }\r\n\r\n #\r\n # Now do a check for the interrupts that the device uses. Line-based interrupts\r\n # aren't assignable.\r\n #\r\n $doubleslashDevId = \"*\" + $pcidev.PNPDeviceID.Replace(\"\\\",\"\\\\\") + \"*\"\r\n $irqAssignments = gwmi -query \"select * from Win32_PnPAllocatedResource\" | Where-Object {$_.__RELPATH -like \"*Win32_IRQResource*\"} | Where-Object {$_.Dependent -like $doubleslashDevId}\r\n\r\n #$irqAssignments | Format-Table -Property __RELPATH\r\n\r\n if ($irqAssignments.length -eq 0) {\r\n Write-Host -ForegroundColor Green -BackgroundColor Black \" And it has no interrupts at all -- assignment can work.\"\r\n } else {\r\n #\r\n # Find the message-signaled interrupts. They are reported with a really big number in\r\n # decimal, one which always happens to start with \"42949...\".\r\n #\r\n $msiAssignments = $irqAssignments | Where-Object {$_.Antecedent -like \"*IRQNumber=42949*\"}\r\n \r\n #$msiAssignments | Format-Table -Property __RELPATH\r\n\r\n if ($msiAssignments.length -eq 0) {\r\n Write-Host -ForegroundColor Red -BackgroundColor Black \"All of the interrupts are line-based, no assignment can work.\"\r\n continue\r\n } else {\r\n Write-Host -ForegroundColor Green -BackgroundColor Black \" And its interrupts are message-based, assignment can work.\"\r\n }\r\n }\r\n\r\n #\r\n # Check how much MMIO space the device needs\r\n # not strictly an issue devices, but very useful when you want to set MMIO gap sizes\r\n #\r\n\r\n $mmioAssignments = gwmi -query \"select * from Win32_PnPAllocatedResource\" | Where-Object {$_.__RELPATH -like \"*Win32_DeviceMemoryAddress*\"} | Where-Object {$_.Dependent -like $doubleslashDevId}\r\n $mmioTotal = 0\r\n foreach ($mem in $mmioAssignments) \r\n {\r\n $baseAdd =$mem.Antecedent.SubString($mem.Antecedent.IndexOf(\"\"\"\")+1)\r\n $baseAdd=$baseAdd.SubString(0,$baseAdd.IndexOf(\"\"\"\"))\r\n $mmioRange = gwmi -query \"select * from Win32_DeviceMemoryAddress\" | Where-Object{$_.StartingAddress -like $baseAdd}\r\n $mmioTotal = $mmioTotal + $mmioRange.EndingAddress - $mmioRange.StartingAddress\r\n }\r\n if ($mmioTotal -eq 0)\r\n {\r\n Write-Host -ForegroundColor Green -BackgroundColor Black \" And it has no MMIO space\"\r\n } else {\r\n \t [int]$mmioMB = [math]::ceiling($mmioTotal / 1MB)\r\n Write-Host -ForegroundColor Green -BackgroundColor Black \" And it requires at least:\" $mmioMB \"MB of MMIO gap space\"\r\n }\r\n \r\n\r\n\r\n #\r\n # Print out the location path, as that's the way to refer to this device that won't\r\n # change even if you add or remove devices from the machine or change the way that\r\n # the BIOS is configured.\r\n #\r\n\t\r\n\t$locationpath = $pcidev.FriendlyName + \"`n Location Path: \" + $locationpath + \"`n MMIO Space: \" + $mmioMB + \" MiB`n`n\"\r\n $locationpath\r\n \r\n\t\r\n}\r\n\r\n#\r\n# Now look at the host as a whole. Asking whether the host supports SR-IOV\r\n# is mostly equivalent to asking whether it supports Discrete Device\r\n# Assignment.\r\n#\r\nif ((Get-VMHost).IovSupport -eq $false) {\r\n Write-Host \"\"\r\n write-host \"Unfortunately, this machine doesn't support using them in a VM.\"\r\n Write-Host \"\"\r\n (Get-VMHost).IovSupportReasons\r\n}";
+ using (PowerShell powerShell = PowerShell.Create())
+ {
+ powerShell.AddScript(script);
+ powerShell.AddCommand("Out-String");
+ Collection PSOutput = powerShell.Invoke();
+ StringBuilder stringBuilder = new StringBuilder();
+ foreach (PSObject pSObject in PSOutput)
+ stringBuilder.AppendLine(pSObject.ToString());
+ richTextBox1.Text = stringBuilder.ToString() + "\n\n";
+ }
+ }
+ }
+}
diff --git a/hyperv-passthrough/DisplayAssignableDevices.resx b/hyperv-passthrough/DisplayAssignableDevices.resx
new file mode 100644
index 000000000..cddba4ac8
--- /dev/null
+++ b/hyperv-passthrough/DisplayAssignableDevices.resx
@@ -0,0 +1,480 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+ AAABAAEAAAAAAAEAIAAKUwAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAEAAAABAAgGAAAAXHKoZgAAIABJ
+ REFUeJzsvXd8HNd57v+dXSx6IQCSIDobQDR2gmhsIEFS1ZJrYtlxiR0nthOn3cSxb27Kzf3d3NyUayeS
+ rTi2JVGWbEeSJUuieqHYFBWSktgAEOwkQKKSRF1gd+b3xxbMzs7MzvYFMA8/4M6ec+bMmZ15nvO+pwqS
+ JGHChIm5CUu8C2DChIn4wRQAEybmMEwBMGFiDsMUABMm5jBMATBhYg7DFAATJuYwTAEwYWIOwxQAEybm
+ MEwBMGFiDsMUABMm5jCS4l0AE5HBro6eVUnwFxdEdloh6YJIDsA6K+fKrDzxaEXhd+JdRhOJB8GcCzBz
+ 4SH9SSd3XHITXguZApIpBiaUMAVghiEY0mvBFAMTHpgCMAMQCdJrwRSDuQ1TABIU0SS9FkwxmHswBSCB
+ EA/Sa8EUg7kBUwDijEQivRZMMZi9MAUgDpgJpNeCKQazC6YAxAhrT/dstgr8jwtOWgYk0uNdnkjAFIOZ
+ D1MAoojZSHotmGIwM2EKQIQxl0ivBVMMZg5MAYgATNJrwxSDxIYpACHCJH3wMMUg8WAKQBAwSR85mGKQ
+ GDAFIABM0kcfHjEot/LknorCv4h3eeYSTAFQwfLTPXfNE/iWSfrYwy0G58utPGGKQfRhCoAbJad6Ppct
+ 8PULIhvHJWzxLs+chwSZFlMMoo05LQAm6RMU8ldScH1kIknrkzhfZhVMMYgg5pwAmKRPYKgQ3y9ScrkJ
+ bjF4ck9F4bdjVLpZiTkhACbpZwAMkl8Jb5tBkikGoWDWCoBJ+hkECRfpPZ9+gaiSXwmPGCy2Ck8+UmmK
+ gRHMKgEwST8D4Xn9/Gp9d2Qwr6dMMzIFpHVJXCi3Ck/sMcVAEzNeAEzSz1CEaPLr5iczGOQnLxIkxz2p
+ 1r9+sKLwfwdZylmPGScAwomeeQss3Ddf4D6T9DMUqia/PJLgya8MkABJch9LIMJvZiQ99fOqok+FUuTZ
+ ihkhAB7SZ8JXz4usjXd5TISBCPn7fnl6DkRf0iNJIIkgSqQJSF/KS7vrB8sLXwjvJmYPEnZjEDnpgbV9
+ IvTFu1AmQoeS1Go1f6gmv4fkPqSXQBRd8U5X3DiS8MHIxA+B8lBvY7YhoQTAJP0shZ+/L6/+QzT5ZTW7
+ KulFcdoaEEVv3JUxqSDc25lNiLsAmKSf5VA1+UMgv49PL4KTAKSXWQWOaSFwJpnbYcoRFwEwST9HIMk+
+ 1fz9QMRXNuQ5JQOk9wiELK3MUnCIomqH41xFzATAJP0cgm4XnzuBFvlVWu+nCRwM6T3EZzoNIDoTv9E7
+ loiqAJikn4MIpX9flfQeUovT8aKsNtckvft8UWRaaNzWA+CUTAtAjogLgHCiZ3GuwGcF+DpQapJ+DiGY
+ Lj5N0ssb7WR/Hn9ej/TeNO4LOGUXcwKIiKIz6j/DTEJEBEA40bN4W0bqn3w0NnEvUDpkWllzD5o1v8zf
+ D0h6ps17uRB4XQA10nvEwV0I0VMW0Ut6V/kk92VNA0COsARgzzDzJNF54EfFC+pSklxZdQ8NsW/wBkdS
+ M+h3mGo76xHI5JfQGJyjQXpvuFwI1Egvq+lFWU3vkPCS3iMI4BUeEdMFkCMsARBEx14sSXUvPvQjTh87
+ QnnFCjbdeRf3La/kPuCaw8Ebw2McGZswxWA2QtXkR0F60RjpfXx+ZQMg+qT31PRe6wKFtSErl2md+iCs
+ ocB7hpHajx3l77/5NZ/wVatW8Xc/+ncQkpgQBSYkUwxmHZTk9xDT67vjNs09RMcA6VE5PwDp8aRzR4kq
+ pJcVOjMnzTF82zpz/ogbYbcBvPLLx/3ChnqvYxdFECaxCQJpgoV5KVYW27K5LzfbFIOZDEl5LG+sw01Y
+ pwHSK8PcpJZkrfeSQdJ7anpRXi5loV3XmAlzX2KJsAVgdGRYN94pgRNXTZAsQLpCDK47HLxuisHMgMeE
+ FhQ+uRgG6b3ny9ir0nrv+iqzBpTmved0n8IynU4RbMKFmI4EdErgFFxikGoRyJAE5qVYKTfFILHh409L
+ smG4sn76YEnvrd09tbeM3Kqk95RBNEh6RZj30FQAOeI2F8AhSTjcjURpFoF0BOZZTTFIGPj43XLz3kNq
+ QHROE9ko6b2+vigjqgQO0Ca9vOaXl092oGra+9f8Jv19EffJQABTSAiuN4oUi0C6JJCZbKE8zxSDmEJu
+ Xiv72T01tNOpIHYQpEdyj9BzHxsiPb7kltfimv68Mr3Z86eFhBAAOURAEiQsOEkTnGQgkGWxmmIQLQQi
+ vXI0nrelX5xutAtIepnN7u2yY9q1ENBpvZcFeF2RgDcECOrVvWkC+CDhBEAOJ+BEwiI4SBcE0gWBLNNN
+ CB9GSO/tjvP43e54hyyttwcAHdJL7kY9d03vHakn++KUl0sOERBkbQVGIGjk5acsJkhwAZBDdFcZSYKI
+ zSq4LAOrlaWmGBhDMKT3DthxE9dLemm6xjc6OMdnYI77HEEM0GWHb766pFWsLaCXpwk/zBgBkENy/7MJ
+ EoIVsrAwz2JleX42w6YYTMOP9B4yapDeS3z54B1ZnDIfI6QH39Z+mK7xfQuq7ev7QTns0P/QePzcxowU
+ ADkkYBIRi8V1MxkWC7lzWQwkGZmMkl6SFI17yFwAMDYiT0F6rYY8LwlVSO8TpQxXa8gzyR8uZrwAyCEB
+ U4hYrJAKZFgt5MnEoNfh4LXZKAahkt7bd68ciovM92f6PNdFgiA90wdyUms15CnFQbf1PgiT3yS/JmaV
+ AMghAQ63GKQBWVYLeVYry5JniRiETXplODIxgNBremVBPS3+AVjoFQiB0IlvJN6EHLNWAOQQcY01sFok
+ koAsq0C+jxg4eW14NPHFQE42L4kJgfSemh1fAfDOqHOHh0N6TzojJPSmCdRfHw75TTVQw5wQADlcloGE
+ 1SqRDmRLFvKtlsQVg4iRXkZ0ua/vSSO4r+MdnBMs6T3CIfoFqcPTT2+UmOGY/PJzTSGQY84JgBwSMCWI
+ JFnBBmSTIGIQFdIrBt8oG/WkcEgv+UZqckzWZRcN8geyCkz4ISoC0Ds4yGP/9x9obGujpHIFqVlZ0bhM
+ ROGyDERsVkgGcmItBtGu6T3Hnrt1gnson+/gHAm8fjtoE86nJtUjodKsD4b8QZBbQnNzUP085jaiIgD2
+ ySl+/cyz/PqZZ1mYl0vTls00tbVRWrmClOyZIgYSyVZIESRyJIH5SVEQg1iT3mPeewbiyGt6QVb7GyK9
+ Is7nUMuXl4IgYZDk9wkyyW8UUXcBegeHVMWgbAaJgVOQsFkh1SqRKwlgsXBfrmsEYtBiEAzpfdbSC6em
+ F33DPddGAklwkd9niC7TXzR9ZiUBA7TcB7UYpx75Jd2vJvmDQ0zbANTEoLltJ2UrKmeEGLh6E+CK4GpE
+ TJUEsm3+YnBgZJwxz6w3r7kbB9J7jj378flMuHE3wnnIP11YHdIr0mlNuFGmlXxsc4N5q50ShFXg99VU
+ ATXErRFQKQb1GzfSuG0ry9dvIDWBxaDf/R6JwJggMS6ABUiVIMdm5b7cbD49L4vHB2/xxvBIfEjvqc09
+ xPcsrIknXHCb/cisgmAIojXhRgmP2BjJOwhyB13rS1oRcx5x7QVInz8fITmF3qEb7H3rAHvf2MfC7Cya
+ NjXT0raTshWJ5yZcE/1fIBEYt8AEElYJskWBL+bngCjyxo0RHdLrrabjIXUQpHcHe316T1nlK+cIgivA
+ OwXXCIxMuFFCCoJrsSK/CSViKgApOfOw5eUz4ZRwCFbGBAGcUzAvDxxT4HDQa3fw61de59cvvMzC7Eya
+ NrWwyS0GqTnxFYNBUcDuqTk14BTghlUi2ynwxQW5dI9N0D4y7ia9rKstkqRHls5T83vI7X3/3RGGd8YJ
+ ZsKNHB6T3yiCIHdQ8YGEwQREWQCS0tJILSplKj0Tuy0Ve2o6dofDRXanAzSP1cWgeVMLm3a6xSAOlkF/
+ EGbyLatEslPgC4vy+W77heiR3iMokiLca3q7a3xvej2EMuFGkTZR/X2T/KqIigBkZ2Rwzze+xQt9wwwM
+ 3XCR20Nyn88p37AAYvDMy6/zjEwMWnbupLxqBWlZ2dG4DR/YJRgSg1tcatQCxSnJzLdY6J+Y9Ce9D4FD
+ IL07qS/kY+8FV5ef7ssfzrh7RVrJUEID+UbQ5DfdAV1ERQBysjK58+N38SWrwPjwKK+ePsvPjpyImhi0
+ xEAMromB0ygx5ebW/CQr/U5ndEnvSec1v4Xpvn0/GJGxIMgfFK/iQf5ghGxuIaouQL9TgvR0mtev5GMN
+ qxi7Ncq+9vM8fuwkPf0DBsVASximxeDpl1/naZkYbNq1i/IVK0iLoJvQJ3rMaeNwepI7JHCIESa9x8eX
+ j72Xlc+P/EbLPttMfpPxeohZI+CAwyUGDetq+djGlYyOjPDaqfP8PFwxkFkKXjHY+xLLiwvZUL+BlrYd
+ FFVUhGUZ9Iuy7vRQIDld6+e7vkSA9AqnX05CQZIlDbbECWLyBzWkNxjySyphcxtx6QbsdYqQlkHT+jru
+ 2biSkeERXj8djhhM+bkNXQM36Hr+JX7xzHNuMahnU9sOiiqWBy0GfYa7yzQgIVsYMxzS45/IS36PyR+q
+ TIVC/kjkqxIfKvl1hSGYMs8dxH02YJ9TgvQMmjfUcU/DKoaHR3jj1Dl9MZC3DxgWgxf5xTPPsry4kPr6
+ erdlsJy0bH0xGBPhVrgvjuj07X4LifSKOFD4+0ZG5akhSP84Yv6+Hnk1LhSsvy+PNMmvirgLgBx9ThEh
+ PZ2WDXXc27CSW8MjvH7qPL+IhBi4wzxi8PNnnmV5USH1Gz2WQYVqm0FPJF4czyi+kEmvTCMnvicqlILO
+ dn9f8g82hcAHCSUAcvSJEkJGBpvrV/LxhlXcdFsGvzh2ip7+foUIyAgfSBjkYjCoEIMGlxgUu9sMnMBg
+ uOY/4DNIxzdiOl4/A/envJaPNfkNJTSQbxBWgV9QkOQ3yR4QCSsAcvS7xWCLWwxuuMXgl3IxUGsvCFYM
+ nnuRnz89LQaFa9ZCdS25hYXh3YBP25NR0sshH3vvroXl4/hDKpD/oWbaaPr7eidEweSXQm8kmZWYEQIg
+ x4BbDFrrV/KJcMVAeez+9IgBTz8LDgeLli9j7Z13UbN1G3khiYHH/DfKJK2x9x7yCzE0+SORd5D+fiRN
+ fp9o0yRQIuYCYBMg12oBYEqCm2GY2EOShJCZwfaNK/lk42qGbo3w+qmz/OexU/T09av0JBgZbOTfkHjt
+ SjcvPvAAL37/+xQuX8a6u1xiYNgykIyQP9DYe4/JH0vyzzB/X7f5xCS/GmIqAKkCLLdZybJasACTEvQ7
+ RS47RP+t3oPEkOgSg7aNq/iUWwxeO3WWJyIsBj1Xutl7/wPs/Z5LDNbfdRc1W1vJKwrFMjA69t709/WF
+ QYf8JvF1EVMBWGC1kC46+csn9tLeM8jvtW6gbU0tE5LE9Ug0trlxQ5SwZGawa+MqPu0Vgy6eOHZaIQZT
+ 4HAqxEBtsJF6F2PPlW6ev/8BnneLwYa77qZ2WyA3IZix96a/7/s1OH9f9Tcz9cAHMRWAPKuFExeucqRX
+ JDNnCf+y7zSL83MpKSmkb9IZthWghpuShDUrg90Nq/lM4xr6b43wxqkunvjgND29kRWD5+6/n+e+9z2v
+ GKxs3cbC+UUE3uwCTH9fNXGE/X1J54S5iZgKgCDALbuDeTkLKSupprPrfZ473sG3SopIFQTGomyu3ZQk
+ krMyuK1hDZ9pWsPAzRFeP93FE0eDtQw85Jd/n46Xi8F3/u2HuPYm0kIi+PuGEhrIN5H9/WCsm7mDmArA
+ hFOiYsE8RodPcPa8nRu3+vjo3ARJAmRYYCyGS+/fEiE5K5PbG9a4LIObI7x08gxPHDnBwOAN7baCIMUA
+ qxXXarxq0CG/afJrnBuCv2+2A2gipgJwQ5RYNj+PFTkOXj51hNGxm+za2oBDgtFo2P8GMSxBanYmtfVr
+ WVW/lrGBAQ6e6OTA6a7QxcDTkGixalw1iv5+kJV5UInDNfn9gqLo75u1fkDEdlVgp8h8p8B/v6eNpQvf
+ 58boON9o28yYKDERZ5V2SgKDoqs3QsjLY82WRnZva2asf4D9Jzo46CMGyoFFOoONrGoCoEJ+s4sv8v6+
+ XzamICgRUwEQga4pJ0syMvmdXdsBmBAlrjjD7wYMFwOi5Dflt1eUEPLyWL+1idtbmxnpG+DAiQ4One6i
+ f3AInM7AYmC14p7/i76/zyzy94Os9X2CImDy+51jEl8LMR8INCFB+5STdPe8dbskucgf5wGavQG6IftE
+ CSE/j/qtzdzR2sxw/yAHjrdri4G8DcCzBZcHkTb5FYeaaRPa34+Eya8Sbvr/uojbUGBPi38iDMy2S8FN
+ +e0Xgfw8GrY1c+f2Zm71DrL/RDuHlWLgcIAlCbBPn+xDfrOLTz0ugia/9kVNMAPnAkQD3WEMQhoQgfn5
+ NLe2cPf2Fm72D7D/I5kYeNoA/Ex+099XjwtgqRgiv2nyG4UpAECvUyIStsigBOTns6m1hY/t2MSNvgGy
+ 0zPh2i13CtPf9w2KgL/vFx5Km8HchSUamdonJxm9dStwwgRAr1MiGsMPhiSQ5udjSU7By3qPvx8z8kci
+ 3wj7+5LPgW9kJPx9k/xBISoC0Ds4xFduu53/++d/zuH9+xkdTlwxGIjQezE0OKQTG66/L/kdaqYNmEaZ
+ t/+h6sWM+PuS6hdFcjV/P1jiqoio3m8r6d3H3EZUXYAjBw9x5OAhADZsamHTXXexeu0aMgOswxcr2CXX
+ ij/hGv/P/+pZOk628/t/9gekpakM+41ZY5+hhAbynUX+vt9iqqYCyBGzNoD3Dx7ifZkYbLnrblatW0Nm
+ DHb10UKkZiDWrKrl+NHjTIxPqAvAXDb5Nc+NkMmvBa1VlE34IC6NgB4xSEpJpfG23WzcvInVq1eRkRXb
+ /f4C9f0bxdLly/j6n36D3LzciOTnY/IbTBpUvqrn6ZFX40KGyG+kFpdHRZH8pg74IeYCkJSaSuqiQkbG
+ J3GkpnHw/Q85+M4RcDio37COLTt3sHpVHRlR3vxzUHS5AJEaiBAZ8gdb68/ALj7Na2DQ5NdKpxancj1T
+ BHwQEwFISk0jtbSMESkJR/Y8RpwOyJSNlnM6weHgveOneO+Dj7xisHXXDlavXBkVMYhU7R85JKK/H2St
+ 7xMUAZM/ZH9f7Z5U4kxEVwAyK1YwkpqNY1EJI06nm+zy2XROxXd1Mdi4YR1bdu1gzaqVEXETJiT34qIR
+ uEcPxsfHSVfz/w3B9PcDhodl8gfhUs0xREUAFubl8nf/dj/PnrnM3g9Py4iu/DQmBu8eP8W7MjHYuquN
+ NavqyAzRMhiMcJ/wkXfe581XXufP/+rbQZ4ZiskfibyD9PdnmsmvViaT/KqIigCkJCeTs2Qxv7dsMf9t
+ Vwvnu3t58sQZXvARAw/pNYhvUAy27W5jzcq6oLoWrzoj+zakpacyfGuU7qvdFBUXGTxrDvj7hsx1vXOC
+ yUON6Cr5mfBBVF2AMRHGsJBRtIivlxTyZyGJgUwQHL4Wg1wMGjxisGolmTpuwk13418kzf+alXX83h/n
+ RZH8hhIayDeB/f2Qh/QarfU9YaYIyBGzXoBxUWIcC5lFi/hGaSH/bfcmzl29zlMnzvCiqhioEF9HDN45
+ fpJ3PGJQv47WXW4xULgJkVx9WI7okj8S+UbD3zdownuj4uXvB/M7zi3EZRyARwxyigv5ZqnLMjjX3Rua
+ GMi/e8Tgo5O8c8wjBuvZ7m4zSM3KplcUic8kZNPfV80sXH9ftZbXuoapAkrEfTbghAgTgpV5JYX8fmkR
+ f2bUMvARAj0xOME7xz4ExxS1K+so2rCByqYm5hUUxOeGE8bkVwmcjf6+4d9ybiLuAiDHuCQxIVjILSnk
+ 98tcYnD26nV+FSExONnZxcnTHbz60MMUlJezensrK5rDF4Mj77zP2wcO8a0/+0P9hDPe5Fc7N0FNfu9H
+ ENeag0goAZBjQpKwWyzklxbxB24x6HKLwUthi4GD69eu88qjj/HKQw+zqLyc1du3UxWGGPRfH9TvBQj0
+ 3gX1XkbQ5PcLmk3+fqDfwkTCCoAcExLYLVYWlBbxh2VFfHv3ZjqvXuPpE5289GG7cTHQGG9w7dp1rj36
+ M15+6CEWlZezZodLDHILFhkq3/qGDeTl5wbRECiHx983+nYaJH+0TX7NaxA7f1/X/5fwLr1mtgFoYkYI
+ gBwuMbCwqLSIPywv5tu7t7jFwGMZaDUcGht8dO3adV565FFe+qlLDNbu2E51SzO5ASyDpRXLQribKPr7
+ PpoSZK3vExQBkz+i/n4wJn8wv+/cRMwFwALkWAQsuLYCs4fxbCYliSmrhcKyIv6orJg/d1sGz0RQDF58
+ 5FFe/OlDFJaXsa5tB9XNLQHFwBii7O+HSv5Z5e+r5WOKgRwxFQCbAEuSrOQlWRBwEfi6U6LbEf6uAJPA
+ lNVKcVkxf1xezLd3b6YjgmLQc62XvQ8/yt6feMSgjVoDloE/PCZ/EOlVDlUDoubvx8nkVyuTrr8voCkI
+ fsJoAuKwPXi25ORHr+zn7bNX+b1t9WysqmRKkuiL4ACdScklBiVlxfxJeQmf3N5Cx9kLHOg8zzvtZ3Xa
+ CowNS3aJwR72/uSnFJaXsb5tJ7WbmskLKAYz1N83bK5rnROOya+Rn08aSZHOqLBp48tnev4oDd7/QUXh
+ QcMnzUDEdntwi8Cpi908ebKfzPQC/r+XP+CB3HksXLCAATE624P3OCXOWqwkVSzj7splfOG2bZw7d5ED
+ ned5N2gx8B+Q1NPTy/MPP8LzP/kJReXlrN/ZRl1LM3mLXA2Il850uksSRX9fK041KMr+fjBDen3SR8vk
+ V35RL8w3zvRsuibxpx862H1OnN7O+eVTPeOrk3h5kcA/z0YxiKkAJFkEbtmdzM8rpqSokq5zx3jq6Em+
+ dXtr1LYHlw/9HZVgLCmJlMrl3LNiOV+83S0GHYHEwNiw5O6e63Q/9AjP/dglBht2trG6upao+/t6J4Rk
+ 8rvDEtHf1yqzIfL7HmqRXo5zImnnJrkXuHc2ikHMtwcvyk7n1vAAV7o7GRm9wYkLoyQJkCrAWIT570B7
+ 3v+YBONWG2mVy/n4iuV86fZWus5e5GDnudDFQPa9u+c6zz70CLX/838F4fNH0N8Pp9bXOMUVHiV/X9fE
+ V15D5u+r3YeOxTA/O1Nobu9567pIvRbptTAbxSCmAnBLkihZkEdJyijvd51nZOwm21vW4pBc3XuRxnWD
+ 037HJBhPspG5YjmfrFrOl+6YcolBh4oY+DUcBhADqxUMOTemv6+Zn0+a4P39gtxs5pcV0JeRyWUEy2UH
+ W3RKaAizRQxiKgB9TpE8WxL/8Bu381dPPMe1G0l8rnkDU0Rne/CrzuAn/njEIHvFcj5VVcGX7pjizNkL
+ HApVDCyBBCAeJr/auQlq8ns/gjP5C/KymV+6iL6MDK4jcF27ZGFjJotBTAVgSoKLDpHyjEy+/5XPIeDa
+ Hfj8VOS3B78hSkxIriX5Q8W4BBNJNnKrKvh0dQVfmpriTNdFtxh0GRMDq97eK6a/73MQpr/vIn1BTEiv
+ hZkmBjEfCDQsSpyecpLtlLAJMOImaqRn6EZ63v+EBPYkG/lVFfxGdQVfnmql04gYWKwaOSaIya95DWLn
+ 7wc0+bX9/YLc+JNeCzNBDOIyFFjEVUNDdGbmOzDu/4eCCQkmbMksqK7gN2sq+PLkdjq6LnBYKQYONQEI
+ stY3h/TKruMKK8jLZn5JYpJeC2piUCjwLw9UFB6IZ7lm3FwAI4gm+ZWwS2C3JbOoppL7aiv58uQkHWdc
+ bQbvtXchWeUCEILJHyr5Z5m/X5CXNeNIrwW5GLx0qmd8TRKvLBL453iIgSkAEYRHDIpqKvl87Qq+MjWJ
+ NAV03yAofz6h/P0ImPxqZdL1911mz4IFuSxclD8rSK8FtxjcA9wTDzGIigDcHB7h5MmT1NXWRiN7XYxI
+ MCJFds3/UDAJTNqSyRXA9Pe18vN3C/IX5ZNXkE93Whp9CPRpX23W4ZyTtHNO7kHgnpdOdo+vsQlRF4Oo
+ CMCt0VH+7ne+RlZuLpvvvpsNmzdTV1sTjUv5wdX1l4AwavLrnTAj/P3gTf78RXle0g8gMKBzmVkJj9Ej
+ q7XOSaSds0suy+Bk9/gaG68WCsI/319RuD+Sl46qCzA8NMQLe/bwwp49ZOXmssUjBnXREYMpoD8O5n/A
+ JcGiTf6Imvwq4VEw+fML8skryJu7pPdA69nLws+JpJ2z8zGQPvZihMUgZm0Aw0ND7N2zh70eMfjYx9iw
+ eRMrI+gmDDglnBHLLTgEXBLMiyD9/Zlu8ss+XKTPNUnvgee3EmQBAeovl5sgfQykj3W1d598qaqoLpwi
+ xKURcHhoiL2PPMLrzz1H5vwFNGzbRn1TA3XVVWHlG+kdf4zC+JJgMfT3DZnreucEk4e2v2+SXgMes18e
+ EOj1lQBJ9H6+PCrW7jhx6ezrdWWhLEcFxEEAUucvQMrMxi5ZmBAEJsan2Pvci+x95jmyszLYsmMH9U0b
+ qasJTgwmRCmujX+BlwSLhsmvdm4ETH7Deaib/PkF+eQtzKU7LZ0BMEkvh4q/r/97y+JFJ4gSOEXXnyjy
+ xphzaTjFiYkApC4sQMpfhD0ljYkkm+bKvbcmHTz/3As8/8yzZGdlsLVtB/WNDYbE4Eqcan9jmP3+fn5B
+ nkn6QFB79nrPS8LFDUkEp+QlvffPKboEIQxEaXNQG9kLChiel89EbgETGVnuIbKK5bfUwtzDaG9NOnju
+ 2Rd47mmPGLTR0LSRWg034ZpTis+GP8FgNvn7Viu5C/OYn5/jNu9N0uvC6+97TACN31/CTXCni/SiKCO+
+ XATc8WFWfFHaHjyPXzy+hw8u9/Dk8TMcuXCFW2NjiqmywYjBFM89u5fnnv412VkZbGtro6GpgbqaFQBc
+ d7ga/+LF/yPvvM/R947wu3/wu+oJJKJL/lj5+1YruQW5ZM85n+W4AAAgAElEQVSfx8WUVIaAIZ3TTMgg
+ yA8Uv7foJrrkJruX+E4F6WUiIHnOCa9YUXMBLttSmL90MX9TuQTrxAQfXOrhqQiJwbPP7uVZtxi0trWR
+ U13FgnUbonUrATExPk73pZ7QegH8gmLs7xuo9bfVLCV1XibvSwL9DqdJeqPw1vqKQAkF6T2kdpNeq+aX
+ JDfxPTV/groAclxzSJCUwsKli/mbyqVYx8f54HLkxODXz+6Fp39NSmoKFfUbqGhoYHlTU7Rvywct2zaT
+ G2wvgGpQNP390Ez+P6qvJsc+SvcH73HvtlZuIXBw0snh0XH6HfHqdJ0B8CG/+4tTi/Qekjunie90E12S
+ plv+nRJIzmnSSwlsAajhukMEWwoFy9xiMDEenmUgW8DT7pzixOF3OHHgkI8YVDY3x+TealcF6o6dmf7+
+ snlZfPvTv8XYyDD/8b/+hide3EtF3ny+mJvJpSknb46Mm2KghJz8XhNeZs77kF4W53CTXVSQHrclANNm
+ v27lYBxxmwzU65TAlsqiZUu8YnDsUg+/UoqBl/BGxcCB3emQicEDVNbXU9nYQGWMLQNNRMPfj9KQ3v7r
+ 1xgbGfZG3xobI3ueAxBYkSKwJDndLQYib46MzW0x8LbvqfjwfqT3tORLviT3Ib2b6R4xEBUXk8If9p4Q
+ swH7nBIkp1K4fAl/u2IZwvg4H1zs5lcnghED9SW57E4Hxw//F8cPHCQ1NYXKjfVUNjayIl5iEDOTXyU8
+ lC4+HYyJEghOEJysSLH4iMG+kTEOzSUx8Pj0Hp/d4dQnvej+w+kittKnlzw+P77vhXLOxUxyAYygzylC
+ cgpFlUv426qlCOMTHLvYzdMnznDk/GVujY+rtAto7O6jGG8w4XTw0aG3+Wi/SwxWbKxnRWMjK5rDE4Oe
+ q928/tKrfOGrX9RONENM/lBfrHFJBAEEwUlVqoWlyRl8YbaLgZL0XnNepd/ex6d3un5fh5v0XqJ7zHv5
+ M5BUnp0nPvx+r4QTADn6RQlSUimpXMrfVi0Dt2UQKTH48NDbfLj/IKkpyaxoaKCqsYGqENoMTn50knOd
+ 5yPQCxCEyQ8GyR9MHpGpVcYlCUFwYhGgOtXCshSXGFyeEnlzdIxDIzNUDDzk9CO929yXJHBokd5j3ouA
+ yPSkFbcF4PMOSKi37rt9DB/iz9A2gGAx4BaDUpkYfP/wh+zrOMvA4A2X8motzGlIDA7z4f4DpKYkU9XQ
+ QFVTA9XNLYbK1nb7TtLSU2NH/hgN6Y0EJiQRQQCbFaqtFpZ6xGByhoiBFum9ffZyssuOla33cvNelNX6
+ 8gt5w5S/vWddOCGwJRkkZowAyDEoSlxPSqGseQN/tXkj0tANDpzoNC4G8u2/VMTgg0OH+WD/AVJT/pXq
+ hgaqmxqpbtG3DDZt2xyg1DPA31eWKTIa4IUdCUGQSBagJk1gWUrmtGUwMs6hkbHEEAO9ml7p43ta772k
+ 1iC93LxX9elRkF+llg/GsjOIGSkA4B76C1x0igjZ2SxurudvtjbgHBhi/4lO3mo/y8BQMGLgP95gwuHg
+ 2KHDHHNbBjWNDVQ3NlLTYswymIZR8ieCvx8d8isxKUkIFiepwEqrwPLkDL6Qm8HlKZF9I+McjLUYGCF9
+ UK33yEgvu4hnMI/y2t4uBKVfr2IpyD7CRcwFIMsikG913egUrrEBwXZm2CX3qsKK3+qiQ0TIyWFZSz3b
+ tzQwNegSg/3t5xgYGtIQA/XeAzUxOHrwMEf37Sc1NYWaxgZqmhqpDVYMQjH5IUb+vsbLFmVMIGGxuPbp
+ WmUVqEj2tBm4xhlETQxCIb289V5iuiFPk/Tg09CnVgZAlfg+8QHCQkRMBSDLIlCZbMU5McHYhJ3i3Hnk
+ CAJnHU6mgsjnsoEJEJecIuTkULlpIzu2NDA5OMQBuRh4iR++GNQ2NlLbrC4GE+NjrgPdh5aIJr96fqP9
+ /WQXBWrrCB12JCxWiXRgVdK0GHQ7RN4aGePN4TDFIFTSe8x7kenRfLqk99T0as9WYzKQTyFV8vMJi4w4
+ x1QAFlgtOCcm+OKPnqB3zMnHVpbzrd2bKbJauRjEWn49juBshiuiBPPmUbVpI23bGpjoH+KgqhiouArK
+ qcuKwUcTTgdHDh7iyL63SEtLobahgdrmJuo2bQKg9+qVGejva5fpz/7gW1SvqKRp5y7W1q8nb0lY09F1
+ YUfCapXIQKAuCZYmZ/DZeZlcd4q8MRyEGPiQXlKMszdAek9NL8jMfURF6737Qpr99Aqf3jD5A4hzmDoQ
+ UwHItgoc6+rBnrKI8oULeOXcJVrOXWJt5VK6nRiyAgacYlgz/646JcjNpWZzA21bG5kYHOTAiU4OnA5f
+ DMadDt4/eJj39+0nLe171DY2sPu2O91XVqn11YK90QbFIuq78vjCPjnFB8dP8sHxk6Qk26heUUnzzl2s
+ rd9A3tIl2mUJE5NAklUiyyohWQS252RwR3Ymw6LIgdFx9t4YYUyUVQxapHfKau9ApFcOw3WKuLrgJN/f
+ KJh+el3CBnoeamEzyAUAEASBtNQMcucVcPNmHy981MGGymWkCgJTei+zGz0R3PKrR3SJwcrNDeza2sRY
+ /wAHT3RyoOMcA4MREIMDh9nZdhsRMflD9veDNPklvwhNKMVg9dq1rF63loatW8iPomVwSZIYt4CARJpF
+ YEd2Bm2Z6fzz9UE6x+2+A3RCJb1nfQlJ0U8veNLr/UbK7jqIqMkfQTcgpgIw7JRYWbyQsZvvc2ZkiBs3
+ e7kmWEkSwOazBZY67JJr1V8hCjP/r4kS5OWxeksju1tdYrD/RCcH20MRA1kaixV8lipNUJPf+2H8pUrJ
+ mYctN48J+xR2p4N3uy7w7qkO9ux5nOqlZbTs2sW6+nrmR9AyGBUFxiTJu+nrhAATFokUC3xnUT5/faGb
+ S/bJEGt69717J95IvsQXtZ6d533Uik9M8kOMBWBIFFmQmcHuijy+98oBJuxj/HbDXUxJ7g1CA6AnRmv+
+ X3eLwbotTdy+rZmR/gEOnOgILAZqPQzercHiZPL7HAZyAyQCNVDVNTTSNQkTtlTsKanYp+xgt8Ok528C
+ +6SdD7r7+OBHPyXlwf+gZuliWnbtZF19PQuWhmcZXNe4/0kBRi1wb34O/3rjavCkV+2yw5XGJ9yDQP30
+ aIdpnqcjBt5DtecaOmIqAINOiT6HyNd2bqGpYgnDdjstK5ZzS5QYM2D+X4vDph+9ogT5eWzY2sQdrc0M
+ 9w1y4EQHh9rP0m9EDCxWjJvrPoEhmvzutLIPzfx80kiKdOoX+9/f/2eE0XHePXuJ/zxynI5LV2XkV/65
+ xOBYdy/HZGKwaXdoYuCUoE/Ubv8Zt8DqzHSwT4ZIevA27oHb3JfHqV1Zj/y6DyzA81AL0xGDEBHzNoDz
+ U04mbBaql7vMwgGnxDUDrfr9TtGQlRBN9LnFYOPWJm7f3sRI3yAHjmuJgfvYag3f5DfsNkTA5A/wYo2J
+ IKSlUVe3go2rqmB0jHfOXuKJYMTgwZ+Q8kOPGOxiff0GFi4NvLJ1X4DnLwFJggCTTlnDnRHSu0UC8Dbc
+ ecmv527GyeSPEPkhDgIgAt0OkW6H6wZ8lkrTQSQb/yKBARGE/DwatzVx5/ZmbvUNsP94B4fbu+gfvDEt
+ ABaLegYJ0cUXgPwBfvJxUYK0NFavrKJxdRXi6Djvdl10i8EVmJxUFQIm7TIx+DEpP/wRNUsXs3n3LtbX
+ 17NwmbplcE30uCgBMOXEGOllVo/yfnVn2unU+qGQX9fkVztPaa2FjhkxFNgpSe7Gv8TEgAjC/HxaWpu5
+ a3szt/oH2P+RSwwEi9X/hLgN6VWSX6VLS+XQCMZFENLTWLOqiqbV1ThHx3in6yJPHj1Ox8XgxWDL7t2s
+ 37iBArebcEtyNQIbegdEpwHSy8PcQ3A9i3noQs/kD+Y8nWfmPdSr9cMnP8wQAehxJFbtr4chCYT8fDZv
+ b+HuHS0kO4BLsj1u4+7vq71EapaASrhBTEgSZKSxfnU1LWuqcYyM819dF3hKUwwmvMf2STvHrl7n2IP/
+ QcoP/52apYvZuns3jtIyChoajRXAp61IjfSee/NMrY0E+bXODUKcfcKiT36IkgD0Dg7y1ptvsmbdOubl
+ 5ISd3+VE3fE3AG5IkOu11uJo8ns/gjH5jb1hNgGSBUGzEdcuARlpbFxdzea1NTiGx3i76wJPed0Eu1sQ
+ JmSf/mLApJ3UZBvVW7dSs2Ubtdu26pRKi/SgOrXWKPkjZfL7hOk8R++hjslvoPFcD1ERAPvkFD/8738J
+ QOW6dbR98hOsWb+OednBi8ENd+OfkKj2vxFoVg4xIL9WbW6E/AHerSyLQG1KErdGRhHS0+iY0p/YNSlJ
+ CJlpNK6pZuvaGiaDEAPsE0xM2jn21gGOvfoaqck2arZupXbrNmq3bVPcm7LgGl12gkDgQT16v0Uw5Ddi
+ 8uucFwXyQwxcgM6jR+k8ehSAFevX0fYJtxjkzDN0fk8CTA8PhIDbg/shyIcZkS4+o/6+jsWgQGGSwPEL
+ V/je6x/wg/vaWGCzcd3gTjWTEpCZTvOaGratrcU+MsbbZ84rxEDjzy0GR986wFG3GNRu3Ubdtm0UtGxz
+ X0Gjy05yx0Xb34+myR8B4nsQ0zaAjiNH6TgyLQY7P/FJtxioWwYOKT59/6EgqO3BdcmrTK5H/mBMfsk/
+ TLc2MvaSHb8ywILFm3juo7PsqK82LAByTCJhyUyjZW0N29fVMu4Rg/fdbQZTgcXgyFv7OfLqqxT9y7+i
+ P7U2XPLH0uRXKafyfQhTC+LWCHj25CmuXu9j5NYwVevW0XbHbaxdvYp5OdneNH0JveHnNAxvDz4T/H1v
+ usC//U0nfHJ9JS8+9BxfvDMyqyxPSpCUkc7mtbWsX13Lyd4B3j3RwdsnOxno69cWA7u7MdFmw3damQoB
+ A96aVppYkj+QlRg++SHGApCUmkpqUTEjdieO9ExGnA7ITaH9zDna/+Vfwemgqq6Wnbffxto1K7mSmhHL
+ 4oUF/e3BpdiQX83k96YLxuQ39mb1OUXmJafwwBfuJCsjg/apyPpr3SI481yjMLdsa2ZiYJB3jrfzzskO
+ +vsGXMRXCoItGRhT3NtM6OKTHwQgv9ZxCIi6ACSlppFatpgRawqOeXmMKCfPKMbPt3eepf3098HpYH5p
+ KTWt21ja0Eh2wcJoFzVGCMfkVztfq5ZRMflV04E/+QMtWOGCCHRMOsmwpTI16cChnzwouIb9To/9GJc8
+ A6+aaW1tYbx/gP863uEWg/5pMUiy4fubRLOLz32C7vNQC9MRA2V+mhVHglsAC1atoy81C8fCIkbki3Aq
+ V9/REYP+633sf+zn7N/zKAvcYrCssZHshQXRKnaUYZT88TT5jZFfDk8XYCR7anp1Rn5OSGBxD7xq297C
+ aP8Abx9v550THQhJNleiiJA/lia/Sjm1TP5EbwQsXVTAz378AFd7+nju1Bme+bCd8fFxBeGDE4O+6328
+ 9djPecstBrWtrSxraiRnYfwtg4Dbg0MMTH5lFqGQP0A5AeeknaTkFN00kUC3wWG/dgls8/PZ2trCru2b
+ yHYAp6+6YwMJmU6tH03yR9LkT1QX4LpDJGlhPp8pmM/v7Wjm8rU+nj95hl9HSAz2PfY4+/bsYUFpKXXb
+ W1ne2EROnNyEgNuDJ8yQXjWLQSOtBjd+e9duttxzD/Vbt7By5UqstmTlHYWNm6LxYb8H9x1gc6trSfZJ
+ 3CsvePr3daFn8gdzns4z8x4GYfKDBuEDpAsRUW8DcEiujUBTFsznN1vn8/UdzVzq6WPvKZkY+BA8eDF4
+ 82eP8+bDe1hYXkpdaysVTU0xtQyMbw+uQKL6+1qWBa5BXq8+8SSvPvEkKck2tt5zD/Vbt7JyZR1JKZGx
+ DPTMfyU6TnWwvHI5RcWF04EzdUivVu2uVibPgqNhIqa9AA7J1bCTVjCf+xYt4PdkYvCsETFQLrihsCB6
+ r/Xxxs8e5w23GKxsbaWyqYmcgui3GQTeHlyGhOniC0R+/RfMPjnFG889z+H/eo+p8Qm23nEbG5saWVVb
+ jTUlNMvAgXsXKIPtCV/5xleDbHvQMu2jaPJ7D43W5rJ4vUZAvzIFj7iNA5iSJAYkyCiYz+cWLeAbO5q5
+ cK2PZz7q5KUTHeGJgcMlBq//7HFef3gPBeVlrNzeSmVjI/MWxbkBMW7+vprJr5eXNiGSUtNILS1nREjC
+ kZHNyJQd0iZ55cB/8crrb5GCxLYd22hobmRVTU1QYjDolMJa9FUbeoQJhvxGTH6d8wyb/Kg8H7U8wlOA
+ hJgNOIVLDLIK5rNuax63tTZz7dJlDnWc50D72bDF4Pq1Xq4/+hivPfQIBeVlrNreyoqmJubFwDLwQdyH
+ 9Bo0+XVM6L/8x3/iYO8t9p3qhKlJ37/JSZiyY5+c5OUDb/OyWwxa27bR0NTIqtpabCk2zbzB0/hnHP9x
+ /7/z6c99hry8XJ1Ueia/Xu6Bnofii6oYh2Dy64qE4tnPVAtADROiq72gz+mEoiLWFBfxyV1b6Ll4mcMd
+ FzjQ3sX42Lj2MlwGxeDVRx/jVbcYrN7RSlVTE/MKFoVcbmPbg+uRP5CJqfYSGan15d/DJz9AXUsTa4Fv
+ 372d01eu8etjp3hLKQaTnmOXGLy0/21ees0lBtvbWmloamBVXS22ZF/LYFSSGJWCq/2XVSwnLS1NJ4UW
+ +YOp9dXCdGp976GR2lzxPZC/78l3NlkAHlxSjPu3S3BqyolQVMy64mI+uWszPRcvc6jjAgcDiYFaD4OK
+ GLyy5zFe+ekjLCovY/WO7VQ3NQXtJgTcHjxR+vdVTX5ZOjWSqMAB3EqyUbK4lD9cUsZ37t7OKYNi8OL+
+ w7z42j5SkNjR1sr6hnpWr1pJWkoyV0MYSLh99w6dNgAtkseS/Hq1uSLekL8/iy2Afp2x/3YJ2h0iQnEx
+ 60uK+dSuzXRfuMLhzvMKMfCQ3qAYuC2Ga9d6ubbnZ7z804dZVF7Gmh3bqW5uJteAm2Bse/AgyO8TH6Eh
+ vXr+vtEVilTgkCSGbcmULinjj5eV8R27cTF4Yf9hXnhtH0xN0rZrB1mVlSxrbCI1w/gQ8KHBIfLylea/
+ Vq2vEaZ5no4Y6KYzSP5Q/P0Ikh8SSABci34aW/N/UoJOh4hQUkx9WTGf3r2FKxcu8bafZaBiHfis4e/U
+ FIOX9vyMl9xisLZtOzUBxCDw9uDoEF0WqfkS6dXe8kM5+UMx+XXIEwAOCUaSkylfWsafLivnO/YdnLrS
+ 4y8GMiHwfH/t0Dvw5gH4tx+wYsM6VjRspLplU0Ax+MkD/8Hnv/Jbvt2AWuVX+x3lkbrPQy1M67dXyS9o
+ f19F0H0sgNCfkxwJIwA9Ic78m5TgjEOEkhI2lpbwqd1buHrhEoc7LnAoWDFQGW9w7dp1XnzkZ7z4k4cp
+ LC9jXdsOapqbg+9NMFKraBI9QK3vk84TZqCLz+8n1ylHkJhCwpGSzJJl5fy35S4xOHmlh2ePBhaDjtNn
+ 6PjoJM8+8CBVG9ZT1egSg7RMfzH4yjd/x98CULsvzdsJhehqYUZqc0VZQjb5I/ecEkIAJsTITP2dkuCs
+ Q0QoLaWprJTP3LaVy+cv8nYgMVDu7KMhBj3XrrP3kUfZ+5OHKFxcxvq2HdQ2NwduQAxEfrWXyvs1FPKj
+ 8nLJzzFIfgOPZJ5FwCoIDEuS5mQghwTO5GSWLyvnz5cZFAP3cfvpTto/OsEz9/+Q6vr1VDc0ULOphbTM
+ TABydVv/te5V7Z61wnTI75dGqzZXKUvIJn/kyA8JIgDR2PFnSoJzbjFoLi/lN27bysXzl3i74zyHIyEG
+ Pdd5/uFHef7HP6VwcTkb2tqobfF3E24ODriPjJA/ekN6p89Re2m0Xjp9FFgtVCRbOXftOqULF3J6KvA2
+ 707AmZJM5bLFfHv5Yr5rb+Otros8dvgoF6/2+HUpyoXh9KlOTn94gl/d/wNq6tdT09hAXcsm0rIy1S+m
+ ex8aJA4ossoog+QP29/3vB+y9OHzP1EEIAJ3ooMpCc47JYSyUja7xeBShMXguYf38NyPf0KRWwzqNrWQ
+ W1DAzcFB/F+OQDWIWu2tCPcjf7j+vk7Np4EcKzz93kc8daKP//fxehZlZga1gKtTAjE5mczK5XyhYhlp
+ o6N0nL3IvmOnuHi1W9NFYMrOqVOdnPrwOE/+2w+orV9PXWMjdZs3celyt8a9qt1zMGE6YuD3u2sQPJQu
+ Pp9no0zrV+igEXcBuCFK7sa/2GBKgktOCcpL2bq4lN+8fRsXz13i7Y5zwYmBxniD7p7rPPvwHp798U8o
+ WryYL/3u1xUl0DHhNGsZtXDZyxApf1+3NlRHbmYWmflZvNZ+kbaNtRBkV96EJHHTPe/fkZFByapafnt1
+ Lcmjo7SfucC+DzTEQHZ88lQnJz88zi//7QG++7//PjTyq303Qv54+Puqzyw0xF0A4rnmv0cMLOWltC4u
+ 5bN3bOP8WZcYvN3exfjYmEbDobHBR9091xTPXVJ/qbxfQyE/Ki+X/BwN8vu9aIprGZhp1u+UaF5ewmvH
+ X2Vn9SamQniUV1WsvynJJQbla+r46po6bGOjnOq8wFsfnuTilW5NF4EpO5KgsRNTSCa/znlRN/mV11Z5
+ dyIwISiuAuCQ3P5/Aiz5PSXBZaeEbXEp2xeXct8drZw/e5G3O8/x9ukwxEC+O7DPA4zHkF6Vl1lVoIy9
+ VINOiW6rhf/x6TuYkEQuGdjjUYlrTkl3JREH4MzIYNnaOqrW1WEZGeH0mQvs+8AtBpN2mJqaFoMktaHG
+ WiKnEuY91Pnu97sbIbhenOx3915Ly99Xkj888sRVAKLt+4cKB66aKWVxGW1Lyvjc7a10nb3AO53ngxcD
+ n92B1V6iYGp9z2eU/P0gyO/BFafIVff4/WBXBLoe5MQfByBkZlKxdiU161bC8DCnzlxg37ETrgbESbtC
+ AHSIriu8emKgRXbF92j5+940OtcJAnEWgMRf8tuBa4JK+pJydi1Z7BaDi7xj1DKwWtSJFTT5PWFhDOnV
+ Jb/WCxs9XAtjw1cHIGRlUb1uFavWr0IcHubEmQtkZXnGCkSa/Hq1uSI+qv6+mjCEjrgJwLAoMSwm7oaf
+ anAA10TIXFrObUvL+dwdrXR16YiB3AJIiCG9ypdYzTLRuI4b77/7LitXryY1zMU/5I1/4cIjBnXrV5Hr
+ AOhwRahaOIow3XQGyR9Tf1/wKVa4KhA3Abg8gzb8VIMDuC5C9tJybl+6mM/fuZ0zXRd4p0MhBhYrxvx9
+ nZon4v6+hhBphcnwT3/0xwBsufdeGlq3snL1GtJCEINrEVpB/PlfPUvbHTtJl88I1K311cK0fnv3sc9X
+ IwSXx2k9h0C1vjKN4jl785iBAuCUJPrExDf/jcIB9Iowb+li7li6mN+6czsdbjHIzkhDtabVrY2CIb/K
+ ixfopfK7jtq10X259j/zDPufeQaArR//OE07tlO3ciWpBhf/uB6h5y9YrEyMT/gKgBeBiK4WZqQ2d6eT
+ AqXTqdVDIr+inBFw0eIiAL1OiRluAGjCCfSJkLd0MXcvW8LCKUA6R3Dk94Rp+fs6tY4h8qv8+HpmrAaS
+ UlOx5ubz1rvHeOu9D2DKzradO2hsbGDVyjpSU9Utg36n5Nrw1dBV9HHnvXdqND4GQX6/NFq1Of7xUff3
+ fYvl/wxnoAUwExr/IgEnKuNi1MjvV+t7DnXIHy1/PwD5iwoXcStnPiO2NBw5eTgUI/T2HXqXffsOwpSd
+ 1p07aGxqYPXKOp82g1D2DwwOKvfuc6hnCQQgf1SH9MqfrTud0uTXfcbBI+YCMC5JDInGpv3OOmjWRnLy
+ x7CLz48MavG+ePg/f0FP7yAvn+zktVNn6B26oTlC781D7/KmWwy279xBU3MjlTW19FuSECK0i8g//t0/
+ 8Du//zXfJcE0RVYR6febKH93DYLHuovPm59aWWeYBRDKYJEZD9kzVX8BPWGx9PcDfVc5Bxi02kgtLOBT
+ RYv4cmsjV91i8LqPGPiP0Hvj0Lu8se8gTNpZvn4tFfX1VDQ3B7X4hxruvPcu0tJSVWL0anmV+0uIIb0q
+ wqBJ/vBrf4iDAMwV818deuQnAAk1yK9pDgaqrfSuqSirCqYkiSGrjfTCAj5TvIgvtzbR3TswLQaDN1Qn
+ 8TA1SVd7F13HT/Higz+iYv06KjfWU9ncTKrKfP9AqFlZq9IGoEN+v/tT+V2j3cXnd+x5D9S6+DTyM/ic
+ AiGmAtDtFHFICTHyNw5Qq43VXlT8H26k/P2AtZ7KOQbgkOBmko3M4kX8RkkhX25t5mpvP68YEIMz7Wc4
+ c/wke3/471SuX8uKhgaqghCDc11nWaa1M7Pf/SrvT2ltGSG4XpySoG5Sy9OrPlsP+ZVWhFpZ1a4ROmIq
+ AJFY9GNmQov8iebvaxHAOFxrBCaRXbKI+0oK+UprM5f7+nnlRCd7PzzNreGRaSFQiEFnexedH53kuR88
+ yIr1a6lqaKC6pUVXDH71i1/xqc9+iqXLlyjuRXm/yvszSP5E8/dV40NHzARgQpLoS5CJP3GB8oHHa0iv
+ arxPRtrpgsQU4Ei2Ma+4kM+VFNLUtIGj7ok8F672+E7ikYvB5CQd7V10fHSSX//gQarWr6O6sYHqTS2k
+ KdoMvvKNr6osCqq4H6Xwatbmivi4+/tK4ivjVcoYJGImAN1zsfHPCwmfBw4BamAN8vu9aMrvQZJftaZU
+ Cos+UgWwCgITkqR7yqgI51NSyaur4rMrq8gaG6fz7EX2fXCKC1e7dcWgvf0M7R+d4OkHfkj1hnXUNDZS
+ 09JMWmamxpJgGuIYiPxxH9KrkZ/yU6uMISB2AjBnzX8P3A/dz/RUHERrSG8wJr+WmCiQZRGoS0nicm8/
+ 8+bn0z7lREvm5Y2/kxIMpqezYGU1n1tVTcbYOB1d7im+8mXBVMTg9GnXsmBP3f8Dajaso7axkTrZGoHe
+ Jdj87kH5uxshuF6cAWKqioOkkgqNxTAAABK5SURBVEZRqwciv8/xDLAAer1Lfs9VGCG/Rq3v/dCo1eJE
+ foDCJIGDp87w47e7+P5nNlOQlqY5xfuaU0TN/5uS4GZ6OoWravjimhrSRsZo77roFoNuXTE4dbqTUx+e
+ 4In7f0DthvXUNTVSWVpm4P41hCEhhvS60/uIjpq4RKZCjbwACILfxPD+MKZ9zg4k0JBeP3JoXAvlsToG
+ xqbIK1nH88fPcXtjnWuhP2Uap+ga+hugBpiSXIt/lK6u4Stra7ANj9F+Vrb4h8YmI0xOcvJ0Byc/PM53
+ /vqv0f1d4+nvK7L0JbeytlfGy8oUglhrIYICIEwLvOxJO5DmuP+PPvljNaRXKR7yNCEQH+CmE3bVLuGF
+ x1+gfmej5vyOnhAqgCkJHJkZLF5dy++sqSVpdJRTZy7wViAx8C4IEoD8EfH3FelVBVoiov5+BMkPkRIA
+ D+EFAZcQTK/L1j1bZ/2EgoA1uJFa3ydQPSwsk9/48+pzimQnJ/N/PnMbGZkZdEz5z/GdEF2Tf8Jx/1zL
+ gmWyfG0d1WvrEEZGON110bUSkFIMkmxoElT5PewuPuWxMo0GaUPx930ESx4fdwvAQ3r537QAXJzrtb8H
+ PkRWqZ1CJn+g7zrnhEF+ABE4MymSnJyC0+5AUmF5f4RHfrqWBcuicm0dtWvrYHiEk13n2XfMbRkkJemQ
+ X/a7J4y/r7yGTq2vdhxm/Rq+AAgCWGTEt1iwi07sIyNMZmbM8cY/N3yIpkF+v5fI52Sd2krlWH45H8tA
+ 5Vr+JwQNz2rAas85mH0CgoUDsGRlUbNuFavWrUIcHiEzKRk+OOdKMNOG9Br19yPYEKi1hnIQOQhgsbhW
+ vrFawZpE7/Aok6Ojc3Pijx5UFTsA+SVCJL+sFvKmUamhlOkC4K9+/w/Y9+ab3Lx1M2DaG+7Gv1jACZCd
+ hS3ZPe1Y9fdR1sDKOBTHnhpa43fUJL/SitAjv+Ia8uetRX6fdyK8HzgCFoAFrEl+IjBut9Or0fUzJzHD
+ /X0POo8epfPoUQBWrF9H2yc+wZr165mXk+OXtidCy37p4T/u/xGf/tynFdOBdWpSOYLy95VplWk0SBvQ
+ 3w9QVjXy+5oXYSF8AbC4CO8hPkk2sNl45p33WXL33Sb9IUTyB6j1Vb/7ZOSbJgLkV6LjyFE6jhwlJTuH
+ FRvr2bKzjbVrVjMvJwen5Or7j/bzb9m6iTSt5cC8PNGp9b0feuQPdKx4hn7kVhJfGS8rU0B/X3a9CCB8
+ AbAmQXKyjPzJYEtm/1uHyF63nvnFxREo5myC2oum/B6A/EF38SnzDP8FSpmXi5A7n4mkZOzWJD46d4WP
+ 7v8RTNqpqqlizZbNpNbUkV0Q5DbqQaJmZY3/+IJo+PuqAi0RUhefVhkN+fuRIz9EQgBsNkhOdX3aUiDZ
+ 9TdptfH8nl/QfNftrFhZE4GiznRomY/KuAC1epxr/dZ7P8GbQ+PYUzNk3W/ylYAmab94lfafPgKTkywo
+ KaZm6xaWNTaSsyjANuohoPtqN8UlRSoxSnElAPlVxDdg/74yjaJWVzX55fko81QJ8ylTZMkPYQrAhN3O
+ +pbNtJ+/6LICUlJdf6npkJbBZFoG+97+gMMnz7G4tJAlZUUsKSuMVNlnELTMR404n6jEIT/A53/rs/xF
+ 4SLOdffy2umzPPXOMfdEHhUxmLTTN3SLt554irce+zkLSoqp3baVigiKweMPPcbnf/vzFBXL3quY9e/j
+ m16N/FoNkHHw99UQlgBcHhnp2dzaWvj0y68w5hQhJQ3S0iE9AzKyIN01QWNycorOs5foPHuJ5GQbS0oL
+ WVpWxJIyNeWepdAlv9YLq3Kslp9q/pEnvwe3BAvziwv5bHEhv7ujma6e67x+SikGimXB3GKw7z+fZN/P
+ HmdhSTF127ZS2dQUlhhoTwd2Ixr+vt9PK+FvXSivoUN+tetEyeRXIiwBqMjPbx63T57/zre/zd//+GHG
+ LFYX6TOzfAYDyTE5OUXH2Ut0uMVgaWkRS8oLWTbrxUDx4qiZnN6oQLW+4rwo+/t6uGWxsLC4kPtkYvDw
+ Ox/x7qlOtxBMqYpB79At3vjPJ3njZ4+zsLSYVdu2UdncRG5BcGKgPh3YDcP+viK9qkBLRH1Ib4xqfTnC
+ EoAvZHHh/4w7/7isuOj/fefrX+Oxw+/R3jtg+PzJySnaz16k/exFlxiUFbHM/Te7IKm8VLJjn6hA5FeG
+ xabWN4Jhq4WkwgIa7mjjk7dt4/KFS7zbfk5HDFzuQu/gLV775RO89uhjFJSWsHrbVqpamplnQAxee/EV
+ NrVu9t8YRM3klx/r1vTKNBqkDcXfj7PJr0TYjYB/sTDte9+9equ7ICvzF9+593ahf2SUoxcuc6DjLJcG
+ hgznMzk5RXvXRdq7XGKwrKyIZeWJJwb5AixPEsgWYEiCi06JgUDPyhD5A33XOScByO9Bn7vv/6o1Ceuy
+ pTQvW8Ynb2/l8vlLvNN+lveUYqCY1Xd98Cav/PIJXnn0MRaVFLNmeytVLc2alsHF85fY0KjYGSgu/r7y
+ Gjq1vtqx8noxgiBFYDihB3uG+dLFW8P/WJ6dNR8gVDGQI8UtBsvLi1lWXjQ94RBcewvIJyF6PgXBN0xw
+ pfUPw5OLIkyWXhY2TxBoTBbg1i2OX7rKhmWLcaSlccwBfZJ6ORZOwd+/fID2a32uwJBG9fkcqL/U/idE
+ BH+1dR3/80uf837/yVNPkF1UBLLfx/PhBPZPOFy/nTD9jOTHBU4HF89f5F0fMVCf4utxF5iaZFFJMWt3
+ bKemuYncRYXePC3y/AWBXAd89YlXVMgsP9axDABfk18Zr5GfUfL7XUf2GeKzk/7ksyEPt4joegBfyOJh
+ srIe3jPMPODeUVH8x111VfN31VWFLAb2ySlOdV3kVNdFlxiUF7G8rJiK8thbBgUWyHBM8Re/eo0T10eZ
+ n3qEf/vCnVTm5DLoRHM1HEC9BgcD5E/8Wt+DHgMzP3uTkkivWEZrxTI+c8d2LpzTE4Npd+Ha0C1efPyX
+ vPjIoxSWFLNux3ZqW5rJW6TSq6RGfjmpvd8VaZXpgiK/nrhohPk8w/g8v6isCPSFLG5AlMTgzEVOnXGJ
+ wfJylxBUlMdmsFGqIDAyPMbF0WQql1czONjDwweP8gd3t5EvSvRpPUNVIivCZjj5AS4FOfGnP8lGVuVy
+ 2iqX8xt37uDc2Qu8136O9051qFsF7u89Q7fY+/gv2fvIHopKS1i/Yzt1LS3kFRZy/eoV9Gt9FbNe1eRX
+ /NZB+ftqJr8iPgHIDzFYEkxdDJz/uHnF8rDF4OSZC5w8c4GUZBsVMRSDVJsNW1IyFquV/+o8yx8JrsUx
+ tZ+jBpE1v+uck6DkHxalsGZ+DibZyF1Rwe4VFfzmnds5e/Yi77WfDSgG3QM36X7slzz38B6KSkv58je+
+ GYLJ7/lPIQx+5FcSWBmPBvkVx8rrxREx3RdgWgyyHwbYM8y9A5OTD25esbwgXDE4ceYCJ2RiULm4mMoI
+ i8GIJJGTm8P8pHE6zx5hfHwY2+RgcJnMoC6+YHA5ggu/3LDZmF9VwR1VFXz2rh2cOXuR90538b6WGLiP
+ uwduIDplZFUjua7Jj2/aQCa/93x8j+MwpDdUxGV3YA++kMUzZOU+A9ETg0q3GKxYXBJ2ea86YZkVvrmz
+ nq888BA9N2/ytR2bcUquuem6mGEmv2C1kVGUfwOYFyitU4I+MTpTv2/ZbCyqquBjVRXcd3cbZ7ou8F57
+ F++f7FC3CpJsvmY+aIvoLBrSGyriKgByREsMjp+5wHG3GKxYXExleQlVi0OzDOxAp1OiprSYF/7yj7jY
+ 209lWTEDosR1vfd/hpDfQ/rU3Oxf97Wt/xLAXx/pCHjBXqfk2vItylP/Rm02iqsrKamu5HN3t9HZdcFl
+ GcjFwLMkGKiQ1H1g2ORXpFeLn0H+vhoSRgDkiJYYfNR5gY86p8WganFJ0JbBJSeMShLF6ZkULcmkU5S4
+ 5HR1gWm//yoviU9U/MivRvpgEc1Vf7QwbkumrLqS8uoVfP7unXScOc977Wex2tyvtGYN7flPUvlp5eRW
+ El8Zjwb5tSyJxCK+BwkpAHKoi8GyiIpB1WKXVVC1xJgYDEgw6JA4jupCyOpIIH8/EqT3YFgUGRbju+zb
+ RHIyi2tXsKS2iiIHcPi4K0LT5J99Q3pDRcILgBzREoMPO8/zYed5UpJtVC8uoWpJMdWLSyNY8vib/JEk
+ vRxaG4HEC95FiHRNfq1aWpFejfyqboA8fuaQH2aYAMgRLTH4oPM8H3SeJ9VtGVQvKaHGoGVgCDEkf7RI
+ L0dPIi77Fq6/H9QUXsWx8noJjhkrAHL4iYE9fDGYUIhB9ZISahaXhi4Gqia/+78Im/xpBfljGQX5T0SL
+ 9B50O0XNzUDiCznZ3QLlZ/ITnr+vlk+C+/tqmBUCIEe0xOBYx3mOdbjEoGaJSwgMi0FAfz984qcXzB9P
+ n5+zvz8t9ZtjW1adDSmTINGTyKs+R2pIrzcvtMk/g0x+JWadAMjhLwb2iIjB0Y5zHO045xWD2iUl1C4N
+ 1GYQefLLST8aI9J7MCFJDIlS1Lv+QkLE+vfVTH5F/AwmP8xyAZDDJQZ5URWD2iWl1C4toW6JjhiESf54
+ kl6OxN7v0ai/H4TJr3Y8w/x9NcwZAZAjWmJwpOMcR2RiULe0lO2lbjEIo4svUUgvr+67E6z13wd+/r6e
+ ye85nv3+vhrmpADIEW0x2P61z4dU6ycM6WF601eL67PXKSb+lm8hmfzy48T3921ZmWJFRfFL4eQx5wVA
+ DqUY9EdADLwwQP6EIr0c7j0fsVgYvDHEzfkL410ifRgmfyCT3/tfwpDflpUpFpcsOFM0L/vvDjXVPBZu
+ fqYAaCASYjA/y7Uqsh75rTlZztySha8lHOnlSPLs/GTj3NnzOJdUyNZXSkTIyR2Cya92HEeTP9Kkl8MU
+ AAPwE4OJCUNi8PH1qwAYm5yUhUpYc7KcmYvmv3czI/V/OLateS1mNxIKBMG12UuSDVJSeOatQ+xu2UxK
+ Wnq8S6YNTfIra3H8yZ8gtb4lPVXKKcjrq1604E8iTXo5TAEIEi4xyNcVgyMXLlOen8umyqVcuznMpYEh
+ rDmZM4f0MhSVlJI+fwFjDhHS0ukZtfP49x9kw66drFq3Mt7F04FBfz+BTH4P6RcuyP3H9k2r/inqFyTC
+ i4LOZewZ5t72/oEHy3OyC9JsNsanpjg3MMTPzl96vzs56TvSDCK9HN882iUef/MN4cCRY5CVAzm5kLcA
+ bMneTV6WlBWxtKxIcyFQ9ePpxVv9j6cXZdU/9l0YVkCgwAFffPQZd+O/3BJIzC6+eJBeDlMATOjiyx+e
+ /5tVeXl//fSb+zlw8ap3tyclPPs6LC0rZFlZcXwFYM/TIXbxKdNHhxuW9BRyCvJ740V6OUwBMBEQnz59
+ 9Z/WZmX9ieR0Cgc6znLkwhX6h0c008v3dViuKQahCYANgQ02gYUW6HJKdDpVBOCRp0k0f9+SnsL8RflD
+ 5Qvzv/duc93/jGjmYcAUABOG8d2rtz4zPDL24NKcnNwx+wRGxMB3KffisAWg0iqwGgc/eOUgX21t5LQt
+ jfOSUgB+pdGnH1t/P1FJL4cpACZCwnev3PrM8GjwYuBZyr2yvDgkAWi0WTh17ASvXk5hd7lE/ZpK9jkU
+ AvDwU9MXjbG/PxNIL4cpACbCxnev3PzM8Mj4g0vnZeeO2e2GxcCzevMKPzHQFoByi0DNxCh/+fQ7LMuz
+ 8jt3buMlLQGI0ZBewWojuyh/pGBh7iMdW9f8fsgZxQGmAJiIKEIVA5cQuJZmC9QGsD1ZYPj6dUrm59Eh
+ 2DglKgTgoafwJzpE0uT3kD4zL+v5Kzs2fDboDBIEpgCYiBq+c/nGb4yMjv9w6byc3NEJOwc7jYlBlXsZ
+ 9+rFJapikAossrqW/+oVBZzKRsCHnoyKvz9bSC+HKQAmYoJQxaD6/2/n/lkSiOM4jn9ocKjlroYgUAgl
+ IqixrTHsGVxbPYq4qblHkATZrkJ7S0t7S3vQrUE15L+OqOEuPdLUS+ru/L1fi8KB6PB98zvUb7iWbXgM
+ fvga8KLRf5Ep7/dnceijCAD+3W9i8H0t29gATHG/P+tDH0UAkCjXe3FeW+1KMWYMepuYVvODAag2FPfI
+ b9LQRxEApIbrBSeDoh0vBv1NTIUwAPXg4pjhN3XoowgAUikag1anq5sJY3B26OjgvK5RP+n92rvwWN7e
+ +7tPkA38GxCpdFKwapJVkyTX6zql/EqlvLUxMgadNz94El0KGj6mdtlKwjgBIFNc7zk8GVgDMdhZK2p3
+ c13Hl1eSpPnlpd7QfzD0QxEAZNbRw9N+s9k+LS3atiQt5HKq3t759+/+NUM/GQIAGGwu6TcAIDkEADAY
+ AQAMRgAAgxEAwGAEADAYAQAM9gmX0HGIBJ6vQAAAAABJRU5ErkJggg==
+
+
+
\ No newline at end of file
diff --git a/hyperv-passthrough/MainForm.Designer.cs b/hyperv-passthrough/MainForm.Designer.cs
index 3c023b334..6712f2039 100644
--- a/hyperv-passthrough/MainForm.Designer.cs
+++ b/hyperv-passthrough/MainForm.Designer.cs
@@ -1,4 +1,4 @@
-namespace DiscreteDeviceAssigner
+namespace HyperVPassthoughDevice
{
partial class MainForm
{
@@ -22,7 +22,6 @@ private void InitializeComponent()
this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.其它toolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.GCCTtoolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.removegpupass = new System.Windows.Forms.ToolStripMenuItem();
this.changeMemoryLocationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.添加设备ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -30,6 +29,8 @@ private void InitializeComponent()
this.复制地址toolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.刷新列表toolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.removeAllAssignedDevicesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.checkAssignableDevicesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenuStrip.SuspendLayout();
this.SuspendLayout();
//
@@ -72,15 +73,17 @@ private void InitializeComponent()
this.移除设备ToolStripMenuItem,
this.复制地址toolStripMenuItem,
this.toolStripSeparator1,
- this.刷新列表toolStripMenuItem});
+ this.刷新列表toolStripMenuItem,
+ this.removeAllAssignedDevicesToolStripMenuItem,
+ this.checkAssignableDevicesToolStripMenuItem});
this.contextMenuStrip.Name = "contextMenuStrip";
resources.ApplyResources(this.contextMenuStrip, "contextMenuStrip");
+ this.contextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip_Opening);
//
// 其它toolStripMenuItem
//
this.其它toolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.GCCTtoolStripMenuItem,
- this.removegpupass,
this.changeMemoryLocationToolStripMenuItem});
this.其它toolStripMenuItem.Name = "其它toolStripMenuItem";
resources.ApplyResources(this.其它toolStripMenuItem, "其它toolStripMenuItem");
@@ -94,12 +97,6 @@ private void InitializeComponent()
resources.ApplyResources(this.GCCTtoolStripMenuItem, "GCCTtoolStripMenuItem");
this.GCCTtoolStripMenuItem.Click += new System.EventHandler(this.GCCTtoolStripMenuItem_Click);
//
- // removegpupass
- //
- this.removegpupass.Name = "removegpupass";
- resources.ApplyResources(this.removegpupass, "removegpupass");
- this.removegpupass.Click += new System.EventHandler(this.removegpupass_Click);
- //
// changeMemoryLocationToolStripMenuItem
//
this.changeMemoryLocationToolStripMenuItem.Name = "changeMemoryLocationToolStripMenuItem";
@@ -140,6 +137,18 @@ private void InitializeComponent()
resources.ApplyResources(this.刷新列表toolStripMenuItem, "刷新列表toolStripMenuItem");
this.刷新列表toolStripMenuItem.Click += new System.EventHandler(this.刷新列表ToolStripMenuItem_Click);
//
+ // removeAllAssignedDevicesToolStripMenuItem
+ //
+ this.removeAllAssignedDevicesToolStripMenuItem.Name = "removeAllAssignedDevicesToolStripMenuItem";
+ resources.ApplyResources(this.removeAllAssignedDevicesToolStripMenuItem, "removeAllAssignedDevicesToolStripMenuItem");
+ this.removeAllAssignedDevicesToolStripMenuItem.Click += new System.EventHandler(this.RemoveAllDev);
+ //
+ // checkAssignableDevicesToolStripMenuItem
+ //
+ this.checkAssignableDevicesToolStripMenuItem.Name = "checkAssignableDevicesToolStripMenuItem";
+ resources.ApplyResources(this.checkAssignableDevicesToolStripMenuItem, "checkAssignableDevicesToolStripMenuItem");
+ this.checkAssignableDevicesToolStripMenuItem.Click += new System.EventHandler(this.CheckAssignableDevice);
+ //
// MainForm
//
resources.ApplyResources(this, "$this");
@@ -171,8 +180,9 @@ private void InitializeComponent()
private System.Windows.Forms.ToolStripMenuItem 复制地址toolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem 其它toolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem GCCTtoolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem removegpupass;
private System.Windows.Forms.ToolStripMenuItem changeMemoryLocationToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem removeAllAssignedDevicesToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem checkAssignableDevicesToolStripMenuItem;
}
}
diff --git a/hyperv-passthrough/MainForm.cs b/hyperv-passthrough/MainForm.cs
index 153c1f377..ac93b7f1a 100644
--- a/hyperv-passthrough/MainForm.cs
+++ b/hyperv-passthrough/MainForm.cs
@@ -1,12 +1,12 @@
-using Microsoft.Management.Infrastructure;
+using HyperVpassthroughdev;
+using Microsoft.Management.Infrastructure;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
using DeviceData = System.Tuple;
-using HyperVpassthroughdev;
-namespace DiscreteDeviceAssigner
+namespace HyperVPassthoughDevice
{
public partial class MainForm : Form
{
@@ -139,7 +139,8 @@ private void 添加设备ToolStripMenuItem_Click(object sender, EventArgs e)
private void 移除设备ToolStripMenuItem_Click(object sender, EventArgs e)
{
- try {
+ try
+ {
DeviceData data = contextMenuStrip.Tag as DeviceData;
if (MessageBox.Show("Perform removal device " + data.Item2.Name + " from " + data.Item1.Name, "Confirm?", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
@@ -154,8 +155,9 @@ private void 移除设备ToolStripMenuItem_Click(object sender, EventArgs e)
UpdateVM();
}
}
- catch (Exception ex) {
- MessageBox.Show($"The specific VM has no device selected, nor the error has occured. \nError:" + ex.Message, $"Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ catch (Exception ex)
+ {
+ MessageBox.Show($"The specific VM has no device selected, nor the error has occured. \nError:" + ex.Message, $"Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
@@ -186,29 +188,61 @@ private void GCCTtoolStripMenuItem_Click(object sender, EventArgs e)
}
}
- private void listView1_SelectedIndexChanged(object sender, EventArgs e)
+ private void memchangeloc(object sender, EventArgs e)
{
+ DeviceData data = contextMenuStrip.Tag as DeviceData;
+ try
+ {
+ UInt32[] LowHighCollection = new SetMemory().ReturnResult();
+ UInt32 MemorySetLow = LowHighCollection[0];
+ UInt32 MemorySetHigh = LowHighCollection[1];
+ PowerShellWrapper.SetLowMemoryMappedIoSpace(data.Item1, MemorySetLow * 1024 * 1024);
+ PowerShellWrapper.SetHighMemoryMappedIoSpace(data.Item1, MemorySetHigh * 1024 * 1024);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
+ }
}
- private void 其它toolStripMenuItem_Click(object sender, EventArgs e)
+ private void RemoveAllDev(object sender, EventArgs e)
+ {
+ if (MessageBox.Show($"This will stop all virtual machines and perform the removal of all assigned device.\nContinue?", $"Warning", MessageBoxButtons.YesNoCancel) == DialogResult.Yes)
+ {
+ try
+ {
+ PowerShellWrapper.StartRemovalAssignedDevices();
+ UpdateVM();
+ }
+ catch (Exception exception)
+ {
+ MessageBox.Show($"An error has occured:\n\n" + exception, $"Error", MessageBoxButtons.OK);
+ }
+ }
+ }
+
+ private void CheckAssignableDevice(object sender, EventArgs e)
+ {
+ new DisplayAssignableDevices();
+ }
+
+ /*
+ * Security functions
+ */
+ private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
- private void removegpupass_Click(object sender, EventArgs e)
+ private void 其它toolStripMenuItem_Click(object sender, EventArgs e)
{
- DeviceData data = contextMenuStrip.Tag as DeviceData;
- PowerShellWrapper.RemoveGpuPartitioning(data.Item1);
+
}
- private void memchangeloc(object sender, EventArgs e)
+ private void contextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
- DeviceData data = contextMenuStrip.Tag as DeviceData;
- UInt32 MemorySet = new SetMemory().ReturnResult();
- PowerShellWrapper.SetLowMemoryMappedIoSpace(data.Item1);
- PowerShellWrapper.SetHighMemoryMappedIoSpace(data.Item1, MemorySet * 1024 * 1024);
-
+
}
}
}
\ No newline at end of file
diff --git a/hyperv-passthrough/MainForm.resx b/hyperv-passthrough/MainForm.resx
index 8ff72bd61..4d72839cd 100644
--- a/hyperv-passthrough/MainForm.resx
+++ b/hyperv-passthrough/MainForm.resx
@@ -165,62 +165,56 @@
21, 18
-
- 228, 22
-
-
- GuestControlledCacheTypes
-
-
- 228, 22
-
-
- Remove GPU Passed through
-
-
- 228, 22
-
-
- Change Memory Location
-
- 182, 22
+ 228, 22
Other settings
- 179, 6
+ 225, 6
- 182, 22
+ 228, 22
Add device
- 182, 22
+ 228, 22
Remove device
- 182, 22
+ 228, 22
Copy device address
- 179, 6
+ 225, 6
- 182, 22
+ 228, 22
Refresh
+
+ 228, 22
+
+
+ Remove All Assigned Devices
+
+
+ 228, 22
+
+
+ Check Assignable Devices
+
- 183, 148
+ 229, 192
contextMenuStrip
@@ -228,6 +222,18 @@
System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 222, 22
+
+
+ GuestControlledCacheTypes
+
+
+ 222, 22
+
+
+ Change Memory Location
+
True
@@ -638,12 +644,6 @@
System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- removegpupass
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
changeMemoryLocationToolStripMenuItem
@@ -686,6 +686,18 @@
System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ removeAllAssignedDevicesToolStripMenuItem
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ checkAssignableDevicesToolStripMenuItem
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
MainForm
diff --git a/hyperv-passthrough/PnpDeviceForm.Designer.cs b/hyperv-passthrough/PnpDeviceForm.Designer.cs
index 15527c2f1..5a1f4dc76 100644
--- a/hyperv-passthrough/PnpDeviceForm.Designer.cs
+++ b/hyperv-passthrough/PnpDeviceForm.Designer.cs
@@ -1,4 +1,4 @@
-namespace DiscreteDeviceAssigner
+namespace HyperVPassthoughDevice
{
partial class PnpDeviceForm
{
diff --git a/hyperv-passthrough/PnpDeviceForm.cs b/hyperv-passthrough/PnpDeviceForm.cs
index 41531ee2d..909a130a4 100644
--- a/hyperv-passthrough/PnpDeviceForm.cs
+++ b/hyperv-passthrough/PnpDeviceForm.cs
@@ -3,7 +3,7 @@
using System.Collections.ObjectModel;
using System.Windows.Forms;
-namespace DiscreteDeviceAssigner
+namespace HyperVPassthoughDevice
{
public partial class PnpDeviceForm : Form
{
diff --git a/hyperv-passthrough/PowerShellWrapper.cs b/hyperv-passthrough/PowerShellWrapper.cs
index d6de4253e..4ec3fc70c 100644
--- a/hyperv-passthrough/PowerShellWrapper.cs
+++ b/hyperv-passthrough/PowerShellWrapper.cs
@@ -1,13 +1,14 @@
using Microsoft.HyperV.PowerShell;
using Microsoft.Management.Infrastructure;
using System;
+using System.Text;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Windows.Forms;
-namespace DiscreteDeviceAssigner
+namespace HyperVPassthoughDevice
{
class PowerShellWrapper
{
@@ -101,9 +102,9 @@ public static void SetGuestControlledCacheTypes(VirtualMachine vm, bool value)
}
}
- public static void SetLowMemoryMappedIoSpace(VirtualMachine vm)
+ public static void SetLowMemoryMappedIoSpace(VirtualMachine vm, uint bytes)
{
- RunScript("Set-VM \"" + vm.Name + "\" -LowMemoryMappedIoSpace " + Convert.ToInt32("512") * 1024 * 1024);
+ RunScript("Set-VM \"" + vm.Name + "\" -LowMemoryMappedIoSpace " + bytes);
}
public static void SetHighMemoryMappedIoSpace(VirtualMachine vm, uint bytes)
@@ -130,18 +131,17 @@ public static void GpuPartitioning(VirtualMachine vm, CimInstance device)
{
string DeviceIDInstance = device.CimInstanceProperties["DeviceId"] != null ? device.CimInstanceProperties["DeviceId"].Value as string : null;
var locationPath = GetPnpDeviceLocationPath(DeviceIDInstance)[0];
-
+
//securing devices from crashing
- try
+ try
{
RunScript("Set-VM -Name \"" + vm.Name + "\" -AutomaticStopAction TurnOff");
- RunScript("Set-VM -GuestControlledCacheTypes $true -VMName \"" + vm.Name + "\"");
- RunScript("Set-VM -LowMemoryMappedIoSpace 3Gb -VMName \"" + vm.Name + "\"");
- RunScript("Set-VM -HighMemoryMappedIoSpace 33280Mb -VMName \"" + vm.Name + "\"");
- } catch
+ RunScript("Set-VM -GuestControlledCacheTypes $true -VMName \"" + vm.Name + "\""); //Needed
+ }
+ catch
{
MessageBox.Show($"Setting VM is failed, failing the application"); //Securing the devices
- throw new InvalidOperationException("Operation failed! Raise function GpuPartitioning (line 129), with the debug DeviceIDInstance: " + DeviceIDInstance);
+ throw new InvalidOperationException("Operation failed! Raise function GpuPartitioning (line 143), with the debug DeviceIDInstance: " + DeviceIDInstance);
}
try
@@ -149,10 +149,11 @@ public static void GpuPartitioning(VirtualMachine vm, CimInstance device)
RunScript("Disable-PnpDevice -InstanceId \"" + DeviceIDInstance + "\" -Confirm:$false");
RunScript("Dismount-VMHostAssignableDevice -Force -LocationPath \"" + locationPath + "\"");
RunScript("Add-VMAssignableDevice -LocationPath \"" + locationPath + "\" -VMName \"" + vm.Name + "\"");
- } catch
+ }
+ catch
{
MessageBox.Show($"Disable device is failed, failing the application"); //Securing the devices and VMs
- throw new InvalidOperationException("Operation failed! Raise function GpuPartitioning (line 129), with the debug locationPath: " + locationPath);
+ throw new InvalidOperationException("Operation failed! Raise function GpuPartitioning (line 154), with the debug locationPath: " + locationPath);
}
}
@@ -206,9 +207,14 @@ public static void AddVMAssignableDevice(VirtualMachine vm, CimInstance device)
RunScript("Add-VMAssignableDevice -LocationPath \"" + locationPaths[0] + "\" -VMName \"" + vm.Name + "\"");
}
- internal static void GpuPartitioning(VirtualMachine item1, VMAssignedDevice item2)
+ public static void StartRemovalAssignedDevices()
{
- throw new NotImplementedException();
+ Collection HostDevicesAssigned = RunScript("Get-VMHostAssignableDevice | Select-Object -ExpandProperty LocationPath");
+ foreach (PSObject obj in HostDevicesAssigned)
+ {
+ //MessageBox.Show("Device: " + obj.ToString(), $"Notification", MessageBoxButtons.OK);
+ RunScript("Mount-VMHostAssignableDevice -LocationPath \"" + obj.ToString() + "\"");
+ }
}
}
}
diff --git a/hyperv-passthrough/Program.cs b/hyperv-passthrough/Program.cs
index 85b6c18f2..ba03f6234 100644
--- a/hyperv-passthrough/Program.cs
+++ b/hyperv-passthrough/Program.cs
@@ -1,7 +1,7 @@
using System;
using System.Windows.Forms;
-namespace DiscreteDeviceAssigner
+namespace HyperVPassthoughDevice
{
static class Program
{
diff --git a/hyperv-passthrough/Properties/Resources.Designer.cs b/hyperv-passthrough/Properties/Resources.Designer.cs
index 19d855052..e34daabbc 100644
--- a/hyperv-passthrough/Properties/Resources.Designer.cs
+++ b/hyperv-passthrough/Properties/Resources.Designer.cs
@@ -8,7 +8,7 @@
//
//------------------------------------------------------------------------------
-namespace HyperVpassthroughdev.Properties {
+namespace HyperVPassthoughDevice.Properties {
using System;
@@ -39,7 +39,7 @@ internal Resources() {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HyperVpassthroughdev.Properties.Resources", typeof(Resources).Assembly);
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HyperVPassthoughDevice.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
diff --git a/hyperv-passthrough/Properties/Settings.Designer.cs b/hyperv-passthrough/Properties/Settings.Designer.cs
index c4ab87d36..322a7f3cf 100644
--- a/hyperv-passthrough/Properties/Settings.Designer.cs
+++ b/hyperv-passthrough/Properties/Settings.Designer.cs
@@ -8,11 +8,11 @@
//
//------------------------------------------------------------------------------
-namespace HyperVpassthroughdev.Properties {
+namespace HyperVPassthoughDevice.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/hyperv-passthrough/SetMemory.Designer.cs b/hyperv-passthrough/SetMemory.Designer.cs
index a40d0a637..af2e176cb 100644
--- a/hyperv-passthrough/SetMemory.Designer.cs
+++ b/hyperv-passthrough/SetMemory.Designer.cs
@@ -32,6 +32,7 @@ private void InitializeComponent()
this.labelhimem = new System.Windows.Forms.Label();
this.HighMem = new System.Windows.Forms.TextBox();
this.OK = new System.Windows.Forms.Button();
+ this.LowMem = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
@@ -40,25 +41,25 @@ private void InitializeComponent()
this.labelhimem.AutoSize = true;
this.labelhimem.Location = new System.Drawing.Point(2, 9);
this.labelhimem.Name = "labelhimem";
- this.labelhimem.Size = new System.Drawing.Size(69, 13);
+ this.labelhimem.Size = new System.Drawing.Size(96, 13);
this.labelhimem.TabIndex = 0;
- this.labelhimem.Text = "High Memory";
- this.labelhimem.Click += new System.EventHandler(this.label1_Click);
+ this.labelhimem.Text = "High Memory (MiB)";
+ this.labelhimem.Click += new System.EventHandler(this.labelhimem_Click);
//
// HighMem
//
this.HighMem.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
- this.HighMem.Location = new System.Drawing.Point(78, 6);
+ this.HighMem.Location = new System.Drawing.Point(104, 6);
this.HighMem.Name = "HighMem";
- this.HighMem.Size = new System.Drawing.Size(156, 20);
+ this.HighMem.Size = new System.Drawing.Size(155, 20);
this.HighMem.TabIndex = 2;
this.HighMem.TextChanged += new System.EventHandler(this.HighMemchanges);
//
// OK
//
- this.OK.Location = new System.Drawing.Point(78, 58);
+ this.OK.Location = new System.Drawing.Point(104, 62);
this.OK.Name = "OK";
this.OK.Size = new System.Drawing.Size(75, 26);
this.OK.TabIndex = 4;
@@ -66,22 +67,34 @@ private void InitializeComponent()
this.OK.UseVisualStyleBackColor = true;
this.OK.Click += new System.EventHandler(this.OKClick);
//
+ // LowMem
+ //
+ this.LowMem.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.LowMem.Cursor = System.Windows.Forms.Cursors.IBeam;
+ this.LowMem.Location = new System.Drawing.Point(104, 32);
+ this.LowMem.Name = "LowMem";
+ this.LowMem.Size = new System.Drawing.Size(155, 20);
+ this.LowMem.TabIndex = 5;
+ this.LowMem.TextChanged += new System.EventHandler(this.LowMemChanges);
+ //
// label1
//
this.label1.AutoSize = true;
- this.label1.ForeColor = System.Drawing.Color.DarkRed;
- this.label1.Location = new System.Drawing.Point(5, 35);
+ this.label1.Location = new System.Drawing.Point(4, 36);
this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(235, 13);
- this.label1.TabIndex = 5;
- this.label1.Text = "By default, Low Memory location is set to 512Mb";
+ this.label1.Size = new System.Drawing.Size(94, 13);
+ this.label1.TabIndex = 6;
+ this.label1.Text = "Low Memory (MiB)";
//
// SetMemory
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(246, 96);
+ this.ClientSize = new System.Drawing.Size(271, 100);
this.Controls.Add(this.label1);
+ this.Controls.Add(this.LowMem);
this.Controls.Add(this.OK);
this.Controls.Add(this.HighMem);
this.Controls.Add(this.labelhimem);
@@ -100,6 +113,7 @@ private void InitializeComponent()
private System.Windows.Forms.Label labelhimem;
private System.Windows.Forms.Button OK;
private System.Windows.Forms.TextBox HighMem;
+ private System.Windows.Forms.TextBox LowMem;
private System.Windows.Forms.Label label1;
}
}
\ No newline at end of file
diff --git a/hyperv-passthrough/SetMemory.cs b/hyperv-passthrough/SetMemory.cs
index f23f7ca08..343790977 100644
--- a/hyperv-passthrough/SetMemory.cs
+++ b/hyperv-passthrough/SetMemory.cs
@@ -8,11 +8,7 @@ public partial class SetMemory : Form
public SetMemory()
{
InitializeComponent();
- }
-
- private void label1_Click(object sender, EventArgs e)
- {
-
+ ShowDialog();
}
private void HighMemchanges(object sender, EventArgs e)
@@ -22,31 +18,23 @@ private void HighMemchanges(object sender, EventArgs e)
public void OKClick(object sender, EventArgs e)
{
- try
- {
- if (Convert.ToInt32(HighMem.Text) < Convert.ToInt32("512"))
- {
- MessageBox.Show($"The high memory location must be higher than 512Mib", $"Error", MessageBoxButtons.OK);
- }
- else
- {
- Close();
- }
- }
- catch (Exception exp)
- {
- MessageBox.Show($"An error has occurred: \n" + exp, "Error", MessageBoxButtons.OK);
- }
+ Close();
+ }
+ public UInt32[] ReturnResult()
+ {
+ UInt32 LowMemSet = (uint)Convert.ToInt32(LowMem.Text);
+ UInt32 HighMemSet = (uint)Convert.ToInt32(HighMem.Text);
+ UInt32[] Memory = { LowMemSet, HighMemSet };
+ return Memory;
}
- public UInt32 ReturnResult()
+ private void LowMemChanges(object sender, EventArgs e)
{
- ShowDialog();
- return (uint)Convert.ToInt32(HighMem.Text);
+
}
- private void label1_Click_1(object sender, EventArgs e)
+ private void labelhimem_Click(object sender, EventArgs e)
{
}
diff --git a/hyperv-passthrough/SetMemory.resx b/hyperv-passthrough/SetMemory.resx
index 7108d3bfd..cddba4ac8 100644
--- a/hyperv-passthrough/SetMemory.resx
+++ b/hyperv-passthrough/SetMemory.resx
@@ -117,9 +117,6 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- True
-
diff --git a/hyperv-passthrough/bin/Hyper-V Device Passthrough.exe.CodeAnalysisLog.xml b/hyperv-passthrough/bin/Hyper-V Device Passthrough.exe.CodeAnalysisLog.xml
new file mode 100644
index 000000000..e2b874cd7
--- /dev/null
+++ b/hyperv-passthrough/bin/Hyper-V Device Passthrough.exe.CodeAnalysisLog.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ Category
+ Certainty
+ Collapse All
+ Check Id
+ Error
+ error(s)
+ Expand All
+ Help
+ Line
+ message(s)
+ [Location not stored in Pdb]
+ Project
+ Resolution
+ Rule
+ Rule File
+ Rule Description
+ Source
+ Status
+ Target
+ Warning
+ warning(s)
+ Code Analysis Report
+
+
diff --git a/hyperv-passthrough/bin/Hyper-V Device Passthrough.exe.config b/hyperv-passthrough/bin/Hyper-V Device Passthrough.exe.config
new file mode 100644
index 000000000..1243f4282
--- /dev/null
+++ b/hyperv-passthrough/bin/Hyper-V Device Passthrough.exe.config
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperv-passthrough/bin/Hyper-V Device Passthrough.exe.lastcodeanalysissucceeded b/hyperv-passthrough/bin/Hyper-V Device Passthrough.exe.lastcodeanalysissucceeded
new file mode 100644
index 000000000..e69de29bb
diff --git a/hyperv-passthrough/hypervpassth.csproj b/hyperv-passthrough/hypervpassth.csproj
index 7d2c03717..19a244471 100644
--- a/hyperv-passthrough/hypervpassth.csproj
+++ b/hyperv-passthrough/hypervpassth.csproj
@@ -7,7 +7,7 @@
{F2A2FC53-F5E9-4350-8D9B-98269DF4C9B1}
WinExe
Properties
- HyperVpassthroughdev
+ HyperVPassthoughDevice
Hyper-V Device Passthrough
v4.8
512
@@ -72,7 +72,7 @@
true
- DiscreteDeviceAssigner.Program
+ HyperVPassthoughDevice.Program
main.ico
@@ -103,7 +103,7 @@
..\!bin!\Hyper-V Device Passthrough\
- CODE_ANALYSIS;TRACE
+ CODE_ANALYSIS;CODE_ANALYSIS
true
true
pdbonly
@@ -111,7 +111,7 @@
true
7.3
prompt
- MixedRecommendedRules.ruleset
+ AllRules.ruleset
true
@@ -142,6 +142,12 @@
+
+ Form
+
+
+ DisplayAssignableDevices.cs
+
Form
@@ -163,6 +169,9 @@
SetMemory.cs
+
+ DisplayAssignableDevices.cs
+
MainForm.cs
@@ -182,7 +191,6 @@
SetMemory.cs
-
SettingsSingleFileGenerator
diff --git a/vlmcsd-beta/license-manager/KmsServer.xaml.cs b/vlmcsd-beta/license-manager/KmsServer.xaml.cs
index 5de848651..e15385081 100644
--- a/vlmcsd-beta/license-manager/KmsServer.xaml.cs
+++ b/vlmcsd-beta/license-manager/KmsServer.xaml.cs
@@ -100,9 +100,6 @@ private set
Dispatcher.InvokeAsync(() =>
{
-#if DEBUG
- Debug.Assert(UseTap.IsChecked != null, "UseTap.IsChecked != null");
-#endif // DEBUG
ButtonStartStop.Content = (value ? "Stop" : "Start") + " Server";
TextBoxPort.IsEnabled = !value;
@@ -431,52 +428,11 @@ private void Button_StartStop_Click(object sender, RoutedEventArgs e)
}
IsRunning = true;
-
KmsLists.LoadDatabase();
-#if DEBUG
- Debug.Assert(CheckBoxPreCharge.IsChecked != null, "CheckBoxPreCharge.IsChecked != null");
-#endif
foreach (AppItem appItem in KmsLists.AppItemList)
{
appItem.PreCharge(CheckBoxPreCharge.IsChecked.Value);
}
- //if
- //(
- // !string.IsNullOrWhiteSpace(TextBoxWindowsPid.Text) &&
- // !string.IsNullOrWhiteSpace(TextBoxOffice2010Pid.Text) &&
- // !string.IsNullOrWhiteSpace(TextBoxOffice2013Pid.Text) &&
- // !string.IsNullOrWhiteSpace(TextBoxOffice2016Pid.Text) &&
- // !string.IsNullOrWhiteSpace(TextBoxWindowsChinaGovPid.Text)
- //)
- //{
- // var winEpid = new EPid(TextBoxWindowsPid.Text);
- // var o2010Epid = new EPid(TextBoxOffice2010Pid.Text);
- // var o2013Epid = new EPid(TextBoxOffice2013Pid.Text);
- // var o2016Epid = new EPid(TextBoxOffice2016Pid.Text);
- // var winChinaGovEpid = new EPid(TextBoxWindowsChinaGovPid.Text);
-
- // if
- // (
- // winEpid.LcidString != o2010Epid.LcidString ||
- // o2010Epid.LcidString != o2013Epid.LcidString ||
- // o2013Epid.LcidString != o2016Epid.LcidString ||
- // o2016Epid.LcidString != winChinaGovEpid.LcidString
- // )
- // {
- // TextBoxInfoText.AppendText($"{nl}Warning: LCIDs of all EPIDs must be the same.");
- // }
- // if
- // (
- // winEpid.OsBuildString != o2010Epid.OsBuildString ||
- // o2010Epid.OsBuildString != o2013Epid.OsBuildString ||
- // o2013Epid.OsBuildString != o2016Epid.OsBuildString ||
- // o2016Epid.OsBuildString != winChinaGovEpid.OsBuildString
- // )
- // {
- // TextBoxInfoText.AppendText($"{nl}Warning: OS build numbers of all EPIDs must be the same.");
- // }
- //}
-
new Thread(KmsServerThread).Start();
}
else
@@ -516,11 +472,6 @@ private void ActivationInterval_TextChanged(object sender, TextChangedEventArgs
private void UseTap_Click(object sender, RoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
-
-#if DEBUG
- Debug.Assert(checkBox.IsChecked != null, "checkBox.IsChecked != null");
-#endif // DEBUG
-
TextBoxTapIp.Visibility = ComboBoxTap.Visibility = checkBox.IsChecked.Value ? Visibility.Visible : Visibility.Collapsed;
}
diff --git a/vlmcsd-beta/license-manager/ProductBrowser.xaml.cs b/vlmcsd-beta/license-manager/ProductBrowser.xaml.cs
index 0566fc6f1..25c335168 100644
--- a/vlmcsd-beta/license-manager/ProductBrowser.xaml.cs
+++ b/vlmcsd-beta/license-manager/ProductBrowser.xaml.cs
@@ -1081,9 +1081,6 @@ private void Button_Install_Click(object sender, RoutedEventArgs e)
private void CheckBoxHideInput_Click(object sender, RoutedEventArgs e)
{
-#if DEBUG
- Debug.Assert(CheckBoxHideInput.IsChecked != null, "CheckBoxHideInput.IsChecked != null");
-#endif
if (CheckBoxHideInput.IsChecked.Value)
{
PassWordBoxEpidInput.Visibility = Visibility.Visible;