RDS fixes
This commit is contained in:
parent
165847909f
commit
7bc697534b
16 changed files with 121 additions and 91 deletions
|
@ -532,9 +532,23 @@ namespace WebsitePanel.EnterpriseServer
|
|||
private static int AddRdsCollectionInternal(int itemId, RdsCollection collection)
|
||||
{
|
||||
var result = TaskManager.StartResultTask<ResultObject>("REMOTE_DESKTOP_SERVICES", "ADD_RDS_COLLECTION");
|
||||
var domainName = IPGlobalProperties.GetIPGlobalProperties().DomainName;
|
||||
|
||||
try
|
||||
{
|
||||
foreach(var server in collection.Servers)
|
||||
{
|
||||
if (!server.FqdName.EndsWith(domainName, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
throw TaskManager.WriteError(new Exception("Fully Qualified Domain Name not valid."));
|
||||
}
|
||||
|
||||
if (!CheckRDSServerAvaliable(server.FqdName))
|
||||
{
|
||||
throw TaskManager.WriteError(new Exception(string.Format("Unable to connect to {0} server.", server.FqdName)));
|
||||
}
|
||||
}
|
||||
|
||||
// load organization
|
||||
Organization org = OrganizationController.GetOrganization(itemId);
|
||||
if (org == null)
|
||||
|
@ -822,7 +836,7 @@ namespace WebsitePanel.EnterpriseServer
|
|||
FillRdsServerData(tmpServer);
|
||||
}
|
||||
|
||||
result.Servers = tmpServers.ToArray();
|
||||
result.Servers = tmpServers.ToArray();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1016,25 +1030,22 @@ namespace WebsitePanel.EnterpriseServer
|
|||
{
|
||||
if (CheckRDSServerAvaliable(rdsServer.FqdName))
|
||||
{
|
||||
rdsServer.Id = DataProvider.AddRDSServer(rdsServer.Name, rdsServer.FqdName, rdsServer.Description);
|
||||
var domainName = IPGlobalProperties.GetIPGlobalProperties().DomainName;
|
||||
|
||||
if (rdsServer.FqdName.EndsWith(domainName, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
rdsServer.Id = DataProvider.AddRDSServer(rdsServer.Name, rdsServer.FqdName, rdsServer.Description);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw TaskManager.WriteError(new Exception("Fully Qualified Domain Name not valid."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AddError("REMOTE_DESKTOP_SERVICES_ADD_RDS_SERVER", new Exception("The server that you are adding, is not available"));
|
||||
return result;
|
||||
throw TaskManager.WriteError(new Exception(string.Format("Unable to connect to {0} server. Please double check Server Full Name setting and retry.", rdsServer.FqdName)));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.InnerException != null)
|
||||
{
|
||||
result.AddError("Unable to add RDS Server", ex.InnerException);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AddError("Unable to add RDS Server", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!result.IsSuccess)
|
||||
|
@ -1753,7 +1764,7 @@ namespace WebsitePanel.EnterpriseServer
|
|||
{
|
||||
bool result = false;
|
||||
var ping = new Ping();
|
||||
var reply = ping.Send(hostname, 1000);
|
||||
var reply = ping.Send(hostname, 1000);
|
||||
|
||||
if (reply.Status == IPStatus.Success)
|
||||
{
|
||||
|
@ -1761,8 +1772,7 @@ namespace WebsitePanel.EnterpriseServer
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static ResultObject DeleteRemoteDesktopServiceInternal(int itemId)
|
||||
{
|
||||
|
@ -1811,7 +1821,7 @@ namespace WebsitePanel.EnterpriseServer
|
|||
private static RemoteDesktopServices GetRemoteDesktopServices(int serviceId)
|
||||
{
|
||||
var rds = new RemoteDesktopServices();
|
||||
ServiceProviderProxy.Init(rds, serviceId);
|
||||
ServiceProviderProxy.Init(rds, serviceId);
|
||||
|
||||
return rds;
|
||||
}
|
||||
|
|
|
@ -26,11 +26,12 @@
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
namespace WebsitePanel.Providers.RemoteDesktopServices
|
||||
{
|
||||
public class RdsServersPaged
|
||||
{
|
||||
public int RecordsCount { get; set; }
|
||||
public RdsServer[] Servers { get; set; }
|
||||
public RdsServer[] Servers { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1343,7 +1343,17 @@ namespace WebsitePanel.Providers.RemoteDesktopServices
|
|||
{
|
||||
runSpace = OpenRunspace();
|
||||
var feature = AddFeature(runSpace, hostName, "RDS-RD-Server", true, true);
|
||||
installationResult = (bool)GetPSObjectProperty(feature, "Success");
|
||||
installationResult = (bool)GetPSObjectProperty(feature, "Success");
|
||||
|
||||
if (!IsFeatureInstalled(hostName, "Desktop-Experience", runSpace))
|
||||
{
|
||||
feature = AddFeature(runSpace, hostName, "Desktop-Experience", true, false);
|
||||
}
|
||||
|
||||
if (!IsFeatureInstalled(hostName, "NET-Framework-Core", runSpace))
|
||||
{
|
||||
feature = AddFeature(runSpace, hostName, "NET-Framework-Core", true, false);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -5656,6 +5656,9 @@
|
|||
<data name="ERROR.RDSSESSIONHOST_CERTIFICATE_NOT_INSTALLED" xml:space="preserve">
|
||||
<value>Session host certificate not installed</value>
|
||||
</data>
|
||||
<data name="ERROR.RDSSERVER_NOT_ADDED" xml:space="preserve">
|
||||
<value>RDS Server not added</value>
|
||||
</data>
|
||||
<data name="Success.RDSSESSIONHOST_CERTIFICATE_INSTALLED" xml:space="preserve">
|
||||
<value>Session host certificate has been installed</value>
|
||||
</data>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<td class="SubHead" style="width:200px" nowrap>
|
||||
<asp:Localize runat="server" meta:resourcekey="lblSelectFile" />
|
||||
</td>
|
||||
<td style="padding: 10px 0 10px 0;"><asp:FileUpload ID="upPFX" onchange="this.form.submit();" runat="server"/></td>
|
||||
<td style="padding: 10px 0 10px 0;"><asp:FileUpload ID="upPFX" runat="server"/></td>
|
||||
</tr>
|
||||
<tr><td></td></tr>
|
||||
<tr>
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace WebsitePanel.Portal.RDS
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
messageBox.ShowErrorMessage("RDSCOLLECTION_NOT_CREATED", ex);
|
||||
ShowErrorMessage("RDSCOLLECTION_NOT_CREATED", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,15 @@ namespace WebsitePanel.Portal.RDS
|
|||
txtApplicationName.Text = remoteApp.DisplayName;
|
||||
//var remoteAppUsers = organizationUsers.Where(x => applicationUsers.Contains(x.AccountName));
|
||||
var remoteAppUsers = organizationUsers.Where(x => applicationUsers.Select(a => a.Split('\\').Last().ToLower()).Contains(x.SamAccountName.Split('\\').Last().ToLower()));
|
||||
var localAdmins = ES.Services.RDS.GetRdsCollectionLocalAdmins(PanelRequest.CollectionID);
|
||||
|
||||
foreach(var user in remoteAppUsers)
|
||||
{
|
||||
if (localAdmins.Select(l => l.AccountName).Contains(user.AccountName))
|
||||
{
|
||||
user.IsVIP = true;
|
||||
}
|
||||
}
|
||||
|
||||
users.SetUsers(remoteAppUsers.ToArray());
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.UI.WebControls;
|
||||
using WebsitePanel.EnterpriseServer;
|
||||
using WebsitePanel.Providers.Common;
|
||||
|
@ -45,6 +46,15 @@ namespace WebsitePanel.Portal.RDS
|
|||
BindQuota();
|
||||
var collectionUsers = ES.Services.RDS.GetRdsCollectionUsers(PanelRequest.CollectionID);
|
||||
var collection = ES.Services.RDS.GetRdsCollection(PanelRequest.CollectionID);
|
||||
var localAdmins = ES.Services.RDS.GetRdsCollectionLocalAdmins(PanelRequest.CollectionID);
|
||||
|
||||
foreach (var user in collectionUsers)
|
||||
{
|
||||
if (localAdmins.Select(l => l.AccountName).Contains(user.AccountName))
|
||||
{
|
||||
user.IsVIP = true;
|
||||
}
|
||||
}
|
||||
|
||||
litCollectionName.Text = collection.DisplayName;
|
||||
users.SetUsers(collectionUsers);
|
||||
|
|
|
@ -4,6 +4,8 @@ using System.Linq;
|
|||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using WebsitePanel.Providers.HostedSolution;
|
||||
using WebsitePanel.Providers.RemoteDesktopServices;
|
||||
|
||||
namespace WebsitePanel.Portal.RDS
|
||||
{
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
<asp:TemplateField meta:resourcekey="gvUsersAccount" HeaderText="gvUsersAccount">
|
||||
<ItemStyle Width="96%" Wrap="false" HorizontalAlign="Left">
|
||||
</ItemStyle>
|
||||
<ItemTemplate>
|
||||
<ItemTemplate>
|
||||
<asp:Literal ID="litAccount" runat="server" Text='<%# Eval("DisplayName") %>'></asp:Literal>
|
||||
<asp:Image ID="Image1" runat="server" ImageUrl='<%# GetThemedImage("Exchange/admin_16.png") %>' Visible='<%# Convert.ToBoolean(Eval("IsVIP")) %>' ImageAlign="AbsMiddle" />
|
||||
<asp:HiddenField ID="hdnSamAccountName" runat="server" Value='<%# Eval("SamAccountName") %>' />
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
|
@ -81,6 +82,7 @@
|
|||
<asp:Image ID="imgAccount" runat="server" ImageUrl='<%# GetAccountImage((int)Eval("AccountType")) %>' ImageAlign="AbsMiddle" />
|
||||
<asp:Literal ID="litDisplayName" runat="server" Text='<%# Eval("DisplayName") %>'></asp:Literal>
|
||||
<asp:HiddenField ID="hdnSamName" runat="server" Value='<%# Eval("SamAccountName") %>' />
|
||||
<asp:HiddenField ID="hdnLocalAdmin" runat="server" Value='<%# Eval("IsVIP").ToString() %>' />
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
<asp:TemplateField meta:resourcekey="gvAccountsEmail">
|
||||
|
|
|
@ -132,6 +132,15 @@ namespace WebsitePanel.Portal.RDS.UserControls
|
|||
protected void BindPopupAccounts()
|
||||
{
|
||||
OrganizationUser[] accounts = ES.Services.Organizations.GetOrganizationUsersPaged(PanelRequest.ItemID, null, null, null, 0, Int32.MaxValue).PageUsers;
|
||||
var localAdmins = ES.Services.RDS.GetRdsCollectionLocalAdmins(PanelRequest.CollectionID);
|
||||
|
||||
foreach (var user in accounts)
|
||||
{
|
||||
if (localAdmins.Select(l => l.AccountName).Contains(user.AccountName))
|
||||
{
|
||||
user.IsVIP = true;
|
||||
}
|
||||
}
|
||||
|
||||
accounts = accounts.Where(x => !GetUsers().Select(p => p.AccountName).Contains(x.AccountName)).ToArray();
|
||||
Array.Sort(accounts, CompareAccount);
|
||||
|
@ -221,7 +230,8 @@ namespace WebsitePanel.Portal.RDS.UserControls
|
|||
{
|
||||
AccountName = (string)gvPopupAccounts.DataKeys[i][0],
|
||||
DisplayName = ((Literal)row.FindControl("litDisplayName")).Text,
|
||||
SamAccountName = ((HiddenField)row.FindControl("hdnSamName")).Value
|
||||
SamAccountName = ((HiddenField)row.FindControl("hdnSamName")).Value,
|
||||
IsVIP = Convert.ToBoolean(((HiddenField)row.FindControl("hdnLocalAdmin")).Value)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
<wsp:SimpleMessageBox id="messageBox" runat="server" />
|
||||
</ContentTemplate>
|
||||
</asp:UpdatePanel>
|
||||
<asp:UpdatePanel runat="server" ID="updatePanelUsers">
|
||||
<ContentTemplate>
|
||||
|
||||
<div class="FormButtonsBar">
|
||||
<div class="FormButtonsBar">
|
||||
<div class="Left">
|
||||
<asp:Button ID="btnAddRDSServer" runat="server"
|
||||
meta:resourcekey="btnAddRDSServer" Text="Add RDS Server" CssClass="Button3"
|
||||
|
@ -35,11 +33,20 @@
|
|||
<asp:ListItem>100</asp:ListItem>
|
||||
</asp:DropDownList>
|
||||
|
||||
<asp:TextBox ID="txtSearchValue" runat="server" CssClass="NormalTextBox" Width="100">
|
||||
</asp:TextBox><asp:ImageButton ID="cmdSearch" Runat="server" meta:resourcekey="cmdSearch" SkinID="SearchButton" CausesValidation="false"/>
|
||||
<asp:TextBox ID="txtSearchValue" runat="server" CssClass="NormalTextBox" Width="100"/>
|
||||
<asp:ImageButton ID="cmdSearch" Runat="server" meta:resourcekey="cmdSearch" SkinID="SearchButton" CausesValidation="false"/>
|
||||
</asp:Panel>
|
||||
</div>
|
||||
</div>
|
||||
<asp:ObjectDataSource ID="odsRDSServersPaged" runat="server" EnablePaging="True" SelectCountMethod="GetRDSServersPagedCount"
|
||||
SelectMethod="GetRDSServersPaged" SortParameterName="sortColumn" TypeName="WebsitePanel.Portal.RDSHelper" OnSelected="odsRDSServersPaged_Selected">
|
||||
<SelectParameters>
|
||||
<asp:ControlParameter Name="filterValue" ControlID="txtSearchValue" PropertyName="Text" />
|
||||
</SelectParameters>
|
||||
</asp:ObjectDataSource>
|
||||
|
||||
<asp:UpdatePanel runat="server" ID="updatePanelUsers" UpdateMode="Conditional">
|
||||
<ContentTemplate>
|
||||
|
||||
<asp:GridView id="gvRDSServers" runat="server" AutoGenerateColumns="False"
|
||||
AllowPaging="True" AllowSorting="True"
|
||||
|
@ -97,13 +104,7 @@
|
|||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
</Columns>
|
||||
</asp:GridView>
|
||||
<asp:ObjectDataSource ID="odsRDSServersPaged" runat="server" EnablePaging="True" SelectCountMethod="GetRDSServersPagedCount"
|
||||
SelectMethod="GetRDSServersPaged" SortParameterName="sortColumn" TypeName="WebsitePanel.Portal.RDSHelper" OnSelected="odsRDSServersPaged_Selected">
|
||||
<SelectParameters>
|
||||
<asp:ControlParameter Name="filterValue" ControlID="txtSearchValue" PropertyName="Text" />
|
||||
</SelectParameters>
|
||||
</asp:ObjectDataSource>
|
||||
</asp:GridView>
|
||||
|
||||
<asp:Panel ID="ServerInfoPanel" runat="server" CssClass="Popup" style="display:none">
|
||||
<table class="Popup-Header" cellpadding="0" cellspacing="0">
|
||||
|
|
|
@ -39,15 +39,6 @@ namespace WebsitePanel.Portal {
|
|||
/// </remarks>
|
||||
protected global::WebsitePanel.Portal.UserControls.SimpleMessageBox messageBox;
|
||||
|
||||
/// <summary>
|
||||
/// updatePanelUsers control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.UpdatePanel updatePanelUsers;
|
||||
|
||||
/// <summary>
|
||||
/// btnAddRDSServer control.
|
||||
/// </summary>
|
||||
|
@ -102,15 +93,6 @@ namespace WebsitePanel.Portal {
|
|||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.ImageButton cmdSearch;
|
||||
|
||||
/// <summary>
|
||||
/// gvRDSServers control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.GridView gvRDSServers;
|
||||
|
||||
/// <summary>
|
||||
/// odsRDSServersPaged control.
|
||||
/// </summary>
|
||||
|
@ -120,6 +102,24 @@ namespace WebsitePanel.Portal {
|
|||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.ObjectDataSource odsRDSServersPaged;
|
||||
|
||||
/// <summary>
|
||||
/// updatePanelUsers control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.UpdatePanel updatePanelUsers;
|
||||
|
||||
/// <summary>
|
||||
/// gvRDSServers control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.GridView gvRDSServers;
|
||||
|
||||
/// <summary>
|
||||
/// ServerInfoPanel control.
|
||||
/// </summary>
|
||||
|
|
|
@ -11,16 +11,16 @@
|
|||
<div class="FormContentRDSConf">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="FormLabel150"><asp:Localize ID="locServerName" runat="server" meta:resourcekey="locServerName" Text="Server Full Name:"></asp:Localize></td>
|
||||
<td class="FormLabel260"><asp:Localize ID="locServerName" runat="server" meta:resourcekey="locServerName" Text="Server Fully Qualified Domain Name:"></asp:Localize></td>
|
||||
<td>
|
||||
<asp:TextBox ID="txtServerName" runat="server" CssClass="NormalTextBox" Width="145px"></asp:TextBox>
|
||||
<asp:TextBox ID="txtServerName" runat="server" CssClass="NormalTextBox" Width="300px"></asp:TextBox>
|
||||
<asp:RequiredFieldValidator ID="valServerName" runat="server" ErrorMessage="*" ControlToValidate="txtServerName"></asp:RequiredFieldValidator>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="FormLabel150"><asp:Localize ID="locServerComments" runat="server" meta:resourcekey="locServerComments" Text="Server Comments:"></asp:Localize></td>
|
||||
<td class="FormLabel260"><asp:Localize ID="locServerComments" runat="server" meta:resourcekey="locServerComments" Text="Server Comments:"></asp:Localize></td>
|
||||
<td>
|
||||
<asp:TextBox ID="txtServerComments" runat="server" CssClass="NormalTextBox" Width="145px"></asp:TextBox>
|
||||
<asp:TextBox ID="txtServerComments" runat="server" CssClass="NormalTextBox" Width="300px"></asp:TextBox>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -62,8 +62,8 @@ namespace WebsitePanel.Portal
|
|||
ResultObject result = ES.Services.RDS.AddRdsServer(rdsServer);
|
||||
|
||||
if (!result.IsSuccess && result.ErrorCodes.Count > 0)
|
||||
{
|
||||
messageBox.ShowMessage(result, "", "");
|
||||
{
|
||||
messageBox.ShowMessage(result, "RDSSERVER_NOT_ADDED", "");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ namespace WebsitePanel.Portal
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
messageBox.ShowErrorMessage("", ex);
|
||||
ShowErrorMessage("RDSSERVER_NOT_ADDED", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,31 +1,3 @@
|
|||
// Copyright (c) 2015, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue