196c62e8d8408e06f1ae39c447c5fb6d34ad5d0a
[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: computername.c,v 1.1 2003/06/08 20:59:30 ekohl Exp $
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 <kernel32/kernel32.h>
34
35
36 /* FUNCTIONS *****************************************************************/
37
38 BOOL STDCALL
39 GetComputerNameA (LPSTR lpBuffer,
40 LPDWORD lpnSize)
41 {
42 UNICODE_STRING UnicodeString;
43 ANSI_STRING AnsiString;
44 BOOL Result;
45
46 AnsiString.MaximumLength = *lpnSize;
47 AnsiString.Length = 0;
48 AnsiString.Buffer = lpBuffer;
49
50 UnicodeString.MaximumLength = *lpnSize * sizeof(WCHAR);
51 UnicodeString.Length = 0;
52 UnicodeString.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
53 0,
54 UnicodeString.MaximumLength);
55 if (UnicodeString.Buffer == NULL)
56 {
57 SetLastError (ERROR_OUTOFMEMORY);
58 return FALSE;
59 }
60
61 if (!GetComputerNameW (UnicodeString.Buffer, lpnSize))
62 {
63 RtlFreeUnicodeString (&UnicodeString);
64 return FALSE;
65 }
66
67 UnicodeString.Length = *lpnSize * sizeof(WCHAR);
68
69 RtlUnicodeStringToAnsiString (&AnsiString,
70 &UnicodeString,
71 FALSE);
72
73 RtlFreeUnicodeString (&UnicodeString);
74
75 return TRUE;
76 }
77
78
79 BOOL STDCALL
80 GetComputerNameW (LPWSTR lpBuffer,
81 LPDWORD lpnSize)
82 {
83 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
84 OBJECT_ATTRIBUTES ObjectAttributes;
85 UNICODE_STRING KeyName;
86 UNICODE_STRING ValueName;
87 HANDLE KeyHandle;
88 ULONG KeyInfoSize;
89 ULONG ReturnSize;
90 NTSTATUS Status;
91
92 RtlInitUnicodeString (&KeyName,
93 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName");
94 InitializeObjectAttributes (&ObjectAttributes,
95 &KeyName,
96 OBJ_CASE_INSENSITIVE,
97 NULL,
98 NULL);
99 Status = NtOpenKey (&KeyHandle,
100 KEY_READ,
101 &ObjectAttributes);
102 if (!NT_SUCCESS(Status))
103 {
104 SetLastErrorByStatus (Status);
105 return FALSE;
106 }
107
108 KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
109 *lpnSize * sizeof(WCHAR);
110 KeyInfo = RtlAllocateHeap (RtlGetProcessHeap (),
111 0,
112 KeyInfoSize);
113 if (KeyInfo == NULL)
114 {
115 NtClose (KeyHandle);
116 SetLastError (ERROR_OUTOFMEMORY);
117 return FALSE;
118 }
119
120 RtlInitUnicodeString (&ValueName,
121 L"ComputerName");
122
123 Status = NtQueryValueKey (KeyHandle,
124 &ValueName,
125 KeyValuePartialInformation,
126 KeyInfo,
127 KeyInfoSize,
128 &ReturnSize);
129 if (!NT_SUCCESS(Status))
130 {
131 RtlFreeHeap (RtlGetProcessHeap (),
132 0,
133 KeyInfo);
134 NtClose (KeyHandle);
135 SetLastErrorByStatus (Status);
136 return FALSE;
137 }
138
139 *lpnSize =
140 (KeyInfo->DataLength != 0) ? (KeyInfo->DataLength / sizeof(WCHAR)) - 1 : 0;
141
142 RtlCopyMemory (lpBuffer,
143 KeyInfo->Data,
144 KeyInfo->DataLength);
145 lpBuffer[*lpnSize] = 0;
146
147 RtlFreeHeap (RtlGetProcessHeap (),
148 0,
149 KeyInfo);
150 NtClose (KeyHandle);
151
152 return TRUE;
153 }
154
155
156 BOOL STDCALL
157 SetComputerNameA (LPCSTR lpComputerName)
158 {
159 UNICODE_STRING ComputerName;
160 BOOL bResult;
161
162 RtlCreateUnicodeStringFromAsciiz (&ComputerName,
163 (LPSTR)lpComputerName);
164
165 bResult = SetComputerNameW (ComputerName.Buffer);
166
167 RtlFreeUnicodeString (&ComputerName);
168
169 return bResult;
170 }
171
172
173 static BOOL
174 IsValidComputerName (LPCWSTR lpComputerName)
175 {
176 PWCHAR p;
177 ULONG Length;
178
179 Length = 0;
180 p = (PWCHAR)lpComputerName;
181 while (*p != 0)
182 {
183 if (!(iswctype (*p, _ALPHA || _DIGIT) ||
184 *p == L'!' ||
185 *p == L'@' ||
186 *p == L'#' ||
187 *p == L'$' ||
188 *p == L'%' ||
189 *p == L'^' ||
190 *p == L'&' ||
191 *p == L'\'' ||
192 *p == L')' ||
193 *p == L'(' ||
194 *p == L'.' ||
195 *p == L'-' ||
196 *p == L'_' ||
197 *p == L'{' ||
198 *p == L'}' ||
199 *p == L'~'))
200 return FALSE;
201
202 Length++;
203 p++;
204 }
205
206 if (Length == 0 ||
207 Length > MAX_COMPUTERNAME_LENGTH)
208 return FALSE;
209
210 return TRUE;
211 }
212
213
214 BOOL STDCALL
215 SetComputerNameW (LPCWSTR lpComputerName)
216 {
217 OBJECT_ATTRIBUTES ObjectAttributes;
218 UNICODE_STRING KeyName;
219 UNICODE_STRING ValueName;
220 HANDLE KeyHandle;
221 NTSTATUS Status;
222
223 if (!IsValidComputerName (lpComputerName))
224 {
225 SetLastError (ERROR_INVALID_PARAMETER);
226 return FALSE;
227 }
228
229 RtlInitUnicodeString (&KeyName,
230 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName");
231 InitializeObjectAttributes (&ObjectAttributes,
232 &KeyName,
233 OBJ_CASE_INSENSITIVE,
234 NULL,
235 NULL);
236 Status = NtOpenKey (&KeyHandle,
237 KEY_WRITE,
238 &ObjectAttributes);
239 if (!NT_SUCCESS(Status))
240 {
241 SetLastErrorByStatus (Status);
242 return FALSE;
243 }
244
245 RtlInitUnicodeString (&ValueName,
246 L"ComputerName");
247
248 Status = NtSetValueKey (KeyHandle,
249 &ValueName,
250 0,
251 REG_SZ,
252 (PVOID)lpComputerName,
253 (wcslen (lpComputerName) + 1) * sizeof(WCHAR));
254 if (!NT_SUCCESS(Status))
255 {
256 NtClose (KeyHandle);
257 SetLastErrorByStatus (Status);
258 return FALSE;
259 }
260
261 NtFlushKey (KeyHandle);
262 NtClose (KeyHandle);
263
264 return TRUE;
265 }
266
267 /* EOF */