GIT: perform LF normalization
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
|
||||
+140
-140
@@ -1,141 +1,141 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{D6B85A86-0FAA-4B04-BC9E-D01A08C03387}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Disco.Client</RootNamespace>
|
||||
<AssemblyName>Disco.Client</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>Disco.Client.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup />
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Disco.Models\ClientServices\Enrol.cs">
|
||||
<Link>Models\ClientServices\Enrol.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\EnrolResponse.cs">
|
||||
<Link>Models\ClientServices\EnrolResponse.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\MacEnrol.cs">
|
||||
<Link>Models\ClientServices\MacEnrol.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\MacEnrolResponse.cs">
|
||||
<Link>Models\ClientServices\MacEnrolResponse.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\MacSecureEnrolResponse.cs">
|
||||
<Link>Models\ClientServices\MacSecureEnrolResponse.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\ServiceBase.cs">
|
||||
<Link>Models\ClientServices\ServiceBase.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\WhoAmI.cs">
|
||||
<Link>Models\ClientServices\WhoAmI.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\WhoAmIResponse.cs">
|
||||
<Link>Models\ClientServices\WhoAmIResponse.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="ErrorReporting.cs" />
|
||||
<Compile Include="Extensions\ClientServiceException.cs" />
|
||||
<Compile Include="Extensions\ClientServicesExtensions.cs" />
|
||||
<Compile Include="Extensions\EnrolExtensions.cs" />
|
||||
<Compile Include="Extensions\WhoAmIExtensions.cs" />
|
||||
<Compile Include="Interop\Certificates.cs" />
|
||||
<Compile Include="Interop\LocalAuthentication.cs" />
|
||||
<Compile Include="Interop\Network.cs" />
|
||||
<Compile Include="Presentation.cs" />
|
||||
<Compile Include="Interop\SystemAudit.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="Package Creation\PreparationClient.zip" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\app.manifest" />
|
||||
<None Include="Start.bat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PsExec.exe">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Icon.ico" />
|
||||
<None Include="Package Creation\7z.dll" />
|
||||
<None Include="Package Creation\7z.exe" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties BuildVersion_UseGlobalSettings="True" BuildVersion_DetectChanges="False" BuildVersion_StartDate="2001/1/1" BuildVersion_BuildAction="ReBuild" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>DEL "$(ProjectDir)Package Creation\PreparationClient.zip"
|
||||
"$(ProjectDir)Package Creation\7z.exe" a -tzip "$(ProjectDir)Package Creation\PreparationClient.zip" "$(TargetDir)*.*" -x!*.tmp -x!*.vshost.* -x!Newtonsoft.Json.xml -x!*.pdb
|
||||
COPY "$(ProjectDir)Package Creation\PreparationClient.zip" "$(ProjectDir)..\Disco.Web\ClientBin"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{D6B85A86-0FAA-4B04-BC9E-D01A08C03387}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Disco.Client</RootNamespace>
|
||||
<AssemblyName>Disco.Client</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>Disco.Client.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup />
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Disco.Models\ClientServices\Enrol.cs">
|
||||
<Link>Models\ClientServices\Enrol.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\EnrolResponse.cs">
|
||||
<Link>Models\ClientServices\EnrolResponse.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\MacEnrol.cs">
|
||||
<Link>Models\ClientServices\MacEnrol.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\MacEnrolResponse.cs">
|
||||
<Link>Models\ClientServices\MacEnrolResponse.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\MacSecureEnrolResponse.cs">
|
||||
<Link>Models\ClientServices\MacSecureEnrolResponse.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\ServiceBase.cs">
|
||||
<Link>Models\ClientServices\ServiceBase.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\WhoAmI.cs">
|
||||
<Link>Models\ClientServices\WhoAmI.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Disco.Models\ClientServices\WhoAmIResponse.cs">
|
||||
<Link>Models\ClientServices\WhoAmIResponse.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="ErrorReporting.cs" />
|
||||
<Compile Include="Extensions\ClientServiceException.cs" />
|
||||
<Compile Include="Extensions\ClientServicesExtensions.cs" />
|
||||
<Compile Include="Extensions\EnrolExtensions.cs" />
|
||||
<Compile Include="Extensions\WhoAmIExtensions.cs" />
|
||||
<Compile Include="Interop\Certificates.cs" />
|
||||
<Compile Include="Interop\LocalAuthentication.cs" />
|
||||
<Compile Include="Interop\Network.cs" />
|
||||
<Compile Include="Presentation.cs" />
|
||||
<Compile Include="Interop\SystemAudit.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="Package Creation\PreparationClient.zip" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\app.manifest" />
|
||||
<None Include="Start.bat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PsExec.exe">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Icon.ico" />
|
||||
<None Include="Package Creation\7z.dll" />
|
||||
<None Include="Package Creation\7z.exe" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties BuildVersion_UseGlobalSettings="True" BuildVersion_DetectChanges="False" BuildVersion_StartDate="2001/1/1" BuildVersion_BuildAction="ReBuild" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>DEL "$(ProjectDir)Package Creation\PreparationClient.zip"
|
||||
"$(ProjectDir)Package Creation\7z.exe" a -tzip "$(ProjectDir)Package Creation\PreparationClient.zip" "$(TargetDir)*.*" -x!*.tmp -x!*.vshost.* -x!Newtonsoft.Json.xml -x!*.pdb
|
||||
COPY "$(ProjectDir)Package Creation\PreparationClient.zip" "$(ProjectDir)..\Disco.Web\ClientBin"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
+192
-192
@@ -1,192 +1,192 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Disco.Client.Extensions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Disco.Client
|
||||
{
|
||||
public static class ErrorReporting
|
||||
{
|
||||
private const string ServicePathTemplate = "http://DISCO:9292/Services/Client/ClientError";
|
||||
public static string DeviceIdentifier { get; set; }
|
||||
public static string EnrolmentSessionId { get; set; }
|
||||
|
||||
public static void ReportError(Exception Ex, bool ReportToServer)
|
||||
{
|
||||
bool isClientServiceException = Ex is ClientServiceException;
|
||||
|
||||
ErrorReport report = new ErrorReport()
|
||||
{
|
||||
DeviceIdentifier = DeviceIdentifier,
|
||||
SessionId = EnrolmentSessionId,
|
||||
JsonException = Ex.IntenseExceptionSerialization()
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
LogToFile(report);
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
try
|
||||
{
|
||||
LogToEventLog(report);
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
// Don't log server errors back to the server
|
||||
if (!isClientServiceException && ReportToServer)
|
||||
{
|
||||
try
|
||||
{
|
||||
LogToServer(report);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Presentation.WriteFatalError(Ex);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
#region Log Actions
|
||||
|
||||
private static void LogToFile(ErrorReport report)
|
||||
{
|
||||
var logPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ErrorLog.csv");
|
||||
|
||||
using (var streamWriter = File.AppendText(logPath))
|
||||
{
|
||||
streamWriter.Write(DateTime.Now.ToString("s"));
|
||||
streamWriter.Write(",");
|
||||
streamWriter.Write(report.DeviceIdentifier);
|
||||
streamWriter.Write(",\"");
|
||||
streamWriter.Write(report.JsonException);
|
||||
streamWriter.Write("\"");
|
||||
streamWriter.Flush();
|
||||
}
|
||||
}
|
||||
private static void LogToEventLog(ErrorReport report)
|
||||
{
|
||||
string eventSource = "Disco Client";
|
||||
|
||||
if (!EventLog.SourceExists(eventSource))
|
||||
EventLog.CreateEventSource(eventSource, "Application");
|
||||
|
||||
EventLog.WriteEntry(eventSource, report.JsonException, EventLogEntryType.Error, 400);
|
||||
}
|
||||
private static void LogToServer(ErrorReport report)
|
||||
{
|
||||
string reportJson = JsonConvert.SerializeObject(report);
|
||||
string reportResponse;
|
||||
|
||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(ServicePathTemplate);
|
||||
request.UserAgent = string.Format("Disco-Client/{0}", Assembly.GetExecutingAssembly().GetName().Version.ToString(3));
|
||||
request.ContentType = "application/json";
|
||||
request.Method = WebRequestMethods.Http.Post;
|
||||
request.UseDefaultCredentials = true;
|
||||
request.Timeout = 300000; // 5 Minutes
|
||||
|
||||
using (StreamWriter requestWriter = new StreamWriter(request.GetRequestStream()))
|
||||
{
|
||||
requestWriter.Write(reportJson);
|
||||
}
|
||||
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
using (StreamReader responseReader = new StreamReader(response.GetResponseStream()))
|
||||
{
|
||||
reportResponse = responseReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("Error Report Logged to Server; Response: {0}", reportResponse);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public class ErrorReport
|
||||
{
|
||||
public string SessionId { get; set; }
|
||||
public string DeviceIdentifier { get; set; }
|
||||
public string JsonException { get; set; }
|
||||
}
|
||||
|
||||
public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ex = e.ExceptionObject as Exception;
|
||||
if (ex != null)
|
||||
{
|
||||
ReportError(ex, true);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Igore failure to Log Errors
|
||||
}
|
||||
}
|
||||
|
||||
#region Exception Serialization
|
||||
private static string IntenseExceptionSerialization(this Exception Ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return JsonConvert.SerializeObject(Ex);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
var encapsulatedEx = Ex.ToEncapsulatedException();
|
||||
return JsonConvert.SerializeObject(encapsulatedEx);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
var encapsulatedEx = Ex.ToEncapsulatedException(0);
|
||||
return JsonConvert.SerializeObject(encapsulatedEx);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return JsonConvert.SerializeObject(Ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static EncapsulatedException ToEncapsulatedException(this Exception ex, int InnerRecursionDepth = 4)
|
||||
{
|
||||
EncapsulatedException inner = null;
|
||||
if (InnerRecursionDepth > 0 && ex.InnerException != null)
|
||||
inner = ex.InnerException.ToEncapsulatedException(--InnerRecursionDepth);
|
||||
|
||||
return new EncapsulatedException()
|
||||
{
|
||||
EncapsulatedType = ex.GetType().Name,
|
||||
Message = ex.Message,
|
||||
StackTrace = ex.StackTrace,
|
||||
InnerException = inner
|
||||
};
|
||||
}
|
||||
public class EncapsulatedException
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public string EncapsulatedType { get; set; }
|
||||
public string StackTrace { get; set; }
|
||||
public EncapsulatedException InnerException { get; set; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Disco.Client.Extensions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Disco.Client
|
||||
{
|
||||
public static class ErrorReporting
|
||||
{
|
||||
private const string ServicePathTemplate = "http://DISCO:9292/Services/Client/ClientError";
|
||||
public static string DeviceIdentifier { get; set; }
|
||||
public static string EnrolmentSessionId { get; set; }
|
||||
|
||||
public static void ReportError(Exception Ex, bool ReportToServer)
|
||||
{
|
||||
bool isClientServiceException = Ex is ClientServiceException;
|
||||
|
||||
ErrorReport report = new ErrorReport()
|
||||
{
|
||||
DeviceIdentifier = DeviceIdentifier,
|
||||
SessionId = EnrolmentSessionId,
|
||||
JsonException = Ex.IntenseExceptionSerialization()
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
LogToFile(report);
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
try
|
||||
{
|
||||
LogToEventLog(report);
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
// Don't log server errors back to the server
|
||||
if (!isClientServiceException && ReportToServer)
|
||||
{
|
||||
try
|
||||
{
|
||||
LogToServer(report);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Presentation.WriteFatalError(Ex);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
#region Log Actions
|
||||
|
||||
private static void LogToFile(ErrorReport report)
|
||||
{
|
||||
var logPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ErrorLog.csv");
|
||||
|
||||
using (var streamWriter = File.AppendText(logPath))
|
||||
{
|
||||
streamWriter.Write(DateTime.Now.ToString("s"));
|
||||
streamWriter.Write(",");
|
||||
streamWriter.Write(report.DeviceIdentifier);
|
||||
streamWriter.Write(",\"");
|
||||
streamWriter.Write(report.JsonException);
|
||||
streamWriter.Write("\"");
|
||||
streamWriter.Flush();
|
||||
}
|
||||
}
|
||||
private static void LogToEventLog(ErrorReport report)
|
||||
{
|
||||
string eventSource = "Disco Client";
|
||||
|
||||
if (!EventLog.SourceExists(eventSource))
|
||||
EventLog.CreateEventSource(eventSource, "Application");
|
||||
|
||||
EventLog.WriteEntry(eventSource, report.JsonException, EventLogEntryType.Error, 400);
|
||||
}
|
||||
private static void LogToServer(ErrorReport report)
|
||||
{
|
||||
string reportJson = JsonConvert.SerializeObject(report);
|
||||
string reportResponse;
|
||||
|
||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(ServicePathTemplate);
|
||||
request.UserAgent = string.Format("Disco-Client/{0}", Assembly.GetExecutingAssembly().GetName().Version.ToString(3));
|
||||
request.ContentType = "application/json";
|
||||
request.Method = WebRequestMethods.Http.Post;
|
||||
request.UseDefaultCredentials = true;
|
||||
request.Timeout = 300000; // 5 Minutes
|
||||
|
||||
using (StreamWriter requestWriter = new StreamWriter(request.GetRequestStream()))
|
||||
{
|
||||
requestWriter.Write(reportJson);
|
||||
}
|
||||
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
using (StreamReader responseReader = new StreamReader(response.GetResponseStream()))
|
||||
{
|
||||
reportResponse = responseReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("Error Report Logged to Server; Response: {0}", reportResponse);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public class ErrorReport
|
||||
{
|
||||
public string SessionId { get; set; }
|
||||
public string DeviceIdentifier { get; set; }
|
||||
public string JsonException { get; set; }
|
||||
}
|
||||
|
||||
public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ex = e.ExceptionObject as Exception;
|
||||
if (ex != null)
|
||||
{
|
||||
ReportError(ex, true);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Igore failure to Log Errors
|
||||
}
|
||||
}
|
||||
|
||||
#region Exception Serialization
|
||||
private static string IntenseExceptionSerialization(this Exception Ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return JsonConvert.SerializeObject(Ex);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
var encapsulatedEx = Ex.ToEncapsulatedException();
|
||||
return JsonConvert.SerializeObject(encapsulatedEx);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
var encapsulatedEx = Ex.ToEncapsulatedException(0);
|
||||
return JsonConvert.SerializeObject(encapsulatedEx);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return JsonConvert.SerializeObject(Ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static EncapsulatedException ToEncapsulatedException(this Exception ex, int InnerRecursionDepth = 4)
|
||||
{
|
||||
EncapsulatedException inner = null;
|
||||
if (InnerRecursionDepth > 0 && ex.InnerException != null)
|
||||
inner = ex.InnerException.ToEncapsulatedException(--InnerRecursionDepth);
|
||||
|
||||
return new EncapsulatedException()
|
||||
{
|
||||
EncapsulatedType = ex.GetType().Name,
|
||||
Message = ex.Message,
|
||||
StackTrace = ex.StackTrace,
|
||||
InnerException = inner
|
||||
};
|
||||
}
|
||||
public class EncapsulatedException
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public string EncapsulatedType { get; set; }
|
||||
public string StackTrace { get; set; }
|
||||
public EncapsulatedException InnerException { get; set; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Client.Extensions
|
||||
{
|
||||
public class ClientServiceException : Exception
|
||||
{
|
||||
public string ServiceFeature { get; private set; }
|
||||
|
||||
public ClientServiceException(string ServiceFeature, string ServerMessage) : base(ServerMessage)
|
||||
{
|
||||
this.ServiceFeature = ServiceFeature;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Client.Extensions
|
||||
{
|
||||
public class ClientServiceException : Exception
|
||||
{
|
||||
public string ServiceFeature { get; private set; }
|
||||
|
||||
public ClientServiceException(string ServiceFeature, string ServerMessage) : base(ServerMessage)
|
||||
{
|
||||
this.ServiceFeature = ServiceFeature;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Disco.Models.ClientServices;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Disco.Client.Extensions
|
||||
{
|
||||
public static class ClientServicesExtensions
|
||||
{
|
||||
public const string ServicePathAuthenticatedTemplate = "http://DISCO:9292/Services/Client/Authenticated/{0}";
|
||||
public const string ServicePathUnauthenticatedTemplate = "http://DISCO:9292/Services/Client/Unauthenticated/{0}";
|
||||
|
||||
public static ResponseType Post<ResponseType>(this ServiceBase<ResponseType> Service, bool Authenticated)
|
||||
{
|
||||
string jsonResponse;
|
||||
string serviceUrl;
|
||||
if (Authenticated)
|
||||
serviceUrl = string.Format(ServicePathAuthenticatedTemplate, Service.Feature);
|
||||
else
|
||||
serviceUrl = string.Format(ServicePathUnauthenticatedTemplate, Service.Feature);
|
||||
|
||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceUrl);
|
||||
request.UserAgent = string.Format("Disco-Client/{0}", Assembly.GetExecutingAssembly().GetName().Version.ToString(3));
|
||||
request.ContentType = "application/json";
|
||||
request.Method = WebRequestMethods.Http.Post;
|
||||
request.UseDefaultCredentials = true;
|
||||
request.Timeout = 300000; // 5 Minutes
|
||||
string jsonRequest = JsonConvert.SerializeObject(Service);
|
||||
|
||||
using (StreamWriter requestWriter = new StreamWriter(request.GetRequestStream()))
|
||||
{
|
||||
requestWriter.Write(jsonRequest);
|
||||
}
|
||||
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
using (StreamReader responseReader = new StreamReader(response.GetResponseStream()))
|
||||
{
|
||||
jsonResponse = responseReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(jsonResponse))
|
||||
return default(ResponseType);
|
||||
else
|
||||
return JsonConvert.DeserializeObject<ResponseType>(jsonResponse);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Disco.Models.ClientServices;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Disco.Client.Extensions
|
||||
{
|
||||
public static class ClientServicesExtensions
|
||||
{
|
||||
public const string ServicePathAuthenticatedTemplate = "http://DISCO:9292/Services/Client/Authenticated/{0}";
|
||||
public const string ServicePathUnauthenticatedTemplate = "http://DISCO:9292/Services/Client/Unauthenticated/{0}";
|
||||
|
||||
public static ResponseType Post<ResponseType>(this ServiceBase<ResponseType> Service, bool Authenticated)
|
||||
{
|
||||
string jsonResponse;
|
||||
string serviceUrl;
|
||||
if (Authenticated)
|
||||
serviceUrl = string.Format(ServicePathAuthenticatedTemplate, Service.Feature);
|
||||
else
|
||||
serviceUrl = string.Format(ServicePathUnauthenticatedTemplate, Service.Feature);
|
||||
|
||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceUrl);
|
||||
request.UserAgent = string.Format("Disco-Client/{0}", Assembly.GetExecutingAssembly().GetName().Version.ToString(3));
|
||||
request.ContentType = "application/json";
|
||||
request.Method = WebRequestMethods.Http.Post;
|
||||
request.UseDefaultCredentials = true;
|
||||
request.Timeout = 300000; // 5 Minutes
|
||||
string jsonRequest = JsonConvert.SerializeObject(Service);
|
||||
|
||||
using (StreamWriter requestWriter = new StreamWriter(request.GetRequestStream()))
|
||||
{
|
||||
requestWriter.Write(jsonRequest);
|
||||
}
|
||||
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
using (StreamReader responseReader = new StreamReader(response.GetResponseStream()))
|
||||
{
|
||||
jsonResponse = responseReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(jsonResponse))
|
||||
return default(ResponseType);
|
||||
else
|
||||
return JsonConvert.DeserializeObject<ResponseType>(jsonResponse);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,188 +1,188 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Disco.Models.ClientServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Win32;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Disco.Client.Extensions
|
||||
{
|
||||
public static class EnrolExtensions
|
||||
{
|
||||
|
||||
public static void Build(this Enrol enrol)
|
||||
{
|
||||
enrol.DeviceUUID = Interop.SystemAudit.DeviceUUID;
|
||||
enrol.DeviceSerialNumber = Interop.SystemAudit.DeviceSerialNumber;
|
||||
|
||||
enrol.DeviceComputerName = Interop.LocalAuthentication.ComputerName;
|
||||
|
||||
enrol.DeviceManufacturer = Interop.SystemAudit.DeviceManufacturer;
|
||||
enrol.DeviceModel = Interop.SystemAudit.DeviceModel;
|
||||
enrol.DeviceModelType = Interop.SystemAudit.DeviceType;
|
||||
|
||||
enrol.DeviceIsPartOfDomain = Interop.SystemAudit.DeviceIsPartOfDomain;
|
||||
|
||||
// LAN
|
||||
enrol.DeviceLanMacAddress = Interop.Network.PrimaryLanMacAddress;
|
||||
|
||||
// WAN
|
||||
enrol.DeviceWlanMacAddress = Interop.Network.PrimaryWlanMacAddress;
|
||||
|
||||
// Certificates
|
||||
enrol.DeviceCertificates = Interop.Certificates.GetCertificateSubjects(StoreName.My, StoreLocation.LocalMachine);
|
||||
}
|
||||
|
||||
public static void Process(this EnrolResponse enrolResponse)
|
||||
{
|
||||
if (enrolResponse == null)
|
||||
throw new ClientServiceException("Enrolment", "Server denied enrolment (Empty Response)");
|
||||
|
||||
ErrorReporting.EnrolmentSessionId = enrolResponse.SessionId;
|
||||
|
||||
if (!string.IsNullOrEmpty(enrolResponse.ErrorMessage))
|
||||
throw new ClientServiceException("Enrolment", enrolResponse.ErrorMessage);
|
||||
|
||||
// Offline Domain Join
|
||||
bool requireReboot = enrolResponse.ApplyOfflineDomainJoin();
|
||||
|
||||
// Certificates
|
||||
enrolResponse.ApplyDeviceCertificates();
|
||||
|
||||
// Device Owner
|
||||
enrolResponse.ApplyDeviceAssignedUser();
|
||||
|
||||
|
||||
Presentation.UpdateStatus("Enrolling Device", "Device Enrolment Successfully Completed", false, 0, 1500);
|
||||
|
||||
Program.RebootRequired = requireReboot;
|
||||
Program.AllowUninstall = enrolResponse.AllowBootstrapperUninstall;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a Client Service Enrol Response for Offline Domain Join Actions
|
||||
/// </summary>
|
||||
/// <param name="enrolResponse"></param>
|
||||
/// <returns>Boolean indicating whether a reboot is required.</returns>
|
||||
private static bool ApplyOfflineDomainJoin(this EnrolResponse enrolResponse)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(enrolResponse.OfflineDomainJoin))
|
||||
{
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Performing Offline Domain Join:{0}Renaming Computer: {1} -> {2}", Environment.NewLine, Interop.LocalAuthentication.ComputerName, enrolResponse.DeviceComputerName), true, -1, 1500);
|
||||
|
||||
string odjFile = Path.GetTempFileName();
|
||||
File.WriteAllBytes(odjFile, Convert.FromBase64String(enrolResponse.OfflineDomainJoin));
|
||||
|
||||
string odjWindowsPath = Environment.GetEnvironmentVariable("SystemRoot");
|
||||
string odjProcessArguments = string.Format("/REQUESTODJ /LOADFILE \"{0}\" /WINDOWSPATH \"{1}\" /LOCALOS", odjFile, odjWindowsPath);
|
||||
|
||||
ProcessStartInfo odjProcessStartInfo = new ProcessStartInfo("DJOIN.EXE", odjProcessArguments)
|
||||
{
|
||||
CreateNoWindow = true,
|
||||
ErrorDialog = false,
|
||||
LoadUserProfile = true,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
string odjResult;
|
||||
using (Process odjProcess = System.Diagnostics.Process.Start(odjProcessStartInfo))
|
||||
{
|
||||
odjResult = odjProcess.StandardOutput.ReadToEnd();
|
||||
odjProcess.WaitForExit(20000); // 20 Seconds
|
||||
}
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Offline Domain Join Result:{0}{1}", Environment.NewLine, odjResult), true, -1, 3000);
|
||||
|
||||
if (File.Exists(odjFile))
|
||||
File.Delete(odjFile);
|
||||
|
||||
// Flush Logged-On History
|
||||
if (!string.IsNullOrEmpty(enrolResponse.DeviceDomainName))
|
||||
{
|
||||
using (RegistryKey regWinlogon = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true)){
|
||||
regWinlogon.SetValue("DefaultDomainName", enrolResponse.DeviceDomainName, RegistryValueKind.String);
|
||||
regWinlogon.SetValue("DefaultUserName", String.Empty, RegistryValueKind.String);
|
||||
}
|
||||
using (RegistryKey regLogonUI = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI", true))
|
||||
{
|
||||
regLogonUI.DeleteValue("LastLoggedOnUser", false);
|
||||
}
|
||||
}
|
||||
|
||||
return true; // Reboot required
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Domain Join
|
||||
return false; // Reboot not required
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a Client Service Enrol Response for Device Assigned User Actions
|
||||
/// </summary>
|
||||
/// <param name="enrolResponse"></param>
|
||||
private static void ApplyDeviceAssignedUser(this EnrolResponse enrolResponse)
|
||||
{
|
||||
// Only run task if Assigned User was specified
|
||||
if (!string.IsNullOrWhiteSpace(enrolResponse.DeviceAssignedUserSID))
|
||||
{
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format(@"Configuring permissions for the device owner:{0}{1} ({2}\{3})", Environment.NewLine, enrolResponse.DeviceAssignedUserName, enrolResponse.DeviceAssignedUserDomain, enrolResponse.DeviceAssignedUserUsername), true, -1, 3000);
|
||||
|
||||
Interop.LocalAuthentication.AddLocalGroupMembership("Administrators", enrolResponse.DeviceAssignedUserSID, enrolResponse.DeviceAssignedUserUsername, enrolResponse.DeviceAssignedUserDomain);
|
||||
|
||||
// Make Windows think this user was the last to logon
|
||||
using (RegistryKey regWinlogon = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true))
|
||||
{
|
||||
regWinlogon.SetValue("DefaultDomainName", enrolResponse.DeviceAssignedUserDomain, RegistryValueKind.String);
|
||||
regWinlogon.SetValue("DefaultUserName", enrolResponse.DeviceAssignedUserUsername, RegistryValueKind.String);
|
||||
}
|
||||
using (RegistryKey regLogonUI = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI", true))
|
||||
{
|
||||
regLogonUI.SetValue("LastLoggedOnUser", string.Format(@"{0}\{1}", enrolResponse.DeviceAssignedUserDomain, enrolResponse.DeviceAssignedUserUsername), RegistryValueKind.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a Client Service Enrol Response for Device Certificate Actions
|
||||
/// </summary>
|
||||
/// <param name="enrolResponse"></param>
|
||||
private static void ApplyDeviceCertificates(this EnrolResponse enrolResponse)
|
||||
{
|
||||
// Only run if a Certificate was supplied
|
||||
if (!string.IsNullOrEmpty(enrolResponse.DeviceCertificate))
|
||||
{
|
||||
Presentation.UpdateStatus("Enrolling Device", "Configuring Wireless Certificates", true, -1, 1000);
|
||||
|
||||
var certPersonalBytes = Convert.FromBase64String(enrolResponse.DeviceCertificate);
|
||||
var certPersonal = new X509Certificate2(certPersonalBytes, "password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
|
||||
if (certPersonal == null)
|
||||
throw new ClientServiceException("Enrolment > Device Certificate", "Unable to Import Device Certificate Provided, possibly check password.");
|
||||
|
||||
// Certificate Removal
|
||||
if (enrolResponse.DeviceCertificateRemoveExisting != null && enrolResponse.DeviceCertificateRemoveExisting.Count > 0)
|
||||
{
|
||||
List<Regex> regExMatchesSubject = new List<Regex>();
|
||||
foreach (var subjectRegEx in enrolResponse.DeviceCertificateRemoveExisting)
|
||||
regExMatchesSubject.Add(new Regex(subjectRegEx, RegexOptions.IgnoreCase));
|
||||
|
||||
// Remove from 'My' Store
|
||||
Interop.Certificates.RemoveCertificates(StoreName.My, StoreLocation.LocalMachine, regExMatchesSubject, certPersonal);
|
||||
// Remove from 'Root' Store
|
||||
Interop.Certificates.RemoveCertificates(StoreName.Root, StoreLocation.LocalMachine, regExMatchesSubject, certPersonal);
|
||||
// Remove from 'CertificateAuthority' Store
|
||||
Interop.Certificates.RemoveCertificates(StoreName.CertificateAuthority, StoreLocation.LocalMachine, regExMatchesSubject, certPersonal);
|
||||
}
|
||||
|
||||
// Add Certificate
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Configuring Wireless Certificates{0}Installing Certificate: {1}", Environment.NewLine, Interop.Certificates.GetCertificateFriendlyName(certPersonal)), true, -1);
|
||||
Interop.Certificates.AddCertificate(StoreName.My, StoreLocation.LocalMachine, certPersonal);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Disco.Models.ClientServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Win32;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Disco.Client.Extensions
|
||||
{
|
||||
public static class EnrolExtensions
|
||||
{
|
||||
|
||||
public static void Build(this Enrol enrol)
|
||||
{
|
||||
enrol.DeviceUUID = Interop.SystemAudit.DeviceUUID;
|
||||
enrol.DeviceSerialNumber = Interop.SystemAudit.DeviceSerialNumber;
|
||||
|
||||
enrol.DeviceComputerName = Interop.LocalAuthentication.ComputerName;
|
||||
|
||||
enrol.DeviceManufacturer = Interop.SystemAudit.DeviceManufacturer;
|
||||
enrol.DeviceModel = Interop.SystemAudit.DeviceModel;
|
||||
enrol.DeviceModelType = Interop.SystemAudit.DeviceType;
|
||||
|
||||
enrol.DeviceIsPartOfDomain = Interop.SystemAudit.DeviceIsPartOfDomain;
|
||||
|
||||
// LAN
|
||||
enrol.DeviceLanMacAddress = Interop.Network.PrimaryLanMacAddress;
|
||||
|
||||
// WAN
|
||||
enrol.DeviceWlanMacAddress = Interop.Network.PrimaryWlanMacAddress;
|
||||
|
||||
// Certificates
|
||||
enrol.DeviceCertificates = Interop.Certificates.GetCertificateSubjects(StoreName.My, StoreLocation.LocalMachine);
|
||||
}
|
||||
|
||||
public static void Process(this EnrolResponse enrolResponse)
|
||||
{
|
||||
if (enrolResponse == null)
|
||||
throw new ClientServiceException("Enrolment", "Server denied enrolment (Empty Response)");
|
||||
|
||||
ErrorReporting.EnrolmentSessionId = enrolResponse.SessionId;
|
||||
|
||||
if (!string.IsNullOrEmpty(enrolResponse.ErrorMessage))
|
||||
throw new ClientServiceException("Enrolment", enrolResponse.ErrorMessage);
|
||||
|
||||
// Offline Domain Join
|
||||
bool requireReboot = enrolResponse.ApplyOfflineDomainJoin();
|
||||
|
||||
// Certificates
|
||||
enrolResponse.ApplyDeviceCertificates();
|
||||
|
||||
// Device Owner
|
||||
enrolResponse.ApplyDeviceAssignedUser();
|
||||
|
||||
|
||||
Presentation.UpdateStatus("Enrolling Device", "Device Enrolment Successfully Completed", false, 0, 1500);
|
||||
|
||||
Program.RebootRequired = requireReboot;
|
||||
Program.AllowUninstall = enrolResponse.AllowBootstrapperUninstall;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a Client Service Enrol Response for Offline Domain Join Actions
|
||||
/// </summary>
|
||||
/// <param name="enrolResponse"></param>
|
||||
/// <returns>Boolean indicating whether a reboot is required.</returns>
|
||||
private static bool ApplyOfflineDomainJoin(this EnrolResponse enrolResponse)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(enrolResponse.OfflineDomainJoin))
|
||||
{
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Performing Offline Domain Join:{0}Renaming Computer: {1} -> {2}", Environment.NewLine, Interop.LocalAuthentication.ComputerName, enrolResponse.DeviceComputerName), true, -1, 1500);
|
||||
|
||||
string odjFile = Path.GetTempFileName();
|
||||
File.WriteAllBytes(odjFile, Convert.FromBase64String(enrolResponse.OfflineDomainJoin));
|
||||
|
||||
string odjWindowsPath = Environment.GetEnvironmentVariable("SystemRoot");
|
||||
string odjProcessArguments = string.Format("/REQUESTODJ /LOADFILE \"{0}\" /WINDOWSPATH \"{1}\" /LOCALOS", odjFile, odjWindowsPath);
|
||||
|
||||
ProcessStartInfo odjProcessStartInfo = new ProcessStartInfo("DJOIN.EXE", odjProcessArguments)
|
||||
{
|
||||
CreateNoWindow = true,
|
||||
ErrorDialog = false,
|
||||
LoadUserProfile = true,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
string odjResult;
|
||||
using (Process odjProcess = System.Diagnostics.Process.Start(odjProcessStartInfo))
|
||||
{
|
||||
odjResult = odjProcess.StandardOutput.ReadToEnd();
|
||||
odjProcess.WaitForExit(20000); // 20 Seconds
|
||||
}
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Offline Domain Join Result:{0}{1}", Environment.NewLine, odjResult), true, -1, 3000);
|
||||
|
||||
if (File.Exists(odjFile))
|
||||
File.Delete(odjFile);
|
||||
|
||||
// Flush Logged-On History
|
||||
if (!string.IsNullOrEmpty(enrolResponse.DeviceDomainName))
|
||||
{
|
||||
using (RegistryKey regWinlogon = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true)){
|
||||
regWinlogon.SetValue("DefaultDomainName", enrolResponse.DeviceDomainName, RegistryValueKind.String);
|
||||
regWinlogon.SetValue("DefaultUserName", String.Empty, RegistryValueKind.String);
|
||||
}
|
||||
using (RegistryKey regLogonUI = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI", true))
|
||||
{
|
||||
regLogonUI.DeleteValue("LastLoggedOnUser", false);
|
||||
}
|
||||
}
|
||||
|
||||
return true; // Reboot required
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Domain Join
|
||||
return false; // Reboot not required
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a Client Service Enrol Response for Device Assigned User Actions
|
||||
/// </summary>
|
||||
/// <param name="enrolResponse"></param>
|
||||
private static void ApplyDeviceAssignedUser(this EnrolResponse enrolResponse)
|
||||
{
|
||||
// Only run task if Assigned User was specified
|
||||
if (!string.IsNullOrWhiteSpace(enrolResponse.DeviceAssignedUserSID))
|
||||
{
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format(@"Configuring permissions for the device owner:{0}{1} ({2}\{3})", Environment.NewLine, enrolResponse.DeviceAssignedUserName, enrolResponse.DeviceAssignedUserDomain, enrolResponse.DeviceAssignedUserUsername), true, -1, 3000);
|
||||
|
||||
Interop.LocalAuthentication.AddLocalGroupMembership("Administrators", enrolResponse.DeviceAssignedUserSID, enrolResponse.DeviceAssignedUserUsername, enrolResponse.DeviceAssignedUserDomain);
|
||||
|
||||
// Make Windows think this user was the last to logon
|
||||
using (RegistryKey regWinlogon = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true))
|
||||
{
|
||||
regWinlogon.SetValue("DefaultDomainName", enrolResponse.DeviceAssignedUserDomain, RegistryValueKind.String);
|
||||
regWinlogon.SetValue("DefaultUserName", enrolResponse.DeviceAssignedUserUsername, RegistryValueKind.String);
|
||||
}
|
||||
using (RegistryKey regLogonUI = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI", true))
|
||||
{
|
||||
regLogonUI.SetValue("LastLoggedOnUser", string.Format(@"{0}\{1}", enrolResponse.DeviceAssignedUserDomain, enrolResponse.DeviceAssignedUserUsername), RegistryValueKind.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a Client Service Enrol Response for Device Certificate Actions
|
||||
/// </summary>
|
||||
/// <param name="enrolResponse"></param>
|
||||
private static void ApplyDeviceCertificates(this EnrolResponse enrolResponse)
|
||||
{
|
||||
// Only run if a Certificate was supplied
|
||||
if (!string.IsNullOrEmpty(enrolResponse.DeviceCertificate))
|
||||
{
|
||||
Presentation.UpdateStatus("Enrolling Device", "Configuring Wireless Certificates", true, -1, 1000);
|
||||
|
||||
var certPersonalBytes = Convert.FromBase64String(enrolResponse.DeviceCertificate);
|
||||
var certPersonal = new X509Certificate2(certPersonalBytes, "password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
|
||||
if (certPersonal == null)
|
||||
throw new ClientServiceException("Enrolment > Device Certificate", "Unable to Import Device Certificate Provided, possibly check password.");
|
||||
|
||||
// Certificate Removal
|
||||
if (enrolResponse.DeviceCertificateRemoveExisting != null && enrolResponse.DeviceCertificateRemoveExisting.Count > 0)
|
||||
{
|
||||
List<Regex> regExMatchesSubject = new List<Regex>();
|
||||
foreach (var subjectRegEx in enrolResponse.DeviceCertificateRemoveExisting)
|
||||
regExMatchesSubject.Add(new Regex(subjectRegEx, RegexOptions.IgnoreCase));
|
||||
|
||||
// Remove from 'My' Store
|
||||
Interop.Certificates.RemoveCertificates(StoreName.My, StoreLocation.LocalMachine, regExMatchesSubject, certPersonal);
|
||||
// Remove from 'Root' Store
|
||||
Interop.Certificates.RemoveCertificates(StoreName.Root, StoreLocation.LocalMachine, regExMatchesSubject, certPersonal);
|
||||
// Remove from 'CertificateAuthority' Store
|
||||
Interop.Certificates.RemoveCertificates(StoreName.CertificateAuthority, StoreLocation.LocalMachine, regExMatchesSubject, certPersonal);
|
||||
}
|
||||
|
||||
// Add Certificate
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Configuring Wireless Certificates{0}Installing Certificate: {1}", Environment.NewLine, Interop.Certificates.GetCertificateFriendlyName(certPersonal)), true, -1);
|
||||
Interop.Certificates.AddCertificate(StoreName.My, StoreLocation.LocalMachine, certPersonal);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Disco.Models.ClientServices;
|
||||
|
||||
namespace Disco.Client.Extensions
|
||||
{
|
||||
public static class WhoAmIExtensions
|
||||
{
|
||||
|
||||
public static void Process(this WhoAmIResponse whoAmIResponse)
|
||||
{
|
||||
Program.IsAuthenticated = true;
|
||||
whoAmIResponse.PresentResponse();
|
||||
}
|
||||
|
||||
private static void PresentResponse(this WhoAmIResponse whoAmIResponse)
|
||||
{
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.AppendLine("Authenticated Connection:");
|
||||
message.Append("Username: ").AppendLine(whoAmIResponse.Username);
|
||||
message.Append("Name: ").Append(whoAmIResponse.DisplayName);
|
||||
message.Append(" (").Append(whoAmIResponse.Type).AppendLine(")");
|
||||
Presentation.UpdateStatus("Connection Established to Preparation Server", message.ToString(), false, 0, 1500);
|
||||
}
|
||||
public static void UnauthenticatedResponse()
|
||||
{
|
||||
Program.IsAuthenticated = false;
|
||||
Presentation.UpdateStatus("Connection Established to Preparation Server", "Unauthenticated connection to the server...", false, 0, 1500);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Disco.Models.ClientServices;
|
||||
|
||||
namespace Disco.Client.Extensions
|
||||
{
|
||||
public static class WhoAmIExtensions
|
||||
{
|
||||
|
||||
public static void Process(this WhoAmIResponse whoAmIResponse)
|
||||
{
|
||||
Program.IsAuthenticated = true;
|
||||
whoAmIResponse.PresentResponse();
|
||||
}
|
||||
|
||||
private static void PresentResponse(this WhoAmIResponse whoAmIResponse)
|
||||
{
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.AppendLine("Authenticated Connection:");
|
||||
message.Append("Username: ").AppendLine(whoAmIResponse.Username);
|
||||
message.Append("Name: ").Append(whoAmIResponse.DisplayName);
|
||||
message.Append(" (").Append(whoAmIResponse.Type).AppendLine(")");
|
||||
Presentation.UpdateStatus("Connection Established to Preparation Server", message.ToString(), false, 0, 1500);
|
||||
}
|
||||
public static void UnauthenticatedResponse()
|
||||
{
|
||||
Program.IsAuthenticated = false;
|
||||
Presentation.UpdateStatus("Connection Established to Preparation Server", "Unauthenticated connection to the server...", false, 0, 1500);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,103 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Disco.Client.Interop
|
||||
{
|
||||
public static class Certificates
|
||||
{
|
||||
|
||||
public static string GetCertificateFriendlyName(X509Certificate2 Certificate)
|
||||
{
|
||||
string subject = Certificate.Subject;
|
||||
return subject.Substring(subject.IndexOf("=") + 1, subject.IndexOf(",") - subject.IndexOf("=") - 1);
|
||||
}
|
||||
|
||||
public static List<string> GetCertificateSubjects(StoreName StoreName, StoreLocation StoreLocation)
|
||||
{
|
||||
X509Store certStore = new X509Store(StoreName, StoreLocation);
|
||||
certStore.Open(OpenFlags.ReadOnly);
|
||||
var certSubjects = certStore.Certificates.Cast<X509Certificate2>().Select(c => c.Subject).ToList();
|
||||
certStore.Close();
|
||||
return certSubjects;
|
||||
}
|
||||
|
||||
public static bool AddCertificate(StoreName StoreName, StoreLocation StoreLocation, X509Certificate2 Certificate)
|
||||
{
|
||||
X509Store certStore = new X509Store(StoreName, StoreLocation);
|
||||
bool certAlreadyAdded = false;
|
||||
|
||||
certStore.Open(OpenFlags.ReadWrite);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (X509Certificate2 cert in certStore.Certificates)
|
||||
{
|
||||
if (cert.SerialNumber.Equals(Certificate.SerialNumber))
|
||||
{
|
||||
certAlreadyAdded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!certAlreadyAdded)
|
||||
{
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Configuring Wireless Certificates{0}Adding Certificate: '{1}' from {2}@{3}", Environment.NewLine, GetCertificateFriendlyName(Certificate), StoreName.ToString(), StoreLocation.ToString()), true, -1, 3000);
|
||||
certStore.Add(Certificate);
|
||||
}
|
||||
}
|
||||
catch (Exception) { throw; }
|
||||
finally
|
||||
{
|
||||
certStore.Close();
|
||||
}
|
||||
|
||||
return !certAlreadyAdded;
|
||||
}
|
||||
|
||||
public static List<string> RemoveCertificates(StoreName StoreName, StoreLocation StoreLocation, List<Regex> RegExMatchesSubject, X509Certificate2 CertificateException)
|
||||
{
|
||||
X509Store certStore = new X509Store(StoreName, StoreLocation);
|
||||
List<string> results = new List<string>();
|
||||
List<X509Certificate2> certStoreRemove = new List<X509Certificate2>();
|
||||
|
||||
certStore.Open(OpenFlags.ReadWrite);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (X509Certificate2 cert in certStore.Certificates)
|
||||
{
|
||||
if (!cert.SerialNumber.Equals(CertificateException.SerialNumber))
|
||||
{
|
||||
foreach (var subjectRegEx in RegExMatchesSubject)
|
||||
{
|
||||
if (subjectRegEx.IsMatch(cert.Subject))
|
||||
{
|
||||
certStoreRemove.Add(cert);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var cert in certStoreRemove)
|
||||
{
|
||||
results.Add(cert.Subject);
|
||||
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Configuring Wireless Certificates{0}Removing Certificate: '{1}' from {2}@{3}", Environment.NewLine, GetCertificateFriendlyName(cert), StoreName.ToString(), StoreLocation.ToString()), true, -1, 1500);
|
||||
certStore.Remove(cert);
|
||||
}
|
||||
}
|
||||
catch (Exception) { throw; }
|
||||
finally
|
||||
{
|
||||
certStore.Close();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Disco.Client.Interop
|
||||
{
|
||||
public static class Certificates
|
||||
{
|
||||
|
||||
public static string GetCertificateFriendlyName(X509Certificate2 Certificate)
|
||||
{
|
||||
string subject = Certificate.Subject;
|
||||
return subject.Substring(subject.IndexOf("=") + 1, subject.IndexOf(",") - subject.IndexOf("=") - 1);
|
||||
}
|
||||
|
||||
public static List<string> GetCertificateSubjects(StoreName StoreName, StoreLocation StoreLocation)
|
||||
{
|
||||
X509Store certStore = new X509Store(StoreName, StoreLocation);
|
||||
certStore.Open(OpenFlags.ReadOnly);
|
||||
var certSubjects = certStore.Certificates.Cast<X509Certificate2>().Select(c => c.Subject).ToList();
|
||||
certStore.Close();
|
||||
return certSubjects;
|
||||
}
|
||||
|
||||
public static bool AddCertificate(StoreName StoreName, StoreLocation StoreLocation, X509Certificate2 Certificate)
|
||||
{
|
||||
X509Store certStore = new X509Store(StoreName, StoreLocation);
|
||||
bool certAlreadyAdded = false;
|
||||
|
||||
certStore.Open(OpenFlags.ReadWrite);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (X509Certificate2 cert in certStore.Certificates)
|
||||
{
|
||||
if (cert.SerialNumber.Equals(Certificate.SerialNumber))
|
||||
{
|
||||
certAlreadyAdded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!certAlreadyAdded)
|
||||
{
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Configuring Wireless Certificates{0}Adding Certificate: '{1}' from {2}@{3}", Environment.NewLine, GetCertificateFriendlyName(Certificate), StoreName.ToString(), StoreLocation.ToString()), true, -1, 3000);
|
||||
certStore.Add(Certificate);
|
||||
}
|
||||
}
|
||||
catch (Exception) { throw; }
|
||||
finally
|
||||
{
|
||||
certStore.Close();
|
||||
}
|
||||
|
||||
return !certAlreadyAdded;
|
||||
}
|
||||
|
||||
public static List<string> RemoveCertificates(StoreName StoreName, StoreLocation StoreLocation, List<Regex> RegExMatchesSubject, X509Certificate2 CertificateException)
|
||||
{
|
||||
X509Store certStore = new X509Store(StoreName, StoreLocation);
|
||||
List<string> results = new List<string>();
|
||||
List<X509Certificate2> certStoreRemove = new List<X509Certificate2>();
|
||||
|
||||
certStore.Open(OpenFlags.ReadWrite);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (X509Certificate2 cert in certStore.Certificates)
|
||||
{
|
||||
if (!cert.SerialNumber.Equals(CertificateException.SerialNumber))
|
||||
{
|
||||
foreach (var subjectRegEx in RegExMatchesSubject)
|
||||
{
|
||||
if (subjectRegEx.IsMatch(cert.Subject))
|
||||
{
|
||||
certStoreRemove.Add(cert);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var cert in certStoreRemove)
|
||||
{
|
||||
results.Add(cert.Subject);
|
||||
|
||||
Presentation.UpdateStatus("Enrolling Device", string.Format("Configuring Wireless Certificates{0}Removing Certificate: '{1}' from {2}@{3}", Environment.NewLine, GetCertificateFriendlyName(cert), StoreName.ToString(), StoreLocation.ToString()), true, -1, 1500);
|
||||
certStore.Remove(cert);
|
||||
}
|
||||
}
|
||||
catch (Exception) { throw; }
|
||||
finally
|
||||
{
|
||||
certStore.Close();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.DirectoryServices;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Client.Interop
|
||||
{
|
||||
public static class LocalAuthentication
|
||||
{
|
||||
|
||||
public static bool AddLocalGroupMembership(string GroupName, string UserSID, string Username, string UserDomain)
|
||||
{
|
||||
|
||||
using (DirectoryEntry group = new DirectoryEntry(string.Format("WinNT://./{0},group", GroupName)))
|
||||
{
|
||||
// Check to see if the User is already a member
|
||||
foreach (object memberRef in (IEnumerable)group.Invoke("Members"))
|
||||
{
|
||||
using (DirectoryEntry member = new DirectoryEntry(memberRef))
|
||||
{
|
||||
var memberPath = member.Path;
|
||||
if (memberPath.Equals(string.Format("WinNT://{0}/{1}", UserDomain, Username), StringComparison.InvariantCultureIgnoreCase) ||
|
||||
memberPath.Equals(string.Format("WinNT://{0}", UserSID), StringComparison.InvariantCultureIgnoreCase))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
group.Invoke("Add", string.Format("WinNT://{0}", UserSID));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string CurrentUserDomain
|
||||
{
|
||||
get
|
||||
{
|
||||
return Environment.UserDomainName;
|
||||
}
|
||||
}
|
||||
public static string CurrentUserName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Environment.UserName;
|
||||
}
|
||||
}
|
||||
|
||||
public static string ComputerName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Environment.MachineName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.DirectoryServices;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Client.Interop
|
||||
{
|
||||
public static class LocalAuthentication
|
||||
{
|
||||
|
||||
public static bool AddLocalGroupMembership(string GroupName, string UserSID, string Username, string UserDomain)
|
||||
{
|
||||
|
||||
using (DirectoryEntry group = new DirectoryEntry(string.Format("WinNT://./{0},group", GroupName)))
|
||||
{
|
||||
// Check to see if the User is already a member
|
||||
foreach (object memberRef in (IEnumerable)group.Invoke("Members"))
|
||||
{
|
||||
using (DirectoryEntry member = new DirectoryEntry(memberRef))
|
||||
{
|
||||
var memberPath = member.Path;
|
||||
if (memberPath.Equals(string.Format("WinNT://{0}/{1}", UserDomain, Username), StringComparison.InvariantCultureIgnoreCase) ||
|
||||
memberPath.Equals(string.Format("WinNT://{0}", UserSID), StringComparison.InvariantCultureIgnoreCase))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
group.Invoke("Add", string.Format("WinNT://{0}", UserSID));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string CurrentUserDomain
|
||||
{
|
||||
get
|
||||
{
|
||||
return Environment.UserDomainName;
|
||||
}
|
||||
}
|
||||
public static string CurrentUserName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Environment.UserName;
|
||||
}
|
||||
}
|
||||
|
||||
public static string ComputerName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Environment.MachineName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+327
-327
@@ -1,327 +1,327 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Disco.Client.Interop
|
||||
{
|
||||
public static class Network
|
||||
{
|
||||
private static List<NetworkAdapterInfo> NetworkAdapters { get; set; }
|
||||
private static NetworkAdapterInfo PrimaryLanNetworkAdapter { get; set; }
|
||||
private static NetworkAdapterInfo PrimaryWlanNetworkAdapter { get; set; }
|
||||
|
||||
static Network()
|
||||
{
|
||||
// Get All Adapters
|
||||
RetrieveLanAdapters();
|
||||
|
||||
if (NetworkAdapters.Count > 0)
|
||||
{
|
||||
// Only Retrieve Wlan Adapters if at least one adapter was found by WMI
|
||||
RetrieveWlanAdapters();
|
||||
|
||||
// Determine Primary Adapters
|
||||
|
||||
// Lan
|
||||
PrimaryLanNetworkAdapter = NetworkAdapters.Where(n => !n.IsWLanAdapter && n.NetConnectionId.StartsWith("Local Area Connection", StringComparison.InvariantCultureIgnoreCase)).OrderByDescending(n => n.Speed).FirstOrDefault();
|
||||
// Might be too restrictive - remove name restriction just in case.
|
||||
if (PrimaryLanNetworkAdapter == null)
|
||||
PrimaryLanNetworkAdapter = NetworkAdapters.Where(n => !n.IsWLanAdapter).OrderByDescending(n => n.Speed).FirstOrDefault();
|
||||
|
||||
// Wan
|
||||
PrimaryWlanNetworkAdapter = NetworkAdapters.Where(n => n.IsWLanAdapter).OrderByDescending(n => n.Speed).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private static void RetrieveLanAdapters()
|
||||
{
|
||||
// Get NetworkAdapter Information
|
||||
try
|
||||
{
|
||||
using (ManagementObjectSearcher mSearcher = new ManagementObjectSearcher("SELECT Index, GUID, MACAddress, Name, NetConnectionID, Speed FROM Win32_NetworkAdapter WHERE PhysicalAdapter=true AND MACAddress IS NOT NULL AND Name IS NOT NULL AND NetConnectionID IS NOT NULL AND Speed IS NOT NULL"))
|
||||
{
|
||||
using (ManagementObjectCollection mResults = mSearcher.Get())
|
||||
{
|
||||
NetworkAdapters = new List<NetworkAdapterInfo>();
|
||||
foreach (var mResult in mResults.Cast<ManagementObject>())
|
||||
{
|
||||
NetworkAdapterInfo nic = new NetworkAdapterInfo()
|
||||
{
|
||||
Index = (UInt32)mResult.GetPropertyValue("Index"),
|
||||
Guid = Guid.Parse((string)mResult.GetPropertyValue("GUID")),
|
||||
MacAddress = mResult.GetPropertyValue("MACAddress").ToString(),
|
||||
Name = mResult.GetPropertyValue("Name").ToString(),
|
||||
NetConnectionId = mResult.GetPropertyValue("NetConnectionID").ToString(),
|
||||
Speed = Convert.ToUInt64(mResult.GetPropertyValue("Speed")),
|
||||
IsWLanAdapter = false
|
||||
};
|
||||
NetworkAdapters.Add(nic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Disco Client was unable to retrieve NetworkAdapter information from WMI", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RetrieveWlanAdapters()
|
||||
{
|
||||
WLAN_INTERFACE_INFO_LIST wlanApiInterfaceList;
|
||||
|
||||
IntPtr wlanApiHandle = IntPtr.Zero;
|
||||
uint wlanApiServiceVersion = 0;
|
||||
|
||||
if (WlanOpenHandle(WLAN_API_VERSION_2_0, IntPtr.Zero, out wlanApiServiceVersion, ref wlanApiHandle) == ERROR_SUCCESS)
|
||||
{
|
||||
IntPtr wlanApiInterfaceListPointer = IntPtr.Zero;
|
||||
|
||||
if (WlanEnumInterfaces(wlanApiHandle, IntPtr.Zero, ref wlanApiInterfaceListPointer) == ERROR_SUCCESS)
|
||||
{
|
||||
wlanApiInterfaceList = new WLAN_INTERFACE_INFO_LIST(wlanApiInterfaceListPointer);
|
||||
WlanFreeMemory(wlanApiInterfaceListPointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error - No Wlan Adapters Reported
|
||||
WlanCloseHandle(wlanApiHandle, IntPtr.Zero);
|
||||
return;
|
||||
}
|
||||
|
||||
WlanCloseHandle(wlanApiHandle, IntPtr.Zero);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error - No Wlan Adapters Reported
|
||||
return;
|
||||
}
|
||||
|
||||
if (wlanApiInterfaceList.InterfaceInfo != null)
|
||||
{
|
||||
foreach (var wlanApiAdapter in wlanApiInterfaceList.InterfaceInfo)
|
||||
{
|
||||
var wlanApiAdapterInfo = wlanApiAdapter;
|
||||
var wmiAdapterInfo = NetworkAdapters.FirstOrDefault(n => n.Guid == wlanApiAdapterInfo.InterfaceGuid);
|
||||
if (wmiAdapterInfo != null)
|
||||
{
|
||||
wmiAdapterInfo.IsWLanAdapter = true;
|
||||
wmiAdapterInfo.WlanState = wlanApiAdapterInfo.isState;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string PrimaryLanMacAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
// Return null if no Primary LAN Network Adapter found on this Device
|
||||
|
||||
return (PrimaryLanNetworkAdapter == null) ? null : PrimaryLanNetworkAdapter.MacAddress;
|
||||
}
|
||||
}
|
||||
public static string PrimaryWlanMacAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
// Return null if no Primary WLAN Network Adapter found on this Device
|
||||
|
||||
return (PrimaryWlanNetworkAdapter == null) ? null : PrimaryWlanNetworkAdapter.MacAddress;
|
||||
}
|
||||
}
|
||||
|
||||
private class NetworkAdapterInfo
|
||||
{
|
||||
public UInt32 Index { get; set; }
|
||||
public Guid Guid { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string NetConnectionId { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public UInt64 Speed { get; set; }
|
||||
|
||||
public bool IsWLanAdapter { get; set; }
|
||||
public WLAN_INTERFACE_STATE WlanState { get; set; }
|
||||
|
||||
public string WlanStateDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (WlanState)
|
||||
{
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_not_ready:
|
||||
return "Not Ready";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_connected:
|
||||
return "Connected";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_ad_hoc_network_formed:
|
||||
return "Ad Hoc Network Formed";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_disconnecting:
|
||||
return "Disconnecting";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_disconnected:
|
||||
return "Disconnected";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_associating:
|
||||
return "Associating";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_discovering:
|
||||
return "Discovering";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_authenticating:
|
||||
return "Authenticating";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Wlan Win32 Interop
|
||||
|
||||
private const uint WLAN_API_VERSION_2_0 = 2; // Windows Vista WiFi API Version
|
||||
private const int ERROR_SUCCESS = 0;
|
||||
|
||||
/// <summary >
|
||||
/// Opens a connection to the server
|
||||
/// </summary >
|
||||
[DllImport("Wlanapi.dll")]
|
||||
private static extern int WlanOpenHandle(
|
||||
uint dwClientVersion,
|
||||
IntPtr pReserved, //not in MSDN but required
|
||||
[Out] out uint pdwNegotiatedVersion,
|
||||
ref IntPtr ClientHandle);
|
||||
|
||||
/// <summary >
|
||||
/// Closes a connection to the server
|
||||
/// </summary >
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanCloseHandle")]
|
||||
private static extern uint WlanCloseHandle(
|
||||
[In] IntPtr hClientHandle,
|
||||
IntPtr pReserved);
|
||||
|
||||
/// <summary >
|
||||
/// Enumerates all wireless interfaces in the laptop
|
||||
/// </summary >
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanEnumInterfaces")]
|
||||
private static extern uint WlanEnumInterfaces(
|
||||
[In] IntPtr hClientHandle,
|
||||
IntPtr pReserved,
|
||||
ref IntPtr ppInterfaceList);
|
||||
|
||||
/// <summary >
|
||||
/// Frees memory returned by native WiFi functions
|
||||
/// </summary >
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanFreeMemory")]
|
||||
private static extern void WlanFreeMemory([In] IntPtr pMemory);
|
||||
|
||||
/// <summary>
|
||||
/// Defines the state of the interface. e.g. connected, disconnected.
|
||||
/// </summary>
|
||||
private enum WLAN_INTERFACE_STATE
|
||||
{
|
||||
/// <summary>
|
||||
/// wlan_interface_state_not_ready -> 0
|
||||
/// </summary>
|
||||
wlan_interface_state_not_ready = 0,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_connected -> 1
|
||||
/// </summary>
|
||||
wlan_interface_state_connected = 1,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_ad_hoc_network_formed -> 2
|
||||
/// </summary>
|
||||
wlan_interface_state_ad_hoc_network_formed = 2,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_disconnecting -> 3
|
||||
/// </summary>
|
||||
wlan_interface_state_disconnecting = 3,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_disconnected -> 4
|
||||
/// </summary>
|
||||
wlan_interface_state_disconnected = 4,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_associating -> 5
|
||||
/// </summary>
|
||||
wlan_interface_state_associating = 5,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_discovering -> 6
|
||||
/// </summary>
|
||||
wlan_interface_state_discovering = 6,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_authenticating -> 7
|
||||
/// </summary>
|
||||
wlan_interface_state_authenticating = 7,
|
||||
}
|
||||
|
||||
|
||||
/// <summary >
|
||||
/// Stores interface info
|
||||
/// </summary >
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
private struct WLAN_INTERFACE_INFO
|
||||
{
|
||||
/// GUID->_GUID
|
||||
public Guid InterfaceGuid;
|
||||
|
||||
/// WCHAR[256]
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string strInterfaceDescription;
|
||||
|
||||
/// WLAN_INTERFACE_STATE->_WLAN_INTERFACE_STATE
|
||||
public WLAN_INTERFACE_STATE isState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains an array of NIC information
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WLAN_INTERFACE_INFO_LIST
|
||||
{
|
||||
/// <summary>
|
||||
/// Length of <see cref="InterfaceInfo"/> array
|
||||
/// </summary>
|
||||
public Int32 dwNumberOfItems;
|
||||
/// <summary>
|
||||
/// This member is not used by the wireless service. Applications can use this member when processing individual interfaces.
|
||||
/// </summary>
|
||||
public Int32 dwIndex;
|
||||
/// <summary>
|
||||
/// Array of WLAN interfaces.
|
||||
/// </summary>
|
||||
public WLAN_INTERFACE_INFO[] InterfaceInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for WLAN_INTERFACE_INFO_LIST.
|
||||
/// Constructor is needed because the InterfaceInfo member varies based on how many adapters are in the system.
|
||||
/// </summary>
|
||||
/// <param name="pList">the unmanaged pointer containing the list.</param>
|
||||
public WLAN_INTERFACE_INFO_LIST(IntPtr pList)
|
||||
{
|
||||
// The first 4 bytes are the number of WLAN_INTERFACE_INFO structures.
|
||||
dwNumberOfItems = Marshal.ReadInt32(pList, 0);
|
||||
|
||||
// The next 4 bytes are the index of the current item in the unmanaged API.
|
||||
dwIndex = Marshal.ReadInt32(pList, 4);
|
||||
|
||||
// Construct the array of WLAN_INTERFACE_INFO structures.
|
||||
InterfaceInfo = new WLAN_INTERFACE_INFO[dwNumberOfItems];
|
||||
|
||||
for (int i = 0; i <= dwNumberOfItems - 1; i++)
|
||||
{
|
||||
// The offset of the array of structures is 8 bytes past the beginning.
|
||||
// Then, take the index and multiply it by the number of bytes in the
|
||||
// structure.
|
||||
// The length of the WLAN_INTERFACE_INFO structure is 532 bytes - this
|
||||
// was determined by doing a Marshall.SizeOf(WLAN_INTERFACE_INFO)
|
||||
IntPtr pItemList = new IntPtr(pList.ToInt64() + (i * 532) + 8);
|
||||
|
||||
// Construct the WLAN_INTERFACE_INFO structure, marshal the unmanaged
|
||||
// structure into it, then copy it to the array of structures.
|
||||
InterfaceInfo[i] = (WLAN_INTERFACE_INFO)Marshal.PtrToStructure(pItemList, typeof(WLAN_INTERFACE_INFO));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Disco.Client.Interop
|
||||
{
|
||||
public static class Network
|
||||
{
|
||||
private static List<NetworkAdapterInfo> NetworkAdapters { get; set; }
|
||||
private static NetworkAdapterInfo PrimaryLanNetworkAdapter { get; set; }
|
||||
private static NetworkAdapterInfo PrimaryWlanNetworkAdapter { get; set; }
|
||||
|
||||
static Network()
|
||||
{
|
||||
// Get All Adapters
|
||||
RetrieveLanAdapters();
|
||||
|
||||
if (NetworkAdapters.Count > 0)
|
||||
{
|
||||
// Only Retrieve Wlan Adapters if at least one adapter was found by WMI
|
||||
RetrieveWlanAdapters();
|
||||
|
||||
// Determine Primary Adapters
|
||||
|
||||
// Lan
|
||||
PrimaryLanNetworkAdapter = NetworkAdapters.Where(n => !n.IsWLanAdapter && n.NetConnectionId.StartsWith("Local Area Connection", StringComparison.InvariantCultureIgnoreCase)).OrderByDescending(n => n.Speed).FirstOrDefault();
|
||||
// Might be too restrictive - remove name restriction just in case.
|
||||
if (PrimaryLanNetworkAdapter == null)
|
||||
PrimaryLanNetworkAdapter = NetworkAdapters.Where(n => !n.IsWLanAdapter).OrderByDescending(n => n.Speed).FirstOrDefault();
|
||||
|
||||
// Wan
|
||||
PrimaryWlanNetworkAdapter = NetworkAdapters.Where(n => n.IsWLanAdapter).OrderByDescending(n => n.Speed).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private static void RetrieveLanAdapters()
|
||||
{
|
||||
// Get NetworkAdapter Information
|
||||
try
|
||||
{
|
||||
using (ManagementObjectSearcher mSearcher = new ManagementObjectSearcher("SELECT Index, GUID, MACAddress, Name, NetConnectionID, Speed FROM Win32_NetworkAdapter WHERE PhysicalAdapter=true AND MACAddress IS NOT NULL AND Name IS NOT NULL AND NetConnectionID IS NOT NULL AND Speed IS NOT NULL"))
|
||||
{
|
||||
using (ManagementObjectCollection mResults = mSearcher.Get())
|
||||
{
|
||||
NetworkAdapters = new List<NetworkAdapterInfo>();
|
||||
foreach (var mResult in mResults.Cast<ManagementObject>())
|
||||
{
|
||||
NetworkAdapterInfo nic = new NetworkAdapterInfo()
|
||||
{
|
||||
Index = (UInt32)mResult.GetPropertyValue("Index"),
|
||||
Guid = Guid.Parse((string)mResult.GetPropertyValue("GUID")),
|
||||
MacAddress = mResult.GetPropertyValue("MACAddress").ToString(),
|
||||
Name = mResult.GetPropertyValue("Name").ToString(),
|
||||
NetConnectionId = mResult.GetPropertyValue("NetConnectionID").ToString(),
|
||||
Speed = Convert.ToUInt64(mResult.GetPropertyValue("Speed")),
|
||||
IsWLanAdapter = false
|
||||
};
|
||||
NetworkAdapters.Add(nic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Disco Client was unable to retrieve NetworkAdapter information from WMI", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RetrieveWlanAdapters()
|
||||
{
|
||||
WLAN_INTERFACE_INFO_LIST wlanApiInterfaceList;
|
||||
|
||||
IntPtr wlanApiHandle = IntPtr.Zero;
|
||||
uint wlanApiServiceVersion = 0;
|
||||
|
||||
if (WlanOpenHandle(WLAN_API_VERSION_2_0, IntPtr.Zero, out wlanApiServiceVersion, ref wlanApiHandle) == ERROR_SUCCESS)
|
||||
{
|
||||
IntPtr wlanApiInterfaceListPointer = IntPtr.Zero;
|
||||
|
||||
if (WlanEnumInterfaces(wlanApiHandle, IntPtr.Zero, ref wlanApiInterfaceListPointer) == ERROR_SUCCESS)
|
||||
{
|
||||
wlanApiInterfaceList = new WLAN_INTERFACE_INFO_LIST(wlanApiInterfaceListPointer);
|
||||
WlanFreeMemory(wlanApiInterfaceListPointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error - No Wlan Adapters Reported
|
||||
WlanCloseHandle(wlanApiHandle, IntPtr.Zero);
|
||||
return;
|
||||
}
|
||||
|
||||
WlanCloseHandle(wlanApiHandle, IntPtr.Zero);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error - No Wlan Adapters Reported
|
||||
return;
|
||||
}
|
||||
|
||||
if (wlanApiInterfaceList.InterfaceInfo != null)
|
||||
{
|
||||
foreach (var wlanApiAdapter in wlanApiInterfaceList.InterfaceInfo)
|
||||
{
|
||||
var wlanApiAdapterInfo = wlanApiAdapter;
|
||||
var wmiAdapterInfo = NetworkAdapters.FirstOrDefault(n => n.Guid == wlanApiAdapterInfo.InterfaceGuid);
|
||||
if (wmiAdapterInfo != null)
|
||||
{
|
||||
wmiAdapterInfo.IsWLanAdapter = true;
|
||||
wmiAdapterInfo.WlanState = wlanApiAdapterInfo.isState;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string PrimaryLanMacAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
// Return null if no Primary LAN Network Adapter found on this Device
|
||||
|
||||
return (PrimaryLanNetworkAdapter == null) ? null : PrimaryLanNetworkAdapter.MacAddress;
|
||||
}
|
||||
}
|
||||
public static string PrimaryWlanMacAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
// Return null if no Primary WLAN Network Adapter found on this Device
|
||||
|
||||
return (PrimaryWlanNetworkAdapter == null) ? null : PrimaryWlanNetworkAdapter.MacAddress;
|
||||
}
|
||||
}
|
||||
|
||||
private class NetworkAdapterInfo
|
||||
{
|
||||
public UInt32 Index { get; set; }
|
||||
public Guid Guid { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string NetConnectionId { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public UInt64 Speed { get; set; }
|
||||
|
||||
public bool IsWLanAdapter { get; set; }
|
||||
public WLAN_INTERFACE_STATE WlanState { get; set; }
|
||||
|
||||
public string WlanStateDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (WlanState)
|
||||
{
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_not_ready:
|
||||
return "Not Ready";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_connected:
|
||||
return "Connected";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_ad_hoc_network_formed:
|
||||
return "Ad Hoc Network Formed";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_disconnecting:
|
||||
return "Disconnecting";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_disconnected:
|
||||
return "Disconnected";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_associating:
|
||||
return "Associating";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_discovering:
|
||||
return "Discovering";
|
||||
case WLAN_INTERFACE_STATE.wlan_interface_state_authenticating:
|
||||
return "Authenticating";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Wlan Win32 Interop
|
||||
|
||||
private const uint WLAN_API_VERSION_2_0 = 2; // Windows Vista WiFi API Version
|
||||
private const int ERROR_SUCCESS = 0;
|
||||
|
||||
/// <summary >
|
||||
/// Opens a connection to the server
|
||||
/// </summary >
|
||||
[DllImport("Wlanapi.dll")]
|
||||
private static extern int WlanOpenHandle(
|
||||
uint dwClientVersion,
|
||||
IntPtr pReserved, //not in MSDN but required
|
||||
[Out] out uint pdwNegotiatedVersion,
|
||||
ref IntPtr ClientHandle);
|
||||
|
||||
/// <summary >
|
||||
/// Closes a connection to the server
|
||||
/// </summary >
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanCloseHandle")]
|
||||
private static extern uint WlanCloseHandle(
|
||||
[In] IntPtr hClientHandle,
|
||||
IntPtr pReserved);
|
||||
|
||||
/// <summary >
|
||||
/// Enumerates all wireless interfaces in the laptop
|
||||
/// </summary >
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanEnumInterfaces")]
|
||||
private static extern uint WlanEnumInterfaces(
|
||||
[In] IntPtr hClientHandle,
|
||||
IntPtr pReserved,
|
||||
ref IntPtr ppInterfaceList);
|
||||
|
||||
/// <summary >
|
||||
/// Frees memory returned by native WiFi functions
|
||||
/// </summary >
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanFreeMemory")]
|
||||
private static extern void WlanFreeMemory([In] IntPtr pMemory);
|
||||
|
||||
/// <summary>
|
||||
/// Defines the state of the interface. e.g. connected, disconnected.
|
||||
/// </summary>
|
||||
private enum WLAN_INTERFACE_STATE
|
||||
{
|
||||
/// <summary>
|
||||
/// wlan_interface_state_not_ready -> 0
|
||||
/// </summary>
|
||||
wlan_interface_state_not_ready = 0,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_connected -> 1
|
||||
/// </summary>
|
||||
wlan_interface_state_connected = 1,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_ad_hoc_network_formed -> 2
|
||||
/// </summary>
|
||||
wlan_interface_state_ad_hoc_network_formed = 2,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_disconnecting -> 3
|
||||
/// </summary>
|
||||
wlan_interface_state_disconnecting = 3,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_disconnected -> 4
|
||||
/// </summary>
|
||||
wlan_interface_state_disconnected = 4,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_associating -> 5
|
||||
/// </summary>
|
||||
wlan_interface_state_associating = 5,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_discovering -> 6
|
||||
/// </summary>
|
||||
wlan_interface_state_discovering = 6,
|
||||
/// <summary>
|
||||
/// wlan_interface_state_authenticating -> 7
|
||||
/// </summary>
|
||||
wlan_interface_state_authenticating = 7,
|
||||
}
|
||||
|
||||
|
||||
/// <summary >
|
||||
/// Stores interface info
|
||||
/// </summary >
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
private struct WLAN_INTERFACE_INFO
|
||||
{
|
||||
/// GUID->_GUID
|
||||
public Guid InterfaceGuid;
|
||||
|
||||
/// WCHAR[256]
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string strInterfaceDescription;
|
||||
|
||||
/// WLAN_INTERFACE_STATE->_WLAN_INTERFACE_STATE
|
||||
public WLAN_INTERFACE_STATE isState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains an array of NIC information
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WLAN_INTERFACE_INFO_LIST
|
||||
{
|
||||
/// <summary>
|
||||
/// Length of <see cref="InterfaceInfo"/> array
|
||||
/// </summary>
|
||||
public Int32 dwNumberOfItems;
|
||||
/// <summary>
|
||||
/// This member is not used by the wireless service. Applications can use this member when processing individual interfaces.
|
||||
/// </summary>
|
||||
public Int32 dwIndex;
|
||||
/// <summary>
|
||||
/// Array of WLAN interfaces.
|
||||
/// </summary>
|
||||
public WLAN_INTERFACE_INFO[] InterfaceInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for WLAN_INTERFACE_INFO_LIST.
|
||||
/// Constructor is needed because the InterfaceInfo member varies based on how many adapters are in the system.
|
||||
/// </summary>
|
||||
/// <param name="pList">the unmanaged pointer containing the list.</param>
|
||||
public WLAN_INTERFACE_INFO_LIST(IntPtr pList)
|
||||
{
|
||||
// The first 4 bytes are the number of WLAN_INTERFACE_INFO structures.
|
||||
dwNumberOfItems = Marshal.ReadInt32(pList, 0);
|
||||
|
||||
// The next 4 bytes are the index of the current item in the unmanaged API.
|
||||
dwIndex = Marshal.ReadInt32(pList, 4);
|
||||
|
||||
// Construct the array of WLAN_INTERFACE_INFO structures.
|
||||
InterfaceInfo = new WLAN_INTERFACE_INFO[dwNumberOfItems];
|
||||
|
||||
for (int i = 0; i <= dwNumberOfItems - 1; i++)
|
||||
{
|
||||
// The offset of the array of structures is 8 bytes past the beginning.
|
||||
// Then, take the index and multiply it by the number of bytes in the
|
||||
// structure.
|
||||
// The length of the WLAN_INTERFACE_INFO structure is 532 bytes - this
|
||||
// was determined by doing a Marshall.SizeOf(WLAN_INTERFACE_INFO)
|
||||
IntPtr pItemList = new IntPtr(pList.ToInt64() + (i * 532) + 8);
|
||||
|
||||
// Construct the WLAN_INTERFACE_INFO structure, marshal the unmanaged
|
||||
// structure into it, then copy it to the array of structures.
|
||||
InterfaceInfo[i] = (WLAN_INTERFACE_INFO)Marshal.PtrToStructure(pItemList, typeof(WLAN_INTERFACE_INFO));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+104
-104
@@ -1,104 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Disco.Client.Extensions;
|
||||
|
||||
namespace Disco.Client
|
||||
{
|
||||
public static class Presentation
|
||||
{
|
||||
public static bool DelayUI { get; set; }
|
||||
|
||||
private static string EscapeMessage(this string Message)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Message))
|
||||
return Message.Replace(",", "{comma}").Replace(Environment.NewLine, "{newline}");
|
||||
else
|
||||
return null;
|
||||
}
|
||||
public static void UpdateStatus(string SubHeading, string Message, bool ShowProgress, int Progress, int TryDelay)
|
||||
{
|
||||
Presentation.UpdateStatus(SubHeading, Message, ShowProgress, Progress);
|
||||
if (TryDelay > 0)
|
||||
Presentation.TryDelay(TryDelay);
|
||||
}
|
||||
public static void UpdateStatus(string SubHeading, string Message, bool ShowProgress, int Progress)
|
||||
{
|
||||
Console.WriteLine("#{0},{1},{2},{3}", SubHeading.EscapeMessage(), Message.EscapeMessage(), ShowProgress.ToString(), Progress.ToString());
|
||||
}
|
||||
public static void TryDelay(int Milliseconds)
|
||||
{
|
||||
if (DelayUI)
|
||||
Thread.Sleep(Milliseconds);
|
||||
}
|
||||
|
||||
public static void WriteBanner()
|
||||
{
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.Append("Version: ").AppendLine(Assembly.GetExecutingAssembly().GetName().Version.ToString(3));
|
||||
message.Append("Device: ").Append(Interop.SystemAudit.DeviceSerialNumber).Append(" (").Append(Interop.SystemAudit.DeviceManufacturer).Append(" ").Append(Interop.SystemAudit.DeviceModel).AppendLine(")");
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
UpdateStatus("Preparation Client Started", message.ToString(), false, 0);
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
TryDelay(3000);
|
||||
}
|
||||
public static void WriteFatalError(Exception ex)
|
||||
{
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||
ClientServiceException clientServiceException = ex as ClientServiceException;
|
||||
if (clientServiceException != null)
|
||||
{
|
||||
UpdateStatus(string.Format("An error occurred during {0}", clientServiceException.ServiceFeature),
|
||||
clientServiceException.Message, false, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.Append("Type: ").AppendLine(ex.GetType().Name);
|
||||
message.Append("Message: ").AppendLine(ex.Message);
|
||||
message.Append("Source: ").AppendLine(ex.Source);
|
||||
message.Append("Stack: ").AppendLine(ex.StackTrace);
|
||||
UpdateStatus("An error occurred", message.ToString(), false, 0);
|
||||
}
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
|
||||
TryDelay(30000);
|
||||
}
|
||||
public static void WriteFooter(bool RebootRequired, bool AllowUninstall, bool ErrorEncountered)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
|
||||
if (ErrorEncountered)
|
||||
{
|
||||
UpdateStatus("Client Finished due to Error", "An error occurred which caused the Preparation Client to stop running.", false, 0);
|
||||
TryDelay(5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateStatus("Client Finished Successfully", "The Preparation Client finished successfully.", false, 0);
|
||||
TryDelay(1000);
|
||||
}
|
||||
|
||||
if (RebootRequired)
|
||||
RegisterBootstrapperPostActions(ShutdownActions.Reboot, AllowUninstall && !ErrorEncountered);
|
||||
else
|
||||
RegisterBootstrapperPostActions(ShutdownActions.None, AllowUninstall && !ErrorEncountered);
|
||||
}
|
||||
|
||||
public static void RegisterBootstrapperPostActions(ShutdownActions ShutdownAction, bool Uninstall)
|
||||
{
|
||||
Console.WriteLine("!{0},{1}", Enum.GetName(typeof(ShutdownActions), ShutdownAction), Uninstall ? "UninstallBootstrapper" : "DontUninstallBootstrapper");
|
||||
}
|
||||
public enum ShutdownActions
|
||||
{
|
||||
None,
|
||||
Shutdown,
|
||||
Reboot
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Disco.Client.Extensions;
|
||||
|
||||
namespace Disco.Client
|
||||
{
|
||||
public static class Presentation
|
||||
{
|
||||
public static bool DelayUI { get; set; }
|
||||
|
||||
private static string EscapeMessage(this string Message)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Message))
|
||||
return Message.Replace(",", "{comma}").Replace(Environment.NewLine, "{newline}");
|
||||
else
|
||||
return null;
|
||||
}
|
||||
public static void UpdateStatus(string SubHeading, string Message, bool ShowProgress, int Progress, int TryDelay)
|
||||
{
|
||||
Presentation.UpdateStatus(SubHeading, Message, ShowProgress, Progress);
|
||||
if (TryDelay > 0)
|
||||
Presentation.TryDelay(TryDelay);
|
||||
}
|
||||
public static void UpdateStatus(string SubHeading, string Message, bool ShowProgress, int Progress)
|
||||
{
|
||||
Console.WriteLine("#{0},{1},{2},{3}", SubHeading.EscapeMessage(), Message.EscapeMessage(), ShowProgress.ToString(), Progress.ToString());
|
||||
}
|
||||
public static void TryDelay(int Milliseconds)
|
||||
{
|
||||
if (DelayUI)
|
||||
Thread.Sleep(Milliseconds);
|
||||
}
|
||||
|
||||
public static void WriteBanner()
|
||||
{
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.Append("Version: ").AppendLine(Assembly.GetExecutingAssembly().GetName().Version.ToString(3));
|
||||
message.Append("Device: ").Append(Interop.SystemAudit.DeviceSerialNumber).Append(" (").Append(Interop.SystemAudit.DeviceManufacturer).Append(" ").Append(Interop.SystemAudit.DeviceModel).AppendLine(")");
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
UpdateStatus("Preparation Client Started", message.ToString(), false, 0);
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
TryDelay(3000);
|
||||
}
|
||||
public static void WriteFatalError(Exception ex)
|
||||
{
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||
ClientServiceException clientServiceException = ex as ClientServiceException;
|
||||
if (clientServiceException != null)
|
||||
{
|
||||
UpdateStatus(string.Format("An error occurred during {0}", clientServiceException.ServiceFeature),
|
||||
clientServiceException.Message, false, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.Append("Type: ").AppendLine(ex.GetType().Name);
|
||||
message.Append("Message: ").AppendLine(ex.Message);
|
||||
message.Append("Source: ").AppendLine(ex.Source);
|
||||
message.Append("Stack: ").AppendLine(ex.StackTrace);
|
||||
UpdateStatus("An error occurred", message.ToString(), false, 0);
|
||||
}
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
|
||||
TryDelay(30000);
|
||||
}
|
||||
public static void WriteFooter(bool RebootRequired, bool AllowUninstall, bool ErrorEncountered)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
|
||||
if (ErrorEncountered)
|
||||
{
|
||||
UpdateStatus("Client Finished due to Error", "An error occurred which caused the Preparation Client to stop running.", false, 0);
|
||||
TryDelay(5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateStatus("Client Finished Successfully", "The Preparation Client finished successfully.", false, 0);
|
||||
TryDelay(1000);
|
||||
}
|
||||
|
||||
if (RebootRequired)
|
||||
RegisterBootstrapperPostActions(ShutdownActions.Reboot, AllowUninstall && !ErrorEncountered);
|
||||
else
|
||||
RegisterBootstrapperPostActions(ShutdownActions.None, AllowUninstall && !ErrorEncountered);
|
||||
}
|
||||
|
||||
public static void RegisterBootstrapperPostActions(ShutdownActions ShutdownAction, bool Uninstall)
|
||||
{
|
||||
Console.WriteLine("!{0},{1}", Enum.GetName(typeof(ShutdownActions), ShutdownAction), Uninstall ? "UninstallBootstrapper" : "DontUninstallBootstrapper");
|
||||
}
|
||||
public enum ShutdownActions
|
||||
{
|
||||
None,
|
||||
Shutdown,
|
||||
Reboot
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+137
-137
@@ -1,137 +1,137 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Disco.Models.ClientServices;
|
||||
using Disco.Client.Extensions;
|
||||
|
||||
namespace Disco.Client
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static bool IsAuthenticated { get; set; }
|
||||
public static bool RebootRequired { get; set; }
|
||||
public static bool AllowUninstall { get; set; }
|
||||
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
bool keepProcessing;
|
||||
|
||||
// Initialize Environment Settings
|
||||
SetupEnvironment();
|
||||
|
||||
// Report to Bootstrapper
|
||||
Presentation.WriteBanner();
|
||||
|
||||
// WhoAmI Phase
|
||||
keepProcessing = Program.WhoAmI();
|
||||
|
||||
// Enrol Phase
|
||||
if (keepProcessing)
|
||||
keepProcessing = Program.Enrol();
|
||||
|
||||
// End conversation with Bootstrapper
|
||||
Presentation.WriteFooter(Program.RebootRequired, Program.AllowUninstall, !keepProcessing);
|
||||
}
|
||||
|
||||
public static void SetupEnvironment()
|
||||
{
|
||||
// Hookup Unhandled Error Handling
|
||||
AppDomain.CurrentDomain.UnhandledException += ErrorReporting.CurrentDomain_UnhandledException;
|
||||
|
||||
// Ignore Local Proxies
|
||||
WebRequest.DefaultWebProxy = new WebProxy();
|
||||
// Override Http 100 Continue Behavour
|
||||
ServicePointManager.Expect100Continue = false;
|
||||
|
||||
// Assume success unless otherwise notified
|
||||
AllowUninstall = true;
|
||||
|
||||
// Detect Disco.Bootstrapper - Create Enable UI Delay if Running
|
||||
try
|
||||
{
|
||||
Presentation.DelayUI = (System.Diagnostics.Process.GetProcessesByName("Disco.ClientBootstrapper").Length > 0);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Presentation.DelayUI = true; // Add Delays on Error
|
||||
}
|
||||
}
|
||||
|
||||
public static bool WhoAmI()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
WhoAmIResponse response;
|
||||
WhoAmI request;
|
||||
|
||||
// Build Request
|
||||
request = new WhoAmI();
|
||||
|
||||
// Send Request
|
||||
Presentation.UpdateStatus("Connecting to Preparation Server", "Determining connection authentication, please wait...", true, -1);
|
||||
response = request.Post(true);
|
||||
|
||||
// Process Response
|
||||
response.Process();
|
||||
|
||||
// Complete
|
||||
return true;
|
||||
}
|
||||
catch (WebException webEx)
|
||||
{
|
||||
// Check for 'Unauthenticated' Connection
|
||||
if ((webEx.Status == WebExceptionStatus.ProtocolError) && ((HttpWebResponse)webEx.Response).StatusCode == HttpStatusCode.Unauthorized)
|
||||
{
|
||||
WhoAmIExtensions.UnauthenticatedResponse();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some other Web Error
|
||||
ErrorReporting.ReportError(webEx, false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorReporting.ReportError(ex, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool Enrol()
|
||||
{
|
||||
try
|
||||
{
|
||||
Enrol request;
|
||||
EnrolResponse response = null;
|
||||
|
||||
// Build Request
|
||||
Presentation.UpdateStatus("Enrolling Device", "Building enrolment request and preparing to send data to the server.", true, -1);
|
||||
request = new Enrol();
|
||||
request.Build();
|
||||
|
||||
// Send Request
|
||||
Presentation.UpdateStatus("Enrolling Device", "Sending the enrolment request to the server.", true, -1);
|
||||
response = request.Post(Program.IsAuthenticated);
|
||||
|
||||
// Process Response
|
||||
Presentation.UpdateStatus("Enrolling Device", "Processing the enrolment response from the server.", true, -1);
|
||||
response.Process();
|
||||
|
||||
// Complete
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorReporting.ReportError(ex, true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Disco.Models.ClientServices;
|
||||
using Disco.Client.Extensions;
|
||||
|
||||
namespace Disco.Client
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static bool IsAuthenticated { get; set; }
|
||||
public static bool RebootRequired { get; set; }
|
||||
public static bool AllowUninstall { get; set; }
|
||||
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
bool keepProcessing;
|
||||
|
||||
// Initialize Environment Settings
|
||||
SetupEnvironment();
|
||||
|
||||
// Report to Bootstrapper
|
||||
Presentation.WriteBanner();
|
||||
|
||||
// WhoAmI Phase
|
||||
keepProcessing = Program.WhoAmI();
|
||||
|
||||
// Enrol Phase
|
||||
if (keepProcessing)
|
||||
keepProcessing = Program.Enrol();
|
||||
|
||||
// End conversation with Bootstrapper
|
||||
Presentation.WriteFooter(Program.RebootRequired, Program.AllowUninstall, !keepProcessing);
|
||||
}
|
||||
|
||||
public static void SetupEnvironment()
|
||||
{
|
||||
// Hookup Unhandled Error Handling
|
||||
AppDomain.CurrentDomain.UnhandledException += ErrorReporting.CurrentDomain_UnhandledException;
|
||||
|
||||
// Ignore Local Proxies
|
||||
WebRequest.DefaultWebProxy = new WebProxy();
|
||||
// Override Http 100 Continue Behavour
|
||||
ServicePointManager.Expect100Continue = false;
|
||||
|
||||
// Assume success unless otherwise notified
|
||||
AllowUninstall = true;
|
||||
|
||||
// Detect Disco.Bootstrapper - Create Enable UI Delay if Running
|
||||
try
|
||||
{
|
||||
Presentation.DelayUI = (System.Diagnostics.Process.GetProcessesByName("Disco.ClientBootstrapper").Length > 0);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Presentation.DelayUI = true; // Add Delays on Error
|
||||
}
|
||||
}
|
||||
|
||||
public static bool WhoAmI()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
WhoAmIResponse response;
|
||||
WhoAmI request;
|
||||
|
||||
// Build Request
|
||||
request = new WhoAmI();
|
||||
|
||||
// Send Request
|
||||
Presentation.UpdateStatus("Connecting to Preparation Server", "Determining connection authentication, please wait...", true, -1);
|
||||
response = request.Post(true);
|
||||
|
||||
// Process Response
|
||||
response.Process();
|
||||
|
||||
// Complete
|
||||
return true;
|
||||
}
|
||||
catch (WebException webEx)
|
||||
{
|
||||
// Check for 'Unauthenticated' Connection
|
||||
if ((webEx.Status == WebExceptionStatus.ProtocolError) && ((HttpWebResponse)webEx.Response).StatusCode == HttpStatusCode.Unauthorized)
|
||||
{
|
||||
WhoAmIExtensions.UnauthenticatedResponse();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some other Web Error
|
||||
ErrorReporting.ReportError(webEx, false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorReporting.ReportError(ex, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool Enrol()
|
||||
{
|
||||
try
|
||||
{
|
||||
Enrol request;
|
||||
EnrolResponse response = null;
|
||||
|
||||
// Build Request
|
||||
Presentation.UpdateStatus("Enrolling Device", "Building enrolment request and preparing to send data to the server.", true, -1);
|
||||
request = new Enrol();
|
||||
request.Build();
|
||||
|
||||
// Send Request
|
||||
Presentation.UpdateStatus("Enrolling Device", "Sending the enrolment request to the server.", true, -1);
|
||||
response = request.Post(Program.IsAuthenticated);
|
||||
|
||||
// Process Response
|
||||
Presentation.UpdateStatus("Enrolling Device", "Processing the enrolment response from the server.", true, -1);
|
||||
response.Process();
|
||||
|
||||
// Complete
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorReporting.ReportError(ex, true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<assemblyIdentity version="1.0.0.0" name="DiscoClientBootstrapper.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
Specifying requestedExecutionLevel node will disable file and registry virtualization.
|
||||
If you want to utilize File and Registry Virtualization for backward
|
||||
compatibility then delete the requestedExecutionLevel node.
|
||||
-->
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of all Windows versions that this application is designed to work with. Windows will automatically select the most compatible environment.-->
|
||||
|
||||
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
<!-- <dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>-->
|
||||
|
||||
</asmv1:assembly>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<assemblyIdentity version="1.0.0.0" name="DiscoClientBootstrapper.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
Specifying requestedExecutionLevel node will disable file and registry virtualization.
|
||||
If you want to utilize File and Registry Virtualization for backward
|
||||
compatibility then delete the requestedExecutionLevel node.
|
||||
-->
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of all Windows versions that this application is designed to work with. Windows will automatically select the most compatible environment.-->
|
||||
|
||||
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
<!-- <dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>-->
|
||||
|
||||
</asmv1:assembly>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
@ECHO OFF
|
||||
IF /I "%USERDOMAIN%"=="NT AUTHORITY" GOTO RunAsNetworkService
|
||||
Disco.Client.exe
|
||||
EXIT /B 0
|
||||
|
||||
:RunAsNetworkService
|
||||
ECHO #Running,Launching Preparation Client, Please wait...{newline}Starting client as 'NT AUTHORITY\Network Service',true,-1
|
||||
PsExec -acceptula -i -u "NT AUTHORITY\Network Service" -w "%CD%" "%CD%\Start.bat"
|
||||
@ECHO OFF
|
||||
IF /I "%USERDOMAIN%"=="NT AUTHORITY" GOTO RunAsNetworkService
|
||||
Disco.Client.exe
|
||||
EXIT /B 0
|
||||
|
||||
:RunAsNetworkService
|
||||
ECHO #Running,Launching Preparation Client, Please wait...{newline}Starting client as 'NT AUTHORITY\Network Service',true,-1
|
||||
PsExec -acceptula -i -u "NT AUTHORITY\Network Service" -w "%CD%" "%CD%\Start.bat"
|
||||
EXIT /B 0
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40-Client" />
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40-Client" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user