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