migrate substitution keywords to SVN
[reactos.git] / reactos / lib / kernel32 / misc / computername.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2003 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /* $Id$
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS system libraries
23 * PURPOSE: Computer name functions
24 * FILE: lib/kernel32/misc/computername.c
25 * PROGRAMER: Eric Kohl (ekohl@rz-online.de)
26 */
27
28 /* INCLUDES ******************************************************************/
29
30 #include <k32.h>
31
32 #define NDEBUG
33 #include "../include/debug.h"
34
35
36 /* FUNCTIONS *****************************************************************/
37
38 static BOOL GetComputerNameFromRegistry( LPWSTR RegistryKey,
39 LPWSTR ValueNameStr,
40 LPWSTR lpBuffer,
41 LPDWORD nSize ) {
42 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
43 OBJECT_ATTRIBUTES ObjectAttributes;
44 UNICODE_STRING KeyName;
45 UNICODE_STRING ValueName;
46 HANDLE KeyHandle;
47 ULONG KeyInfoSize;
48 ULONG ReturnSize;
49 NTSTATUS Status;
50
51 RtlInitUnicodeString (&KeyName,RegistryKey);
52 InitializeObjectAttributes (&ObjectAttributes,
53 &KeyName,
54 OBJ_CASE_INSENSITIVE,
55 NULL,
56 NULL);
57 Status = ZwOpenKey (&KeyHandle,
58 KEY_READ,
59 &ObjectAttributes);
60 if (!NT_SUCCESS(Status))
61 {
62 SetLastErrorByStatus (Status);
63 return FALSE;
64 }
65
66 KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
67 *nSize * sizeof(WCHAR);
68 KeyInfo = RtlAllocateHeap (RtlGetProcessHeap (),
69 0,
70 KeyInfoSize);
71 if (KeyInfo == NULL)
72 {
73 ZwClose (KeyHandle);
74 SetLastError (ERROR_OUTOFMEMORY);
75 return FALSE;
76 }
77
78 RtlInitUnicodeString (&ValueName,ValueNameStr);
79
80 Status = ZwQueryValueKey (KeyHandle,
81 &ValueName,
82 KeyValuePartialInformation,
83 KeyInfo,
84 KeyInfoSize,
85 &ReturnSize);
86 if (!NT_SUCCESS(Status))
87 {
88 RtlFreeHeap (RtlGetProcessHeap (),
89 0,
90 KeyInfo);
91 ZwClose (KeyHandle);
92 SetLastErrorByStatus (Status);
93 return FALSE;
94 }
95
96 if( *nSize > (KeyInfo->DataLength / sizeof(WCHAR)) ) {
97 *nSize = KeyInfo->DataLength / sizeof(WCHAR);
98 lpBuffer[*nSize] = 0;
99 }
100
101 RtlCopyMemory (lpBuffer,
102 KeyInfo->Data,
103 *nSize * sizeof(WCHAR));
104
105 RtlFreeHeap (RtlGetProcessHeap (),
106 0,
107 KeyInfo)
108 ;
109 ZwClose (KeyHandle);
110
111 return TRUE;
112 }
113
114 /*
115 * @implemented
116 */
117 BOOL STDCALL
118 GetComputerNameExW (
119 COMPUTER_NAME_FORMAT NameType,
120 LPWSTR lpBuffer,
121 LPDWORD nSize
122 )
123 {
124 UNICODE_STRING ResultString;
125 UNICODE_STRING DomainPart, Dot;
126 UNICODE_STRING RegKey, RegValue;
127
128 switch( NameType ) {
129 case ComputerNameNetBIOS:
130 return GetComputerNameFromRegistry
131 ( L"\\Registry\\Machine\\System\\CurrentControlSet"
132 L"\\Control\\ComputerName\\ComputerName",
133 L"ComputerName",
134 lpBuffer,
135 nSize );
136
137 case ComputerNameDnsDomain:
138 return GetComputerNameFromRegistry
139 ( L"\\Registry\\Machine\\System\\CurrentControlSet"
140 L"\\Services\\Tcpip\\Parameters",
141 L"Domain",
142 lpBuffer,
143 nSize );
144
145 case ComputerNameDnsFullyQualified:
146 RtlInitUnicodeString(&Dot,L".");
147 RosInitializeString(&ResultString,0,*nSize * sizeof(WCHAR),lpBuffer);
148 RtlInitUnicodeString(&RegKey,
149 L"\\Registry\\Machine\\System"
150 L"\\CurrentControlSet\\Services\\Tcpip"
151 L"\\Parameters");
152 RtlInitUnicodeString(&RegValue,L"HostName");
153 RtlInitUnicodeString(&DomainPart,L"");
154 if( NT_SUCCESS(RosReadRegistryValue(&RegKey,&RegValue,&DomainPart)) ) {
155 RtlAppendUnicodeStringToString(&ResultString,&DomainPart);
156 RtlAppendUnicodeStringToString(&ResultString,&Dot);
157 RtlFreeUnicodeString(&DomainPart);
158 RtlInitUnicodeString(&RegValue,L"Domain");
159 RtlInitUnicodeString(&DomainPart,L"");
160 if( NT_SUCCESS(RosReadRegistryValue
161 (&RegKey,&RegValue,&DomainPart)) ) {
162 RtlAppendUnicodeStringToString(&ResultString,&DomainPart);
163 RtlFreeUnicodeString(&DomainPart);
164 *nSize = ResultString.Length / sizeof(WCHAR);
165 return TRUE;
166 }
167 }
168 return FALSE;
169
170 case ComputerNameDnsHostname:
171 return GetComputerNameFromRegistry
172 ( L"\\Registry\\Machine\\System\\CurrentControlSet"
173 L"\\Services\\Tcpip\\Parameters",
174 L"Hostname",
175 lpBuffer,
176 nSize );
177
178 case ComputerNamePhysicalDnsDomain:
179 return GetComputerNameFromRegistry
180 ( L"\\Registry\\Machine\\System\\CurrentControlSet"
181 L"\\Services\\Tcpip\\Parameters",
182 L"Domain",
183 lpBuffer,
184 nSize );
185
186 /* XXX Redo these */
187 case ComputerNamePhysicalDnsFullyQualified:
188 return GetComputerNameExW( ComputerNameDnsFullyQualified,
189 lpBuffer, nSize );
190 case ComputerNamePhysicalDnsHostname:
191 return GetComputerNameExW( ComputerNameDnsHostname,
192 lpBuffer, nSize );
193 case ComputerNamePhysicalNetBIOS:
194 return GetComputerNameExW( ComputerNameNetBIOS,
195 lpBuffer, nSize );
196
197 case ComputerNameMax:
198 return FALSE;
199 }
200
201 return FALSE;
202 }
203
204 /*
205 * @implemented
206 */
207 BOOL
208 STDCALL
209 GetComputerNameExA (
210 COMPUTER_NAME_FORMAT NameType,
211 LPSTR lpBuffer,
212 LPDWORD nSize
213 )
214 {
215 UNICODE_STRING UnicodeString;
216 ANSI_STRING AnsiString;
217 BOOL Result;
218 PWCHAR TempBuffer = RtlAllocateHeap( GetProcessHeap(), 0, *nSize * sizeof(WCHAR) );
219
220 if( !TempBuffer ) {
221 return ERROR_OUTOFMEMORY;
222 }
223
224 AnsiString.MaximumLength = *nSize;
225 AnsiString.Length = 0;
226 AnsiString.Buffer = lpBuffer;
227
228 Result = GetComputerNameExW( NameType, TempBuffer, nSize );
229
230 if( Result ) {
231 UnicodeString.MaximumLength = *nSize * sizeof(WCHAR);
232 UnicodeString.Length = *nSize * sizeof(WCHAR);
233 UnicodeString.Buffer = TempBuffer;
234
235 RtlUnicodeStringToAnsiString (&AnsiString,
236 &UnicodeString,
237 FALSE);
238 }
239
240 HeapFree( GetProcessHeap(), 0, TempBuffer );
241
242 return Result;
243 }
244
245 /*
246 * @implemented
247 */
248 BOOL STDCALL
249 GetComputerNameA (LPSTR lpBuffer,
250 LPDWORD lpnSize)
251 {
252 return GetComputerNameExA( ComputerNameNetBIOS, lpBuffer, lpnSize );
253 }
254
255
256 /*
257 * @implemented
258 */
259 BOOL STDCALL
260 GetComputerNameW (LPWSTR lpBuffer,
261 LPDWORD lpnSize)
262 {
263 return GetComputerNameExW( ComputerNameNetBIOS, lpBuffer, lpnSize );
264 }
265
266
267 /*
268 * @implemented
269 */
270 BOOL STDCALL
271 SetComputerNameA (LPCSTR lpComputerName)
272 {
273 UNICODE_STRING ComputerName;
274 BOOL bResult;
275
276 RtlCreateUnicodeStringFromAsciiz (&ComputerName,
277 (LPSTR)lpComputerName);
278
279 bResult = SetComputerNameW (ComputerName.Buffer);
280
281 RtlFreeUnicodeString (&ComputerName);
282
283 return bResult;
284 }
285
286
287 /*
288 * @implemented
289 */
290 static BOOL
291 IsValidComputerName (LPCWSTR lpComputerName)
292 {
293 PWCHAR p;
294 ULONG Length;
295
296 Length = 0;
297 p = (PWCHAR)lpComputerName;
298 while (*p != 0)
299 {
300 if (!(iswctype (*p, _ALPHA || _DIGIT) ||
301 *p == L'!' ||
302 *p == L'@' ||
303 *p == L'#' ||
304 *p == L'$' ||
305 *p == L'%' ||
306 *p == L'^' ||
307 *p == L'&' ||
308 *p == L'\'' ||
309 *p == L')' ||
310 *p == L'(' ||
311 *p == L'.' ||
312 *p == L'-' ||
313 *p == L'_' ||
314 *p == L'{' ||
315 *p == L'}' ||
316 *p == L'~'))
317 return FALSE;
318
319 Length++;
320 p++;
321 }
322
323 if (Length == 0 ||
324 Length > MAX_COMPUTERNAME_LENGTH)
325 return FALSE;
326
327 return TRUE;
328 }
329
330
331 /*
332 * @implemented
333 */
334 BOOL STDCALL
335 SetComputerNameW (LPCWSTR lpComputerName)
336 {
337 OBJECT_ATTRIBUTES ObjectAttributes;
338 UNICODE_STRING KeyName;
339 UNICODE_STRING ValueName;
340 HANDLE KeyHandle;
341 NTSTATUS Status;
342
343 if (!IsValidComputerName (lpComputerName))
344 {
345 SetLastError (ERROR_INVALID_PARAMETER);
346 return FALSE;
347 }
348
349 RtlInitUnicodeString (&KeyName,
350 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName");
351 InitializeObjectAttributes (&ObjectAttributes,
352 &KeyName,
353 OBJ_CASE_INSENSITIVE,
354 NULL,
355 NULL);
356 Status = NtOpenKey (&KeyHandle,
357 KEY_WRITE,
358 &ObjectAttributes);
359 if (!NT_SUCCESS(Status))
360 {
361 SetLastErrorByStatus (Status);
362 return FALSE;
363 }
364
365 RtlInitUnicodeString (&ValueName,
366 L"ComputerName");
367
368 Status = NtSetValueKey (KeyHandle,
369 &ValueName,
370 0,
371 REG_SZ,
372 (PVOID)lpComputerName,
373 (wcslen (lpComputerName) + 1) * sizeof(WCHAR));
374 if (!NT_SUCCESS(Status))
375 {
376 ZwClose (KeyHandle);
377 SetLastErrorByStatus (Status);
378 return FALSE;
379 }
380
381 NtFlushKey (KeyHandle);
382 ZwClose (KeyHandle);
383
384 return TRUE;
385 }
386
387 /* EOF */