]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSWindows/Applications/NSPTool/Tool.c
bee72f834656eaaaa64997cc1474d30be11cfa2c
[apple/mdnsresponder.git] / mDNSWindows / Applications / NSPTool / Tool.c
1 /*
2 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24
25 Change History (most recent first):
26
27 $Log: Tool.c,v $
28 Revision 1.1 2004/01/30 03:02:58 bradley
29 NameSpace Provider Tool for installing, removing, list, etc. NameSpace Providers.
30
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35
36 #include "CommonServices.h"
37 #include "DebugServices.h"
38
39 #include <guiddef.h>
40 #include <ws2spi.h>
41
42 //===========================================================================================================================
43 // Prototypes
44 //===========================================================================================================================
45
46 int main( int argc, char *argv[] );
47 DEBUG_LOCAL void Usage( void );
48 DEBUG_LOCAL int ProcessArgs( int argc, char *argv[] );
49 DEBUG_LOCAL OSStatus InstallNSP( const char *inName, const char *inGUID, const char *inPath );
50 DEBUG_LOCAL OSStatus RemoveNSP( const char *inGUID );
51 DEBUG_LOCAL OSStatus EnableNSP( const char *inGUID, BOOL inEnable );
52 DEBUG_LOCAL OSStatus ListNameSpaces( void );
53 DEBUG_LOCAL OSStatus ReorderNameSpaces( void );
54
55 DEBUG_LOCAL WCHAR * CharToWCharString( const char *inCharString, WCHAR *outWCharString );
56 DEBUG_LOCAL char * GUIDtoString( const GUID *inGUID, char *outString );
57 DEBUG_LOCAL OSStatus StringToGUID( const char *inCharString, GUID *outGUID );
58
59 //===========================================================================================================================
60 // main
61 //===========================================================================================================================
62
63 int main( int argc, char *argv[] )
64 {
65 OSStatus err;
66
67 debug_initialize( kDebugOutputTypeMetaConsole );
68 debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelVerbose );
69
70 err = ProcessArgs( argc, argv );
71 return( (int) err );
72 }
73
74 //===========================================================================================================================
75 // Usage
76 //===========================================================================================================================
77
78 DEBUG_LOCAL void Usage( void )
79 {
80 fprintf( stderr, "\n" );
81 fprintf( stderr, "NSP Tool 1.0d1\n" );
82 fprintf( stderr, " Name Space Provider Tool\n" );
83 fprintf( stderr, "\n" );
84
85 fprintf( stderr, " -install <name> <guid> <path> - Installs a Name Space Provider\n" );
86 fprintf( stderr, "\n" );
87 fprintf( stderr, " <name> Name of the NSP\n" );
88 fprintf( stderr, " <guid> GUID of the NSP\n" );
89 fprintf( stderr, " <path> Path to the NSP file\n" );
90 fprintf( stderr, "\n" );
91
92 fprintf( stderr, " -remove <guid> - Removes a Name Space Provider\n" );
93 fprintf( stderr, "\n" );
94 fprintf( stderr, " <guid> GUID of the NSP\n" );
95 fprintf( stderr, "\n" );
96
97 fprintf( stderr, " -enable/-disable <guid> - Enables or Disables a Name Space Provider\n" );
98 fprintf( stderr, "\n" );
99 fprintf( stderr, " <guid> GUID of the NSP\n" );
100 fprintf( stderr, "\n" );
101
102 fprintf( stderr, " -list - Lists Name Space Providers\n" );
103 fprintf( stderr, " -reorder - Reorders Name Space Providers\n" );
104 fprintf( stderr, " -h[elp] - Help\n" );
105 fprintf( stderr, "\n" );
106 }
107
108 //===========================================================================================================================
109 // ProcessArgs
110 //===========================================================================================================================
111
112 DEBUG_LOCAL int ProcessArgs( int argc, char* argv[] )
113 {
114 OSStatus err;
115 int i;
116 const char * name;
117 const char * guid;
118 const char * path;
119
120 if( argc <= 1 )
121 {
122 Usage();
123 err = 0;
124 goto exit;
125 }
126 for( i = 1; i < argc; ++i )
127 {
128 if( strcmp( argv[ i ], "-install" ) == 0 )
129 {
130 // Install
131
132 if( argc <= ( i + 3 ) )
133 {
134 fprintf( stderr, "\n### ERROR: missing arguments for %s\n\n", argv[ i ] );
135 Usage();
136 err = kParamErr;
137 goto exit;
138 }
139 name = argv[ ++i ];
140 guid = argv[ ++i ];
141 path = argv[ ++i ];
142
143 if( *name == '\0' )
144 {
145 name = "DotLocalNSP";
146 }
147 if( *guid == '\0' )
148 {
149 guid = "B600E6E9-553B-4a19-8696-335E5C896153";
150 }
151
152 err = InstallNSP( name, guid, path );
153 require_noerr( err, exit );
154 }
155 else if( strcmp( argv[ i ], "-remove" ) == 0 )
156 {
157 // Remove
158
159 if( argc <= ( i + 1 ) )
160 {
161 fprintf( stderr, "\n### ERROR: missing arguments for %s\n\n", argv[ i ] );
162 Usage();
163 err = kParamErr;
164 goto exit;
165 }
166 guid = argv[ ++i ];
167 if( *guid == '\0' )
168 {
169 guid = "B600E6E9-553B-4a19-8696-335E5C896153";
170 }
171
172 err = RemoveNSP( guid );
173 require_noerr( err, exit );
174 }
175 else if( ( strcmp( argv[ i ], "-enable" ) == 0 ) ||
176 ( strcmp( argv[ i ], "-disable" ) == 0 ) )
177 {
178 BOOL enable;
179
180 // Enable/Disable
181
182 enable = ( strcmp( argv[ i ], "-enable" ) == 0 );
183 if( argc <= ( i + 1 ) )
184 {
185 fprintf( stderr, "\n### ERROR: missing arguments for %s\n\n", argv[ i ] );
186 Usage();
187 err = kParamErr;
188 goto exit;
189 }
190 guid = argv[ ++i ];
191
192 err = EnableNSP( guid, enable );
193 require_noerr( err, exit );
194 }
195 else if( strcmp( argv[ i ], "-list" ) == 0 )
196 {
197 // List
198
199 err = ListNameSpaces();
200 require_noerr( err, exit );
201 }
202 else if( strcmp( argv[ i ], "-reorder" ) == 0 )
203 {
204 // Reorder
205
206 err = ReorderNameSpaces();
207 require_noerr( err, exit );
208 }
209 else if( ( strcmp( argv[ i ], "-help" ) == 0 ) ||
210 ( strcmp( argv[ i ], "-h" ) == 0 ) )
211 {
212 // Help
213
214 Usage();
215 err = 0;
216 goto exit;
217 }
218 else
219 {
220 fprintf( stderr, "\n### ERROR: unknown argment: \"%s\"\n\n", argv[ i ] );
221 Usage();
222 err = kParamErr;
223 goto exit;
224 }
225 }
226 err = kNoErr;
227
228 exit:
229 return( err );
230 }
231
232 #if 0
233 #pragma mark -
234 #endif
235
236 //===========================================================================================================================
237 // InstallNSP
238 //===========================================================================================================================
239
240 OSStatus InstallNSP( const char *inName, const char *inGUID, const char *inPath )
241 {
242 OSStatus err;
243 size_t size;
244 WSADATA wsd;
245 WCHAR name[ 256 ];
246 GUID guid;
247 WCHAR path[ MAX_PATH ];
248
249 require_action( inName && ( *inName != '\0' ), exit, err = kParamErr );
250 require_action( inGUID && ( *inGUID != '\0' ), exit, err = kParamErr );
251 require_action( inPath && ( *inPath != '\0' ), exit, err = kParamErr );
252
253 size = strlen( inName );
254 require_action( size < sizeof_array( name ), exit, err = kSizeErr );
255 CharToWCharString( inName, name );
256
257 err = StringToGUID( inGUID, &guid );
258 require_noerr( err, exit );
259
260 size = strlen( inPath );
261 require_action( size < sizeof_array( path ), exit, err = kSizeErr );
262 CharToWCharString( inPath, path );
263
264 err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
265 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
266 require_noerr( err, exit );
267
268 err = WSCInstallNameSpace( name, path, NS_DNS, 1, &guid );
269 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
270 WSACleanup();
271 require_noerr( err, exit );
272
273 fprintf( stderr, "Installed NSP \"%s\" (%s) at %s\n", inName, inGUID, inPath );
274
275 exit:
276 if( err != kNoErr )
277 {
278 fprintf( stderr, "### FAILED (%d) to install \"%s\" (%s) Name Space Provider at %s\n", err, inName, inGUID, inPath );
279 }
280 return( err );
281 }
282
283 //===========================================================================================================================
284 // RemoveNSP
285 //===========================================================================================================================
286
287 DEBUG_LOCAL OSStatus RemoveNSP( const char *inGUID )
288 {
289 OSStatus err;
290 WSADATA wsd;
291 GUID guid;
292
293 require_action( inGUID && ( *inGUID != '\0' ), exit, err = kParamErr );
294
295 err = StringToGUID( inGUID, &guid );
296 require_noerr( err, exit );
297
298 err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
299 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
300 require_noerr( err, exit );
301
302 err = WSCUnInstallNameSpace( &guid );
303 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
304 WSACleanup();
305 require_noerr( err, exit );
306
307 fprintf( stderr, "Removed NSP %s\n", inGUID );
308
309 exit:
310 if( err != kNoErr )
311 {
312 fprintf( stderr, "### FAILED (%d) to remove %s Name Space Provider\n", err, inGUID );
313 }
314 return( err );
315 }
316
317 //===========================================================================================================================
318 // EnableNSP
319 //===========================================================================================================================
320
321 DEBUG_LOCAL OSStatus EnableNSP( const char *inGUID, BOOL inEnable )
322 {
323 OSStatus err;
324 WSADATA wsd;
325 GUID guid;
326
327 require_action( inGUID && ( *inGUID != '\0' ), exit, err = kParamErr );
328
329 err = StringToGUID( inGUID, &guid );
330 require_noerr( err, exit );
331
332 err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
333 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
334 require_noerr( err, exit );
335
336 err = WSCEnableNSProvider( &guid, inEnable );
337 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
338 WSACleanup();
339 require_noerr( err, exit );
340
341 fprintf( stderr, "Removed NSP %s\n", inGUID );
342
343 exit:
344 if( err != kNoErr )
345 {
346 fprintf( stderr, "### FAILED (%d) to remove %s Name Space Provider\n", err, inGUID );
347 }
348 return( err );
349 }
350
351 //===========================================================================================================================
352 // ListNameSpaces
353 //===========================================================================================================================
354
355 DEBUG_LOCAL OSStatus ListNameSpaces( void )
356 {
357 OSStatus err;
358 WSADATA wsd;
359 bool started;
360 int n;
361 int i;
362 DWORD size;
363 WSANAMESPACE_INFO * array;
364 char s[ 256 ];
365
366 array = NULL;
367 started = false;
368
369 err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
370 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
371 require_noerr( err, exit );
372 started = true;
373
374 // Build an array of all the NSPs. Call it first with NULL to get the size, allocate a buffer, then get them into it.
375
376 size = 0;
377 n = WSAEnumNameSpaceProviders( &size, NULL );
378 err = translate_errno( n != SOCKET_ERROR, (OSStatus) GetLastError(), kUnknownErr );
379 require_action( err == WSAEFAULT, exit, err = kUnknownErr );
380
381 array = (WSANAMESPACE_INFO *) malloc( size );
382 require_action( array, exit, err = kNoMemoryErr );
383
384 n = WSAEnumNameSpaceProviders( &size, array );
385 err = translate_errno( n != SOCKET_ERROR, (OSStatus) GetLastError(), kUnknownErr );
386 require_noerr( err, exit );
387
388 fprintf( stdout, "\n" );
389 for( i = 0; i < n; ++i )
390 {
391 fprintf( stdout, "Name Space %d\n", i + 1 );
392 fprintf( stdout, " NSProviderId: %s\n", GUIDtoString( &array[ i ].NSProviderId, s ) );
393 fprintf( stdout, " dwNameSpace: %d\n", array[ i ].dwNameSpace );
394 fprintf( stdout, " fActive: %s\n", array[ i ].fActive ? "YES" : "NO" );
395 fprintf( stdout, " dwVersion: %d\n", array[ i ].dwVersion );
396 fprintf( stdout, " lpszIdentifier: \"%s\"\n", array[ i ].lpszIdentifier );
397 fprintf( stdout, "\n" );
398 }
399 err = kNoErr;
400
401 exit:
402 if( array )
403 {
404 free( array );
405 }
406 if( started )
407 {
408 WSACleanup();
409 }
410 if( err != kNoErr )
411 {
412 fprintf( stderr, "### FAILED (%d) to list Name Space Providers\n", err );
413 }
414 return( err );
415 }
416
417 //===========================================================================================================================
418 // ReorderNameSpaces
419 //===========================================================================================================================
420
421 DEBUG_LOCAL OSStatus ReorderNameSpaces( void )
422 {
423 OSStatus err;
424 WSADATA wsd;
425 bool started;
426 int n;
427 int i;
428 DWORD size;
429 WSANAMESPACE_INFO * array;
430 WCHAR name[ 256 ];
431 WCHAR path[ MAX_PATH ];
432
433 array = NULL;
434 started = false;
435
436 err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
437 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
438 require_noerr( err, exit );
439 started = true;
440
441 // Build an array of all the NSPs. Call it first with NULL to get the size, allocate a buffer, then get them into it.
442
443 size = 0;
444 n = WSAEnumNameSpaceProviders( &size, NULL );
445 err = translate_errno( n != SOCKET_ERROR, (OSStatus) GetLastError(), kUnknownErr );
446 require_action( err == WSAEFAULT, exit, err = kUnknownErr );
447
448 array = (WSANAMESPACE_INFO *) malloc( size );
449 require_action( array, exit, err = kNoMemoryErr );
450
451 n = WSAEnumNameSpaceProviders( &size, array );
452 err = translate_errno( n != SOCKET_ERROR, (OSStatus) GetLastError(), kUnknownErr );
453 require_noerr( err, exit );
454
455 // Find the "Tcpip" NSP.
456
457 for( i = 0; i < n; ++i )
458 {
459 if( strcmp( array[ i ].lpszIdentifier, "Tcpip" ) == 0 )
460 {
461 break;
462 }
463 }
464 require_action( i < n, exit, err = kNotFoundErr );
465
466 // Uninstall it then re-install it to move it to the end.
467
468 size = strlen( array[ i ].lpszIdentifier );
469 require_action( size < sizeof_array( name ), exit, err = kSizeErr );
470 CharToWCharString( array[ i ].lpszIdentifier, name );
471
472 size = strlen( "%SystemRoot%\\System32\\mswsock.dll" );
473 require_action( size < sizeof_array( path ), exit, err = kSizeErr );
474 CharToWCharString( "%SystemRoot%\\System32\\mswsock.dll", path );
475
476 err = WSCUnInstallNameSpace( &array[ i ].NSProviderId );
477 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
478 require_noerr( err, exit );
479
480 err = WSCInstallNameSpace( name, path, NS_DNS, array[ i ].dwVersion, &array[ i ].NSProviderId );
481 err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
482 require_noerr( err, exit );
483
484 // Success!
485
486 fprintf( stderr, "Reordered \"Tcpip\" NSP to to the bottom of the NSP chain\n" );
487 err = kNoErr;
488
489 exit:
490 if( array )
491 {
492 free( array );
493 }
494 if( started )
495 {
496 WSACleanup();
497 }
498 if( err != kNoErr )
499 {
500 fprintf( stderr, "### FAILED (%d) to reorder Name Space Providers\n", err );
501 }
502 return( err );
503 }
504
505 #if 0
506 #pragma mark -
507 #endif
508
509 //===========================================================================================================================
510 // CharToWCharString
511 //===========================================================================================================================
512
513 DEBUG_LOCAL WCHAR * CharToWCharString( const char *inCharString, WCHAR *outWCharString )
514 {
515 const char * src;
516 WCHAR * dst;
517 char c;
518
519 check( inCharString );
520 check( outWCharString );
521
522 src = inCharString;
523 dst = outWCharString;
524 do
525 {
526 c = *src++;
527 *dst++ = (WCHAR) c;
528
529 } while( c != '\0' );
530
531 return( outWCharString );
532 }
533
534 //===========================================================================================================================
535 // GUIDtoString
536 //===========================================================================================================================
537
538 DEBUG_LOCAL char * GUIDtoString( const GUID *inGUID, char *outString )
539 {
540 check( inGUID );
541 check( outString );
542
543 sprintf( outString, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
544 inGUID->Data1, inGUID->Data2, inGUID->Data3,
545 inGUID->Data4[ 0 ], inGUID->Data4[ 1 ], inGUID->Data4[ 2 ], inGUID->Data4[ 3 ],
546 inGUID->Data4[ 4 ], inGUID->Data4[ 5 ], inGUID->Data4[ 6 ], inGUID->Data4[ 7 ] );
547 return( outString );
548 }
549
550 //===========================================================================================================================
551 // StringToGUID
552 //===========================================================================================================================
553
554 DEBUG_LOCAL OSStatus StringToGUID( const char *inCharString, GUID *outGUID )
555 {
556 OSStatus err;
557 int n;
558 unsigned int v[ 8 ];
559
560 check( inCharString );
561 check( outGUID );
562
563 n = sscanf( inCharString, "%lX-%hX-%hX-%02X%02X-%02X%02X%02X%02X%02X%02X",
564 &outGUID->Data1, &outGUID->Data2, &outGUID->Data3,
565 &v[ 0 ], &v[ 1 ], &v[ 2 ], &v[ 3 ], &v[ 4 ], &v[ 5 ], &v[ 6 ], &v[ 7 ] );
566 require_action( n == 11, exit, err = kFormatErr );
567
568 outGUID->Data4[ 0 ] = (unsigned char) v[ 0 ];
569 outGUID->Data4[ 1 ] = (unsigned char) v[ 1 ];
570 outGUID->Data4[ 2 ] = (unsigned char) v[ 2 ];
571 outGUID->Data4[ 3 ] = (unsigned char) v[ 3 ];
572 outGUID->Data4[ 4 ] = (unsigned char) v[ 4 ];
573 outGUID->Data4[ 5 ] = (unsigned char) v[ 5 ];
574 outGUID->Data4[ 6 ] = (unsigned char) v[ 6 ];
575 outGUID->Data4[ 7 ] = (unsigned char) v[ 7 ];
576 err = kNoErr;
577
578 exit:
579 return( err );
580 }