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: dll/win32/kernel32/client/compname.c
24 * PROGRAMER: Eric Kohl
27 /* INCLUDES ******************************************************************/
35 /* FUNCTIONS *****************************************************************/
39 GetComputerNameFromRegistry(LPWSTR RegistryKey
,
44 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
45 OBJECT_ATTRIBUTES ObjectAttributes
;
46 UNICODE_STRING KeyName
;
47 UNICODE_STRING ValueName
;
53 if (lpBuffer
!= NULL
&& *nSize
> 0)
56 RtlInitUnicodeString(&KeyName
, RegistryKey
);
57 InitializeObjectAttributes(&ObjectAttributes
,
63 Status
= NtOpenKey(&KeyHandle
,
66 if (!NT_SUCCESS(Status
))
68 BaseSetLastNTError (Status
);
72 KeyInfoSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + *nSize
* sizeof(WCHAR
);
73 KeyInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, KeyInfoSize
);
77 SetLastError(ERROR_OUTOFMEMORY
);
81 RtlInitUnicodeString(&ValueName
, ValueNameStr
);
83 Status
= NtQueryValueKey(KeyHandle
,
85 KeyValuePartialInformation
,
92 if (!NT_SUCCESS(Status
))
94 *nSize
= (ReturnSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
)) / sizeof(WCHAR
);
98 if (KeyInfo
->Type
!= REG_SZ
)
100 Status
= STATUS_UNSUCCESSFUL
;
104 if (!lpBuffer
|| *nSize
< (KeyInfo
->DataLength
/ sizeof(WCHAR
)))
106 *nSize
= (ReturnSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
)) / sizeof(WCHAR
);
107 Status
= STATUS_BUFFER_OVERFLOW
;
111 *nSize
= KeyInfo
->DataLength
/ sizeof(WCHAR
) - 1;
112 RtlCopyMemory(lpBuffer
, KeyInfo
->Data
, KeyInfo
->DataLength
);
113 lpBuffer
[*nSize
] = 0;
115 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo
);
120 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo
);
121 BaseSetLastNTError(Status
);
130 GetComputerNameExW(COMPUTER_NAME_FORMAT NameType
,
134 UNICODE_STRING ResultString
;
135 UNICODE_STRING DomainPart
;
136 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
141 if ((nSize
== NULL
) ||
142 (lpBuffer
== NULL
&& *nSize
> 0))
144 SetLastError(ERROR_INVALID_PARAMETER
);
150 case ComputerNameNetBIOS
:
151 return GetComputerNameFromRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
152 L
"\\Control\\ComputerName\\ComputerName",
157 case ComputerNameDnsDomain
:
158 return GetComputerNameFromRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
159 L
"\\Services\\Tcpip\\Parameters",
164 case ComputerNameDnsFullyQualified
:
165 ResultString
.Length
= 0;
166 ResultString
.MaximumLength
= (USHORT
)*nSize
* sizeof(WCHAR
);
167 ResultString
.Buffer
= lpBuffer
;
169 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
170 RtlInitUnicodeString(&DomainPart
, NULL
);
172 QueryTable
[0].Name
= L
"HostName";
173 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
174 QueryTable
[0].EntryContext
= &DomainPart
;
176 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
177 L
"\\Registry\\Machine\\System"
178 L
"\\CurrentControlSet\\Services\\Tcpip"
184 if (NT_SUCCESS(Status
))
186 Status
= RtlAppendUnicodeStringToString(&ResultString
, &DomainPart
);
187 HostSize
= DomainPart
.Length
;
189 if (!NT_SUCCESS(Status
))
194 RtlAppendUnicodeToString(&ResultString
, L
".");
195 RtlFreeUnicodeString(&DomainPart
);
197 RtlInitUnicodeString(&DomainPart
, NULL
);
198 QueryTable
[0].Name
= L
"Domain";
199 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
200 QueryTable
[0].EntryContext
= &DomainPart
;
202 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
203 L
"\\Registry\\Machine\\System"
204 L
"\\CurrentControlSet\\Services\\Tcpip"
210 if (NT_SUCCESS(Status
))
212 Status
= RtlAppendUnicodeStringToString(&ResultString
, &DomainPart
);
213 if ((!NT_SUCCESS(Status
)) || (!ret
))
215 *nSize
= HostSize
+ DomainPart
.Length
;
216 SetLastError(ERROR_MORE_DATA
);
217 RtlFreeUnicodeString(&DomainPart
);
220 RtlFreeUnicodeString(&DomainPart
);
221 *nSize
= ResultString
.Length
/ sizeof(WCHAR
) - 1;
227 case ComputerNameDnsHostname
:
228 return GetComputerNameFromRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
229 L
"\\Services\\Tcpip\\Parameters",
234 case ComputerNamePhysicalDnsDomain
:
235 return GetComputerNameFromRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
236 L
"\\Services\\Tcpip\\Parameters",
242 case ComputerNamePhysicalDnsFullyQualified
:
243 return GetComputerNameExW(ComputerNameDnsFullyQualified
,
247 case ComputerNamePhysicalDnsHostname
:
248 return GetComputerNameExW(ComputerNameDnsHostname
,
252 case ComputerNamePhysicalNetBIOS
:
253 return GetComputerNameExW(ComputerNameNetBIOS
,
257 case ComputerNameMax
:
269 GetComputerNameExA(COMPUTER_NAME_FORMAT NameType
,
273 UNICODE_STRING UnicodeString
;
274 ANSI_STRING AnsiString
;
276 PWCHAR TempBuffer
= NULL
;
278 if ((nSize
== NULL
) ||
279 (lpBuffer
== NULL
&& *nSize
> 0))
281 SetLastError(ERROR_INVALID_PARAMETER
);
287 TempBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, *nSize
* sizeof(WCHAR
));
290 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
295 AnsiString
.MaximumLength
= (USHORT
)*nSize
;
296 AnsiString
.Length
= 0;
297 AnsiString
.Buffer
= lpBuffer
;
299 Result
= GetComputerNameExW(NameType
, TempBuffer
, nSize
);
303 UnicodeString
.MaximumLength
= (USHORT
)*nSize
* sizeof(WCHAR
) + sizeof(WCHAR
);
304 UnicodeString
.Length
= (USHORT
)*nSize
* sizeof(WCHAR
);
305 UnicodeString
.Buffer
= TempBuffer
;
307 RtlUnicodeStringToAnsiString(&AnsiString
,
312 RtlFreeHeap(RtlGetProcessHeap(), 0, TempBuffer
);
322 GetComputerNameA(LPSTR lpBuffer
, LPDWORD lpnSize
)
326 ret
= GetComputerNameExA(ComputerNameNetBIOS
, lpBuffer
, lpnSize
);
327 if (!ret
&& GetLastError() == ERROR_MORE_DATA
)
328 SetLastError(ERROR_BUFFER_OVERFLOW
);
339 GetComputerNameW(LPWSTR lpBuffer
, LPDWORD lpnSize
)
342 ret
=GetComputerNameExW(ComputerNameNetBIOS
, lpBuffer
, lpnSize
);
343 if(!ret
&& GetLastError() == ERROR_MORE_DATA
)
344 SetLastError(ERROR_BUFFER_OVERFLOW
);
354 IsValidComputerName(COMPUTER_NAME_FORMAT NameType
,
355 LPCWSTR lpComputerName
)
360 /* FIXME: do verification according to NameType */
363 p
= (PWCHAR
)lpComputerName
;
367 if (!(iswctype(*p
, _ALPHA
| _DIGIT
) || *p
== L
'!' || *p
== L
'@' || *p
== L
'#' ||
368 *p
== L
'$' || *p
== L
'%' || *p
== L
'^' || *p
== L
'&' || *p
== L
'\'' ||
369 *p
== L
')' || *p
== L
'(' || *p
== L
'.' || *p
== L
'-' || *p
== L
'_' ||
370 *p
== L
'{' || *p
== L
'}' || *p
== L
'~'))
377 if (Length
== 0 || Length
> MAX_COMPUTERNAME_LENGTH
)
386 SetComputerNameToRegistry(LPCWSTR RegistryKey
,
387 LPCWSTR ValueNameStr
,
390 OBJECT_ATTRIBUTES ObjectAttributes
;
391 UNICODE_STRING KeyName
;
392 UNICODE_STRING ValueName
;
397 StringLength
= wcslen(lpBuffer
);
398 if (StringLength
> ((MAXULONG
/ sizeof(WCHAR
)) - 1))
403 RtlInitUnicodeString(&KeyName
, RegistryKey
);
404 InitializeObjectAttributes(&ObjectAttributes
,
406 OBJ_CASE_INSENSITIVE
,
410 Status
= NtOpenKey(&KeyHandle
,
413 if (!NT_SUCCESS(Status
))
415 BaseSetLastNTError(Status
);
419 RtlInitUnicodeString(&ValueName
, ValueNameStr
);
421 Status
= NtSetValueKey(KeyHandle
,
426 (StringLength
+ 1) * sizeof(WCHAR
));
427 if (!NT_SUCCESS(Status
))
430 BaseSetLastNTError(Status
);
434 NtFlushKey(KeyHandle
);
446 SetComputerNameA(LPCSTR lpComputerName
)
448 return SetComputerNameExA(ComputerNamePhysicalNetBIOS
, lpComputerName
);
457 SetComputerNameW(LPCWSTR lpComputerName
)
459 return SetComputerNameExW(ComputerNamePhysicalNetBIOS
, lpComputerName
);
468 SetComputerNameExA(COMPUTER_NAME_FORMAT NameType
,
471 UNICODE_STRING Buffer
;
474 RtlCreateUnicodeStringFromAsciiz(&Buffer
, (LPSTR
)lpBuffer
);
476 bResult
= SetComputerNameExW(NameType
, Buffer
.Buffer
);
478 RtlFreeUnicodeString(&Buffer
);
489 SetComputerNameExW(COMPUTER_NAME_FORMAT NameType
,
492 if (!IsValidComputerName(NameType
, lpBuffer
))
494 SetLastError(ERROR_INVALID_PARAMETER
);
500 case ComputerNamePhysicalDnsDomain
:
501 return SetComputerNameToRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
502 L
"\\Services\\Tcpip\\Parameters",
506 case ComputerNamePhysicalDnsHostname
:
507 return SetComputerNameToRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
508 L
"\\Services\\Tcpip\\Parameters",
512 case ComputerNamePhysicalNetBIOS
:
513 return SetComputerNameToRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
514 L
"\\Control\\ComputerName\\ComputerName",
519 SetLastError (ERROR_INVALID_PARAMETER
);
530 DnsHostnameToComputerNameA(LPCSTR Hostname
,
536 DPRINT("(%s, %p, %p)\n", Hostname
, ComputerName
, nSize
);
538 if (!Hostname
|| !nSize
)
541 len
= lstrlenA(Hostname
);
543 if (len
> MAX_COMPUTERNAME_LENGTH
)
544 len
= MAX_COMPUTERNAME_LENGTH
;
552 if (!ComputerName
) return FALSE
;
554 memcpy(ComputerName
, Hostname
, len
);
555 ComputerName
[len
+ 1] = 0;
565 DnsHostnameToComputerNameW(LPCWSTR hostname
,
571 DPRINT("(%s, %p, %p): stub\n", hostname
, computername
, size
);
573 if (!hostname
|| !size
) return FALSE
;
574 len
= lstrlenW(hostname
);
576 if (len
> MAX_COMPUTERNAME_LENGTH
)
577 len
= MAX_COMPUTERNAME_LENGTH
;
584 if (!computername
) return FALSE
;
586 memcpy(computername
, hostname
, len
* sizeof(WCHAR
));
587 computername
[len
+ 1] = 0;
593 AddLocalAlternateComputerNameA(LPSTR lpName
, PNTSTATUS Status
)
601 AddLocalAlternateComputerNameW(LPWSTR lpName
, PNTSTATUS Status
)
609 EnumerateLocalComputerNamesA(PVOID pUnknown
, DWORD Size
, LPSTR lpBuffer
, LPDWORD lpnSize
)
612 return ERROR_CALL_NOT_IMPLEMENTED
;
617 EnumerateLocalComputerNamesW(PVOID pUnknown
, DWORD Size
, LPWSTR lpBuffer
, LPDWORD lpnSize
)
620 return ERROR_CALL_NOT_IMPLEMENTED
;
625 RemoveLocalAlternateComputerNameA(LPSTR lpName
, DWORD Unknown
)
628 return ERROR_CALL_NOT_IMPLEMENTED
;
633 RemoveLocalAlternateComputerNameW(LPWSTR lpName
, DWORD Unknown
)
636 return ERROR_CALL_NOT_IMPLEMENTED
;
644 SetLocalPrimaryComputerNameA(IN DWORD Unknown1
,
656 SetLocalPrimaryComputerNameW(IN DWORD Unknown1
,