diff --git a/SimpleDLNA/FormSettings.Designer.cs b/SimpleDLNA/FormSettings.Designer.cs index 13e8a210..7c74915f 100644 --- a/SimpleDLNA/FormSettings.Designer.cs +++ b/SimpleDLNA/FormSettings.Designer.cs @@ -27,137 +27,164 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.numericPort = new System.Windows.Forms.NumericUpDown(); - this.toolTip = new System.Windows.Forms.ToolTip(this.components); - this.textCacheFile = new System.Windows.Forms.TextBox(); - this.groupBox2 = new System.Windows.Forms.GroupBox(); - this.buttonBrowseCacheFile = new System.Windows.Forms.Button(); - this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); - this.checkStartMinimized = new System.Windows.Forms.CheckBox(); - this.checkFileLogging = new System.Windows.Forms.CheckBox(); - this.buttonOK = new System.Windows.Forms.Button(); - this.groupBox1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.numericPort)).BeginInit(); - this.groupBox2.SuspendLayout(); - this.SuspendLayout(); - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.numericPort); - this.groupBox1.Location = new System.Drawing.Point(14, 14); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(303, 55); - this.groupBox1.TabIndex = 1; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Port"; - // - // numericPort - // - this.numericPort.DataBindings.Add(new System.Windows.Forms.Binding("Value", global::NMaier.SimpleDlna.GUI.Properties.Settings.Default, "port", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.numericPort.Location = new System.Drawing.Point(7, 22); - this.numericPort.Maximum = new decimal(new int[] { + this.components = new System.ComponentModel.Container(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.numericPort = new System.Windows.Forms.NumericUpDown(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.textCacheFile = new System.Windows.Forms.TextBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.buttonBrowseCacheFile = new System.Windows.Forms.Button(); + this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); + this.checkStartMinimized = new System.Windows.Forms.CheckBox(); + this.checkFileLogging = new System.Windows.Forms.CheckBox(); + this.buttonOK = new System.Windows.Forms.Button(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.comboInterfaceList = new System.Windows.Forms.ComboBox(); + this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numericPort)).BeginInit(); + this.groupBox2.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.numericPort); + this.groupBox1.Location = new System.Drawing.Point(14, 14); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(303, 55); + this.groupBox1.TabIndex = 1; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Port"; + // + // numericPort + // + this.numericPort.DataBindings.Add(new System.Windows.Forms.Binding("Value", global::NMaier.SimpleDlna.GUI.Properties.Settings.Default, "port", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.numericPort.Location = new System.Drawing.Point(7, 22); + this.numericPort.Maximum = new decimal(new int[] { 65535, 0, 0, 0}); - this.numericPort.Name = "numericPort"; - this.numericPort.Size = new System.Drawing.Size(80, 23); - this.numericPort.TabIndex = 0; - this.toolTip.SetToolTip(this.numericPort, "Port of the http server.\r\nLeave at 0 to automatically have a port selected on sta" + + this.numericPort.Name = "numericPort"; + this.numericPort.Size = new System.Drawing.Size(80, 23); + this.numericPort.TabIndex = 0; + this.toolTip.SetToolTip(this.numericPort, "Port of the http server.\r\nLeave at 0 to automatically have a port selected on sta" + "rtup.\r\n\r\n(Requires restart)"); - this.numericPort.Value = global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.port; - // - // textCacheFile - // - this.textCacheFile.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::NMaier.SimpleDlna.GUI.Properties.Settings.Default, "cache", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.textCacheFile.Location = new System.Drawing.Point(7, 22); - this.textCacheFile.Name = "textCacheFile"; - this.textCacheFile.Size = new System.Drawing.Size(194, 23); - this.textCacheFile.TabIndex = 1; - this.textCacheFile.Text = global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.cache; - this.toolTip.SetToolTip(this.textCacheFile, "Location of the cache directory.\r\nLeave blank to use the default location (TEMP)." + + this.numericPort.Value = global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.port; + // + // textCacheFile + // + this.textCacheFile.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::NMaier.SimpleDlna.GUI.Properties.Settings.Default, "cache", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.textCacheFile.Location = new System.Drawing.Point(7, 22); + this.textCacheFile.Name = "textCacheFile"; + this.textCacheFile.Size = new System.Drawing.Size(194, 23); + this.textCacheFile.TabIndex = 1; + this.textCacheFile.Text = global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.cache; + this.toolTip.SetToolTip(this.textCacheFile, "Location of the cache directory.\r\nLeave blank to use the default location (TEMP)." + "\r\n\r\n(Requires restart)"); - // - // groupBox2 - // - this.groupBox2.Controls.Add(this.buttonBrowseCacheFile); - this.groupBox2.Controls.Add(this.textCacheFile); - this.groupBox2.Location = new System.Drawing.Point(14, 76); - this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(303, 55); - this.groupBox2.TabIndex = 2; - this.groupBox2.TabStop = false; - this.groupBox2.Text = "Cache directory"; - // - // buttonBrowseCacheFile - // - this.buttonBrowseCacheFile.Location = new System.Drawing.Point(209, 20); - this.buttonBrowseCacheFile.Name = "buttonBrowseCacheFile"; - this.buttonBrowseCacheFile.Size = new System.Drawing.Size(87, 27); - this.buttonBrowseCacheFile.TabIndex = 0; - this.buttonBrowseCacheFile.Text = "Browse"; - this.buttonBrowseCacheFile.UseVisualStyleBackColor = true; - this.buttonBrowseCacheFile.Click += new System.EventHandler(this.buttonBrowseCacheFile_Click); - // - // checkStartMinimized - // - this.checkStartMinimized.AutoSize = true; - this.checkStartMinimized.Checked = global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.startminimized; - this.checkStartMinimized.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::NMaier.SimpleDlna.GUI.Properties.Settings.Default, "startminimized", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.checkStartMinimized.Location = new System.Drawing.Point(14, 165); - this.checkStartMinimized.Name = "checkStartMinimized"; - this.checkStartMinimized.Size = new System.Drawing.Size(109, 19); - this.checkStartMinimized.TabIndex = 4; - this.checkStartMinimized.Text = "Start minimized"; - this.checkStartMinimized.UseVisualStyleBackColor = true; - // - // checkFileLogging - // - this.checkFileLogging.AutoSize = true; - this.checkFileLogging.Checked = global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.filelogging; - this.checkFileLogging.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::NMaier.SimpleDlna.GUI.Properties.Settings.Default, "filelogging", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.checkFileLogging.Location = new System.Drawing.Point(14, 138); - this.checkFileLogging.Name = "checkFileLogging"; - this.checkFileLogging.Size = new System.Drawing.Size(200, 19); - this.checkFileLogging.TabIndex = 3; - this.checkFileLogging.Text = "Log diagnostic messages to a file"; - this.checkFileLogging.UseVisualStyleBackColor = true; - // - // buttonOK - // - this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK; - this.buttonOK.Location = new System.Drawing.Point(230, 192); - this.buttonOK.Name = "buttonOK"; - this.buttonOK.Size = new System.Drawing.Size(87, 27); - this.buttonOK.TabIndex = 0; - this.buttonOK.Text = "OK"; - this.buttonOK.UseVisualStyleBackColor = true; - // - // FormSettings - // - this.AcceptButton = this.buttonOK; - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(331, 232); - this.Controls.Add(this.buttonOK); - this.Controls.Add(this.checkFileLogging); - this.Controls.Add(this.checkStartMinimized); - this.Controls.Add(this.groupBox2); - this.Controls.Add(this.groupBox1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.Name = "FormSettings"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Settings"; - this.groupBox1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.numericPort)).EndInit(); - this.groupBox2.ResumeLayout(false); - this.groupBox2.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.buttonBrowseCacheFile); + this.groupBox2.Controls.Add(this.textCacheFile); + this.groupBox2.Location = new System.Drawing.Point(14, 140); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(303, 55); + this.groupBox2.TabIndex = 2; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Cache directory"; + // + // buttonBrowseCacheFile + // + this.buttonBrowseCacheFile.Location = new System.Drawing.Point(209, 20); + this.buttonBrowseCacheFile.Name = "buttonBrowseCacheFile"; + this.buttonBrowseCacheFile.Size = new System.Drawing.Size(87, 27); + this.buttonBrowseCacheFile.TabIndex = 0; + this.buttonBrowseCacheFile.Text = "Browse"; + this.buttonBrowseCacheFile.UseVisualStyleBackColor = true; + this.buttonBrowseCacheFile.Click += new System.EventHandler(this.buttonBrowseCacheFile_Click); + // + // checkStartMinimized + // + this.checkStartMinimized.AutoSize = true; + this.checkStartMinimized.Checked = global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.startminimized; + this.checkStartMinimized.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::NMaier.SimpleDlna.GUI.Properties.Settings.Default, "startminimized", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.checkStartMinimized.Location = new System.Drawing.Point(21, 232); + this.checkStartMinimized.Name = "checkStartMinimized"; + this.checkStartMinimized.Size = new System.Drawing.Size(109, 19); + this.checkStartMinimized.TabIndex = 4; + this.checkStartMinimized.Text = "Start minimized"; + this.checkStartMinimized.UseVisualStyleBackColor = true; + // + // checkFileLogging + // + this.checkFileLogging.AutoSize = true; + this.checkFileLogging.Checked = global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.filelogging; + this.checkFileLogging.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::NMaier.SimpleDlna.GUI.Properties.Settings.Default, "filelogging", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.checkFileLogging.Location = new System.Drawing.Point(21, 205); + this.checkFileLogging.Name = "checkFileLogging"; + this.checkFileLogging.Size = new System.Drawing.Size(200, 19); + this.checkFileLogging.TabIndex = 3; + this.checkFileLogging.Text = "Log diagnostic messages to a file"; + this.checkFileLogging.UseVisualStyleBackColor = true; + // + // buttonOK + // + this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.buttonOK.Location = new System.Drawing.Point(230, 256); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(87, 27); + this.buttonOK.TabIndex = 0; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.comboInterfaceList); + this.groupBox3.Location = new System.Drawing.Point(14, 75); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(303, 59); + this.groupBox3.TabIndex = 5; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "Listen Interface"; + // + // comboInterfaceList + // + this.comboInterfaceList.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboInterfaceList.FormattingEnabled = true; + this.comboInterfaceList.Location = new System.Drawing.Point(7, 22); + this.comboInterfaceList.Name = "comboInterfaceList"; + this.comboInterfaceList.Size = new System.Drawing.Size(289, 23); + this.comboInterfaceList.TabIndex = 0; + this.comboInterfaceList.SelectedIndexChanged += new System.EventHandler(this.comboInterfaceList_SelectedIndexChanged); + // + // FormSettings + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(331, 296); + this.Controls.Add(this.groupBox3); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.checkFileLogging); + this.Controls.Add(this.checkStartMinimized); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Name = "FormSettings"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Settings"; + this.Load += new System.EventHandler(this.FormSettings_Load); + this.groupBox1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.numericPort)).EndInit(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); } @@ -173,5 +200,7 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox checkStartMinimized; private System.Windows.Forms.CheckBox checkFileLogging; private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.ComboBox comboInterfaceList; } } \ No newline at end of file diff --git a/SimpleDLNA/FormSettings.cs b/SimpleDLNA/FormSettings.cs index 00e51fd5..4d9b2972 100644 --- a/SimpleDLNA/FormSettings.cs +++ b/SimpleDLNA/FormSettings.cs @@ -1,21 +1,76 @@ using System; using System.Windows.Forms; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; namespace NMaier.SimpleDlna.GUI { - public partial class FormSettings : NMaier.Windows.Forms.Form - { - public FormSettings() + public partial class FormSettings : NMaier.Windows.Forms.Form { - InitializeComponent(); - Icon = Properties.Resources.preferencesIcon; - } + public FormSettings() + { + InitializeComponent(); + Icon = Properties.Resources.preferencesIcon; + } - private void buttonBrowseCacheFile_Click(object sender, EventArgs e) - { - if (folderBrowserDialog.ShowDialog() == DialogResult.OK) { - textCacheFile.Text = folderBrowserDialog.SelectedPath; - } + private void buttonBrowseCacheFile_Click(object sender, EventArgs e) + { + if (folderBrowserDialog.ShowDialog() == DialogResult.OK) + { + textCacheFile.Text = folderBrowserDialog.SelectedPath; + } + } + + private void buttonOK_Click(object sender, EventArgs e) + { + + } + + private void FormSettings_Load(object sender, EventArgs e) + { + comboInterfaceList.Items.Add("Auto"); + if (global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.listeninterface == "Auto") + { + comboInterfaceList.SelectedItem = ("Auto"); + } + + foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces()) + { + IPInterfaceProperties ipProps = netInterface.GetIPProperties(); + foreach (UnicastIPAddressInformation addr in ipProps.UnicastAddresses) + { + if (addr.Address.AddressFamily == AddressFamily.InterNetwork) + { + comboInterfaceList.Items.Add(addr.Address.ToString() + " (" + netInterface.Name + ")"); + } + + if (netInterface.Id == global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.listeninterface) + { + comboInterfaceList.SelectedItem = (addr.Address.ToString() + " (" + netInterface.Name + ")"); + } + } + } + + } + + private void comboInterfaceList_SelectedIndexChanged(object sender, EventArgs e) + { + for (int i = 0; i < comboInterfaceList.Items.Count; i++) + { + foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces()) + { + if (comboInterfaceList.Text.Contains(netInterface.Name)) + { + global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.listeninterface = (netInterface.Id); + return; + } + } + } + global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.listeninterface = ("Auto"); + + } } - } } diff --git a/SimpleDLNA/Properties/Settings.Designer.cs b/SimpleDLNA/Properties/Settings.Designer.cs index db06330a..137bfd1d 100644 --- a/SimpleDLNA/Properties/Settings.Designer.cs +++ b/SimpleDLNA/Properties/Settings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18444 +// Runtime Version:4.0.30319.34209 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -82,5 +82,17 @@ public bool startminimized { this["startminimized"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Auto")] + public string listeninterface { + get { + return ((string)(this["listeninterface"])); + } + set { + this["listeninterface"] = value; + } + } } } diff --git a/SimpleDLNA/Properties/Settings.settings b/SimpleDLNA/Properties/Settings.settings index 8a76ab1f..e9fa13d4 100644 --- a/SimpleDLNA/Properties/Settings.settings +++ b/SimpleDLNA/Properties/Settings.settings @@ -17,5 +17,8 @@ False + + Auto + \ No newline at end of file diff --git a/SimpleDLNA/ServerListViewItem.cs b/SimpleDLNA/ServerListViewItem.cs index 4fcc465e..c0499008 100644 --- a/SimpleDLNA/ServerListViewItem.cs +++ b/SimpleDLNA/ServerListViewItem.cs @@ -124,7 +124,7 @@ where d.Exists authorizer.AddMethod(new UserAgentAuthorizer(Description.UserAgents)); } fileServer.Authorizer = authorizer; - server.RegisterMediaServer(fileServer); + server.RegisterMediaServer(fileServer, global::NMaier.SimpleDlna.GUI.Properties.Settings.Default.listeninterface); state = State.Running; var elapsed = DateTime.Now - start; LogManager.GetLogger("State").Logger.Log( diff --git a/SimpleDLNA/app.config b/SimpleDLNA/app.config index a3471e29..53c487f5 100644 --- a/SimpleDLNA/app.config +++ b/SimpleDLNA/app.config @@ -22,6 +22,9 @@ False + + Auto + \ No newline at end of file diff --git a/UpgradeLog.htm b/UpgradeLog.htm new file mode 100644 index 00000000..bca6dcac Binary files /dev/null and b/UpgradeLog.htm differ diff --git a/sdlna.sln b/sdlna.sln index 6e569fae..ece2548d 100644 --- a/sdlna.sln +++ b/sdlna.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30501.0 +VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sdlna", "sdlna\sdlna.csproj", "{C99E77FD-0728-4A2F-A9C0-47AAC7CAEFED}" EndProject @@ -22,8 +22,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "util", "util\util.csproj", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleDLNA", "SimpleDLNA\SimpleDLNA.csproj", "{9BAEFB29-C818-446B-9BB5-014E6A0CBB49}" EndProject -Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "setup", "setup\setup.vdproj", "{3C78015C-E0A0-45BD-BE00-FEF8D1477DAE}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Global", "Global", "{4710D7C1-4ADC-4D3E-BD48-3295B7573B2A}" ProjectSection(SolutionItems) = preProject GlobalAssemblyInfo.cs = GlobalAssemblyInfo.cs @@ -62,8 +60,6 @@ Global {9BAEFB29-C818-446B-9BB5-014E6A0CBB49}.Debug|Any CPU.Build.0 = Debug|Any CPU {9BAEFB29-C818-446B-9BB5-014E6A0CBB49}.Release|Any CPU.ActiveCfg = Release|Any CPU {9BAEFB29-C818-446B-9BB5-014E6A0CBB49}.Release|Any CPU.Build.0 = Release|Any CPU - {3C78015C-E0A0-45BD-BE00-FEF8D1477DAE}.Debug|Any CPU.ActiveCfg = Debug - {3C78015C-E0A0-45BD-BE00-FEF8D1477DAE}.Release|Any CPU.ActiveCfg = Release {56667283-EBCD-4D63-BF61-FF319CB28A0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {56667283-EBCD-4D63-BF61-FF319CB28A0B}.Debug|Any CPU.Build.0 = Debug|Any CPU {56667283-EBCD-4D63-BF61-FF319CB28A0B}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/sdlna/Program.cs b/sdlna/Program.cs index 59feb970..ac4f0fb3 100644 --- a/sdlna/Program.cs +++ b/sdlna/Program.cs @@ -128,7 +128,7 @@ private static void Main(string[] args) var fs = SetupFileServer( options, types, new DirectoryInfo[] { d }); friendlyName = fs.FriendlyName; - server.RegisterMediaServer(fs); + server.RegisterMediaServer(fs, "Auto"); server.NoticeFormat("{0} mounted", d.FullName); } } @@ -138,7 +138,7 @@ private static void Main(string[] args) options.Directories[0], options.Directories.Length); var fs = SetupFileServer(options, types, options.Directories); friendlyName = fs.FriendlyName; - server.RegisterMediaServer(fs); + server.RegisterMediaServer(fs, "Auto"); server.NoticeFormat( "{0} ({1}) mounted", options.Directories[0], options.Directories.Length); diff --git a/server/Http/HTTPServer.cs b/server/Http/HTTPServer.cs index 8bbe6e33..a9635a76 100644 --- a/server/Http/HTTPServer.cs +++ b/server/Http/HTTPServer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Net.NetworkInformation; using System.Linq; using System.Net; using System.Net.Sockets; @@ -11,300 +12,378 @@ namespace NMaier.SimpleDlna.Server { - public sealed class HttpServer : Logging, IDisposable - { - private readonly ConcurrentDictionary clients = - new ConcurrentDictionary(); - - private readonly ConcurrentDictionary prefixes = - new ConcurrentDictionary(); - - private readonly ConcurrentDictionary> devicesForServers = - new ConcurrentDictionary>(); - - private readonly ConcurrentDictionary servers = - new ConcurrentDictionary(); + public sealed class HttpServer : Logging, IDisposable + { + private readonly ConcurrentDictionary clients = + new ConcurrentDictionary(); - public static readonly string Signature = GenerateServerSignature(); + private readonly ConcurrentDictionary prefixes = + new ConcurrentDictionary(); - private readonly Timer timeouter = new Timer(10 * 1000); + private readonly ConcurrentDictionary> devicesForServers = + new ConcurrentDictionary>(); - private readonly TcpListener listener = null; + private readonly ConcurrentDictionary servers = + new ConcurrentDictionary(); - private readonly SsdpHandler ssdpServer; + public static readonly string Signature = GenerateServerSignature(); - public HttpServer() - : this(port: 0) - { - } + private readonly Timer timeouter = new Timer(10 * 1000); - public HttpServer(int port) - { - prefixes.TryAdd( - "/favicon.ico", - new StaticHandler( - new ResourceResponse(HttpCode.Ok, "image/icon", "favicon")) - ); - prefixes.TryAdd( - "/static/browse.css", - new StaticHandler( - new ResourceResponse(HttpCode.Ok, "text/css", "browse_css")) - ); - RegisterHandler(new IconHandler()); - - listener = new TcpListener(new IPEndPoint(IPAddress.Any, port)); - listener.Server.Ttl = 32; - listener.Server.UseOnlyOverlappedIO = true; - listener.Start(); - - RealPort = (listener.LocalEndpoint as IPEndPoint).Port; - - NoticeFormat( - "Running HTTP Server: {0} on port {1}", Signature, RealPort); - ssdpServer = new SsdpHandler(); - - timeouter.Elapsed += TimeouterCallback; - timeouter.Enabled = true; - - Accept(); - } + private readonly TcpListener listener = null; - public event EventHandler OnAuthorizeClient; + private readonly SsdpHandler ssdpServer; - public Dictionary MediaMounts - { - get - { - var rv = new Dictionary(); - foreach (var m in servers) { - rv[m.Value.Prefix] = m.Value.FriendlyName; + public HttpServer() + : this(port: 0) + { } - return rv; - } - } - - public int RealPort { get; private set; } - private void Accept() - { - try { - if (!listener.Server.IsBound) { - return; + public HttpServer(int port) + { + prefixes.TryAdd( + "/favicon.ico", + new StaticHandler( + new ResourceResponse(HttpCode.Ok, "image/icon", "favicon")) + ); + prefixes.TryAdd( + "/static/browse.css", + new StaticHandler( + new ResourceResponse(HttpCode.Ok, "text/css", "browse_css")) + ); + RegisterHandler(new IconHandler()); + + listener = new TcpListener(new IPEndPoint(IPAddress.Any, port)); + listener.Server.Ttl = 32; + listener.Server.UseOnlyOverlappedIO = true; + listener.Start(); + + RealPort = (listener.LocalEndpoint as IPEndPoint).Port; + + NoticeFormat( + "Running HTTP Server: {0} on port {1}", Signature, RealPort); + ssdpServer = new SsdpHandler(); + + timeouter.Elapsed += TimeouterCallback; + timeouter.Enabled = true; + + Accept(); } - listener.BeginAcceptTcpClient(AcceptCallback, null); - } - catch (ObjectDisposedException) { - } - catch (Exception ex) { - Fatal("Failed to accept", ex); - } - } - private void AcceptCallback(IAsyncResult result) - { - try { - var tcpclient = listener.EndAcceptTcpClient(result); - var client = new HttpClient(this, tcpclient); - try { - clients.AddOrUpdate(client, DateTime.Now, (k, v) => - { - return DateTime.Now; - }); - DebugFormat("Accepted client {0}", client); - client.Start(); - } - catch (Exception) { - client.Dispose(); - throw; + public event EventHandler OnAuthorizeClient; + + public Dictionary MediaMounts + { + get + { + var rv = new Dictionary(); + foreach (var m in servers) + { + rv[m.Value.Prefix] = m.Value.FriendlyName; + } + return rv; + } } - } - catch (ObjectDisposedException) { - } - catch (Exception ex) { - Error("Failed to accept a client", ex); - } - finally { - Accept(); - } - } - private static string GenerateServerSignature() - { - var os = Environment.OSVersion; - var pstring = os.Platform.ToString(); - switch (os.Platform) { - case PlatformID.Win32NT: - case PlatformID.Win32S: - case PlatformID.Win32Windows: - pstring = "WIN"; - break; - default: - break; - } - return String.Format( - "{0}{1}/{2}.{3} UPnP/1.0 DLNADOC/1.5 sdlna/{4}.{5}", - pstring, - IntPtr.Size * 8, - os.Version.Major, - os.Version.Minor, - Assembly.GetExecutingAssembly().GetName().Version.Major, - Assembly.GetExecutingAssembly().GetName().Version.Minor - ); - } - - private void TimeouterCallback(object sender, ElapsedEventArgs e) - { - foreach (var c in clients.ToList()) { - if (c.Key.IsATimeout) { - DebugFormat("Collected timeout client {0}", c); - c.Key.Close(); + public int RealPort { get; private set; } + + private void Accept() + { + try + { + if (!listener.Server.IsBound) + { + return; + } + listener.BeginAcceptTcpClient(AcceptCallback, null); + } + catch (ObjectDisposedException) + { + } + catch (Exception ex) + { + Fatal("Failed to accept", ex); + } } - } - } - internal bool AuthorizeClient(HttpClient client) - { - if (OnAuthorizeClient == null) { - return true; - } - if (IPAddress.IsLoopback(client.RemoteEndpoint.Address)) { - return true; - } - var e = new HttpAuthorizationEventArgs( - client.Headers, client.RemoteEndpoint); - OnAuthorizeClient(this, e); - return !e.Cancel; - } - - internal IPrefixHandler FindHandler(string prefix) - { - if (string.IsNullOrEmpty(prefix)) { - throw new ArgumentNullException("prefix"); - } + private void AcceptCallback(IAsyncResult result) + { + try + { + var tcpclient = listener.EndAcceptTcpClient(result); + var client = new HttpClient(this, tcpclient); + try + { + clients.AddOrUpdate(client, DateTime.Now, (k, v) => + { + return DateTime.Now; + }); + DebugFormat("Accepted client {0}", client); + client.Start(); + } + catch (Exception) + { + client.Dispose(); + throw; + } + } + catch (ObjectDisposedException) + { + } + catch (Exception ex) + { + Error("Failed to accept a client", ex); + } + finally + { + Accept(); + } + } - if (prefix == "/") { - return new IndexHandler(this); - } + private static string GenerateServerSignature() + { + var os = Environment.OSVersion; + var pstring = os.Platform.ToString(); + switch (os.Platform) + { + case PlatformID.Win32NT: + case PlatformID.Win32S: + case PlatformID.Win32Windows: + pstring = "WIN"; + break; + default: + break; + } + return String.Format( + "{0}{1}/{2}.{3} UPnP/1.0 DLNADOC/1.5 sdlna/{4}.{5}", + pstring, + IntPtr.Size * 8, + os.Version.Major, + os.Version.Minor, + Assembly.GetExecutingAssembly().GetName().Version.Major, + Assembly.GetExecutingAssembly().GetName().Version.Minor + ); + } - foreach (var s in prefixes.Keys) { - if (prefix.StartsWith(s, StringComparison.Ordinal)) { - return prefixes[s]; + private void TimeouterCallback(object sender, ElapsedEventArgs e) + { + foreach (var c in clients.ToList()) + { + if (c.Key.IsATimeout) + { + DebugFormat("Collected timeout client {0}", c); + c.Key.Close(); + } + } } - } - return null; - } - internal void RegisterHandler(IPrefixHandler handler) - { - if (handler == null) { - throw new ArgumentNullException("handler"); - } - var prefix = handler.Prefix; - if (!prefix.StartsWith("/", StringComparison.Ordinal)) { - throw new ArgumentException("Invalid prefix; must start with /"); - } - if (!prefix.EndsWith("/", StringComparison.Ordinal)) { - throw new ArgumentException("Invalid prefix; must end with /"); - } - if (FindHandler(prefix) != null) { - throw new ArgumentException("Invalid prefix; already taken"); - } - if (!prefixes.TryAdd(prefix, handler)) { - throw new ArgumentException("Invalid preifx; already taken"); - } - DebugFormat("Registered Handler for {0}", prefix); - } + internal bool AuthorizeClient(HttpClient client) + { + if (OnAuthorizeClient == null) + { + return true; + } + if (IPAddress.IsLoopback(client.RemoteEndpoint.Address)) + { + return true; + } + var e = new HttpAuthorizationEventArgs( + client.Headers, client.RemoteEndpoint); + OnAuthorizeClient(this, e); + return !e.Cancel; + } - internal void RemoveClient(HttpClient client) - { - DateTime ignored; - clients.TryRemove(client, out ignored); - } + internal IPrefixHandler FindHandler(string prefix) + { + if (string.IsNullOrEmpty(prefix)) + { + throw new ArgumentNullException("prefix"); + } + + if (prefix == "/") + { + return new IndexHandler(this); + } + + foreach (var s in prefixes.Keys) + { + if (prefix.StartsWith(s, StringComparison.Ordinal)) + { + return prefixes[s]; + } + } + return null; + } - internal void UnregisterHandler(IPrefixHandler handler) - { - IPrefixHandler ignored; - if (prefixes.TryRemove(handler.Prefix, out ignored)) { - DebugFormat("Unregistered Handler for {0}", handler.Prefix); - } - } + internal void RegisterHandler(IPrefixHandler handler) + { + if (handler == null) + { + throw new ArgumentNullException("handler"); + } + var prefix = handler.Prefix; + if (!prefix.StartsWith("/", StringComparison.Ordinal)) + { + throw new ArgumentException("Invalid prefix; must start with /"); + } + if (!prefix.EndsWith("/", StringComparison.Ordinal)) + { + throw new ArgumentException("Invalid prefix; must end with /"); + } + if (FindHandler(prefix) != null) + { + throw new ArgumentException("Invalid prefix; already taken"); + } + if (!prefixes.TryAdd(prefix, handler)) + { + throw new ArgumentException("Invalid preifx; already taken"); + } + DebugFormat("Registered Handler for {0}", prefix); + } - public void Dispose() - { - Debug("Disposing HTTP"); - timeouter.Enabled = false; - foreach (var s in servers.Values.ToList()) { - UnregisterMediaServer(s); - } - ssdpServer.Dispose(); - timeouter.Dispose(); - listener.Stop(); - foreach (var c in clients.ToList()) { - c.Key.Dispose(); - } - clients.Clear(); - } + internal void RemoveClient(HttpClient client) + { + DateTime ignored; + clients.TryRemove(client, out ignored); + } - public void RegisterMediaServer(IMediaServer server) - { - if (server == null) { - throw new ArgumentNullException("server"); - } - var guid = server.Uuid; - if (servers.ContainsKey(guid)) { - throw new ArgumentException("Attempting to register more than once"); - } - - var end = listener.LocalEndpoint as IPEndPoint; - var mount = new MediaMount(server); - servers[guid] = mount; - RegisterHandler(mount); - - foreach (var address in IP.ExternalIPAddresses) { - DebugFormat("Registering device for {0}", address); - var deviceGuid = Guid.NewGuid(); - var list = devicesForServers.GetOrAdd(guid, new List()); - lock (list) { - list.Add(deviceGuid); + internal void UnregisterHandler(IPrefixHandler handler) + { + IPrefixHandler ignored; + if (prefixes.TryRemove(handler.Prefix, out ignored)) + { + DebugFormat("Unregistered Handler for {0}", handler.Prefix); + } } - mount.AddDeviceGuid(deviceGuid, address); - var uri = new Uri(string.Format( - "http://{0}:{1}{2}", - address, - end.Port, - mount.DescriptorURI - )); - ssdpServer.RegisterNotification(deviceGuid, uri, address); - NoticeFormat("New mount at: {0}", uri); - } - } - public void UnregisterMediaServer(IMediaServer server) - { - if (server == null) { - throw new ArgumentNullException("server"); - } - MediaMount mount; - if (!servers.TryGetValue(server.Uuid, out mount)) { - return; - } - - List list; - if (devicesForServers.TryGetValue(server.Uuid, out list)) { - lock (list) { - foreach (var deviceGuid in list) { - ssdpServer.UnregisterNotification(deviceGuid); - } + public void Dispose() + { + Debug("Disposing HTTP"); + timeouter.Enabled = false; + foreach (var s in servers.Values.ToList()) + { + UnregisterMediaServer(s); + } + ssdpServer.Dispose(); + timeouter.Dispose(); + listener.Stop(); + foreach (var c in clients.ToList()) + { + c.Key.Dispose(); + } + clients.Clear(); } - devicesForServers.TryRemove(server.Uuid, out list); - } - UnregisterHandler(mount); + public void RegisterMediaServer(IMediaServer server, String listenID) + { + if (server == null) + { + throw new ArgumentNullException("server"); + } + var guid = server.Uuid; + if (servers.ContainsKey(guid)) + { + throw new ArgumentException("Attempting to register more than once"); + } + var end = listener.LocalEndpoint as IPEndPoint; + var mount = new MediaMount(server); + servers[guid] = mount; + RegisterHandler(mount); + + IPAddress overrideIP = null; + foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces()) + { + if (listenID == "Auto") + { + + } + else if (listenID == netInterface.Id) + { + IPInterfaceProperties ipProps = netInterface.GetIPProperties(); + foreach (UnicastIPAddressInformation addr in ipProps.UnicastAddresses) + { + if (addr.Address.AddressFamily == AddressFamily.InterNetwork) + { + overrideIP = addr.Address; + } + } + } + else + { + + } + } + + foreach (var address in IP.ExternalIPAddresses) + { + DebugFormat("Registering device for {0}", address); + var deviceGuid = Guid.NewGuid(); + var list = devicesForServers.GetOrAdd(guid, new List()); + lock (list) + { + list.Add(deviceGuid); + } + + if (overrideIP == null) + { + mount.AddDeviceGuid(deviceGuid, address); + var uri = new Uri(string.Format( + "http://{0}:{1}{2}", + address, + end.Port, + mount.DescriptorURI + )); + ssdpServer.RegisterNotification(deviceGuid, uri, address); + NoticeFormat("New mount at: {0}", uri); + } + else + { + mount.AddDeviceGuid(deviceGuid, overrideIP); + var uri = new Uri(string.Format( + "http://{0}:{1}{2}", + overrideIP, + end.Port, + mount.DescriptorURI + )); + ssdpServer.RegisterNotification(deviceGuid, uri, address); + NoticeFormat("New mount at: {0}", uri); + } + + } + } - MediaMount ignored; - if (servers.TryRemove(server.Uuid, out ignored)) { - InfoFormat("Unregistered Media Server {0}", server.Uuid); - } + public void UnregisterMediaServer(IMediaServer server) + { + if (server == null) + { + throw new ArgumentNullException("server"); + } + MediaMount mount; + if (!servers.TryGetValue(server.Uuid, out mount)) + { + return; + } + + List list; + if (devicesForServers.TryGetValue(server.Uuid, out list)) + { + lock (list) + { + foreach (var deviceGuid in list) + { + ssdpServer.UnregisterNotification(deviceGuid); + } + } + devicesForServers.TryRemove(server.Uuid, out list); + } + + UnregisterHandler(mount); + + MediaMount ignored; + if (servers.TryRemove(server.Uuid, out ignored)) + { + InfoFormat("Unregistered Media Server {0}", server.Uuid); + } + } } - } } diff --git a/util/IP.cs b/util/IP.cs index e8abb665..63e6451f 100644 --- a/util/IP.cs +++ b/util/IP.cs @@ -49,6 +49,7 @@ public static IEnumerable ExternalIPAddresses private static IEnumerable GetIPsDefault() { var returned = false; + foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) { var props = adapter.GetIPProperties(); var gateways = from ga in props.GatewayAddresses