xactengine3_7: Add new dll.
[wine.git] / dlls / kernel32 / computername.c
blobf4b56335ddccaa021f26cadba2c7deeb3a2753d8
1 /*
2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
5 * Copyright 1999 Peter Ganten
6 * Copyright 2002 Martin Wilck
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "config.h"
24 #include "wine/port.h"
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
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 "wine/debug.h"
48 #include "kernel_private.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(computername);
52 /* Registry key and value names */
53 static const WCHAR ComputerW[] = {'\\','R','e','g','i','s','t','r','y','\\',
54 '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};
62 static const WCHAR default_ComputerName[] = {'W','I','N','E',0};
64 /***********************************************************************
65 * dns_gethostbyname (INTERNAL)
67 * From hostname(1):
68 * "The FQDN is the name gethostbyname(2) returns for the host name returned by gethostname(2)."
70 * Wine can use this technique only if the thread-safe gethostbyname_r is available.
72 static void dns_gethostbyname ( char *name, int size )
74 #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6
75 struct hostent* host = NULL;
76 char *extrabuf;
77 int ebufsize = 1024;
78 struct hostent hostentry;
79 int locerr = ENOBUFS, res;
81 for (;;)
83 if (!(extrabuf = HeapAlloc( GetProcessHeap(), 0, ebufsize ))) return;
84 res = gethostbyname_r ( name, &hostentry, extrabuf, ebufsize, &host, &locerr );
85 if( res != ERANGE ) break;
86 ebufsize *= 2;
87 HeapFree( GetProcessHeap(), 0, extrabuf );
90 if ( res )
91 WARN ("Error in gethostbyname_r %d (%d)\n", res, locerr);
92 else if ( !host )
93 WARN ("gethostbyname_r returned NULL host, locerr = %d\n", locerr);
94 else
95 if (strlen( host->h_name ) < size) strcpy( name, host->h_name );
97 HeapFree( GetProcessHeap(), 0, extrabuf );
98 #endif
101 /***********************************************************************
102 * dns_fqdn (INTERNAL)
104 static BOOL dns_fqdn ( char *name, int size )
106 if (gethostname( name, size ))
108 switch( errno )
110 case ENAMETOOLONG:
111 SetLastError ( ERROR_MORE_DATA );
112 break;
113 default:
114 SetLastError ( ERROR_INVALID_PARAMETER );
115 break;
117 return FALSE;
119 dns_gethostbyname( name, size );
120 return TRUE;
123 /***********************************************************************
124 * COMPUTERNAME_Init (INTERNAL)
126 void COMPUTERNAME_Init (void)
128 HANDLE hkey = INVALID_HANDLE_VALUE, hsubkey = INVALID_HANDLE_VALUE;
129 OBJECT_ATTRIBUTES attr;
130 UNICODE_STRING nameW;
131 char buf[offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ) + (MAX_COMPUTERNAME_LENGTH + 1) * sizeof( WCHAR )];
132 DWORD len = sizeof( buf );
133 const WCHAR *computer_name = (WCHAR *)(buf + offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ));
134 NTSTATUS st = STATUS_INTERNAL_ERROR;
135 char hbuf[256];
136 WCHAR *dot, bufW[256];
138 if (dns_fqdn( hbuf, sizeof(hbuf) ))
140 MultiByteToWideChar( CP_UNIXCP, 0, hbuf, -1, bufW, ARRAY_SIZE(bufW) );
141 dot = strchrW( bufW, '.' );
142 if (dot) *dot++ = 0;
143 else dot = bufW + strlenW(bufW);
144 SetComputerNameExW( ComputerNamePhysicalDnsDomain, dot );
145 SetComputerNameExW( ComputerNamePhysicalDnsHostname, bufW );
148 TRACE("(void)\n");
149 InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
150 RtlInitUnicodeString( &nameW, ComputerW );
151 if ( ( st = NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) ) != STATUS_SUCCESS )
152 goto out;
154 attr.RootDirectory = hkey;
155 RtlInitUnicodeString( &nameW, ComputerNameW );
156 if ( (st = NtCreateKey( &hsubkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) ) != STATUS_SUCCESS )
157 goto out;
159 st = NtQueryValueKey( hsubkey, &nameW, KeyValuePartialInformation, buf, len, &len );
161 if ( st != STATUS_SUCCESS)
163 computer_name = default_ComputerName;
164 len = sizeof(default_ComputerName);
166 else
168 len = (len - offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ));
171 NtClose( hsubkey );
172 TRACE(" ComputerName: %s (%u)\n", debugstr_w (computer_name), len);
174 RtlInitUnicodeString( &nameW, ActiveComputerNameW );
175 if ( ( st = NtCreateKey( &hsubkey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, NULL ) )
176 != STATUS_SUCCESS )
177 goto out;
179 RtlInitUnicodeString( &nameW, ComputerNameW );
180 st = NtSetValueKey( hsubkey, &nameW, 0, REG_SZ, computer_name, len );
182 out:
183 NtClose( hsubkey );
184 NtClose( hkey );
186 if ( st == STATUS_SUCCESS )
187 TRACE( "success\n" );
188 else
190 WARN( "status trying to set ComputerName: %x\n", st );
191 SetLastError ( RtlNtStatusToDosError ( st ) );
196 /***********************************************************************
197 * GetComputerNameW (KERNEL32.@)
199 BOOL WINAPI GetComputerNameW(LPWSTR name,LPDWORD size)
201 BOOL ret = GetComputerNameExW( ComputerNameNetBIOS, name, size );
202 if (!ret && GetLastError() == ERROR_MORE_DATA) SetLastError( ERROR_BUFFER_OVERFLOW );
203 return ret;
206 /***********************************************************************
207 * GetComputerNameA (KERNEL32.@)
209 BOOL WINAPI GetComputerNameA(LPSTR name, LPDWORD size)
211 WCHAR nameW[ MAX_COMPUTERNAME_LENGTH + 1 ];
212 DWORD sizeW = MAX_COMPUTERNAME_LENGTH + 1;
213 unsigned int len;
214 BOOL ret;
216 if ( !GetComputerNameW (nameW, &sizeW) ) return FALSE;
218 len = WideCharToMultiByte ( CP_ACP, 0, nameW, -1, NULL, 0, NULL, 0 );
219 /* for compatibility with Win9x */
220 __TRY
222 if ( *size < len )
224 *size = len;
225 SetLastError( ERROR_BUFFER_OVERFLOW );
226 ret = FALSE;
228 else
230 WideCharToMultiByte ( CP_ACP, 0, nameW, -1, name, len, NULL, 0 );
231 *size = len - 1;
232 ret = TRUE;
235 __EXCEPT_PAGE_FAULT
237 SetLastError( ERROR_INVALID_PARAMETER );
238 ret = FALSE;
240 __ENDTRY
242 return ret;
245 /***********************************************************************
246 * DnsHostnameToComputerNameA (KERNEL32.@)
248 BOOL WINAPI DnsHostnameToComputerNameA(LPCSTR hostname,
249 LPSTR computername, LPDWORD size)
251 WCHAR *hostW, nameW[MAX_COMPUTERNAME_LENGTH + 1];
252 DWORD len;
253 BOOL ret;
255 if (!hostname || !size) return FALSE;
256 len = MultiByteToWideChar( CP_ACP, 0, hostname, -1, NULL, 0 );
257 if (!(hostW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
258 MultiByteToWideChar( CP_ACP, 0, hostname, -1, hostW, len );
259 len = ARRAY_SIZE(nameW);
260 if ((ret = DnsHostnameToComputerNameW( hostW, nameW, &len )))
262 if (!computername || !WideCharToMultiByte( CP_ACP, 0, nameW, -1, computername, *size, NULL, NULL ))
263 *size = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL );
264 else
265 *size = strlen(computername);
267 HeapFree( GetProcessHeap(), 0, hostW );
268 return TRUE;
271 /***********************************************************************
272 * DnsHostnameToComputerNameW (KERNEL32.@)
274 BOOL WINAPI DnsHostnameToComputerNameW(LPCWSTR hostname,
275 LPWSTR computername, LPDWORD size)
277 return DnsHostnameToComputerNameExW( hostname, computername, size );