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.6 2005/02/10 22:35:06 cheshire
27 <rdar://problem/3727944> Update name
29 Revision 1.5 2004/09/21 16:26:58 shersche
30 Check to make sure browse list selected item is not null before resolving
31 Submitted by: prepin@gmail.com
33 Revision 1.4 2004/09/13 19:38:17 shersche
34 Changed code to reflect namespace and type changes to dnssd.NET library
36 Revision 1.3 2004/09/11 00:38:14 shersche
37 DNSService APIs now assume port in host format. Check for null text record in resolve callback.
39 Revision 1.2 2004/07/22 23:15:25 shersche
40 Fix service names for teleport, tftp, and bootps
42 Revision 1.1 2004/07/19 07:54:24 shersche
51 using System.Collections;
52 using System.ComponentModel;
53 using System.Windows.Forms;
58 namespace DNSServiceBrowser_NET
61 /// Summary description for Form1.
63 public class Form1 : System.Windows.Forms.Form
65 private System.Windows.Forms.ComboBox typeBox;
66 private System.Windows.Forms.ListBox browseList;
67 private ServiceRef browser = null;
68 private ServiceRef resolver = null;
70 /// Required designer variable.
72 private System.ComponentModel.Container components = null;
76 // These delegates are invoked as a result of DNSService
79 delegate void AddServiceCallback(BrowseData data);
80 delegate void RemoveServiceCallback(BrowseData data);
81 delegate void ResolveServiceCallback(ResolveData data);
83 AddServiceCallback addServiceCallback;
84 RemoveServiceCallback removeServiceCallback;
85 private System.Windows.Forms.Label label1;
86 private System.Windows.Forms.Label label2;
87 private System.Windows.Forms.Label label3;
88 private System.Windows.Forms.Label label4;
89 private System.Windows.Forms.TextBox nameField;
90 private System.Windows.Forms.TextBox typeField;
91 private System.Windows.Forms.TextBox domainField;
92 private System.Windows.Forms.TextBox hostField;
93 private System.Windows.Forms.TextBox portField;
94 private System.Windows.Forms.Label label5;
95 private System.Windows.Forms.ListBox serviceTextField;
96 ResolveServiceCallback resolveServiceCallback;
101 // Required for Windows Form Designer support
103 InitializeComponent();
105 addServiceCallback = new AddServiceCallback(OnAddService);
106 removeServiceCallback = new RemoveServiceCallback(OnRemoveService);
107 resolveServiceCallback = new ResolveServiceCallback(OnResolveService);
109 this.Load += new System.EventHandler(this.Form1_Load);
112 private void Form1_Load(object sender, EventArgs e)
116 typeBox.SelectedItem = "_spike._tcp";
122 /// Clean up any resources being used.
124 protected override void Dispose( bool disposing )
128 if (components != null)
130 components.Dispose();
138 base.Dispose( disposing );
141 #region Windows Form Designer generated code
143 /// Required method for Designer support - do not modify
144 /// the contents of this method with the code editor.
146 private void InitializeComponent()
148 this.browseList = new System.Windows.Forms.ListBox();
149 this.typeBox = new System.Windows.Forms.ComboBox();
150 this.label1 = new System.Windows.Forms.Label();
151 this.label2 = new System.Windows.Forms.Label();
152 this.label3 = new System.Windows.Forms.Label();
153 this.label4 = new System.Windows.Forms.Label();
154 this.nameField = new System.Windows.Forms.TextBox();
155 this.typeField = new System.Windows.Forms.TextBox();
156 this.domainField = new System.Windows.Forms.TextBox();
157 this.hostField = new System.Windows.Forms.TextBox();
158 this.portField = new System.Windows.Forms.TextBox();
159 this.label5 = new System.Windows.Forms.Label();
160 this.serviceTextField = new System.Windows.Forms.ListBox();
161 this.SuspendLayout();
165 this.browseList.Location = new System.Drawing.Point(8, 48);
166 this.browseList.Name = "browseList";
167 this.browseList.Size = new System.Drawing.Size(488, 147);
168 this.browseList.TabIndex = 0;
169 this.browseList.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
173 this.typeBox.Items.AddRange(new object[]
183 "_animobserver._tcp",
197 "_contactserver._tcp",
208 "_ecbyesfsgksc._tcp",
218 "_fmpro-internal._tcp",
228 "_ica-networking._tcp",
236 "_ipbroadcaster._tcp",
250 "_macfoh-remote._tcp",
257 "_ncsyncserver._tcp",
258 "_net-assistant._tcp",
261 "_nssocketport._tcp",
263 "_omni-bookmark._tcp",
266 "_pdl-datastream._tcp",
276 "_realplayfavs._tcp",
281 "_sallingclicker._tcp",
297 "_ssscreenshare._tcp",
308 "_ticonnectmgr._tcp",
313 "_vue4rendercow._tcp",
326 this.typeBox.Location = new System.Drawing.Point(8, 16);
327 this.typeBox.Name = "typeBox";
328 this.typeBox.Size = new System.Drawing.Size(192, 21);
329 this.typeBox.Sorted = true;
330 this.typeBox.TabIndex = 3;
331 this.typeBox.SelectedIndexChanged += new System.EventHandler(this.typeBox_SelectedIndexChanged);
335 this.label1.Location = new System.Drawing.Point(8, 208);
336 this.label1.Name = "label1";
337 this.label1.Size = new System.Drawing.Size(48, 16);
338 this.label1.TabIndex = 4;
339 this.label1.Text = "Name:";
340 this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
344 this.label2.Location = new System.Drawing.Point(8, 240);
345 this.label2.Name = "label2";
346 this.label2.Size = new System.Drawing.Size(48, 16);
347 this.label2.TabIndex = 5;
348 this.label2.Text = "Type:";
349 this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
353 this.label3.Location = new System.Drawing.Point(8, 272);
354 this.label3.Name = "label3";
355 this.label3.Size = new System.Drawing.Size(48, 16);
356 this.label3.TabIndex = 6;
357 this.label3.Text = "Domain:";
358 this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
362 this.label4.Location = new System.Drawing.Point(8, 304);
363 this.label4.Name = "label4";
364 this.label4.Size = new System.Drawing.Size(48, 16);
365 this.label4.TabIndex = 7;
366 this.label4.Text = "Host:";
367 this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
371 this.nameField.Location = new System.Drawing.Point(56, 208);
372 this.nameField.Name = "nameField";
373 this.nameField.ReadOnly = true;
374 this.nameField.Size = new System.Drawing.Size(168, 20);
375 this.nameField.TabIndex = 8;
376 this.nameField.Text = "";
380 this.typeField.Location = new System.Drawing.Point(56, 240);
381 this.typeField.Name = "typeField";
382 this.typeField.ReadOnly = true;
383 this.typeField.Size = new System.Drawing.Size(168, 20);
384 this.typeField.TabIndex = 9;
385 this.typeField.Text = "";
389 this.domainField.Location = new System.Drawing.Point(56, 272);
390 this.domainField.Name = "domainField";
391 this.domainField.ReadOnly = true;
392 this.domainField.Size = new System.Drawing.Size(168, 20);
393 this.domainField.TabIndex = 10;
394 this.domainField.Text = "";
398 this.hostField.Location = new System.Drawing.Point(56, 304);
399 this.hostField.Name = "hostField";
400 this.hostField.ReadOnly = true;
401 this.hostField.Size = new System.Drawing.Size(168, 20);
402 this.hostField.TabIndex = 11;
403 this.hostField.Text = "";
408 this.portField.Location = new System.Drawing.Point(56, 336);
409 this.portField.Name = "portField";
410 this.portField.ReadOnly = true;
411 this.portField.Size = new System.Drawing.Size(168, 20);
412 this.portField.TabIndex = 12;
413 this.portField.Text = "";
417 this.label5.Location = new System.Drawing.Point(8, 336);
418 this.label5.Name = "label5";
419 this.label5.Size = new System.Drawing.Size(48, 16);
420 this.label5.TabIndex = 14;
421 this.label5.Text = "Port:";
422 this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
426 this.serviceTextField.HorizontalScrollbar = true;
427 this.serviceTextField.Location = new System.Drawing.Point(264, 208);
428 this.serviceTextField.Name = "serviceTextField";
429 this.serviceTextField.Size = new System.Drawing.Size(232, 147);
430 this.serviceTextField.TabIndex = 16;
434 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
435 this.ClientSize = new System.Drawing.Size(512, 365);
436 this.Controls.AddRange(new System.Windows.Forms.Control[] {
437 this.serviceTextField,
451 this.Text = "DNSServices Browser";
452 this.ResumeLayout(false);
458 /// The main entry point for the application.
463 Application.Run(new Form1());
468 // This class is used to store data associated
469 // with a DNSService.Browse() operation
471 public class BrowseData
473 public int InterfaceIndex;
476 public String Domain;
478 public override String
491 if ((object) this == other)
495 else if (other is BrowseData)
497 BrowseData otherBrowseData = (BrowseData) other;
499 result = (this.Name == otherBrowseData.Name);
509 return Name.GetHashCode();
517 // This class is used to store data associated
518 // with a DNSService.Resolve() operation
520 public class ResolveData
522 public int InterfaceIndex;
523 public String FullName;
524 public String HostName;
526 public Byte[] TxtRecord;
528 public override String
538 // Populate this form with data associated with a
539 // DNSService.Resolve() call
542 Populate(BrowseData browseData, ResolveData resolveData)
544 nameField.Text = browseData.Name;
545 typeField.Text = browseData.Type;
546 domainField.Text = browseData.Domain;
547 hostField.Text = resolveData.HostName;
548 portField.Text = resolveData.Port.ToString();
550 serviceTextField.Items.Clear();
552 if (resolveData.TxtRecord != null)
554 for (int idx = 0; idx < TextRecord.GetCount(resolveData.TxtRecord); idx++)
559 bytes = TextRecord.GetItemAtIndex(resolveData.TxtRecord, idx, out key);
567 val = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
570 serviceTextField.Items.Add(key + "=" + val);
577 // called when the type field changes
579 private void typeBox_SelectedIndexChanged(object sender, System.EventArgs e)
581 browseList.Items.Clear();
590 domainField.Text = "";
593 serviceTextField.Items.Clear();
597 browser = DNSService.Browse(0, 0, typeBox.SelectedItem.ToString(), null, new DNSService.BrowseReply(OnBrowseReply));
601 MessageBox.Show("Browse Failed", "Error");
606 private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
608 if (resolver != null)
613 if (browseList.SelectedItem != null)
617 BrowseData data = (BrowseData) browseList.SelectedItem;
619 resolver = DNSService.Resolve(0, 0, data.Name, data.Type, data.Domain, new DNSService.ResolveReply(OnResolveReply));
623 MessageBox.Show("Resolve Failed", "Error");
632 // This method is "Invoked" by OnBrowseReply. This call
633 // executes in the context of the main thread
635 private void OnAddService
640 browseList.Items.Add(data);
641 browseList.Invalidate();
647 // This method is "Invoked" by OnBrowseReply. This call
648 // executes in the context of the main thread
650 private void OnRemoveService
655 browseList.Items.Remove(data);
656 browseList.Invalidate();
662 // This method is "Invoked" by OnResolveReply. This call
663 // executes in the context of the main thread
665 private void OnResolveService
673 Populate((BrowseData) browseList.SelectedItem, data);
679 // This call is invoked by the DNSService core. It is
680 // executed in the context of a worker thread, not the
681 // main (GUI) thread. We create a BrowseData object
682 // and invoked the appropriate method in the GUI thread
683 // so we can update the UI
685 private void OnBrowseReply
696 if (errorCode == ErrorCode.NoError)
698 BrowseData data = new BrowseData();
700 data.InterfaceIndex = interfaceIndex;
703 data.Domain = domain;
705 if ((flags & ServiceFlags.Add) != 0)
707 Invoke(addServiceCallback, new Object[]{data});
710 else if ((flags == 0) || ((flags & ServiceFlags.MoreComing) != 0))
712 Invoke(removeServiceCallback, new Object[]{data});
717 MessageBox.Show("OnBrowseReply returned an error code: " + errorCode, "Error");
721 private void OnResolveReply
733 if (errorCode == ErrorCode.NoError)
735 ResolveData data = new ResolveData();
737 data.InterfaceIndex = interfaceIndex;
738 data.FullName = fullName;
739 data.HostName = hostName;
741 data.TxtRecord = txtRecord;
743 Invoke(resolveServiceCallback, new Object[]{data});
747 MessageBox.Show("OnResolveReply returned an error code: " + errorCode, "Error");