/
TVRadio.cs
771 lines (694 loc) · 30.1 KB
/
TVRadio.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
#region Copyright (C) 2005-2011 Team MediaPortal
// Copyright (C) 2005-2011 Team MediaPortal
// http://www.team-mediaportal.com
//
// MediaPortal is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// MediaPortal is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with MediaPortal. If not, see <http://www.gnu.org/licenses/>.
#endregion
#region Using
using System;
using System.Collections;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using MediaPortal.GUI.Library;
using MediaPortal.Profile;
using MediaPortal.UserInterface.Controls;
#endregion
#pragma warning disable 108
namespace MediaPortal.Configuration.Sections
{
public class TVRadio : SectionSettings
{
#region Variables
/// <summary>
/// The verified hostname of the TV Server
/// </summary>
private static string _verifiedHostname = string.Empty;
/// <summary>
/// The hostname from the settings
/// </summary>
private string _settingsHostname;
public int pluginVersion;
#endregion
#region Constructor
public TVRadio()
: this("TV/Radio") {}
public TVRadio(string name)
: base(name)
{
// This call is required by the Windows Form Designer.
InitializeComponent();
}
#endregion
#region Public methods and properties
public override void LoadSettings()
{
using (Settings xmlreader = new MPSettings())
{
// Get hostname entry
_settingsHostname = xmlreader.GetValueAsString("tvservice", "hostname", string.Empty);
if (string.IsNullOrEmpty(_settingsHostname))
{
// Set hostname to local host
mpTextBoxHostname.Text = Dns.GetHostName();
_verifiedHostname = string.Empty;
Log.Debug("LoadSettings: set hostname to local host: \"{0}\"", mpTextBoxHostname.Text);
}
else
{
// Take verified hostname from MediaPortal.xml
mpTextBoxHostname.Text = _settingsHostname;
_verifiedHostname = mpTextBoxHostname.Text;
mpTextBoxHostname.BackColor = Color.YellowGreen;
Log.Debug("LoadSettings: take hostname from settings: \"{0}\"", mpTextBoxHostname.Text);
}
mpCheckBoxIsWakeOnLanEnabled.Checked = xmlreader.GetValueAsBool("tvservice", "isWakeOnLanEnabled", false);
mpNumericTextBoxWOLTimeOut.Text = xmlreader.GetValueAsString("tvservice", "WOLTimeOut", "10");
mpCheckBoxIsAutoMacAddressEnabled.Checked = xmlreader.GetValueAsBool("tvservice", "isAutoMacAddressEnabled",
true);
mpTextBoxMacAddress.Text = xmlreader.GetValueAsString("tvservice", "macAddress", "00:00:00:00:00:00");
mpCheckBoxIsWakeOnLanEnabled_CheckedChanged(null, null);
}
}
public override void SaveSettings()
{
using (Settings xmlwriter = new MPSettings())
{
// If hostname is empty, use local hostname
if (string.IsNullOrEmpty(mpTextBoxHostname.Text))
mpTextBoxHostname.Text = Dns.GetHostName();
// Save hostname only, if it is verified
if (mpTextBoxHostname.BackColor == Color.YellowGreen ||
(mpTextBoxHostname.BackColor != Color.Red && VerifyHostname(mpTextBoxHostname.Text, verbose)))
{
// Hostname is valid, update database connection
Log.Debug("SaveSettings: hostname is valid - update gentle.config if needed");
if (UpdateGentleConfig(mpTextBoxHostname.Text, mpTextBoxHostname.Text.Equals(_settingsHostname)))
{
Log.Debug("SaveSettings: update gentle.config was successfull - save hostname");
xmlwriter.SetValue("tvservice", "hostname", mpTextBoxHostname.Text);
_verifiedHostname = mpTextBoxHostname.Text;
}
else
{
Log.Debug("SaveSettings: error in updating gentle.config - save empty string");
xmlwriter.SetValue("tvservice", "hostname", string.Empty);
mpTextBoxHostname.BackColor = Color.Red;
_verifiedHostname = string.Empty;
}
}
else
{
// Hostname is invalid
Log.Debug("SaveSettings: hostname is invalid - save empty string");
mpTextBoxHostname.BackColor = Color.Red;
xmlwriter.SetValue("tvservice", "hostname", string.Empty);
_verifiedHostname = string.Empty;
}
xmlwriter.SetValueAsBool("tvservice", "isWakeOnLanEnabled", mpCheckBoxIsWakeOnLanEnabled.Checked);
xmlwriter.SetValue("tvservice", "WOLTimeOut", mpNumericTextBoxWOLTimeOut.Text);
xmlwriter.SetValueAsBool("tvservice", "isAutoMacAddressEnabled", mpCheckBoxIsAutoMacAddressEnabled.Checked);
xmlwriter.SetValue("tvservice", "macAddress", mpTextBoxMacAddress.Text);
}
}
public static string Hostname
{
get { return _verifiedHostname; }
}
#endregion
#region Designer generated code
private MPRadioButton radioButton1;
private MPGroupBox mpGroupBox2;
private MPButton mpButtonTestConnection;
private MPTextBox mpTextBoxHostname;
private MPComboBox mpComboBoxHostname;
private MPLabel mpLabel3;
private MPGroupBox mpGroupBox900;
private MPNumericTextBox mpNumericTextBoxWOLTimeOut;
private MPLabel mpLabelWOLTimeOut;
private MPTextBox mpTextBoxMacAddress;
private MPLabel mpLabel400;
private MPCheckBox mpCheckBoxIsAutoMacAddressEnabled;
private MPCheckBox mpCheckBoxIsWakeOnLanEnabled;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.radioButton1 = new MediaPortal.UserInterface.Controls.MPRadioButton();
this.mpGroupBox2 = new MediaPortal.UserInterface.Controls.MPGroupBox();
this.mpTextBoxHostname = new MediaPortal.UserInterface.Controls.MPTextBox();
this.mpButtonTestConnection = new MediaPortal.UserInterface.Controls.MPButton();
this.mpLabel3 = new MediaPortal.UserInterface.Controls.MPLabel();
this.mpComboBoxHostname = new MediaPortal.UserInterface.Controls.MPComboBox();
this.mpGroupBox900 = new MediaPortal.UserInterface.Controls.MPGroupBox();
this.mpNumericTextBoxWOLTimeOut = new MediaPortal.UserInterface.Controls.MPNumericTextBox();
this.mpLabelWOLTimeOut = new MediaPortal.UserInterface.Controls.MPLabel();
this.mpTextBoxMacAddress = new MediaPortal.UserInterface.Controls.MPTextBox();
this.mpLabel400 = new MediaPortal.UserInterface.Controls.MPLabel();
this.mpCheckBoxIsAutoMacAddressEnabled = new MediaPortal.UserInterface.Controls.MPCheckBox();
this.mpCheckBoxIsWakeOnLanEnabled = new MediaPortal.UserInterface.Controls.MPCheckBox();
this.mpGroupBox2.SuspendLayout();
this.mpGroupBox900.SuspendLayout();
this.SuspendLayout();
//
// radioButton1
//
this.radioButton1.AutoSize = true;
this.radioButton1.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.radioButton1.Location = new System.Drawing.Point(0, 0);
this.radioButton1.Name = "radioButton1";
this.radioButton1.Size = new System.Drawing.Size(104, 24);
this.radioButton1.TabIndex = 0;
this.radioButton1.UseVisualStyleBackColor = true;
//
// mpGroupBox2
//
this.mpGroupBox2.Controls.Add(this.mpTextBoxHostname);
this.mpGroupBox2.Controls.Add(this.mpButtonTestConnection);
this.mpGroupBox2.Controls.Add(this.mpLabel3);
this.mpGroupBox2.Controls.Add(this.mpComboBoxHostname);
this.mpGroupBox2.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.mpGroupBox2.Location = new System.Drawing.Point(6, 0);
this.mpGroupBox2.Name = "mpGroupBox2";
this.mpGroupBox2.Size = new System.Drawing.Size(462, 53);
this.mpGroupBox2.TabIndex = 17;
this.mpGroupBox2.TabStop = false;
this.mpGroupBox2.Text = "TV-Server";
//
// mpTextBoxHostname
//
this.mpTextBoxHostname.BorderColor = System.Drawing.Color.Empty;
this.mpTextBoxHostname.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.mpTextBoxHostname.Location = new System.Drawing.Point(129, 25);
this.mpTextBoxHostname.Multiline = true;
this.mpTextBoxHostname.Name = "mpTextBoxHostname";
this.mpTextBoxHostname.Size = new System.Drawing.Size(141, 15);
this.mpTextBoxHostname.TabIndex = 1;
this.mpTextBoxHostname.TextChanged += new System.EventHandler(this.mpTextBoxHostname_TextChanged);
//
// mpButtonTestConnection
//
this.mpButtonTestConnection.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.mpButtonTestConnection.Location = new System.Drawing.Point(325, 21);
this.mpButtonTestConnection.Name = "mpButtonTestConnection";
this.mpButtonTestConnection.Size = new System.Drawing.Size(131, 23);
this.mpButtonTestConnection.TabIndex = 3;
this.mpButtonTestConnection.Text = "Test connection";
this.mpButtonTestConnection.UseVisualStyleBackColor = true;
this.mpButtonTestConnection.Click += new System.EventHandler(this.mpButtonTestConnection_Click);
//
// mpLabel3
//
this.mpLabel3.AutoSize = true;
this.mpLabel3.Location = new System.Drawing.Point(19, 25);
this.mpLabel3.Name = "mpLabel3";
this.mpLabel3.Size = new System.Drawing.Size(58, 13);
this.mpLabel3.TabIndex = 5;
this.mpLabel3.Text = "Hostname:";
//
// mpComboBoxHostname
//
this.mpComboBoxHostname.BorderColor = System.Drawing.Color.Empty;
this.mpComboBoxHostname.FormattingEnabled = true;
this.mpComboBoxHostname.Location = new System.Drawing.Point(126, 22);
this.mpComboBoxHostname.Name = "mpComboBoxHostname";
this.mpComboBoxHostname.Size = new System.Drawing.Size(164, 21);
this.mpComboBoxHostname.TabIndex = 2;
this.mpComboBoxHostname.DropDown += new System.EventHandler(this.mpComboBoxHostname_DropDown);
this.mpComboBoxHostname.SelectionChangeCommitted += new System.EventHandler(this.mpComboBoxHostname_SelectionChangeCommitted);
//
// mpGroupBox900
//
this.mpGroupBox900.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.mpGroupBox900.Controls.Add(this.mpNumericTextBoxWOLTimeOut);
this.mpGroupBox900.Controls.Add(this.mpLabelWOLTimeOut);
this.mpGroupBox900.Controls.Add(this.mpTextBoxMacAddress);
this.mpGroupBox900.Controls.Add(this.mpLabel400);
this.mpGroupBox900.Controls.Add(this.mpCheckBoxIsAutoMacAddressEnabled);
this.mpGroupBox900.Controls.Add(this.mpCheckBoxIsWakeOnLanEnabled);
this.mpGroupBox900.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.mpGroupBox900.Location = new System.Drawing.Point(6, 59);
this.mpGroupBox900.Name = "mpGroupBox900";
this.mpGroupBox900.Size = new System.Drawing.Size(462, 126);
this.mpGroupBox900.TabIndex = 18;
this.mpGroupBox900.TabStop = false;
this.mpGroupBox900.Text = "Wake-On-Lan";
//
// mpNumericTextBoxWOLTimeOut
//
this.mpNumericTextBoxWOLTimeOut.AutoCompleteCustomSource.AddRange(new string[] {
"10",
"20",
"30",
"40",
"50",
"60",
"70",
"80",
"90"});
this.mpNumericTextBoxWOLTimeOut.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
this.mpNumericTextBoxWOLTimeOut.Enabled = false;
this.mpNumericTextBoxWOLTimeOut.Location = new System.Drawing.Point(126, 42);
this.mpNumericTextBoxWOLTimeOut.MaxLength = 4;
this.mpNumericTextBoxWOLTimeOut.Name = "mpNumericTextBoxWOLTimeOut";
this.mpNumericTextBoxWOLTimeOut.Size = new System.Drawing.Size(45, 20);
this.mpNumericTextBoxWOLTimeOut.TabIndex = 1;
this.mpNumericTextBoxWOLTimeOut.Tag = "Default timeout is 10 seconds";
this.mpNumericTextBoxWOLTimeOut.Text = "10";
this.mpNumericTextBoxWOLTimeOut.Value = 10;
this.mpNumericTextBoxWOLTimeOut.WordWrap = false;
//
// mpLabelWOLTimeOut
//
this.mpLabelWOLTimeOut.AutoSize = true;
this.mpLabelWOLTimeOut.Location = new System.Drawing.Point(41, 45);
this.mpLabelWOLTimeOut.Name = "mpLabelWOLTimeOut";
this.mpLabelWOLTimeOut.Size = new System.Drawing.Size(72, 13);
this.mpLabelWOLTimeOut.TabIndex = 8;
this.mpLabelWOLTimeOut.Text = "WOL timeout:";
//
// mpTextBoxMacAddress
//
this.mpTextBoxMacAddress.BorderColor = System.Drawing.Color.Empty;
this.mpTextBoxMacAddress.Location = new System.Drawing.Point(126, 91);
this.mpTextBoxMacAddress.MaxLength = 17;
this.mpTextBoxMacAddress.Name = "mpTextBoxMacAddress";
this.mpTextBoxMacAddress.Size = new System.Drawing.Size(97, 20);
this.mpTextBoxMacAddress.TabIndex = 3;
this.mpTextBoxMacAddress.Text = "00:00:00:00:00:00";
//
// mpLabel400
//
this.mpLabel400.AutoSize = true;
this.mpLabel400.Location = new System.Drawing.Point(41, 94);
this.mpLabel400.Name = "mpLabel400";
this.mpLabel400.Size = new System.Drawing.Size(74, 13);
this.mpLabel400.TabIndex = 6;
this.mpLabel400.Text = "MAC Address:";
//
// mpCheckBoxIsAutoMacAddressEnabled
//
this.mpCheckBoxIsAutoMacAddressEnabled.AutoSize = true;
this.mpCheckBoxIsAutoMacAddressEnabled.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.mpCheckBoxIsAutoMacAddressEnabled.Location = new System.Drawing.Point(44, 68);
this.mpCheckBoxIsAutoMacAddressEnabled.Name = "mpCheckBoxIsAutoMacAddressEnabled";
this.mpCheckBoxIsAutoMacAddressEnabled.Size = new System.Drawing.Size(192, 17);
this.mpCheckBoxIsAutoMacAddressEnabled.TabIndex = 2;
this.mpCheckBoxIsAutoMacAddressEnabled.Text = "Auto-configure server MAC Address";
this.mpCheckBoxIsAutoMacAddressEnabled.UseVisualStyleBackColor = true;
this.mpCheckBoxIsAutoMacAddressEnabled.CheckedChanged += new System.EventHandler(this.mpCheckBoxIsAutoMacAddressEnabled_CheckedChanged);
//
// mpCheckBoxIsWakeOnLanEnabled
//
this.mpCheckBoxIsWakeOnLanEnabled.AutoSize = true;
this.mpCheckBoxIsWakeOnLanEnabled.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.mpCheckBoxIsWakeOnLanEnabled.Location = new System.Drawing.Point(22, 19);
this.mpCheckBoxIsWakeOnLanEnabled.Name = "mpCheckBoxIsWakeOnLanEnabled";
this.mpCheckBoxIsWakeOnLanEnabled.Size = new System.Drawing.Size(172, 17);
this.mpCheckBoxIsWakeOnLanEnabled.TabIndex = 0;
this.mpCheckBoxIsWakeOnLanEnabled.Text = "Wake up TV Server as needed";
this.mpCheckBoxIsWakeOnLanEnabled.UseVisualStyleBackColor = true;
this.mpCheckBoxIsWakeOnLanEnabled.CheckedChanged += new System.EventHandler(this.mpCheckBoxIsWakeOnLanEnabled_CheckedChanged);
//
// TVRadio
//
this.Controls.Add(this.mpGroupBox900);
this.Controls.Add(this.mpGroupBox2);
this.Name = "TVRadio";
this.Size = new System.Drawing.Size(472, 427);
this.mpGroupBox2.ResumeLayout(false);
this.mpGroupBox2.PerformLayout();
this.mpGroupBox900.ResumeLayout(false);
this.mpGroupBox900.PerformLayout();
this.ResumeLayout(false);
}
#endregion
#region Private methods
const bool silent = false;
const bool verbose = true;
/// <summary>
/// Verifies that the given hostname is a working tv server
/// </summary>
/// <param name="hostname">The TV server's hostname</param>
/// <param name="verbose">Indicates if a messagebox should be displayed or not</param>
/// <returns></returns>
private bool VerifyHostname(string hostname, bool verbose)
{
// See if the tv server port is accessible (with timeout)
if (!CanConnect(hostname))
{
Log.Debug("VerifyHostname: unable to connect to TV server on host \"{0}\"", hostname);
if (verbose)
MessageBox.Show(string.Format("Unable to connect to TV server on host \"{0}\"", hostname),
"TV Client Settings", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
// Set the hostname of the TV server
TvServerRemote.HostName = hostname;
// Get the database connection string from the TV server
string connectionString, provider;
TvServerRemote.GetDatabaseConnectionString(out connectionString, out provider);
if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(provider))
{
Log.Debug("VerifyHostname: unable to get data from TV server on host \"{0}\"", hostname);
if (verbose)
MessageBox.Show(string.Format("Unable to get data from TV server on host \"{0}\"", hostname),
"TV Client Settings", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
Log.Debug("VerifyHostname: verified a working TV server on host \"{0}\"", hostname);
return true;
}
private string _hostname;
private bool _connected;
private bool CanConnect(string hostname)
{
_hostname = hostname;
_connected = false;
// kick off the thread that tries to connect
Thread thread = new Thread(new ThreadStart(ConnectThread));
thread.IsBackground = true; // So that a failed connection attempt
// wont prevent the process from terminating while it does the long timeout
thread.Start();
// wait for either the timeout or the thread to finish
if (thread.Join(2000))
return _connected;
// Timeout, so abort thread
thread.Abort();
return false;
}
private void ConnectThread()
{
TcpClient connection = new TcpClient();
try
{
connection.Connect(_hostname, 31456);
_connected = true;
}
catch (Exception) { }
finally
{
connection.Close();
}
}
/// <summary>
/// Updates the database connection string in the gentle.config file
/// if the hostname has been changed or gentle.config contains "-" as server name.
/// The connection string is fetched from the TV server.
/// </summary>
/// <param name="hostname">The TV server's hostname</param>
/// <param name="unchanged">Indicates if the hostname has been loaded from the settings</param>
/// <returns>Returns true, if the gentle.config file is updated</returns>
private bool UpdateGentleConfig(string hostname, bool unchanged)
{
Log.Debug("UpdateGentleConfig({0}, {1})", hostname, unchanged);
// Load the gentle.config file with the database connection string
XmlNode node, nodeProvider;
XmlDocument doc = new XmlDocument();
try
{
doc.Load(Config.GetFile(Config.Dir.Config, "gentle.config"));
XmlNode nodeKey = doc.SelectSingleNode("/Gentle.Framework/DefaultProvider");
node = nodeKey.Attributes.GetNamedItem("connectionString");
nodeProvider = nodeKey.Attributes.GetNamedItem("name");
}
catch (Exception ex)
{
Log.Error("UpdateGentleConfig: unable to open gentle.config" + Environment.NewLine + "{0}", ex.Message);
MessageBox.Show(string.Format("Unable to open gentle.config" + Environment.NewLine + "{0}", ex.Message),
"TV Client Settings", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
// See if gentle.config has to be updated
if (unchanged && node.InnerText.IndexOf("Server=-;") == -1)
{
Log.Debug("UpdateGentleConfig: no need to update gentle.config file");
return true;
}
// Verify tvServer (could be down at the moment)
if (!VerifyHostname(hostname, verbose))
{
Log.Error("UpdateGentleConfig: unable to contact TV server on host \"{0}\"", hostname);
return false;
}
// Get the database connection string from the TV server
string connectionString, provider;
TvServerRemote.GetDatabaseConnectionString(out connectionString, out provider);
if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(provider))
{
Log.Error("UpdateGentleConfig: unable to get database connection string from TV server \"{0}\"", hostname);
MessageBox.Show(string.Format("Unable to get database connection string from TV server \"{0}\"", hostname),
"TV Client Settings", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
// Save the gentle.config file with the database connection string
try
{
node.InnerText = connectionString;
nodeProvider.InnerText = provider;
doc.Save(Config.GetFile(Config.Dir.Config, "gentle.config"));
}
catch (Exception ex)
{
Log.Error("UpdateGentleConfig: unable to modify gentle.config" + Environment.NewLine + "{0}", ex.Message);
MessageBox.Show(string.Format("Unable to modify gentle.config" + Environment.NewLine + "{0}", ex.Message),
"TV Client Settings", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
Log.Debug("UpdateGentleConfig: updated gentle.config with connectionString \"{0}\" for provider \"{1}\"", connectionString, provider);
return true;
}
/// <summary>
/// The NetServerEnum function lists all servers of the specified type that are visible in a domain.
/// </summary>
[DllImport("Netapi32", CharSet = CharSet.Auto,
SetLastError = true),
SuppressUnmanagedCodeSecurityAttribute]
public static extern int NetServerEnum(
string ServerNane, // must be null
int dwLevel,
ref IntPtr pBuf,
int dwPrefMaxLen,
out int dwEntriesRead,
out int dwTotalEntries,
int dwServerType,
string domain, // null for login domain
out int dwResumeHandle
);
/// <summary>
/// The NetApiBufferFree function frees the memory that the NetApiBufferAllocate function allocates.
/// </summary>
[DllImport("Netapi32", SetLastError = true),
SuppressUnmanagedCodeSecurityAttribute]
public static extern int NetApiBufferFree(IntPtr pBuf);
/// <summary>
/// SERVER_INFO_100 STRUCTURE
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct _SERVER_INFO_100
{
internal int sv100_platform_id;
[MarshalAs(UnmanagedType.LPWStr)]
internal string sv100_name;
}
/// <summary>
/// Retrieves a list of domain SV_TYPE_WORKSTATION and SV_TYPE_SERVER PC's (thx to Sacha Barber)
/// </summary>
/// <returns>Arraylist that represents all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER PC's in the Domain</returns>
private ArrayList GetNetworkComputers()
{
//local fields
ArrayList networkComputers = new ArrayList();
const int MAX_PREFERRED_LENGTH = -1;
int SV_TYPE_WORKSTATION = 1;
int SV_TYPE_SERVER = 2;
IntPtr buffer = IntPtr.Zero;
IntPtr tmpBuffer = IntPtr.Zero;
int entriesRead = 0;
int totalEntries = 0;
int resHandle = 0;
int sizeofINFO = Marshal.SizeOf(typeof(_SERVER_INFO_100));
try
{
//Call NetServerEnum
int ret = NetServerEnum(null, 100, ref buffer, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries,
SV_TYPE_WORKSTATION | SV_TYPE_SERVER, null, out resHandle);
if (ret == 0)
{
//Loop through all SV_TYPE_WORKSTATION and SV_TYPE_SERVER PC's
for (int i = 0; i < totalEntries; i++)
{
//Get Pointer to the buffer that received the data
tmpBuffer = new IntPtr((int)buffer + (i * sizeofINFO));
_SERVER_INFO_100 svrInfo = (_SERVER_INFO_100)Marshal.PtrToStructure(tmpBuffer, typeof(_SERVER_INFO_100));
// Check if the PC is a MP TV server
string hostname = svrInfo.sv100_name.ToLower();
if (VerifyHostname(hostname, silent))
networkComputers.Add(hostname);
}
}
}
catch (Exception ex)
{
Log.Error("GetNetworkComputers: {0}", ex.Message);
return new ArrayList();
}
finally
{
//Free the memory that the NetApiBufferAllocate function allocates
NetApiBufferFree(buffer);
}
return networkComputers;
}
#endregion
#region Control event handlers
private void mpCheckBoxIsAutoMacAddressEnabled_CheckedChanged(object sender, EventArgs e)
{
if (mpCheckBoxIsAutoMacAddressEnabled.Checked)
{
mpTextBoxMacAddress.Enabled = false;
}
else
{
mpTextBoxMacAddress.Enabled = true;
}
}
private void mpCheckBoxIsWakeOnLanEnabled_CheckedChanged(object sender, EventArgs e)
{
if (mpCheckBoxIsWakeOnLanEnabled.Checked)
{
mpNumericTextBoxWOLTimeOut.Enabled = true;
mpCheckBoxIsAutoMacAddressEnabled.Enabled = true;
if (mpCheckBoxIsAutoMacAddressEnabled.Checked)
{
mpTextBoxMacAddress.Enabled = false;
}
else
{
mpTextBoxMacAddress.Enabled = true;
}
}
else
{
mpNumericTextBoxWOLTimeOut.Enabled = false;
mpCheckBoxIsAutoMacAddressEnabled.Enabled = false;
mpTextBoxMacAddress.Enabled = false;
}
}
private void mpButtonTestConnection_Click(object sender, EventArgs e)
{
// Save current cursor, display wait cursor and disable button
Cursor currentCursor = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;
mpButtonTestConnection.Enabled = false;
// Save hostname from textbox
string text = mpTextBoxHostname.Text;
// If hostname is empty, try local hostname
if (string.IsNullOrEmpty(text))
{
text = Dns.GetHostName();
mpTextBoxHostname.Text = "Trying local host...";
}
else
mpTextBoxHostname.Text = "Trying " + text + "...";
mpTextBoxHostname.Refresh();
// Restore hostname to textbox and verify it
mpTextBoxHostname.Text = text;
if (!VerifyHostname(mpTextBoxHostname.Text, verbose))
{
// No connection to tv server
mpTextBoxHostname.BackColor = Color.Red;
_verifiedHostname = string.Empty;
// Reset cursor, enable button
Cursor.Current = currentCursor;
mpButtonTestConnection.Enabled = true;
}
else
{
// Connection to tv server successful
mpTextBoxHostname.BackColor = Color.YellowGreen;
_verifiedHostname = mpTextBoxHostname.Text;
// Disable WOL for localhost
try
{
if (Dns.GetHostEntry(_verifiedHostname).HostName == Dns.GetHostName())
mpCheckBoxIsWakeOnLanEnabled.Checked = false;
}
catch { }
// Reset cursor, enable button
Cursor.Current = currentCursor;
mpButtonTestConnection.Enabled = true;
// Show success message
MessageBox.Show("Connection to the TV server successful",
"TV Client Settings", MessageBoxButtons.OK, MessageBoxIcon.None);
}
}
private void mpTextBoxHostname_TextChanged(object sender, EventArgs e)
{
mpTextBoxHostname.BackColor = mpTextBoxMacAddress.BackColor;
_verifiedHostname = string.Empty;
}
private void mpComboBoxHostname_DropDown(object sender, EventArgs e)
{
// Save current cursor and display wait cursor
Cursor currentCursor = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;
// Save hostname and color from textbox
string text = mpTextBoxHostname.Text;
Color color = mpTextBoxHostname.BackColor;
// Display scanning ...
mpTextBoxHostname.Text = "Scanning network ...";
mpTextBoxHostname.Refresh();
// Fill comboBox with hostnames of TV servers
mpComboBoxHostname.Items.Clear();
int selectedIdx = -1;
foreach (string hostname in GetNetworkComputers())
{
int idx = mpComboBoxHostname.Items.Add(hostname);
// Preselect verified hostname or local hostname
if (hostname == _verifiedHostname || (_verifiedHostname == string.Empty && hostname == Dns.GetHostName()))
selectedIdx = idx;
}
mpComboBoxHostname.SelectedIndex = selectedIdx;
// Restore hostname and color of textbox and reset cursor
mpTextBoxHostname.Text = text;
mpTextBoxHostname.BackColor = color;
if (color == Color.YellowGreen)
_verifiedHostname = text;
Cursor.Current = currentCursor;
}
private void mpComboBoxHostname_SelectionChangeCommitted(object sender, System.EventArgs e)
{
// Take selected hostname to hostname textbox
mpTextBoxHostname.Text = mpComboBoxHostname.SelectedItem.ToString();
mpTextBoxHostname.BackColor = Color.YellowGreen;
_verifiedHostname = mpTextBoxHostname.Text;
// Disable WOL for localhost
try
{
if (mpTextBoxHostname.Text == Dns.GetHostName())
mpCheckBoxIsWakeOnLanEnabled.Checked = false;
}
catch { }
}
#endregion
}
}