]> git.saurik.com Git - apple/mdnsresponder.git/blob - Clients/DNSServiceBrowser.NET/DNSServiceBrowser.cs
mDNSResponder-379.38.1.tar.gz
[apple/mdnsresponder.git] / Clients / DNSServiceBrowser.NET / DNSServiceBrowser.cs
1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 using System;
19 using System.Drawing;
20 using System.Collections;
21 using System.ComponentModel;
22 using System.Windows.Forms;
23 using System.Data;
24 using System.Text;
25 using Bonjour;
26
27 namespace DNSServiceBrowser_NET
28 {
29 /// <summary>
30 /// Summary description for Form1.
31 /// </summary>
32 public class Form1 : System.Windows.Forms.Form
33 {
34 private System.Windows.Forms.ComboBox typeBox;
35 private System.Windows.Forms.ListBox browseList;
36 private Bonjour.DNSSDEventManager eventManager = null;
37 private Bonjour.DNSSDService service = null;
38 private Bonjour.DNSSDService browser = null;
39 private Bonjour.DNSSDService resolver = null;
40 /// <summary>
41 /// Required designer variable.
42 /// </summary>
43 private System.ComponentModel.Container components = null;
44
45 private System.Windows.Forms.Label label1;
46 private System.Windows.Forms.Label label2;
47 private System.Windows.Forms.Label label3;
48 private System.Windows.Forms.Label label4;
49 private System.Windows.Forms.TextBox nameField;
50 private System.Windows.Forms.TextBox typeField;
51 private System.Windows.Forms.TextBox domainField;
52 private System.Windows.Forms.TextBox hostField;
53 private System.Windows.Forms.TextBox portField;
54 private System.Windows.Forms.Label label5;
55 private System.Windows.Forms.ListBox serviceTextField;
56
57 public Form1()
58 {
59 //
60 // Required for Windows Form Designer support
61 //
62 InitializeComponent();
63
64 this.Load += new System.EventHandler(this.Form1_Load);
65
66 //
67 // Create the DNSSDEventManager. You can then associate event handlers
68 // with the instance that will be invoked when the event occurs
69 //
70 // In this example, we're associating ServiceFound, ServiceLost,
71 // ServiceResolved, and OperationFailed event handlers with the
72 // event manager instance.
73 //
74 eventManager = new DNSSDEventManager();
75 eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound);
76 eventManager.ServiceLost += new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost);
77 eventManager.ServiceResolved += new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved);
78 eventManager.OperationFailed += new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed);
79
80 service = new DNSSDService();
81 }
82
83 private void Form1_Load(object sender, EventArgs e)
84 {
85 typeBox.SelectedItem = "_http._tcp";
86 }
87
88
89 /// <summary>
90 /// Clean up any resources being used.
91 /// </summary>
92 protected override void Dispose( bool disposing )
93 {
94 if( disposing )
95 {
96 if (components != null)
97 {
98 components.Dispose();
99 }
100
101 //
102 // Clean up
103 //
104 if (resolver != null)
105 {
106 resolver.Stop();
107 }
108
109 if (browser != null)
110 {
111 browser.Stop();
112 }
113
114 if (service != null)
115 {
116 service.Stop();
117 }
118
119 eventManager.ServiceFound -= new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound);
120 eventManager.ServiceLost -= new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost);
121 eventManager.ServiceResolved -= new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved);
122 eventManager.OperationFailed -= new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed);
123 }
124 base.Dispose( disposing );
125 }
126
127 #region Windows Form Designer generated code
128 /// <summary>
129 /// Required method for Designer support - do not modify
130 /// the contents of this method with the code editor.
131 /// </summary>
132 private void InitializeComponent()
133 {
134 this.browseList = new System.Windows.Forms.ListBox();
135 this.typeBox = new System.Windows.Forms.ComboBox();
136 this.label1 = new System.Windows.Forms.Label();
137 this.label2 = new System.Windows.Forms.Label();
138 this.label3 = new System.Windows.Forms.Label();
139 this.label4 = new System.Windows.Forms.Label();
140 this.nameField = new System.Windows.Forms.TextBox();
141 this.typeField = new System.Windows.Forms.TextBox();
142 this.domainField = new System.Windows.Forms.TextBox();
143 this.hostField = new System.Windows.Forms.TextBox();
144 this.portField = new System.Windows.Forms.TextBox();
145 this.label5 = new System.Windows.Forms.Label();
146 this.serviceTextField = new System.Windows.Forms.ListBox();
147 this.SuspendLayout();
148 //
149 // browseList
150 //
151 this.browseList.Location = new System.Drawing.Point(8, 48);
152 this.browseList.Name = "browseList";
153 this.browseList.Size = new System.Drawing.Size(488, 147);
154 this.browseList.TabIndex = 0;
155 this.browseList.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
156 //
157 // typeBox
158 //
159 this.typeBox.Items.AddRange(new object[]
160 {
161 "_accessone._tcp",
162 "_accountedge._tcp",
163 "_actionitems._tcp",
164 "_addressbook._tcp",
165 "_aecoretech._tcp",
166 "_afpovertcp._tcp",
167 "_airport._tcp",
168 "_animolmd._tcp",
169 "_animobserver._tcp",
170 "_apple-sasl._tcp",
171 "_aquamon._tcp",
172 "_async._tcp",
173 "_auth._tcp",
174 "_beep._tcp",
175 "_bfagent._tcp",
176 "_bootps._udp",
177 "_bousg._tcp",
178 "_bsqdea._tcp",
179 "_cheat._tcp",
180 "_chess._tcp",
181 "_clipboard._tcp",
182 "_collection._tcp",
183 "_contactserver._tcp",
184 "_cvspserver._tcp",
185 "_cytv._tcp",
186 "_daap._tcp",
187 "_difi._tcp",
188 "_distcc._tcp",
189 "_dossier._tcp",
190 "_dpap._tcp",
191 "_earphoria._tcp",
192 "_ebms._tcp",
193 "_ebreg._tcp",
194 "_ecbyesfsgksc._tcp",
195 "_eheap._tcp",
196 "_embrace._tcp",
197 "_eppc._tcp",
198 "_eventserver._tcp",
199 "_exec._tcp",
200 "_facespan._tcp",
201 "_faxstfx._tcp",
202 "_fish._tcp",
203 "_fjork._tcp",
204 "_fmpro-internal._tcp",
205 "_ftp._tcp",
206 "_ftpcroco._tcp",
207 "_gbs-smp._tcp",
208 "_gbs-stp._tcp",
209 "_grillezvous._tcp",
210 "_h323._tcp",
211 "_http._tcp",
212 "_hotwayd._tcp",
213 "_hydra._tcp",
214 "_ica-networking._tcp",
215 "_ichalkboard._tcp",
216 "_ichat._tcp",
217 "_iconquer._tcp",
218 "_ifolder._tcp",
219 "_ilynx._tcp",
220 "_imap._tcp",
221 "_imidi._tcp",
222 "_ipbroadcaster._tcp",
223 "_ipp._tcp",
224 "_isparx._tcp",
225 "_ispq-vc._tcp",
226 "_ishare._tcp",
227 "_isticky._tcp",
228 "_istorm._tcp",
229 "_iwork._tcp",
230 "_lan2p._tcp",
231 "_ldap._tcp",
232 "_liaison._tcp",
233 "_login._tcp",
234 "_lontalk._tcp",
235 "_lonworks._tcp",
236 "_macfoh-remote._tcp",
237 "_macminder._tcp",
238 "_moneyworks._tcp",
239 "_mp3sushi._tcp",
240 "_mttp._tcp",
241 "_ncbroadcast._tcp",
242 "_ncdirect._tcp",
243 "_ncsyncserver._tcp",
244 "_net-assistant._tcp",
245 "_newton-dock._tcp",
246 "_nfs._udp",
247 "_nssocketport._tcp",
248 "_odabsharing._tcp",
249 "_omni-bookmark._tcp",
250 "_openbase._tcp",
251 "_p2pchat._udp",
252 "_pdl-datastream._tcp",
253 "_poch._tcp",
254 "_pop3._tcp",
255 "_postgresql._tcp",
256 "_presence._tcp",
257 "_printer._tcp",
258 "_ptp._tcp",
259 "_quinn._tcp",
260 "_raop._tcp",
261 "_rce._tcp",
262 "_realplayfavs._tcp",
263 "_riousbprint._tcp",
264 "_rfb._tcp",
265 "_rtsp._tcp",
266 "_safarimenu._tcp",
267 "_sallingclicker._tcp",
268 "_scone._tcp",
269 "_sdsharing._tcp",
270 "_see._tcp",
271 "_seeCard._tcp",
272 "_serendipd._tcp",
273 "_servermgr._tcp",
274 "_shell._tcp",
275 "_shout._tcp",
276 "_shoutcast._tcp",
277 "_soap._tcp",
278 "_spike._tcp",
279 "_spincrisis._tcp",
280 "_spl-itunes._tcp",
281 "_spr-itunes._tcp",
282 "_ssh._tcp",
283 "_ssscreenshare._tcp",
284 "_strateges._tcp",
285 "_sge-exec._tcp",
286 "_sge-qmaster._tcp",
287 "_stickynotes._tcp",
288 "_sxqdea._tcp",
289 "_sybase-tds._tcp",
290 "_teamlist._tcp",
291 "_teleport._udp",
292 "_telnet._tcp",
293 "_tftp._udp",
294 "_ticonnectmgr._tcp",
295 "_tinavigator._tcp",
296 "_tryst._tcp",
297 "_upnp._tcp",
298 "_utest._tcp",
299 "_vue4rendercow._tcp",
300 "_webdav._tcp",
301 "_whamb._tcp",
302 "_wired._tcp",
303 "_workstation._tcp",
304 "_wormhole._tcp",
305 "_workgroup._tcp",
306 "_ws._tcp",
307 "_xserveraid._tcp",
308 "_xsync._tcp",
309 "_xtshapro._tcp"
310 });
311
312 this.typeBox.Location = new System.Drawing.Point(8, 16);
313 this.typeBox.Name = "typeBox";
314 this.typeBox.Size = new System.Drawing.Size(192, 21);
315 this.typeBox.Sorted = true;
316 this.typeBox.TabIndex = 3;
317 this.typeBox.SelectedIndexChanged += new System.EventHandler(this.typeBox_SelectedIndexChanged);
318 //
319 // label1
320 //
321 this.label1.Location = new System.Drawing.Point(8, 208);
322 this.label1.Name = "label1";
323 this.label1.Size = new System.Drawing.Size(48, 16);
324 this.label1.TabIndex = 4;
325 this.label1.Text = "Name:";
326 this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
327 //
328 // label2
329 //
330 this.label2.Location = new System.Drawing.Point(8, 240);
331 this.label2.Name = "label2";
332 this.label2.Size = new System.Drawing.Size(48, 16);
333 this.label2.TabIndex = 5;
334 this.label2.Text = "Type:";
335 this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
336 //
337 // label3
338 //
339 this.label3.Location = new System.Drawing.Point(8, 272);
340 this.label3.Name = "label3";
341 this.label3.Size = new System.Drawing.Size(48, 16);
342 this.label3.TabIndex = 6;
343 this.label3.Text = "Domain:";
344 this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
345 //
346 // label4
347 //
348 this.label4.Location = new System.Drawing.Point(8, 304);
349 this.label4.Name = "label4";
350 this.label4.Size = new System.Drawing.Size(48, 16);
351 this.label4.TabIndex = 7;
352 this.label4.Text = "Host:";
353 this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
354 //
355 // nameField
356 //
357 this.nameField.Location = new System.Drawing.Point(56, 208);
358 this.nameField.Name = "nameField";
359 this.nameField.ReadOnly = true;
360 this.nameField.Size = new System.Drawing.Size(168, 20);
361 this.nameField.TabIndex = 8;
362 this.nameField.Text = "";
363 //
364 // typeField
365 //
366 this.typeField.Location = new System.Drawing.Point(56, 240);
367 this.typeField.Name = "typeField";
368 this.typeField.ReadOnly = true;
369 this.typeField.Size = new System.Drawing.Size(168, 20);
370 this.typeField.TabIndex = 9;
371 this.typeField.Text = "";
372 //
373 // domainField
374 //
375 this.domainField.Location = new System.Drawing.Point(56, 272);
376 this.domainField.Name = "domainField";
377 this.domainField.ReadOnly = true;
378 this.domainField.Size = new System.Drawing.Size(168, 20);
379 this.domainField.TabIndex = 10;
380 this.domainField.Text = "";
381 //
382 // hostField
383 //
384 this.hostField.Location = new System.Drawing.Point(56, 304);
385 this.hostField.Name = "hostField";
386 this.hostField.ReadOnly = true;
387 this.hostField.Size = new System.Drawing.Size(168, 20);
388 this.hostField.TabIndex = 11;
389 this.hostField.Text = "";
390
391 //
392 // portField
393 //
394 this.portField.Location = new System.Drawing.Point(56, 336);
395 this.portField.Name = "portField";
396 this.portField.ReadOnly = true;
397 this.portField.Size = new System.Drawing.Size(168, 20);
398 this.portField.TabIndex = 12;
399 this.portField.Text = "";
400 //
401 // label5
402 //
403 this.label5.Location = new System.Drawing.Point(8, 336);
404 this.label5.Name = "label5";
405 this.label5.Size = new System.Drawing.Size(48, 16);
406 this.label5.TabIndex = 14;
407 this.label5.Text = "Port:";
408 this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
409 //
410 // serviceTextField
411 //
412 this.serviceTextField.HorizontalScrollbar = true;
413 this.serviceTextField.Location = new System.Drawing.Point(264, 208);
414 this.serviceTextField.Name = "serviceTextField";
415 this.serviceTextField.Size = new System.Drawing.Size(232, 147);
416 this.serviceTextField.TabIndex = 16;
417 //
418 // Form1
419 //
420 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
421 this.ClientSize = new System.Drawing.Size(512, 365);
422 this.Controls.AddRange(new System.Windows.Forms.Control[] {
423 this.serviceTextField,
424 this.label5,
425 this.portField,
426 this.hostField,
427 this.domainField,
428 this.typeField,
429 this.nameField,
430 this.label4,
431 this.label3,
432 this.label2,
433 this.label1,
434 this.typeBox,
435 this.browseList});
436 this.Name = "Form1";
437 this.Text = "DNSServices Browser";
438 this.ResumeLayout(false);
439
440 }
441 #endregion
442
443 /// <summary>
444 /// The main entry point for the application.
445 /// </summary>
446 [STAThread]
447 static void Main()
448 {
449 Application.Run(new Form1());
450 }
451 //
452 // BrowseData
453 //
454 // This class is used to store data associated
455 // with a DNSService.Browse() operation
456 //
457 public class BrowseData
458 {
459 public uint InterfaceIndex;
460 public String Name;
461 public String Type;
462 public String Domain;
463 public int Refs;
464
465 public override String
466 ToString()
467 {
468 return Name;
469 }
470
471 public override bool
472 Equals(object other)
473 {
474 bool result = false;
475
476 if (other != null)
477 {
478 result = (this.Name == other.ToString());
479 }
480
481 return result;
482 }
483
484 public override int
485 GetHashCode()
486 {
487 return Name.GetHashCode();
488 }
489 };
490
491
492 //
493 // ResolveData
494 //
495 // This class is used to store data associated
496 // with a DNSService.Resolve() operation
497 //
498 public class ResolveData
499 {
500 public uint InterfaceIndex;
501 public String FullName;
502 public String HostName;
503 public int Port;
504 public TXTRecord TxtRecord;
505
506 public override String
507 ToString()
508 {
509 return FullName;
510 }
511 };
512
513 //
514 // Populate()
515 //
516 // Populate this form with data associated with a
517 // DNSService.Resolve() call
518 //
519 public void
520 Populate(BrowseData browseData, ResolveData resolveData)
521 {
522 nameField.Text = browseData.Name;
523 typeField.Text = browseData.Type;
524 domainField.Text = browseData.Domain;
525 hostField.Text = resolveData.HostName;
526 portField.Text = resolveData.Port.ToString();
527
528 serviceTextField.Items.Clear();
529
530 //
531 // When we print the text record, we're going to assume that every value
532 // is a string.
533 //
534 if (resolveData.TxtRecord != null)
535 {
536 for (uint idx = 0; idx < resolveData.TxtRecord.GetCount(); idx++)
537 {
538 String key;
539 Byte[] bytes;
540
541 key = resolveData.TxtRecord.GetKeyAtIndex(idx);
542 bytes = (Byte[])resolveData.TxtRecord.GetValueAtIndex(idx);
543
544 if (key.Length > 0)
545 {
546 String val = "";
547
548 if (bytes != null)
549 {
550 val = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
551 }
552
553 serviceTextField.Items.Add(key + "=" + val);
554 }
555 }
556 }
557 }
558
559 //
560 // called when the type field changes
561 //
562 private void typeBox_SelectedIndexChanged(object sender, System.EventArgs e)
563 {
564 browseList.Items.Clear();
565
566 //
567 // Stop the current browse operation
568 //
569 if (browser != null)
570 {
571 browser.Stop();
572 }
573
574 nameField.Text = "";
575 typeField.Text = "";
576 domainField.Text = "";
577 hostField.Text = "";
578 portField.Text = "";
579 serviceTextField.Items.Clear();
580
581 try
582 {
583 //
584 // Selecting a service type will start a new browse operation.
585 //
586 browser = service.Browse( 0, 0, typeBox.SelectedItem.ToString(), null, eventManager );
587 }
588 catch
589 {
590 MessageBox.Show("Browse Failed", "Error");
591 Application.Exit();
592 }
593 }
594
595 private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
596 {
597 if (resolver != null)
598 {
599 resolver.Stop();
600 resolver = null;
601 }
602
603 if (browseList.SelectedItem != null)
604 {
605 try
606 {
607 BrowseData data = (BrowseData) browseList.SelectedItem;
608
609 //
610 // Clicking on a service instance results in starting a resolve operation
611 // that will call us back with information about the service
612 //
613 resolver = service.Resolve(0, data.InterfaceIndex, data.Name, data.Type, data.Domain, eventManager);
614 }
615 catch
616 {
617 MessageBox.Show("Resolve Failed", "Error");
618 Application.Exit();
619 }
620 }
621 }
622
623 //
624 // ServiceFound
625 //
626 // This call is invoked by the DNSService core. We create
627 // a BrowseData object and invoked the appropriate method
628 // in the GUI thread so we can update the UI
629 //
630 public void ServiceFound
631 (
632 DNSSDService sref,
633 DNSSDFlags flags,
634 uint ifIndex,
635 String serviceName,
636 String regType,
637 String domain
638 )
639 {
640 int index = browseList.Items.IndexOf(serviceName);
641
642 //
643 // Check to see if we've seen this service before. If the machine has multiple
644 // interfaces, we could potentially get called back multiple times for the
645 // same service. Implementing a simple reference counting scheme will address
646 // the problem of the same service showing up more than once in the browse list.
647 //
648 if (index == -1)
649 {
650 BrowseData data = new BrowseData();
651
652 data.InterfaceIndex = ifIndex;
653 data.Name = serviceName;
654 data.Type = regType;
655 data.Domain = domain;
656 data.Refs = 1;
657
658 browseList.Items.Add(data);
659 browseList.Invalidate();
660 }
661 else
662 {
663 BrowseData data = (BrowseData) browseList.Items[index];
664 data.Refs++;
665 }
666 }
667
668 public void ServiceLost
669 (
670 DNSSDService sref,
671 DNSSDFlags flags,
672 uint ifIndex,
673 String serviceName,
674 String regType,
675 String domain
676 )
677 {
678 int index = browseList.Items.IndexOf(serviceName);
679
680 //
681 // See above comment in ServiceFound about reference counting
682 //
683 if (index != -1)
684 {
685 BrowseData data = (BrowseData) browseList.Items[index];
686
687 data.Refs--;
688
689 if (data.Refs == 0)
690 {
691 browseList.Items.Remove(data);
692 browseList.Invalidate();
693 }
694 }
695 }
696
697 public void ServiceResolved
698 (
699 DNSSDService sref,
700 DNSSDFlags flags,
701 uint ifIndex,
702 String fullName,
703 String hostName,
704 ushort port,
705 TXTRecord txtRecord
706 )
707 {
708 ResolveData data = new ResolveData();
709
710 data.InterfaceIndex = ifIndex;
711 data.FullName = fullName;
712 data.HostName = hostName;
713 data.Port = port;
714 data.TxtRecord = txtRecord;
715
716 //
717 // Don't forget to stop the resolver. This eases the burden on the network
718 //
719 resolver.Stop();
720 resolver = null;
721
722 Populate((BrowseData) browseList.SelectedItem, data);
723 }
724
725 public void OperationFailed
726 (
727 DNSSDService sref,
728 DNSSDError error
729 )
730 {
731 MessageBox.Show("Operation failed: error code: " + error, "Error");
732 }
733 }
734 }