Added CSIDL_MYVIDEO|MYPICTURES|MYMUSIC to _SHRegisterUserShellFolders.
[wine] / dlls / kernel / computername.c
1 /*
2  * Win32 kernel functions
3  *
4  * Copyright 1995 Martin von Loewis and Cameron Heide
5  * Copyright 1999 Peter Ganten
6  * Copyright 2002 Martin Wilck
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "config.h"
24 #include "wine/port.h"
25
26 #include <stdarg.h>
27 #include <string.h>
28 #ifdef HAVE_UNISTD_H
29 # include <unistd.h>
30 #endif
31 #include <stdlib.h>
32 #include <errno.h>
33 #ifdef HAVE_NETDB_H
34 #include <netdb.h>
35 #endif
36
37 #include "ntstatus.h"
38 #define WIN32_NO_STATUS
39 #include "windef.h"
40 #include "winbase.h"
41 #include "winerror.h"
42 #include "winnls.h"
43 #include "winternl.h"
44 #include "wine/unicode.h"
45 #include "wine/exception.h"
46 #include "excpt.h"
47 #include "wine/debug.h"
48
49 #include "kernel_private.h"
50
51 WINE_DEFAULT_DEBUG_CHANNEL(computername);
52
53 /* Registry key and value names */
54 static const WCHAR ComputerW[] = {'M','a','c','h','i','n','e','\\',
55                                   'S','y','s','t','e','m','\\',
56                                   'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
57                                   'C','o','n','t','r','o','l','\\',
58                                   'C','o','m','p','u','t','e','r','N','a','m','e',0};
59 static const WCHAR ActiveComputerNameW[] =   {'A','c','t','i','v','e','C','o','m','p','u','t','e','r','N','a','m','e',0};
60 static const WCHAR ComputerNameW[] = {'C','o','m','p','u','t','e','r','N','a','m','e',0};
61
62 static const char default_ComputerName[] = "WINE";
63
64 #define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
65
66 /* filter for page-fault exceptions */
67 static WINE_EXCEPTION_FILTER(page_fault)
68 {
69     if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
70         return EXCEPTION_EXECUTE_HANDLER;
71     return EXCEPTION_CONTINUE_SEARCH;
72 }
73
74 /*********************************************************************** 
75  *                    dns_gethostbyname (INTERNAL)
76  *
77  *  From hostname(1):
78  *  "The FQDN is the name gethostbyname(2) returns for the host name returned by gethostname(2)."
79  *
80  *  Wine can use this technique only if the thread-safe gethostbyname_r is available.
81  */
82 #ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
83 static BOOL dns_gethostbyname ( char *name, int *size )
84 {
85     struct hostent* host = NULL;
86     char *extrabuf;
87     int ebufsize = 1024;
88     struct hostent hostentry;
89     int locerr = ENOBUFS, res = ENOMEM;
90
91     extrabuf = HeapAlloc( GetProcessHeap(), 0, ebufsize ) ;
92
93     while( extrabuf ) 
94     {
95         res = gethostbyname_r ( name, &hostentry, extrabuf, ebufsize, &host, &locerr );
96         if( res != ERANGE ) break;
97         ebufsize *= 2;
98         extrabuf = HeapReAlloc( GetProcessHeap(), 0, extrabuf, ebufsize ) ;
99     }
100     
101     if ( res )
102         WARN ("Error in gethostbyname_r %d (%d)\n", res, locerr);
103     else
104     {
105         int len = strlen ( host->h_name );
106         if ( len < *size )
107         {
108             strcpy ( name, host->h_name );
109             *size = len;
110         }
111         else
112         {
113             memcpy ( name, host->h_name, *size );
114             name[*size] = 0;
115             SetLastError ( ERROR_MORE_DATA );
116             res = 1;
117         }
118     }
119
120     HeapFree( GetProcessHeap(), 0, extrabuf );
121     return !res;
122 }
123 #else
124 #  define dns_gethostbyname(name,size) 0
125 #endif
126
127 /*********************************************************************** 
128  *                     dns_fqdn (INTERNAL)
129  */
130 static BOOL dns_fqdn ( char *name, int *size )
131 {
132     if ( gethostname ( name, *size + 1 ) ) 
133     {
134         switch( errno )
135         {
136         case ENAMETOOLONG:
137             SetLastError ( ERROR_MORE_DATA );
138         default:
139             SetLastError ( ERROR_INVALID_PARAMETER );
140         }
141         return FALSE;
142     }
143
144     if ( !dns_gethostbyname ( name, size ) )
145         *size = strlen ( name );
146
147     return TRUE;
148 }
149
150 /*********************************************************************** 
151  *                     dns_hostname (INTERNAL)
152  */
153 static BOOL dns_hostname ( char *name, int *size )
154 {
155     char *c;
156     if ( ! dns_fqdn ( name, size ) ) return FALSE;
157     c = strchr ( name, '.' );
158     if (c)
159     {
160         *c = 0;
161         *size = (c - name);
162     }
163     return TRUE;
164 }
165
166 /*********************************************************************** 
167  *                     dns_domainname (INTERNAL)
168  */
169 static BOOL dns_domainname ( char *name, int *size )
170 {
171     char *c;
172     if ( ! dns_fqdn ( name, size ) ) return FALSE;
173     c = strchr ( name, '.' );
174     if (c)
175     {
176         c += 1;
177         *size -= (c - name);
178         memmove ( name, c, *size + 1 );
179     }
180     return TRUE;
181 }
182
183 /*********************************************************************** 
184  *                      _init_attr    (INTERNAL)
185  */
186 inline static void _init_attr ( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *name )
187 {
188     attr->Length = sizeof (OBJECT_ATTRIBUTES);
189     attr->RootDirectory = 0;
190     attr->ObjectName = name;
191     attr->Attributes = 0;
192     attr->SecurityDescriptor = NULL;
193     attr->SecurityQualityOfService = NULL;
194 }
195
196 /***********************************************************************
197  *           get_use_dns_option
198  */
199 static BOOL get_use_dns_option(void)
200 {
201     static const WCHAR NetworkW[] = {'S','o','f','t','w','a','r','e','\\',
202                                      'W','i','n','e','\\','N','e','t','w','o','r','k',0};
203     static const WCHAR UseDNSW[] = {'U','s','e','D','n','s','C','o','m','p','u','t','e','r','N','a','m','e',0};
204
205     char tmp[80];
206     HANDLE root, hkey;
207     DWORD dummy;
208     OBJECT_ATTRIBUTES attr;
209     UNICODE_STRING nameW;
210     BOOL ret = TRUE;
211
212     _init_attr( &attr, &nameW );
213     RtlOpenCurrentUser( KEY_ALL_ACCESS, &root );
214     attr.RootDirectory = root;
215     RtlInitUnicodeString( &nameW, NetworkW );
216
217     /* @@ Wine registry key: HKCU\Software\Wine\Network */
218     if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ))
219     {
220         RtlInitUnicodeString( &nameW, UseDNSW );
221         if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
222         {
223             WCHAR *str = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
224             ret = IS_OPTION_TRUE( str[0] );
225         }
226         NtClose( hkey );
227     }
228     NtClose( root );
229     return ret;
230 }
231
232
233 /*********************************************************************** 
234  *                      COMPUTERNAME_Init    (INTERNAL)
235  */
236 void COMPUTERNAME_Init (void)
237 {
238     HANDLE hkey = INVALID_HANDLE_VALUE, hsubkey = INVALID_HANDLE_VALUE;
239     OBJECT_ATTRIBUTES attr;
240     UNICODE_STRING nameW;
241     char buf[offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ) + (MAX_COMPUTERNAME_LENGTH + 1) * sizeof( WCHAR )];
242     DWORD len = sizeof( buf );
243     LPWSTR computer_name = (LPWSTR) (buf + offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ));
244     NTSTATUS st = STATUS_INTERNAL_ERROR;
245
246     TRACE("(void)\n");
247     _init_attr ( &attr, &nameW );
248     
249     RtlInitUnicodeString( &nameW, ComputerW );
250     if ( ( st = NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) ) != STATUS_SUCCESS )
251         goto out;
252     
253     attr.RootDirectory = hkey;
254     RtlInitUnicodeString( &nameW, ComputerNameW );
255     if ( (st = NtCreateKey( &hsubkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) ) != STATUS_SUCCESS )
256         goto out;
257     
258     st = NtQueryValueKey( hsubkey, &nameW, KeyValuePartialInformation, buf, len, &len );
259
260     if ( st != STATUS_SUCCESS || get_use_dns_option() )
261     {
262         char hbuf[256];
263         int hlen = sizeof (hbuf);
264         char *dot;
265         TRACE( "retrieving Unix host name\n" );
266         if ( gethostname ( hbuf, hlen ) )
267         {
268             strcpy ( hbuf, default_ComputerName );
269             WARN( "gethostname() error: %d, using host name %s\n", errno, hbuf );
270         }
271         hbuf[MAX_COMPUTERNAME_LENGTH] = 0;
272         dot = strchr ( hbuf, '.' );
273         if ( dot ) *dot = 0;
274         hlen = strlen ( hbuf );
275         len = MultiByteToWideChar( CP_ACP, 0, hbuf, hlen + 1, computer_name, MAX_COMPUTERNAME_LENGTH + 1 )
276             * sizeof( WCHAR );
277         if ( NtSetValueKey( hsubkey, &nameW, 0, REG_SZ, computer_name, len ) != STATUS_SUCCESS )
278             WARN ( "failed to set ComputerName\n" );
279     }
280     else if ( st == STATUS_SUCCESS)
281     {
282         len = (len - offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ));
283         TRACE( "found in registry\n" );
284     }
285     else goto out;
286     
287     NtClose( hsubkey );
288     TRACE(" ComputerName: %s (%lu)\n", debugstr_w ( computer_name ), len / sizeof(WCHAR));
289
290     RtlInitUnicodeString( &nameW, ActiveComputerNameW );
291     if ( ( st = NtCreateKey( &hsubkey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, NULL ) )
292          != STATUS_SUCCESS )
293         goto out;
294     
295     RtlInitUnicodeString( &nameW, ComputerNameW );
296     st = NtSetValueKey( hsubkey, &nameW, 0, REG_SZ, computer_name, len );
297
298 out:
299     NtClose( hsubkey );
300     NtClose( hkey );
301
302     if ( st == STATUS_SUCCESS )
303         TRACE( "success\n" );
304     else
305     {
306         WARN( "status trying to set ComputerName: %lx\n", st );
307         SetLastError ( RtlNtStatusToDosError ( st ) );
308     }
309 }
310
311
312 /***********************************************************************
313  *              GetComputerNameW         (KERNEL32.@)
314  */
315 BOOL WINAPI GetComputerNameW(LPWSTR name,LPDWORD size)
316 {
317     UNICODE_STRING nameW;
318     OBJECT_ATTRIBUTES attr;
319     HANDLE hkey = INVALID_HANDLE_VALUE, hsubkey = INVALID_HANDLE_VALUE;
320     char buf[offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ) + (MAX_COMPUTERNAME_LENGTH + 1) * sizeof( WCHAR )];
321     DWORD len = sizeof( buf );
322     LPWSTR theName = (LPWSTR) (buf + offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ));
323     NTSTATUS st = STATUS_INVALID_PARAMETER;
324     
325     TRACE ("%p %p\n", name, size);
326
327     _init_attr ( &attr, &nameW );
328     RtlInitUnicodeString( &nameW, ComputerW );
329     if ( ( st = NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) ) != STATUS_SUCCESS )
330         goto out;
331          
332     attr.RootDirectory = hkey;
333     RtlInitUnicodeString( &nameW, ActiveComputerNameW );
334     if ( ( st = NtOpenKey( &hsubkey, KEY_ALL_ACCESS, &attr ) ) != STATUS_SUCCESS )
335         goto out;
336     
337     RtlInitUnicodeString( &nameW, ComputerNameW );
338     if ( ( st = NtQueryValueKey( hsubkey, &nameW, KeyValuePartialInformation, buf, len, &len ) )
339          != STATUS_SUCCESS )
340         goto out;
341
342     len = (len -offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data )) / sizeof (WCHAR) - 1;
343     TRACE ("ComputerName is %s (length %lu)\n", debugstr_w ( theName ), len);
344
345     __TRY
346     {
347         if ( *size < len )
348         {
349             memcpy ( name, theName, *size * sizeof (WCHAR) );
350             name[*size] = 0;
351             *size = len;
352             st = STATUS_MORE_ENTRIES;
353         }
354         else
355         {
356             memcpy ( name, theName, len * sizeof (WCHAR) );
357             name[len] = 0;
358             *size = len;
359             st = STATUS_SUCCESS;
360         }
361     }
362     __EXCEPT(page_fault)
363     {
364         st = STATUS_INVALID_PARAMETER;
365     }
366     __ENDTRY
367
368 out:
369     NtClose ( hsubkey );
370     NtClose ( hkey );
371
372     if ( st == STATUS_SUCCESS )
373         return TRUE;
374     else
375     {
376         SetLastError ( RtlNtStatusToDosError ( st ) );
377         WARN ( "Status %lu reading computer name from registry\n", st );
378         return FALSE;
379     }
380 }
381
382 /***********************************************************************
383  *              GetComputerNameA         (KERNEL32.@)
384  */
385 BOOL WINAPI GetComputerNameA(LPSTR name, LPDWORD size)
386 {
387     WCHAR nameW[ MAX_COMPUTERNAME_LENGTH + 1 ];
388     DWORD sizeW = MAX_COMPUTERNAME_LENGTH;
389     unsigned int len;
390     BOOL ret;
391
392     if ( !GetComputerNameW (nameW, &sizeW) ) return FALSE;
393
394     len = WideCharToMultiByte ( CP_ACP, 0, nameW, sizeW, NULL, 0, NULL, 0 );
395     __TRY
396     {
397         if ( *size < len )
398         {
399             WideCharToMultiByte ( CP_ACP, 0, nameW, sizeW, name, *size, NULL, 0 );
400             name[*size] = 0;
401             *size = len;
402             SetLastError( ERROR_MORE_DATA );
403             ret = FALSE;
404         }
405         else 
406         {
407             WideCharToMultiByte ( CP_ACP, 0, nameW, sizeW, name, len, NULL, 0 );
408             name[len] = 0;
409             *size = len;
410             ret = TRUE;
411         }
412     }
413     __EXCEPT(page_fault)
414     {
415         SetLastError( ERROR_INVALID_PARAMETER );
416         ret = FALSE;
417     }
418     __ENDTRY
419
420     return ret;
421 }
422
423 /***********************************************************************
424  *              GetComputerNameExA         (KERNEL32.@)
425  */
426 BOOL WINAPI GetComputerNameExA(COMPUTER_NAME_FORMAT type, LPSTR name, LPDWORD size)
427 {
428     char buf[256];
429     int len = sizeof (buf), ret;
430     TRACE("%d, %p, %p\n", type, name, size);
431     switch( type )
432     {
433     case ComputerNameNetBIOS:
434     case ComputerNamePhysicalNetBIOS:
435         return GetComputerNameA (name, size);
436     case ComputerNameDnsHostname:
437     case ComputerNamePhysicalDnsHostname:
438         ret = dns_hostname (buf, &len);
439         break;
440     case ComputerNameDnsDomain:
441     case ComputerNamePhysicalDnsDomain:
442         ret = dns_domainname (buf, &len);
443         break;
444     case ComputerNameDnsFullyQualified:
445     case ComputerNamePhysicalDnsFullyQualified:
446         ret = dns_fqdn (buf, &len);
447         break;
448     default:
449         SetLastError (ERROR_INVALID_PARAMETER);
450         return FALSE;
451     }
452
453     if ( ret )
454     {
455         TRACE ("-> %s (%d)\n", debugstr_a (buf), len);
456         __TRY
457         {
458             if ( *size < len )
459             {
460                 memcpy( name, buf, *size );
461                 name[*size] = 0;
462                 *size = len;
463                 SetLastError( ERROR_MORE_DATA );
464                 ret = FALSE;
465             }
466             else
467             {
468                 memcpy( name, buf, len );
469                 name[len] = 0;
470                 *size = len;
471                 ret = TRUE;
472             }
473         }
474         __EXCEPT(page_fault)
475         {
476             SetLastError( ERROR_INVALID_PARAMETER );
477             return FALSE;
478         }
479         __ENDTRY
480     }
481
482     return ret;
483 }
484
485
486 /***********************************************************************
487  *              GetComputerNameExW         (KERNEL32.@)
488  */
489 BOOL WINAPI GetComputerNameExW( COMPUTER_NAME_FORMAT type, LPWSTR name, LPDWORD size )
490 {
491     char buf[256];
492     int len = sizeof (buf), ret;
493
494     TRACE("%d, %p, %p\n", type, name, size);
495     switch( type )
496     {
497     case ComputerNameNetBIOS:
498     case ComputerNamePhysicalNetBIOS:
499         return GetComputerNameW (name, size);
500     case ComputerNameDnsHostname:
501     case ComputerNamePhysicalDnsHostname:
502         ret = dns_hostname (buf, &len);
503         break;
504     case ComputerNameDnsDomain:
505     case ComputerNamePhysicalDnsDomain:
506         ret = dns_domainname (buf, &len);
507         break;
508     case ComputerNameDnsFullyQualified:
509     case ComputerNamePhysicalDnsFullyQualified:
510         ret = dns_fqdn (buf, &len);
511         break;
512     default:
513         SetLastError (ERROR_INVALID_PARAMETER);
514         return FALSE;
515     }
516
517     if ( ret )
518     {
519         TRACE ("-> %s (%d)\n", debugstr_a (buf), len);
520         __TRY
521         {
522             unsigned int lenW = MultiByteToWideChar( CP_ACP, 0, buf, len, NULL, 0 );
523             if ( *size < lenW )
524             {
525                 MultiByteToWideChar( CP_ACP, 0, buf, len, name, *size );
526                 name[*size] = 0;
527                 *size = lenW;
528                 SetLastError( ERROR_MORE_DATA );
529                 ret = FALSE;
530             }
531             else
532             {
533                 MultiByteToWideChar( CP_ACP, 0, buf, len, name, lenW );
534                 name[lenW] = 0;
535                 *size = lenW;
536                 ret = TRUE;
537             }
538         }
539         __EXCEPT(page_fault)
540         {
541             SetLastError( ERROR_INVALID_PARAMETER );
542             return FALSE;
543         }
544         __ENDTRY
545     }
546
547     return ret;
548 }
549
550 /******************************************************************************
551  * netbios_char (INTERNAL)
552  */
553 static WCHAR netbios_char ( WCHAR wc )
554 {
555     static const WCHAR special[] = {'!','@','#','$','%','^','&','\'',')','(','-','_','{','}','~'};
556     static const WCHAR deflt = '_';
557     unsigned int i;
558     
559     if ( isalnumW ( wc ) ) return wc;
560     for ( i = 0; i < sizeof (special) / sizeof (WCHAR); i++ )
561         if ( wc == special[i] ) return wc;
562     return deflt;
563 }
564
565 /******************************************************************************
566  * SetComputerNameW [KERNEL32.@]
567  *
568  * Set a new NetBIOS name for the local computer.
569  *
570  * PARAMS
571  *    lpComputerName [I] Address of new computer name
572  *
573  * RETURNS
574  *    Success: TRUE
575  *    Failure: FALSE
576  */
577 BOOL WINAPI SetComputerNameW( LPCWSTR lpComputerName )
578 {
579     UNICODE_STRING nameW;
580     OBJECT_ATTRIBUTES attr;
581     HANDLE hkey = INVALID_HANDLE_VALUE, hsubkey = INVALID_HANDLE_VALUE;
582     int plen = strlenW ( lpComputerName );
583     int i;
584     NTSTATUS st = STATUS_INTERNAL_ERROR;
585
586     if (get_use_dns_option())
587     {
588         /* This check isn't necessary, but may help debugging problems. */
589         WARN( "Disabled by Wine Configuration.\n" );
590         WARN( "Set \"UseDnsComputerName\" = \"N\" in category [Network] to enable.\n" );
591         SetLastError ( ERROR_ACCESS_DENIED );
592         return FALSE;
593     }
594
595     TRACE( "%s\n", debugstr_w (lpComputerName) );
596
597     /* Check parameter */
598     if ( plen > MAX_COMPUTERNAME_LENGTH ) 
599         goto out;
600
601     /* This is NT behaviour. Win 95/98 would coerce characters. */
602     for ( i = 0; i < plen; i++ )
603     {
604         WCHAR wc = lpComputerName[i];
605         if ( wc != netbios_char( wc ) )
606             goto out;
607     }
608     
609     _init_attr ( &attr, &nameW );
610     
611     RtlInitUnicodeString (&nameW, ComputerW);
612     if ( ( st = NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) ) != STATUS_SUCCESS )
613         goto out;
614     attr.RootDirectory = hkey;
615     RtlInitUnicodeString( &nameW, ComputerNameW );
616     if ( ( st = NtOpenKey( &hsubkey, KEY_ALL_ACCESS, &attr ) ) != STATUS_SUCCESS )
617         goto out;
618     if ( ( st = NtSetValueKey( hsubkey, &nameW, 0, REG_SZ, lpComputerName, ( plen + 1) * sizeof(WCHAR) ) )
619          != STATUS_SUCCESS )
620         goto out;
621
622 out:
623     NtClose( hsubkey );
624     NtClose( hkey );
625     
626     if ( st == STATUS_SUCCESS )
627     {
628         TRACE( "ComputerName changed\n" );
629         return TRUE;
630     }
631
632     else
633     {
634         SetLastError ( RtlNtStatusToDosError ( st ) );
635         WARN ( "status %lu\n", st );
636         return FALSE;
637     }
638 }
639
640 /******************************************************************************
641  * SetComputerNameA [KERNEL32.@]
642  *
643  * See SetComputerNameW.
644  */
645 BOOL WINAPI SetComputerNameA( LPCSTR lpComputerName )
646 {
647     BOOL ret;
648     DWORD len = MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, NULL, 0 );
649     LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
650
651     MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, nameW, len );
652     ret = SetComputerNameW( nameW );
653     HeapFree( GetProcessHeap(), 0, nameW );
654     return ret;
655 }
656
657 /******************************************************************************
658  * SetComputerNameExW [KERNEL32.@]
659  *
660  */
661 BOOL WINAPI SetComputerNameExW( COMPUTER_NAME_FORMAT type, LPCWSTR lpComputerName )
662 {
663     TRACE("%d, %s\n", type, debugstr_w (lpComputerName));
664     switch( type )
665     {
666     case ComputerNameNetBIOS:
667     case ComputerNamePhysicalNetBIOS:
668         return SetComputerNameW( lpComputerName );
669     default:
670         SetLastError( ERROR_ACCESS_DENIED );
671         return FALSE;
672     }
673 }
674
675 /******************************************************************************
676  * SetComputerNameExA [KERNEL32.@]
677  *
678  */
679 BOOL WINAPI SetComputerNameExA( COMPUTER_NAME_FORMAT type, LPCSTR lpComputerName )
680 {
681     TRACE( "%d, %s\n", type, debugstr_a (lpComputerName) );
682     switch( type )
683     {
684     case ComputerNameNetBIOS:
685     case ComputerNamePhysicalNetBIOS:
686         return SetComputerNameA( lpComputerName );
687     default:
688         SetLastError( ERROR_ACCESS_DENIED );
689         return FALSE;
690     }
691 }
692
693 /***********************************************************************
694  *              DnsHostnameToComputerNameA         (KERNEL32.@)
695  */
696 BOOL WINAPI DnsHostnameToComputerNameA(LPCSTR hostname,
697     LPSTR computername, LPDWORD size)
698 {
699     DWORD len;
700
701     FIXME("(%s, %p, %p): stub\n", debugstr_a(hostname), computername, size);
702
703     if (!hostname || !size) return FALSE;
704     len = lstrlenA(hostname);
705
706     if (len > MAX_COMPUTERNAME_LENGTH)
707         len = MAX_COMPUTERNAME_LENGTH;
708
709     if (*size < len)
710     {
711         *size = len;
712         return FALSE;
713     }
714     if (!computername) return FALSE;
715
716     memcpy( computername, hostname, len );
717     computername[len + 1] = 0;
718     return TRUE;
719 }
720
721 /***********************************************************************
722  *              DnsHostnameToComputerNameW         (KERNEL32.@)
723  */
724 BOOL WINAPI DnsHostnameToComputerNameW(LPCWSTR hostname,
725     LPWSTR computername, LPDWORD size)
726 {
727     DWORD len;
728
729     FIXME("(%s, %p, %p): stub\n", debugstr_w(hostname), computername, size);
730
731     if (!hostname || !size) return FALSE;
732     len = lstrlenW(hostname);
733
734     if (len > MAX_COMPUTERNAME_LENGTH)
735         len = MAX_COMPUTERNAME_LENGTH;
736
737     if (*size < len)
738     {
739         *size = len;
740         return FALSE;
741     }
742     if (!computername) return FALSE;
743
744     memcpy( computername, hostname, len * sizeof(WCHAR) );
745     computername[len + 1] = 0;
746     return TRUE;
747 }