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 RtlInitUnicodeString(&KeyName
, RegistryKey
);
54 InitializeObjectAttributes(&ObjectAttributes
,
60 Status
= NtOpenKey(&KeyHandle
,
63 if (!NT_SUCCESS(Status
))
65 BaseSetLastNTError (Status
);
69 KeyInfoSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + *nSize
* sizeof(WCHAR
);
70 KeyInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, KeyInfoSize
);
74 SetLastError(ERROR_OUTOFMEMORY
);
78 RtlInitUnicodeString(&ValueName
, ValueNameStr
);
80 Status
= NtQueryValueKey(KeyHandle
,
82 KeyValuePartialInformation
,
89 if (!NT_SUCCESS(Status
))
91 *nSize
= (ReturnSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
)) / sizeof(WCHAR
);
95 if (KeyInfo
->Type
!= REG_SZ
)
97 Status
= STATUS_UNSUCCESSFUL
;
101 if (!lpBuffer
|| *nSize
< (KeyInfo
->DataLength
/ sizeof(WCHAR
)))
103 *nSize
= (ReturnSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
)) / sizeof(WCHAR
);
104 Status
= STATUS_BUFFER_OVERFLOW
;
108 *nSize
= KeyInfo
->DataLength
/ sizeof(WCHAR
) - 1;
109 RtlCopyMemory(lpBuffer
, KeyInfo
->Data
, KeyInfo
->DataLength
);
110 lpBuffer
[*nSize
] = 0;
112 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo
);
117 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo
);
118 BaseSetLastNTError(Status
);
127 GetComputerNameExW(COMPUTER_NAME_FORMAT NameType
,
131 UNICODE_STRING ResultString
;
132 UNICODE_STRING DomainPart
;
133 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
138 if ((nSize
== NULL
) ||
139 (lpBuffer
== NULL
&& *nSize
> 0))
141 SetLastError(ERROR_INVALID_PARAMETER
);
147 case ComputerNameNetBIOS
:
148 return GetComputerNameFromRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
149 L
"\\Control\\ComputerName\\ComputerName",
154 case ComputerNameDnsDomain
:
155 return GetComputerNameFromRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
156 L
"\\Services\\Tcpip\\Parameters",
161 case ComputerNameDnsFullyQualified
:
162 ResultString
.Length
= 0;
163 ResultString
.MaximumLength
= (USHORT
)*nSize
* sizeof(WCHAR
);
164 ResultString
.Buffer
= lpBuffer
;
166 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
167 RtlInitUnicodeString(&DomainPart
, NULL
);
169 QueryTable
[0].Name
= L
"HostName";
170 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
171 QueryTable
[0].EntryContext
= &DomainPart
;
173 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
174 L
"\\Registry\\Machine\\System"
175 L
"\\CurrentControlSet\\Services\\Tcpip"
181 if (NT_SUCCESS(Status
))
183 Status
= RtlAppendUnicodeStringToString(&ResultString
, &DomainPart
);
184 HostSize
= DomainPart
.Length
;
186 if (!NT_SUCCESS(Status
))
191 RtlAppendUnicodeToString(&ResultString
, L
".");
192 RtlFreeUnicodeString(&DomainPart
);
194 RtlInitUnicodeString(&DomainPart
, NULL
);
195 QueryTable
[0].Name
= L
"Domain";
196 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
197 QueryTable
[0].EntryContext
= &DomainPart
;
199 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
200 L
"\\Registry\\Machine\\System"
201 L
"\\CurrentControlSet\\Services\\Tcpip"
207 if (NT_SUCCESS(Status
))
209 Status
= RtlAppendUnicodeStringToString(&ResultString
, &DomainPart
);
210 if ((!NT_SUCCESS(Status
)) || (!ret
))
212 *nSize
= HostSize
+ DomainPart
.Length
;
213 SetLastError(ERROR_MORE_DATA
);
214 RtlFreeUnicodeString(&DomainPart
);
217 RtlFreeUnicodeString(&DomainPart
);
218 *nSize
= ResultString
.Length
/ sizeof(WCHAR
) - 1;
224 case ComputerNameDnsHostname
:
225 return GetComputerNameFromRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
226 L
"\\Services\\Tcpip\\Parameters",
231 case ComputerNamePhysicalDnsDomain
:
232 return GetComputerNameFromRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
233 L
"\\Services\\Tcpip\\Parameters",
239 case ComputerNamePhysicalDnsFullyQualified
:
240 return GetComputerNameExW(ComputerNameDnsFullyQualified
,
244 case ComputerNamePhysicalDnsHostname
:
245 return GetComputerNameExW(ComputerNameDnsHostname
,
249 case ComputerNamePhysicalNetBIOS
:
250 return GetComputerNameExW(ComputerNameNetBIOS
,
254 case ComputerNameMax
:
266 GetComputerNameExA(COMPUTER_NAME_FORMAT NameType
,
270 UNICODE_STRING UnicodeString
;
271 ANSI_STRING AnsiString
;
273 PWCHAR TempBuffer
= NULL
;
275 if ((nSize
== NULL
) ||
276 (lpBuffer
== NULL
&& *nSize
> 0))
278 SetLastError(ERROR_INVALID_PARAMETER
);
284 TempBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, *nSize
* sizeof(WCHAR
));
287 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
292 AnsiString
.MaximumLength
= (USHORT
)*nSize
;
293 AnsiString
.Length
= 0;
294 AnsiString
.Buffer
= lpBuffer
;
296 Result
= GetComputerNameExW(NameType
, TempBuffer
, nSize
);
300 UnicodeString
.MaximumLength
= (USHORT
)*nSize
* sizeof(WCHAR
) + sizeof(WCHAR
);
301 UnicodeString
.Length
= (USHORT
)*nSize
* sizeof(WCHAR
);
302 UnicodeString
.Buffer
= TempBuffer
;
304 RtlUnicodeStringToAnsiString(&AnsiString
,
309 RtlFreeHeap(RtlGetProcessHeap(), 0, TempBuffer
);
319 GetComputerNameA(LPSTR lpBuffer
, LPDWORD lpnSize
)
323 ret
= GetComputerNameExA(ComputerNameNetBIOS
, lpBuffer
, lpnSize
);
324 if (!ret
&& GetLastError() == ERROR_MORE_DATA
)
325 SetLastError(ERROR_BUFFER_OVERFLOW
);
336 GetComputerNameW(LPWSTR lpBuffer
, LPDWORD lpnSize
)
339 ret
=GetComputerNameExW(ComputerNameNetBIOS
, lpBuffer
, lpnSize
);
340 if(!ret
&& GetLastError() == ERROR_MORE_DATA
)
341 SetLastError(ERROR_BUFFER_OVERFLOW
);
351 IsValidComputerName(COMPUTER_NAME_FORMAT NameType
,
352 LPCWSTR lpComputerName
)
357 /* FIXME: do verification according to NameType */
360 p
= (PWCHAR
)lpComputerName
;
364 if (!(iswctype(*p
, _ALPHA
| _DIGIT
) || *p
== L
'!' || *p
== L
'@' || *p
== L
'#' ||
365 *p
== L
'$' || *p
== L
'%' || *p
== L
'^' || *p
== L
'&' || *p
== L
'\'' ||
366 *p
== L
')' || *p
== L
'(' || *p
== L
'.' || *p
== L
'-' || *p
== L
'_' ||
367 *p
== L
'{' || *p
== L
'}' || *p
== L
'~'))
374 if (Length
== 0 || Length
> MAX_COMPUTERNAME_LENGTH
)
383 SetComputerNameToRegistry(LPCWSTR RegistryKey
,
384 LPCWSTR ValueNameStr
,
387 OBJECT_ATTRIBUTES ObjectAttributes
;
388 UNICODE_STRING KeyName
;
389 UNICODE_STRING ValueName
;
393 RtlInitUnicodeString(&KeyName
, RegistryKey
);
394 InitializeObjectAttributes(&ObjectAttributes
,
396 OBJ_CASE_INSENSITIVE
,
400 Status
= NtOpenKey(&KeyHandle
,
403 if (!NT_SUCCESS(Status
))
405 BaseSetLastNTError(Status
);
409 RtlInitUnicodeString(&ValueName
, ValueNameStr
);
411 Status
= NtSetValueKey(KeyHandle
,
416 (wcslen (lpBuffer
) + 1) * sizeof(WCHAR
));
417 if (!NT_SUCCESS(Status
))
420 BaseSetLastNTError(Status
);
424 NtFlushKey(KeyHandle
);
436 SetComputerNameA(LPCSTR lpComputerName
)
438 return SetComputerNameExA(ComputerNamePhysicalNetBIOS
, lpComputerName
);
447 SetComputerNameW(LPCWSTR lpComputerName
)
449 return SetComputerNameExW(ComputerNamePhysicalNetBIOS
, lpComputerName
);
458 SetComputerNameExA(COMPUTER_NAME_FORMAT NameType
,
461 UNICODE_STRING Buffer
;
464 RtlCreateUnicodeStringFromAsciiz(&Buffer
, (LPSTR
)lpBuffer
);
466 bResult
= SetComputerNameExW(NameType
, Buffer
.Buffer
);
468 RtlFreeUnicodeString(&Buffer
);
479 SetComputerNameExW(COMPUTER_NAME_FORMAT NameType
,
482 if (!IsValidComputerName(NameType
, lpBuffer
))
484 SetLastError(ERROR_INVALID_PARAMETER
);
490 case ComputerNamePhysicalDnsDomain
:
491 return SetComputerNameToRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
492 L
"\\Services\\Tcpip\\Parameters",
496 case ComputerNamePhysicalDnsHostname
:
497 return SetComputerNameToRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
498 L
"\\Services\\Tcpip\\Parameters",
502 case ComputerNamePhysicalNetBIOS
:
503 return SetComputerNameToRegistry(L
"\\Registry\\Machine\\System\\CurrentControlSet"
504 L
"\\Control\\ComputerName\\ComputerName",
509 SetLastError (ERROR_INVALID_PARAMETER
);
520 DnsHostnameToComputerNameA(LPCSTR Hostname
,
526 DPRINT("(%s, %p, %p)\n", Hostname
, ComputerName
, nSize
);
528 if (!Hostname
|| !nSize
)
531 len
= lstrlenA(Hostname
);
533 if (len
> MAX_COMPUTERNAME_LENGTH
)
534 len
= MAX_COMPUTERNAME_LENGTH
;
542 if (!ComputerName
) return FALSE
;
544 memcpy(ComputerName
, Hostname
, len
);
545 ComputerName
[len
+ 1] = 0;
555 DnsHostnameToComputerNameW(LPCWSTR hostname
,
561 DPRINT("(%s, %p, %p): stub\n", hostname
, computername
, size
);
563 if (!hostname
|| !size
) return FALSE
;
564 len
= lstrlenW(hostname
);
566 if (len
> MAX_COMPUTERNAME_LENGTH
)
567 len
= MAX_COMPUTERNAME_LENGTH
;
574 if (!computername
) return FALSE
;
576 memcpy(computername
, hostname
, len
* sizeof(WCHAR
));
577 computername
[len
+ 1] = 0;
583 AddLocalAlternateComputerNameA(LPSTR lpName
, PNTSTATUS Status
)
591 AddLocalAlternateComputerNameW(LPWSTR lpName
, PNTSTATUS Status
)
599 EnumerateLocalComputerNamesA(PVOID pUnknown
, DWORD Size
, LPSTR lpBuffer
, LPDWORD lpnSize
)
602 return ERROR_CALL_NOT_IMPLEMENTED
;
607 EnumerateLocalComputerNamesW(PVOID pUnknown
, DWORD Size
, LPWSTR lpBuffer
, LPDWORD lpnSize
)
610 return ERROR_CALL_NOT_IMPLEMENTED
;
615 RemoveLocalAlternateComputerNameA(LPSTR lpName
, DWORD Unknown
)
618 return ERROR_CALL_NOT_IMPLEMENTED
;
623 RemoveLocalAlternateComputerNameW(LPWSTR lpName
, DWORD Unknown
)
626 return ERROR_CALL_NOT_IMPLEMENTED
;
634 SetLocalPrimaryComputerNameA(IN DWORD Unknown1
,
646 SetLocalPrimaryComputerNameW(IN DWORD Unknown1
,