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
24 #include "wine/port.h"
38 #define WIN32_NO_STATUS
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)
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
;
78 struct hostent hostentry
;
79 int locerr
= ENOBUFS
, res
;
83 if (!(extrabuf
= HeapAlloc( GetProcessHeap(), 0, ebufsize
))) return;
84 res
= gethostbyname_r ( name
, &hostentry
, extrabuf
, ebufsize
, &host
, &locerr
);
85 if( res
!= ERANGE
) break;
87 HeapFree( GetProcessHeap(), 0, extrabuf
);
91 WARN ("Error in gethostbyname_r %d (%d)\n", res
, locerr
);
93 WARN ("gethostbyname_r returned NULL host, locerr = %d\n", locerr
);
95 if (strlen( host
->h_name
) < size
) strcpy( name
, host
->h_name
);
97 HeapFree( GetProcessHeap(), 0, extrabuf
);
101 /***********************************************************************
102 * dns_fqdn (INTERNAL)
104 static BOOL
dns_fqdn ( char *name
, int size
)
106 if (gethostname( name
, size
))
111 SetLastError ( ERROR_MORE_DATA
);
114 SetLastError ( ERROR_INVALID_PARAMETER
);
119 dns_gethostbyname( name
, size
);
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
;
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
, '.' );
143 else dot
= bufW
+ strlenW(bufW
);
144 SetComputerNameExW( ComputerNamePhysicalDnsDomain
, dot
);
145 SetComputerNameExW( ComputerNamePhysicalDnsHostname
, bufW
);
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
)
154 attr
.RootDirectory
= hkey
;
155 RtlInitUnicodeString( &nameW
, ComputerNameW
);
156 if ( (st
= NtCreateKey( &hsubkey
, KEY_ALL_ACCESS
, &attr
, 0, NULL
, 0, NULL
) ) != STATUS_SUCCESS
)
159 st
= NtQueryValueKey( hsubkey
, &nameW
, KeyValuePartialInformation
, buf
, len
, &len
);
161 if ( st
!= STATUS_SUCCESS
)
163 computer_name
= default_ComputerName
;
164 len
= sizeof(default_ComputerName
);
168 len
= (len
- offsetof( KEY_VALUE_PARTIAL_INFORMATION
, Data
));
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
) )
179 RtlInitUnicodeString( &nameW
, ComputerNameW
);
180 st
= NtSetValueKey( hsubkey
, &nameW
, 0, REG_SZ
, computer_name
, len
);
186 if ( st
== STATUS_SUCCESS
)
187 TRACE( "success\n" );
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
);
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;
216 if ( !GetComputerNameW (nameW
, &sizeW
) ) return FALSE
;
218 len
= WideCharToMultiByte ( CP_ACP
, 0, nameW
, -1, NULL
, 0, NULL
, 0 );
219 /* for compatibility with Win9x */
225 SetLastError( ERROR_BUFFER_OVERFLOW
);
230 WideCharToMultiByte ( CP_ACP
, 0, nameW
, -1, name
, len
, NULL
, 0 );
237 SetLastError( ERROR_INVALID_PARAMETER
);
245 /***********************************************************************
246 * DnsHostnameToComputerNameA (KERNEL32.@)
248 BOOL WINAPI
DnsHostnameToComputerNameA(LPCSTR hostname
,
249 LPSTR computername
, LPDWORD size
)
251 WCHAR
*hostW
, nameW
[MAX_COMPUTERNAME_LENGTH
+ 1];
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
);
265 *size
= strlen(computername
);
267 HeapFree( GetProcessHeap(), 0, hostW
);
271 /***********************************************************************
272 * DnsHostnameToComputerNameW (KERNEL32.@)
274 BOOL WINAPI
DnsHostnameToComputerNameW(LPCWSTR hostname
,
275 LPWSTR computername
, LPDWORD size
)
277 return DnsHostnameToComputerNameExW( hostname
, computername
, size
);