From 51a51653083d1555f7f9e3c2e6178dbb0dc512bd Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 9 Aug 2014 14:34:34 +0200 Subject: [PATCH] Fix Server --- ServerLib/CServer.cs | 13 +- WebserverInitalConfig/CConfigHttpApi.cs | 5 +- WebserverInitalConfig/HttpApi.cs | 154 ++++++++++++++++++------ WebserverInitalConfig/Program.cs | 35 ++++-- 4 files changed, 151 insertions(+), 56 deletions(-) diff --git a/ServerLib/CServer.cs b/ServerLib/CServer.cs index d0162e74..e4c46301 100644 --- a/ServerLib/CServer.cs +++ b/ServerLib/CServer.cs @@ -16,7 +16,9 @@ #endregion using System; +#if WIN using System.Diagnostics; +#endif using System.ServiceModel; using System.ServiceModel.Web; using System.Net; @@ -160,7 +162,7 @@ namespace ServerLib catch (CommunicationException) { _Host.Abort(); - MessageBox.Show("Problem while initialization of webserver. You may use a different port (Change in config.xml)"); + MessageBox.Show("Problem while initialization of webserver. You may try a different port (Change it in config.xml)"); } } else @@ -188,7 +190,7 @@ namespace ServerLib { FileName = "VocaluxeServerConfig.exe", WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory, - Arguments = port + " " + (_Encrypted ? "true" : "false") + (reserve ? " reserve" : ""), + Arguments = AppDomain.CurrentDomain.FriendlyName + " " + port + " " + (_Encrypted ? "true" : "false") + (reserve ? " true" : ""), UseShellExecute = true, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, @@ -198,10 +200,15 @@ namespace ServerLib using (Process p = Process.Start(info)) { p.WaitForExit(); + if (p.ExitCode != 0) + MessageBox.Show("Registering the Server failed (Code " + p.ExitCode + ")!\r\nThe Server might not work correctly."); p.Close(); } } - catch (Exception) {} + catch (Exception e) + { + MessageBox.Show("Registering the Server failed (" + e + ")!\r\nThe Server might not work correctly."); + } #else //Required? diff --git a/WebserverInitalConfig/CConfigHttpApi.cs b/WebserverInitalConfig/CConfigHttpApi.cs index e13a9cda..90bdfc2b 100644 --- a/WebserverInitalConfig/CConfigHttpApi.cs +++ b/WebserverInitalConfig/CConfigHttpApi.cs @@ -60,9 +60,10 @@ namespace WebserverInitalConfig HttpApi.ReserveURL(networkString, "D:(A;;GX;;;S-1-1-0)"); } - public void ReserveUrl() + public void ReserveUrl(bool secure) { - _ReserveUrl("https://+:" + _Port + "/"); + string http = secure ? "https" : "http"; + _ReserveUrl(http + "://+:" + _Port + "/"); } private void _BindCert(X509Certificate cert) diff --git a/WebserverInitalConfig/HttpApi.cs b/WebserverInitalConfig/HttpApi.cs index 39f587ff..6473afea 100644 --- a/WebserverInitalConfig/HttpApi.cs +++ b/WebserverInitalConfig/HttpApi.cs @@ -25,6 +25,7 @@ using System.Security.Cryptography.X509Certificates; namespace WebserverInitalConfig { + // ReSharper disable InconsistentNaming static class HttpApi { private static readonly HTTPAPI_VERSION HttpApiVersion = new HTTPAPI_VERSION(1, 0); @@ -144,6 +145,14 @@ namespace WebserverInitalConfig public HTTP_SERVICE_CONFIG_URLACL_PARAM ParamDesc; } + [StructLayout(LayoutKind.Sequential)] + private struct HTTP_SERVICE_CONFIG_URLACL_QUERY + { + public HTTP_SERVICE_CONFIG_QUERY_TYPE QueryDesc; + public HTTP_SERVICE_CONFIG_URLACL_KEY KeyDesc; + public uint dwToken; + } + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct HTTP_SERVICE_CONFIG_URLACL_KEY { @@ -227,7 +236,7 @@ namespace WebserverInitalConfig if (retVal == ERROR_FILE_NOT_FOUND) return; - if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122 + if (ERROR_INSUFFICIENT_BUFFER == retVal) { pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength); @@ -431,7 +440,7 @@ namespace WebserverInitalConfig IntPtr.Zero); if (ERROR_NO_MORE_ITEMS == retVal) break; - if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122 + if (ERROR_INSUFFICIENT_BUFFER == retVal) { pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength); @@ -485,6 +494,101 @@ namespace WebserverInitalConfig return result.ToArray(); } + private static HTTP_SERVICE_CONFIG_URLACL_SET QueryReservation(string networkURL) + { + if (String.IsNullOrEmpty(networkURL)) + throw new ArgumentNullException("networkURL"); + HTTP_SERVICE_CONFIG_URLACL_SET res = new HTTP_SERVICE_CONFIG_URLACL_SET(); + res.KeyDesc = new HTTP_SERVICE_CONFIG_URLACL_KEY(""); + CallHttpApi( + delegate + { + HTTP_SERVICE_CONFIG_URLACL_QUERY inputquery = new HTTP_SERVICE_CONFIG_URLACL_QUERY + { + QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact, + KeyDesc = new HTTP_SERVICE_CONFIG_URLACL_KEY(networkURL) + }; + + IntPtr pInputQuery = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_URLACL_QUERY))); + Marshal.StructureToPtr(inputquery, pInputQuery, false); + IntPtr pOutputConfigInfo = IntPtr.Zero; + int returnLength = 0; + try + { + uint retVal = HttpQueryServiceConfiguration(IntPtr.Zero, + HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo, + pInputQuery, + Marshal.SizeOf(inputquery), + pOutputConfigInfo, + returnLength, + out returnLength, + IntPtr.Zero); + if (ERROR_INSUFFICIENT_BUFFER == retVal) + { + pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength); + retVal = HttpQueryServiceConfiguration(IntPtr.Zero, + HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo, + pInputQuery, + Marshal.SizeOf(inputquery), + pOutputConfigInfo, + returnLength, + out returnLength, + IntPtr.Zero); + if (ERROR_FILE_NOT_FOUND == retVal) + return; + ThrowWin32ExceptionIfError(retVal); + res = (HTTP_SERVICE_CONFIG_URLACL_SET)Marshal.PtrToStructure(pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_URLACL_SET)); + } + else if (ERROR_FILE_NOT_FOUND == retVal) + return; + else + ThrowWin32ExceptionIfError(retVal); + } + finally + { + Marshal.FreeCoTaskMem(pInputQuery); + if (pOutputConfigInfo != IntPtr.Zero) + Marshal.FreeCoTaskMem(pOutputConfigInfo); + } + } + ); + return res; + } + + public static uint DeleteReservation(string networkURL) + { + uint retVal = NOERROR; + if (String.IsNullOrEmpty(networkURL)) + throw new ArgumentNullException("networkURL"); + HTTP_SERVICE_CONFIG_URLACL_SET oldReservation = QueryReservation(networkURL); + if (oldReservation.KeyDesc.pUrlPrefix == "" && networkURL.Contains("+")) + { + networkURL = networkURL.Replace('+', '*'); + oldReservation = QueryReservation(networkURL); + } + if (oldReservation.KeyDesc.pUrlPrefix == "") + return ERROR_FILE_NOT_FOUND; + CallHttpApi( + delegate + { + IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_URLACL_SET))); + Marshal.StructureToPtr(oldReservation, pInputConfigInfo, false); + try + { + retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, + HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo, + pInputConfigInfo, + Marshal.SizeOf(oldReservation), + IntPtr.Zero); + } + finally + { + Marshal.FreeCoTaskMem(pInputConfigInfo); + } + }); + return retVal; + } + public static void ReserveURL(string networkURL, string securityDescriptor) { if (String.IsNullOrEmpty(networkURL)) @@ -495,7 +599,7 @@ namespace WebserverInitalConfig CallHttpApi( delegate { - uint retVal = (uint)NOERROR; // NOERROR = 0 + uint retVal; HTTP_SERVICE_CONFIG_URLACL_KEY keyDesc = new HTTP_SERVICE_CONFIG_URLACL_KEY(networkURL); HTTP_SERVICE_CONFIG_URLACL_PARAM paramDesc = new HTTP_SERVICE_CONFIG_URLACL_PARAM(securityDescriptor); @@ -514,13 +618,15 @@ namespace WebserverInitalConfig Marshal.SizeOf(inputConfigInfoSet), IntPtr.Zero); - if (ERROR_ALREADY_EXISTS == retVal) // ERROR_ALREADY_EXISTS = 183 + if (ERROR_ALREADY_EXISTS == retVal) { - retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, - HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo, - pInputConfigInfo, - Marshal.SizeOf(inputConfigInfoSet), - IntPtr.Zero); + retVal = DeleteReservation(networkURL); + if (ERROR_FILE_NOT_FOUND == retVal) + { + string networkURLOld = networkURL.Contains("https") ? networkURL.Replace("https", "http") : + networkURL.Replace("http", "https"); + retVal = DeleteReservation(networkURLOld); + } if (NOERROR == retVal) { @@ -530,41 +636,11 @@ namespace WebserverInitalConfig Marshal.SizeOf(inputConfigInfoSet), IntPtr.Zero); } - else if (ERROR_FILE_NOT_FOUND == retVal) // ERROR_FILE_NOT_FOUND = 2 - { - string networkURLOld = networkURL.Contains("https") ? networkURL.Replace("https", "http") : - networkURL.Replace("http", "https"); - HTTP_SERVICE_CONFIG_URLACL_KEY keyDescOld = new HTTP_SERVICE_CONFIG_URLACL_KEY(networkURLOld); - HTTP_SERVICE_CONFIG_URLACL_PARAM paramDescOld = new HTTP_SERVICE_CONFIG_URLACL_PARAM(securityDescriptor); - - HTTP_SERVICE_CONFIG_URLACL_SET inputConfigInfoSetOld = new HTTP_SERVICE_CONFIG_URLACL_SET(); - inputConfigInfoSetOld.KeyDesc = keyDescOld; - inputConfigInfoSetOld.ParamDesc = paramDescOld; - - IntPtr pInputConfigInfoOld = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_URLACL_SET))); - Marshal.StructureToPtr(inputConfigInfoSetOld, pInputConfigInfoOld, false); - - retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, - HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo, - pInputConfigInfoOld, - Marshal.SizeOf(inputConfigInfoSetOld), - IntPtr.Zero); - - if (NOERROR == retVal) - { - retVal = HttpSetServiceConfiguration(IntPtr.Zero, - HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo, - pInputConfigInfo, - Marshal.SizeOf(inputConfigInfoSet), - IntPtr.Zero); - } - } } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); - HttpTerminate(HTTP_INITIALIZE_CONFIG, IntPtr.Zero); } if (NOERROR != retVal) ThrowWin32ExceptionIfError(retVal); diff --git a/WebserverInitalConfig/Program.cs b/WebserverInitalConfig/Program.cs index d37f51f9..2223c5e8 100644 --- a/WebserverInitalConfig/Program.cs +++ b/WebserverInitalConfig/Program.cs @@ -30,25 +30,29 @@ namespace WebserverInitalConfig private static void Main(string[] args) // ReSharper restore InconsistentNaming { + int result = 0; try { int port; - if (args.Length < 2 || !int.TryParse(args[0], out port)) + if (args.Length < 3 || !int.TryParse(args[1], out port)) { - Console.WriteLine("Usage: VocaluxeServerConfig port isHttps"); - Environment.Exit(-1); + Console.WriteLine("Usage: VocaluxeServerConfig exeName port isHttps [reserve]"); + result = -1; } else { - CConfigHttpApi config = new CConfigHttpApi("Vocaluxe", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Vocaluxe.exe"), "0.0.0.0", port, true); + String exeName = args[0]; + bool isSecure = (args[2].ToLower() == "true"); + bool doReserve = (args.Length >= 4 && args[3].ToLower() == "true"); + CConfigHttpApi config = new CConfigHttpApi(exeName, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, exeName), "0.0.0.0", port, true); try { config.AddFirewallRule(); - if (args[1].ToLower() == "true") + if (isSecure) config.CreateAndAddCert(Dns.GetHostName()); - if ((args.Length >= 3 && args[2] == "reserve") || CConfigHttpApi.IsAdministrator()) - config.ReserveUrl(); + if (doReserve || CConfigHttpApi.IsAdministrator()) + config.ReserveUrl(isSecure); } catch (AuthenticationException) { @@ -56,8 +60,8 @@ namespace WebserverInitalConfig { UseShellExecute = true, WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory, - FileName = Process.GetCurrentProcess().MainModule.FileName, - Arguments = args[0] + " " + args[1], + FileName = AppDomain.CurrentDomain.FriendlyName, + Arguments = String.Join(" ", args), Verb = "runas", CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, @@ -65,21 +69,28 @@ namespace WebserverInitalConfig try { - Process.Start(proc); + using (Process p = Process.Start(proc)) + { + p.WaitForExit(); + result = p.ExitCode; + p.Close(); + } } catch { // The user refused the elevation. // Do nothing and return directly ... - Environment.Exit(-1); + result = -3; } } } } catch (Exception e) { - MessageBox.Show("Error while installing server: " + e.Message); + MessageBox.Show("Error while installing server: " + e.Message + "\r\n\r\nIn " + e.TargetSite + "\r\nBacktrace: " + e.StackTrace); + result = -4; } + Environment.Exit(result); } } } \ No newline at end of file