2 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
25 $Log: DNSServiceBrowser.cs,v $
26 Revision 1.5 2004/09/21 16:26:58 shersche
27 Check to make sure browse list selected item is not null before resolving
28 Submitted by: prepin@gmail.com
30 Revision 1.4 2004/09/13 19:38:17 shersche
31 Changed code to reflect namespace and type changes to dnssd.NET library
33 Revision 1.3 2004/09/11 00:38:14 shersche
34 DNSService APIs now assume port in host format. Check for null text record in resolve callback.
36 Revision 1.2 2004/07/22 23:15:25 shersche
37 Fix service names for teleport, tftp, and bootps
39 Revision 1.1 2004/07/19 07:54:24 shersche
48 using System.Collections;
49 using System.ComponentModel;
50 using System.Windows.Forms;
55 namespace DNSServiceBrowser_NET
58 /// Summary description for Form1.
60 public class Form1 : System.Windows.Forms.Form
62 private System.Windows.Forms.ComboBox typeBox;
63 private System.Windows.Forms.ListBox browseList;
64 private ServiceRef browser = null;
65 private ServiceRef resolver = null;
67 /// Required designer variable.
69 private System.ComponentModel.Container components = null;
73 // These delegates are invoked as a result of DNSService
76 delegate void AddServiceCallback(BrowseData data);
77 delegate void RemoveServiceCallback(BrowseData data);
78 delegate void ResolveServiceCallback(ResolveData data);
80 AddServiceCallback addServiceCallback;
81 RemoveServiceCallback removeServiceCallback;
82 private System.Windows.Forms.Label label1;
83 private System.Windows.Forms.Label label2;
84 private System.Windows.Forms.Label label3;
85 private System.Windows.Forms.Label label4;
86 private System.Windows.Forms.TextBox nameField;
87 private System.Windows.Forms.TextBox typeField;
88 private System.Windows.Forms.TextBox domainField;
89 private System.Windows.Forms.TextBox hostField;
90 private System.Windows.Forms.TextBox portField;
91 private System.Windows.Forms.Label label5;
92 private System.Windows.Forms.ListBox serviceTextField;
93 ResolveServiceCallback resolveServiceCallback;
98 // Required for Windows Form Designer support
100 InitializeComponent();
102 addServiceCallback = new AddServiceCallback(OnAddService);
103 removeServiceCallback = new RemoveServiceCallback(OnRemoveService);
104 resolveServiceCallback = new ResolveServiceCallback(OnResolveService);
106 this.Load += new System.EventHandler(this.Form1_Load);
109 private void Form1_Load(object sender, EventArgs e)
111 typeBox.SelectedItem = "_spike._tcp";
115 /// Clean up any resources being used.
117 protected override void Dispose( bool disposing )
121 if (components != null)
123 components.Dispose();
131 base.Dispose( disposing );
134 #region Windows Form Designer generated code
136 /// Required method for Designer support - do not modify
137 /// the contents of this method with the code editor.
139 private void InitializeComponent()
141 this.browseList = new System.Windows.Forms.ListBox();
142 this.typeBox = new System.Windows.Forms.ComboBox();
143 this.label1 = new System.Windows.Forms.Label();
144 this.label2 = new System.Windows.Forms.Label();
145 this.label3 = new System.Windows.Forms.Label();
146 this.label4 = new System.Windows.Forms.Label();
147 this.nameField = new System.Windows.Forms.TextBox();
148 this.typeField = new System.Windows.Forms.TextBox();
149 this.domainField = new System.Windows.Forms.TextBox();
150 this.hostField = new System.Windows.Forms.TextBox();
151 this.portField = new System.Windows.Forms.TextBox();
152 this.label5 = new System.Windows.Forms.Label();
153 this.serviceTextField = new System.Windows.Forms.ListBox();
154 this.SuspendLayout();
158 this.browseList.Location = new System.Drawing.Point(8, 48);
159 this.browseList.Name = "browseList";
160 this.browseList.Size = new System.Drawing.Size(488, 147);
161 this.browseList.TabIndex = 0;
162 this.browseList.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
166 this.typeBox.Items.AddRange(new object[]
176 "_animobserver._tcp",
190 "_contactserver._tcp",
201 "_ecbyesfsgksc._tcp",
211 "_fmpro-internal._tcp",
221 "_ica-networking._tcp",
229 "_ipbroadcaster._tcp",
243 "_macfoh-remote._tcp",
250 "_ncsyncserver._tcp",
251 "_net-assistant._tcp",
254 "_nssocketport._tcp",
256 "_omni-bookmark._tcp",
259 "_pdl-datastream._tcp",
269 "_realplayfavs._tcp",
270 "_rendezvouspong._tcp",
275 "_sallingclicker._tcp",
291 "_ssscreenshare._tcp",
302 "_ticonnectmgr._tcp",
307 "_vue4rendercow._tcp",
320 this.typeBox.Location = new System.Drawing.Point(8, 16);
321 this.typeBox.Name = "typeBox";
322 this.typeBox.Size = new System.Drawing.Size(192, 21);
323 this.typeBox.Sorted = true;
324 this.typeBox.TabIndex = 3;
325 this.typeBox.SelectedIndexChanged += new System.EventHandler(this.typeBox_SelectedIndexChanged);
329 this.label1.Location = new System.Drawing.Point(8, 208);
330 this.label1.Name = "label1";
331 this.label1.Size = new System.Drawing.Size(48, 16);
332 this.label1.TabIndex = 4;
333 this.label1.Text = "Name:";
334 this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
338 this.label2.Location = new System.Drawing.Point(8, 240);
339 this.label2.Name = "label2";
340 this.label2.Size = new System.Drawing.Size(48, 16);
341 this.label2.TabIndex = 5;
342 this.label2.Text = "Type:";
343 this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
347 this.label3.Location = new System.Drawing.Point(8, 272);
348 this.label3.Name = "label3";
349 this.label3.Size = new System.Drawing.Size(48, 16);
350 this.label3.TabIndex = 6;
351 this.label3.Text = "Domain:";
352 this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
356 this.label4.Location = new System.Drawing.Point(8, 304);
357 this.label4.Name = "label4";
358 this.label4.Size = new System.Drawing.Size(48, 16);
359 this.label4.TabIndex = 7;
360 this.label4.Text = "Host:";
361 this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
365 this.nameField.Location = new System.Drawing.Point(56, 208);
366 this.nameField.Name = "nameField";
367 this.nameField.ReadOnly = true;
368 this.nameField.Size = new System.Drawing.Size(168, 20);
369 this.nameField.TabIndex = 8;
370 this.nameField.Text = "";
374 this.typeField.Location = new System.Drawing.Point(56, 240);
375 this.typeField.Name = "typeField";
376 this.typeField.ReadOnly = true;
377 this.typeField.Size = new System.Drawing.Size(168, 20);
378 this.typeField.TabIndex = 9;
379 this.typeField.Text = "";
383 this.domainField.Location = new System.Drawing.Point(56, 272);
384 this.domainField.Name = "domainField";
385 this.domainField.ReadOnly = true;
386 this.domainField.Size = new System.Drawing.Size(168, 20);
387 this.domainField.TabIndex = 10;
388 this.domainField.Text = "";
392 this.hostField.Location = new System.Drawing.Point(56, 304);
393 this.hostField.Name = "hostField";
394 this.hostField.ReadOnly = true;
395 this.hostField.Size = new System.Drawing.Size(168, 20);
396 this.hostField.TabIndex = 11;
397 this.hostField.Text = "";
402 this.portField.Location = new System.Drawing.Point(56, 336);
403 this.portField.Name = "portField";
404 this.portField.ReadOnly = true;
405 this.portField.Size = new System.Drawing.Size(168, 20);
406 this.portField.TabIndex = 12;
407 this.portField.Text = "";
411 this.label5.Location = new System.Drawing.Point(8, 336);
412 this.label5.Name = "label5";
413 this.label5.Size = new System.Drawing.Size(48, 16);
414 this.label5.TabIndex = 14;
415 this.label5.Text = "Port:";
416 this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
420 this.serviceTextField.HorizontalScrollbar = true;
421 this.serviceTextField.Location = new System.Drawing.Point(264, 208);
422 this.serviceTextField.Name = "serviceTextField";
423 this.serviceTextField.Size = new System.Drawing.Size(232, 147);
424 this.serviceTextField.TabIndex = 16;
428 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
429 this.ClientSize = new System.Drawing.Size(512, 365);
430 this.Controls.AddRange(new System.Windows.Forms.Control[] {
431 this.serviceTextField,
445 this.Text = "DNSServices Browser";
446 this.ResumeLayout(false);
452 /// The main entry point for the application.
457 Application.Run(new Form1());
462 // This class is used to store data associated
463 // with a DNSService.Browse() operation
465 public class BrowseData
467 public int InterfaceIndex;
470 public String Domain;
472 public override String
485 if ((object) this == other)
489 else if (other is BrowseData)
491 BrowseData otherBrowseData = (BrowseData) other;
493 result = (this.Name == otherBrowseData.Name);
503 return Name.GetHashCode();
511 // This class is used to store data associated
512 // with a DNSService.Resolve() operation
514 public class ResolveData
516 public int InterfaceIndex;
517 public String FullName;
518 public String HostName;
520 public Byte[] TxtRecord;
522 public override String
532 // Populate this form with data associated with a
533 // DNSService.Resolve() call
536 Populate(BrowseData browseData, ResolveData resolveData)
538 nameField.Text = browseData.Name;
539 typeField.Text = browseData.Type;
540 domainField.Text = browseData.Domain;
541 hostField.Text = resolveData.HostName;
542 portField.Text = resolveData.Port.ToString();
544 serviceTextField.Items.Clear();
546 if (resolveData.TxtRecord != null)
548 for (int idx = 0; idx < TextRecord.GetCount(resolveData.TxtRecord); idx++)
553 bytes = TextRecord.GetItemAtIndex(resolveData.TxtRecord, idx, out key);
561 val = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
564 serviceTextField.Items.Add(key + "=" + val);
571 // called when the type field changes
573 private void typeBox_SelectedIndexChanged(object sender, System.EventArgs e)
575 browseList.Items.Clear();
584 domainField.Text = "";
587 serviceTextField.Items.Clear();
591 browser = DNSService.Browse(0, 0, typeBox.SelectedItem.ToString(), null, new DNSService.BrowseReply(OnBrowseReply));
595 MessageBox.Show("Browse Failed", "Error");
600 private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
602 if (resolver != null)
607 if (browseList.SelectedItem != null)
611 BrowseData data = (BrowseData) browseList.SelectedItem;
613 resolver = DNSService.Resolve(0, 0, data.Name, data.Type, data.Domain, new DNSService.ResolveReply(OnResolveReply));
617 MessageBox.Show("Resolve Failed", "Error");
626 // This method is "Invoked" by OnBrowseReply. This call
627 // executes in the context of the main thread
629 private void OnAddService
634 browseList.Items.Add(data);
635 browseList.Invalidate();
641 // This method is "Invoked" by OnBrowseReply. This call
642 // executes in the context of the main thread
644 private void OnRemoveService
649 browseList.Items.Remove(data);
650 browseList.Invalidate();
656 // This method is "Invoked" by OnResolveReply. This call
657 // executes in the context of the main thread
659 private void OnResolveService
667 Populate((BrowseData) browseList.SelectedItem, data);
673 // This call is invoked by the DNSService core. It is
674 // executed in the context of a worker thread, not the
675 // main (GUI) thread. We create a BrowseData object
676 // and invoked the appropriate method in the GUI thread
677 // so we can update the UI
679 private void OnBrowseReply
690 if (errorCode == ErrorCode.NoError)
692 BrowseData data = new BrowseData();
694 data.InterfaceIndex = interfaceIndex;
697 data.Domain = domain;
699 if ((flags & ServiceFlags.Add) != 0)
701 Invoke(addServiceCallback, new Object[]{data});
704 else if ((flags == 0) || ((flags & ServiceFlags.MoreComing) != 0))
706 Invoke(removeServiceCallback, new Object[]{data});
711 MessageBox.Show("OnBrowseReply returned an error code: " + errorCode, "Error");
715 private void OnResolveReply
727 if (errorCode == ErrorCode.NoError)
729 ResolveData data = new ResolveData();
731 data.InterfaceIndex = interfaceIndex;
732 data.FullName = fullName;
733 data.HostName = hostName;
735 data.TxtRecord = txtRecord;
737 Invoke(resolveServiceCallback, new Object[]{data});
741 MessageBox.Show("OnResolveReply returned an error code: " + errorCode, "Error");