3 * Copyright (C) 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS system libraries
22 * PURPOSE: Computer name functions
23 * FILE: lib/kernel32/misc/computername.c
24 * PROGRAMER: Eric Kohl (ekohl@rz-online.de)
27 /* INCLUDES ******************************************************************/
32 #include "../include/debug.h"
35 /* FUNCTIONS *****************************************************************/
37 static BOOL
GetComputerNameFromRegistry( LPWSTR RegistryKey
,
41 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
42 OBJECT_ATTRIBUTES ObjectAttributes
;
43 UNICODE_STRING KeyName
;
44 UNICODE_STRING ValueName
;
50 RtlInitUnicodeString (&KeyName
,RegistryKey
);
51 InitializeObjectAttributes (&ObjectAttributes
,
56 Status
= ZwOpenKey (&KeyHandle
,
59 if (!NT_SUCCESS(Status
))
61 SetLastErrorByStatus (Status
);
65 KeyInfoSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
66 *nSize
* sizeof(WCHAR
);
67 KeyInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
73 SetLastError (ERROR_OUTOFMEMORY
);
77 RtlInitUnicodeString (&ValueName
,ValueNameStr
);
79 Status
= ZwQueryValueKey (KeyHandle
,
81 KeyValuePartialInformation
,
85 if (!NT_SUCCESS(Status
))
87 RtlFreeHeap (RtlGetProcessHeap (),
91 SetLastErrorByStatus (Status
);
95 if( *nSize
> (KeyInfo
->DataLength
/ sizeof(WCHAR
)) ) {
96 *nSize
= KeyInfo
->DataLength
/ sizeof(WCHAR
);
100 RtlCopyMemory (lpBuffer
,
102 *nSize
* sizeof(WCHAR
));
104 RtlFreeHeap (RtlGetProcessHeap (),
118 COMPUTER_NAME_FORMAT NameType
,
123 UNICODE_STRING ResultString
;
124 UNICODE_STRING DomainPart
;
125 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
129 case ComputerNameNetBIOS
:
130 return GetComputerNameFromRegistry
131 ( L
"\\Registry\\Machine\\System\\CurrentControlSet"
132 L
"\\Control\\ComputerName\\ComputerName",
137 case ComputerNameDnsDomain
:
138 return GetComputerNameFromRegistry
139 ( L
"\\Registry\\Machine\\System\\CurrentControlSet"
140 L
"\\Services\\Tcpip\\Parameters",
145 case ComputerNameDnsFullyQualified
:
146 ResultString
.Length
= 0;
147 ResultString
.MaximumLength
= *nSize
* sizeof(WCHAR
);
148 ResultString
.Buffer
= lpBuffer
;
150 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
151 RtlInitUnicodeString(&DomainPart
, NULL
);
152 QueryTable
[0].Name
= L
"HostName";
153 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
154 QueryTable
[0].EntryContext
= &DomainPart
;
156 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
157 L
"\\Registry\\Machine\\System"
158 L
"\\CurrentControlSet\\Services\\Tcpip"
160 QueryTable
, NULL
, NULL
);
162 if( NT_SUCCESS(Status
) ) {
163 RtlAppendUnicodeStringToString(&ResultString
, &DomainPart
);
164 RtlAppendUnicodeToString(&ResultString
, L
".");
165 RtlFreeUnicodeString(&DomainPart
);
167 RtlInitUnicodeString(&DomainPart
, NULL
);
168 QueryTable
[0].Name
= L
"Domain";
169 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
170 QueryTable
[0].EntryContext
= &DomainPart
;
172 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
173 L
"\\Registry\\Machine\\System"
174 L
"\\CurrentControlSet\\Services\\Tcpip"
176 QueryTable
, NULL
, NULL
);
178 if( NT_SUCCESS(Status
) ) {
179 RtlAppendUnicodeStringToString(&ResultString
, &DomainPart
);
180 RtlFreeUnicodeString(&DomainPart
);
181 *nSize
= ResultString
.Length
/ sizeof(WCHAR
);
187 case ComputerNameDnsHostname
:
188 return GetComputerNameFromRegistry
189 ( L
"\\Registry\\Machine\\System\\CurrentControlSet"
190 L
"\\Services\\Tcpip\\Parameters",
195 case ComputerNamePhysicalDnsDomain
:
196 return GetComputerNameFromRegistry
197 ( L
"\\Registry\\Machine\\System\\CurrentControlSet"
198 L
"\\Services\\Tcpip\\Parameters",
204 case ComputerNamePhysicalDnsFullyQualified
:
205 return GetComputerNameExW( ComputerNameDnsFullyQualified
,
207 case ComputerNamePhysicalDnsHostname
:
208 return GetComputerNameExW( ComputerNameDnsHostname
,
210 case ComputerNamePhysicalNetBIOS
:
211 return GetComputerNameExW( ComputerNameNetBIOS
,
214 case ComputerNameMax
:
227 COMPUTER_NAME_FORMAT NameType
,
232 UNICODE_STRING UnicodeString
;
233 ANSI_STRING AnsiString
;
235 PWCHAR TempBuffer
= RtlAllocateHeap( GetProcessHeap(), 0, *nSize
* sizeof(WCHAR
) );
238 return ERROR_OUTOFMEMORY
;
241 AnsiString
.MaximumLength
= *nSize
;
242 AnsiString
.Length
= 0;
243 AnsiString
.Buffer
= lpBuffer
;
245 Result
= GetComputerNameExW( NameType
, TempBuffer
, nSize
);
248 UnicodeString
.MaximumLength
= *nSize
* sizeof(WCHAR
);
249 UnicodeString
.Length
= *nSize
* sizeof(WCHAR
);
250 UnicodeString
.Buffer
= TempBuffer
;
252 RtlUnicodeStringToAnsiString (&AnsiString
,
257 HeapFree( GetProcessHeap(), 0, TempBuffer
);
266 GetComputerNameA (LPSTR lpBuffer
,
269 return GetComputerNameExA( ComputerNameNetBIOS
, lpBuffer
, lpnSize
);
277 GetComputerNameW (LPWSTR lpBuffer
,
280 return GetComputerNameExW( ComputerNameNetBIOS
, lpBuffer
, lpnSize
);
288 IsValidComputerName (
289 COMPUTER_NAME_FORMAT NameType
,
290 LPCWSTR lpComputerName
)
295 /* FIXME: do verification according to NameType */
298 p
= (PWCHAR
)lpComputerName
;
301 if (!(iswctype (*p
, _ALPHA
|| _DIGIT
) ||
325 Length
> MAX_COMPUTERNAME_LENGTH
)
332 static BOOL
SetComputerNameToRegistry(
334 LPCWSTR ValueNameStr
,
337 OBJECT_ATTRIBUTES ObjectAttributes
;
338 UNICODE_STRING KeyName
;
339 UNICODE_STRING ValueName
;
343 RtlInitUnicodeString (&KeyName
, RegistryKey
);
344 InitializeObjectAttributes (&ObjectAttributes
,
346 OBJ_CASE_INSENSITIVE
,
350 Status
= NtOpenKey (&KeyHandle
,
353 if (!NT_SUCCESS(Status
))
355 SetLastErrorByStatus (Status
);
359 RtlInitUnicodeString (&ValueName
, ValueNameStr
);
361 Status
= NtSetValueKey (KeyHandle
,
366 (wcslen (lpBuffer
) + 1) * sizeof(WCHAR
));
367 if (!NT_SUCCESS(Status
))
370 SetLastErrorByStatus (Status
);
374 NtFlushKey (KeyHandle
);
385 SetComputerNameA (LPCSTR lpComputerName
)
387 return SetComputerNameExA( ComputerNamePhysicalNetBIOS
, lpComputerName
);
395 SetComputerNameW (LPCWSTR lpComputerName
)
397 return SetComputerNameExW( ComputerNamePhysicalNetBIOS
, lpComputerName
);
406 COMPUTER_NAME_FORMAT NameType
,
409 UNICODE_STRING Buffer
;
412 RtlCreateUnicodeStringFromAsciiz (&Buffer
,
415 bResult
= SetComputerNameExW (NameType
, Buffer
.Buffer
);
417 RtlFreeUnicodeString (&Buffer
);
428 COMPUTER_NAME_FORMAT NameType
,
431 if (!IsValidComputerName (NameType
, lpBuffer
))
433 SetLastError (ERROR_INVALID_PARAMETER
);
438 case ComputerNamePhysicalDnsDomain
:
439 return SetComputerNameToRegistry
440 ( L
"\\Registry\\Machine\\System\\CurrentControlSet"
441 L
"\\Services\\Tcpip\\Parameters",
445 case ComputerNamePhysicalDnsHostname
:
446 return SetComputerNameToRegistry
447 ( L
"\\Registry\\Machine\\System\\CurrentControlSet"
448 L
"\\Services\\Tcpip\\Parameters",
452 case ComputerNamePhysicalNetBIOS
:
453 return SetComputerNameToRegistry
454 ( L
"\\Registry\\Machine\\System\\CurrentControlSet"
455 L
"\\Control\\ComputerName\\ComputerName",
460 SetLastError (ERROR_INVALID_PARAMETER
);