jscript: Added Date.setYear implementation.
[wine] / dlls / kernel32 / tests / environ.c
1 /*
2  * Unit test suite for environment functions.
3  *
4  * Copyright 2002 Dmitry Timoshkov
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "winnls.h"
28 #include "winreg.h"
29
30 static CHAR string[MAX_PATH];
31 #define ok_w(res, format, szString) \
32 \
33     WideCharToMultiByte(CP_ACP, 0, szString, -1, string, MAX_PATH, NULL, NULL); \
34     ok(res, format, string);
35
36 static BOOL (WINAPI *pGetComputerNameExA)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD);
37 static BOOL (WINAPI *pGetComputerNameExW)(COMPUTER_NAME_FORMAT,LPWSTR,LPDWORD);
38 static BOOL (WINAPI *pOpenProcessToken)(HANDLE,DWORD,PHANDLE);
39 static BOOL (WINAPI *pGetUserProfileDirectoryA)(HANDLE,LPSTR,LPDWORD);
40
41 static void init_functionpointers(void)
42 {
43     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
44     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
45     HMODULE huserenv = LoadLibraryA("userenv.dll");
46
47     pGetComputerNameExA = (void *)GetProcAddress(hkernel32, "GetComputerNameExA");
48     pGetComputerNameExW = (void *)GetProcAddress(hkernel32, "GetComputerNameExW");
49     pOpenProcessToken = (void *)GetProcAddress(hadvapi32, "OpenProcessToken");
50     pGetUserProfileDirectoryA = (void *)GetProcAddress(huserenv,
51                                                        "GetUserProfileDirectoryA");
52 }
53
54 static void test_Predefined(void)
55 {
56     /*
57      * If anything fails here, your test environment is probably not set up
58      * correctly.
59      */
60     HKEY UserEnvironment;
61     LSTATUS Err;
62     DWORD Index;
63     char ValueName[256];
64     DWORD ValueNameSize;
65     DWORD Type;
66     char Data[1024];
67     DWORD DataSize;
68     char Env[sizeof(Data)];
69     DWORD EnvSize;
70     HANDLE Token;
71     BOOL NoErr;
72
73     /*
74      * Enumerate all values in HKCU\Environment and verify that environment
75      * variables with those names/values are present.
76      */
77     Err = RegOpenKeyExA(HKEY_CURRENT_USER, "Environment", 0, KEY_QUERY_VALUE,
78                         &UserEnvironment);
79     ok(Err == ERROR_SUCCESS || Err == ERROR_FILE_NOT_FOUND,
80        "Failed to open HKCU\\Environment key, error %d\n",
81        Err);
82
83     if (Err == ERROR_SUCCESS)
84     {
85         Index = 0;
86         do
87         {
88             ValueNameSize = sizeof(ValueName);
89             DataSize = sizeof(Data);
90             Err = RegEnumValueA(UserEnvironment, Index, ValueName, &ValueNameSize,
91                                 NULL, &Type, (LPBYTE) Data, &DataSize);
92             if (Err == ERROR_SUCCESS)
93             {
94                 if (Type == REG_EXPAND_SZ)
95                 {
96                     char Expanded[sizeof(Data)];
97                     DWORD ExpandedSize;
98                     ExpandedSize = ExpandEnvironmentStringsA(Data, Expanded,
99                                                              sizeof(Expanded));
100                     ok(ExpandedSize != 0 && ExpandedSize <= sizeof(Expanded),
101                        "Failed to expand %s, error %u\n", Data, GetLastError());
102                     memcpy(Data, Expanded, ExpandedSize);
103                     Type = REG_SZ;
104                 }
105                 ok(Type == REG_SZ, "Expected data type REG_SZ, got %d\n", Type);
106                 EnvSize = GetEnvironmentVariableA(ValueName, Env, sizeof(Env));
107                 ok(EnvSize != 0 && EnvSize <= sizeof(Env),
108                    "Failed to retrieve environment variable %s, error %u\n",
109                    ValueName, GetLastError());
110                 ok(strcmp(Data, Env) == 0,
111                    "Expected value %s for env var %s, got %s\n", Data, ValueName,
112                    Env);
113             }
114             Index++;
115         }
116         while (Err == ERROR_SUCCESS);
117         ok(Err == ERROR_NO_MORE_ITEMS,
118            "Unexpected return %d from RegEnumValueA\n", Err);
119
120         Err = RegCloseKey(UserEnvironment);
121         ok(Err == ERROR_SUCCESS, "Failed to close reg key, error %d\n", Err);
122     }
123
124     /*
125      * Check value of %USERPROFILE%, should be same as GetUserProfileDirectory()
126      */
127     if (pOpenProcessToken == NULL || pGetUserProfileDirectoryA == NULL)
128     {
129         skip("Skipping USERPROFILE check\n");
130         return;
131     }
132     NoErr = pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
133     ok(NoErr, "Failed to open token, error %u\n", GetLastError());
134     DataSize = sizeof(Data);
135     NoErr = pGetUserProfileDirectoryA(Token, Data, &DataSize);
136     todo_wine ok(NoErr, "Failed to get user profile dir, error %u\n",
137                  GetLastError());
138     if (NoErr)
139     {
140         EnvSize = GetEnvironmentVariableA("USERPROFILE", Env, sizeof(Env));
141         ok(EnvSize != 0 && EnvSize <= sizeof(Env),
142            "Failed to retrieve environment variable USERPROFILE, error %u\n",
143            GetLastError());
144         ok(strcmp(Data, Env) == 0,
145            "USERPROFILE env var %s doesn't match GetUserProfileDirectory %s\n",
146            Env, Data);
147     }
148     else
149         skip("Skipping USERPROFILE check, can't get user profile dir\n");
150     NoErr = CloseHandle(Token);
151     ok(NoErr, "Failed to close token, error %u\n", GetLastError());
152 }
153
154 static void test_GetSetEnvironmentVariableA(void)
155 {
156     char buf[256];
157     BOOL ret;
158     DWORD ret_size;
159     static const char name[] = "SomeWildName";
160     static const char name_cased[] = "sOMEwILDnAME";
161     static const char value[] = "SomeWildValue";
162
163     ret = SetEnvironmentVariableA(name, value);
164     ok(ret == TRUE,
165        "unexpected error in SetEnvironmentVariableA, GetLastError=%d\n",
166        GetLastError());
167
168     /* Try to retrieve the environment variable we just set */
169     ret_size = GetEnvironmentVariableA(name, NULL, 0);
170     ok(ret_size == strlen(value) + 1,
171        "should return length with terminating 0 ret_size=%d\n", ret_size);
172
173     lstrcpyA(buf, "foo");
174     ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value));
175     ok(lstrcmpA(buf, "foo") == 0, "should not touch the buffer\n");
176     ok(ret_size == strlen(value) + 1,
177        "should return length with terminating 0 ret_size=%d\n", ret_size);
178
179     lstrcpyA(buf, "foo");
180     ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
181     ok(lstrcmpA(buf, value) == 0, "should touch the buffer\n");
182     ok(ret_size == strlen(value),
183        "should return length without terminating 0 ret_size=%d\n", ret_size);
184
185     lstrcpyA(buf, "foo");
186     ret_size = GetEnvironmentVariableA(name_cased, buf, lstrlenA(value) + 1);
187     ok(lstrcmpA(buf, value) == 0, "should touch the buffer\n");
188     ok(ret_size == strlen(value),
189        "should return length without terminating 0 ret_size=%d\n", ret_size);
190
191     /* Remove that environment variable */
192     ret = SetEnvironmentVariableA(name_cased, NULL);
193     ok(ret == TRUE, "should erase existing variable\n");
194
195     lstrcpyA(buf, "foo");
196     ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
197     ok(lstrcmpA(buf, "foo") == 0, "should not touch the buffer\n");
198     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
199        "should not find variable but ret_size=%d GetLastError=%d\n",
200        ret_size, GetLastError());
201
202     /* Check behavior of SetEnvironmentVariableA(name, "") */
203     ret = SetEnvironmentVariableA(name, value);
204     ok(ret == TRUE,
205        "unexpected error in SetEnvironmentVariableA, GetLastError=%d\n",
206        GetLastError());
207
208     lstrcpyA(buf, "foo");
209     ret_size = GetEnvironmentVariableA(name_cased, buf, lstrlenA(value) + 1);
210     ok(lstrcmpA(buf, value) == 0, "should touch the buffer\n");
211     ok(ret_size == strlen(value),
212        "should return length without terminating 0 ret_size=%d\n", ret_size);
213
214     ret = SetEnvironmentVariableA(name_cased, "");
215     ok(ret == TRUE,
216        "should not fail with empty value but GetLastError=%d\n", GetLastError());
217
218     lstrcpyA(buf, "foo");
219     SetLastError(0);
220     ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
221     ok(ret_size == 0 &&
222        ((GetLastError() == 0 && lstrcmpA(buf, "") == 0) ||
223         (GetLastError() == ERROR_ENVVAR_NOT_FOUND)),
224        "%s should be set to \"\" (NT) or removed (Win9x) but ret_size=%d GetLastError=%d and buf=%s\n",
225        name, ret_size, GetLastError(), buf);
226
227     /* Test the limits */
228     ret_size = GetEnvironmentVariableA(NULL, NULL, 0);
229     ok(ret_size == 0 && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
230        "should not find variable but ret_size=%d GetLastError=%d\n",
231        ret_size, GetLastError());
232
233     ret_size = GetEnvironmentVariableA(NULL, buf, lstrlenA(value) + 1);
234     ok(ret_size == 0 && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
235        "should not find variable but ret_size=%d GetLastError=%d\n",
236        ret_size, GetLastError());
237
238     ret_size = GetEnvironmentVariableA("", buf, lstrlenA(value) + 1);
239     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
240        "should not find variable but ret_size=%d GetLastError=%d\n",
241        ret_size, GetLastError());
242 }
243
244 static void test_GetSetEnvironmentVariableW(void)
245 {
246     WCHAR buf[256];
247     BOOL ret;
248     DWORD ret_size;
249     static const WCHAR name[] = {'S','o','m','e','W','i','l','d','N','a','m','e',0};
250     static const WCHAR value[] = {'S','o','m','e','W','i','l','d','V','a','l','u','e',0};
251     static const WCHAR name_cased[] = {'s','O','M','E','w','I','L','D','n','A','M','E',0};
252     static const WCHAR empty_strW[] = { 0 };
253     static const WCHAR fooW[] = {'f','o','o',0};
254
255     ret = SetEnvironmentVariableW(name, value);
256     if (ret == FALSE && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
257     {
258         /* Must be Win9x which doesn't support the Unicode functions */
259         win_skip("SetEnvironmentVariableW is not implemented\n");
260         return;
261     }
262     ok(ret == TRUE,
263        "unexpected error in SetEnvironmentVariableW, GetLastError=%d\n",
264        GetLastError());
265
266     /* Try to retrieve the environment variable we just set */
267     ret_size = GetEnvironmentVariableW(name, NULL, 0);
268     ok(ret_size == lstrlenW(value) + 1,
269        "should return length with terminating 0 ret_size=%d\n",
270        ret_size);
271
272     lstrcpyW(buf, fooW);
273     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value));
274     ok_w(lstrcmpW(buf, fooW) == 0 ||
275          lstrlenW(buf) == 0, /* Vista */
276          "Expected untouched or empty buffer, got \"%s\"\n", buf);
277
278     ok(ret_size == lstrlenW(value) + 1,
279        "should return length with terminating 0 ret_size=%d\n", ret_size);
280
281     lstrcpyW(buf, fooW);
282     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
283     ok(lstrcmpW(buf, value) == 0, "should touch the buffer\n");
284     ok(ret_size == lstrlenW(value),
285        "should return length without terminating 0 ret_size=%d\n", ret_size);
286
287     lstrcpyW(buf, fooW);
288     ret_size = GetEnvironmentVariableW(name_cased, buf, lstrlenW(value) + 1);
289     ok(lstrcmpW(buf, value) == 0, "should touch the buffer\n");
290     ok(ret_size == lstrlenW(value),
291        "should return length without terminating 0 ret_size=%d\n", ret_size);
292
293     /* Remove that environment variable */
294     ret = SetEnvironmentVariableW(name_cased, NULL);
295     ok(ret == TRUE, "should erase existing variable\n");
296
297     lstrcpyW(buf, fooW);
298     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
299     ok(lstrcmpW(buf, fooW) == 0, "should not touch the buffer\n");
300     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
301        "should not find variable but ret_size=%d GetLastError=%d\n",
302        ret_size, GetLastError());
303
304     /* Check behavior of SetEnvironmentVariableW(name, "") */
305     ret = SetEnvironmentVariableW(name, value);
306     ok(ret == TRUE,
307        "unexpected error in SetEnvironmentVariableW, GetLastError=%d\n",
308        GetLastError());
309
310     lstrcpyW(buf, fooW);
311     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
312     ok(lstrcmpW(buf, value) == 0, "should touch the buffer\n");
313     ok(ret_size == lstrlenW(value),
314        "should return length without terminating 0 ret_size=%d\n", ret_size);
315
316     ret = SetEnvironmentVariableW(name_cased, empty_strW);
317     ok(ret == TRUE, "should not fail with empty value but GetLastError=%d\n", GetLastError());
318
319     lstrcpyW(buf, fooW);
320     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
321     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
322        "should not find variable but ret_size=%d GetLastError=%d\n",
323        ret_size, GetLastError());
324     ok(lstrcmpW(buf, empty_strW) == 0, "should copy an empty string\n");
325
326     /* Test the limits */
327     ret_size = GetEnvironmentVariableW(NULL, NULL, 0);
328     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
329        "should not find variable but ret_size=%d GetLastError=%d\n",
330        ret_size, GetLastError());
331
332     if (0) /* Both tests crash on Vista */
333     {
334         ret_size = GetEnvironmentVariableW(NULL, buf, lstrlenW(value) + 1);
335         ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
336            "should not find variable but ret_size=%d GetLastError=%d\n",
337            ret_size, GetLastError());
338
339         ret = SetEnvironmentVariableW(NULL, NULL);
340         ok(ret == FALSE && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
341            "should fail with NULL, NULL but ret=%d and GetLastError=%d\n",
342            ret, GetLastError());
343     }
344 }
345
346 static void test_ExpandEnvironmentStringsA(void)
347 {
348     const char* value="Long long value";
349     const char* not_an_env_var="%NotAnEnvVar%";
350     char buf[256], buf1[256], buf2[0x8000];
351     DWORD ret_size, ret_size1;
352
353     SetEnvironmentVariableA("EnvVar", value);
354
355     ret_size = ExpandEnvironmentStringsA(NULL, buf1, sizeof(buf1));
356     ok(ret_size == 1 || ret_size == 0 /* Win9x */ || ret_size == 2 /* NT4 */,
357        "ExpandEnvironmentStrings returned %d\n", ret_size);
358
359     /* Try to get the required buffer size 'the natural way' */
360     strcpy(buf, "%EnvVar%");
361     ret_size = ExpandEnvironmentStringsA(buf, NULL, 0);
362     ok(ret_size == strlen(value)+1 || /* win98 */
363        ret_size == (strlen(value)+1)*2 || /* NT4 */
364        ret_size == strlen(value)+2 || /* win2k, XP, win2k3 */
365        ret_size == 0 /* Win95 */,
366        "ExpandEnvironmentStrings returned %d instead of %d, %d or %d\n",
367        ret_size, lstrlenA(value)+1, lstrlenA(value)+2, 0);
368
369     /* Again, side-stepping the Win95 bug */
370     ret_size = ExpandEnvironmentStringsA(buf, buf1, 0);
371     /* v5.1.2600.2945 (XP SP2) returns len + 2 here! */
372     ok(ret_size == strlen(value)+1 || ret_size == strlen(value)+2 ||
373        ret_size == (strlen(value)+1)*2 /* NT4 */,
374        "ExpandEnvironmentStrings returned %d instead of %d\n",
375        ret_size, lstrlenA(value)+1);
376
377     /* Try with a buffer that's too small */
378     ret_size = ExpandEnvironmentStringsA(buf, buf1, 12);
379     /* v5.1.2600.2945 (XP SP2) returns len + 2 here! */
380     ok(ret_size == strlen(value)+1 || ret_size == strlen(value)+2 ||
381        ret_size == (strlen(value)+1)*2 /* NT4 */,
382        "ExpandEnvironmentStrings returned %d instead of %d\n",
383        ret_size, lstrlenA(value)+1);
384
385     /* Try with a buffer of just the right size */
386     /* v5.1.2600.2945 (XP SP2) needs and returns len + 2 here! */
387     ret_size = ExpandEnvironmentStringsA(buf, buf1, ret_size);
388     ok(ret_size == strlen(value)+1 || ret_size == strlen(value)+2 ||
389        ret_size == (strlen(value)+1)*2 /* NT4 */,
390        "ExpandEnvironmentStrings returned %d instead of %d\n",
391        ret_size, lstrlenA(value)+1);
392     ok(!strcmp(buf1, value), "ExpandEnvironmentStrings returned [%s]\n", buf1);
393
394     /* Try with an unset environment variable */
395     strcpy(buf, not_an_env_var);
396     ret_size = ExpandEnvironmentStringsA(buf, buf1, sizeof(buf1));
397     ok(ret_size == strlen(not_an_env_var)+1 ||
398        ret_size == (strlen(not_an_env_var)+1)*2 /* NT4 */,
399        "ExpandEnvironmentStrings returned %d instead of %d\n", ret_size, lstrlenA(not_an_env_var)+1);
400     ok(!strcmp(buf1, not_an_env_var), "ExpandEnvironmentStrings returned [%s]\n", buf1);
401
402     /* test a large destination size */
403     strcpy(buf, "12345");
404     ret_size = ExpandEnvironmentStringsA(buf, buf2, sizeof(buf2));
405     ok(!strcmp(buf, buf2), "ExpandEnvironmentStrings failed %s vs %s. ret_size = %d\n", buf, buf2, ret_size);
406
407     ret_size1 = GetWindowsDirectoryA(buf1,256);
408     ok ((ret_size1 >0) && (ret_size1<256), "GetWindowsDirectory Failed\n");
409     ret_size = ExpandEnvironmentStringsA("%SystemRoot%",buf,sizeof(buf));
410     if (ERROR_ENVVAR_NOT_FOUND != GetLastError())
411     {
412         ok(!strcmp(buf, buf1), "ExpandEnvironmentStrings failed %s vs %s. ret_size = %d\n", buf, buf1, ret_size);
413     }
414
415     /* Try with a variable that references another */
416     SetEnvironmentVariableA("IndirectVar", "Foo%EnvVar%Bar");
417     strcpy(buf, "Indirect-%IndirectVar%-Indirect");
418     strcpy(buf2, "Indirect-Foo%EnvVar%Bar-Indirect");
419     ret_size = ExpandEnvironmentStringsA(buf, buf1, sizeof(buf1));
420     ok(ret_size == strlen(buf2)+1 ||
421        ret_size == (strlen(buf2)+1)*2 /* NT4 */,
422        "ExpandEnvironmentStrings returned %d instead of %d\n", ret_size, lstrlen(buf2)+1);
423     ok(!strcmp(buf1, buf2), "ExpandEnvironmentStrings returned [%s]\n", buf1);
424     SetEnvironmentVariableA("IndirectVar", NULL);
425
426     SetEnvironmentVariableA("EnvVar", NULL);
427 }
428
429 static void test_GetComputerName(void)
430 {
431     DWORD size;
432     BOOL ret;
433     LPSTR name;
434     LPWSTR nameW;
435     DWORD error;
436     int name_len;
437
438     size = 0;
439     ret = GetComputerNameA((LPSTR)0xdeadbeef, &size);
440     error = GetLastError();
441     ok(!ret && error == ERROR_BUFFER_OVERFLOW, "GetComputerNameA should have failed with ERROR_BUFFER_OVERFLOW instead of %d\n", error);
442
443     /* Only Vista returns the computer name length as documented in the MSDN */
444     if (size != 0)
445     {
446         size++; /* nul terminating character */
447         name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
448         ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
449         ret = GetComputerNameA(name, &size);
450         ok(ret, "GetComputerNameA failed with error %d\n", GetLastError());
451         HeapFree(GetProcessHeap(), 0, name);
452     }
453
454     size = MAX_COMPUTERNAME_LENGTH + 1;
455     name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
456     ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
457     ret = GetComputerNameA(name, &size);
458     ok(ret, "GetComputerNameA failed with error %d\n", GetLastError());
459     trace("computer name is \"%s\"\n", name);
460     name_len = strlen(name);
461     ok(size == name_len, "size should be same as length, name_len=%d, size=%d\n", name_len, size);
462     HeapFree(GetProcessHeap(), 0, name);
463
464     size = 0;
465     SetLastError(0xdeadbeef);
466     ret = GetComputerNameW((LPWSTR)0xdeadbeef, &size);
467     error = GetLastError();
468     if (error == ERROR_CALL_NOT_IMPLEMENTED)
469         win_skip("GetComputerNameW is not implemented\n");
470     else
471     {
472         ok(!ret && error == ERROR_BUFFER_OVERFLOW, "GetComputerNameW should have failed with ERROR_BUFFER_OVERFLOW instead of %d\n", error);
473         size++; /* nul terminating character */
474         nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
475         ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
476         ret = GetComputerNameW(nameW, &size);
477         ok(ret, "GetComputerNameW failed with error %d\n", GetLastError());
478         HeapFree(GetProcessHeap(), 0, nameW);
479     }
480 }
481
482 static void test_GetComputerNameExA(void)
483 {
484     DWORD size;
485     BOOL ret;
486     LPSTR name;
487     DWORD error;
488
489     static const int MAX_COMP_NAME = 32767;
490
491     if (!pGetComputerNameExA)
492     {
493         win_skip("GetComputerNameExA function not implemented\n");
494         return;
495     }
496
497     size = 0;
498     ret = pGetComputerNameExA(ComputerNameDnsDomain, (LPSTR)0xdeadbeef, &size);
499     error = GetLastError();
500     ok(ret == 0, "Expected 0, got %d\n", ret);
501     ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error);
502
503     /* size is not set in win2k */
504     if (size == 0)
505     {
506         win_skip("Win2k doesn't set the size\n");
507         size = MAX_COMP_NAME;
508     }
509     name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
510     ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
511     ret = pGetComputerNameExA(ComputerNameDnsDomain, name, &size);
512     ok(ret, "GetComputerNameExA(ComputerNameDnsDomain) failed with error %d\n", GetLastError());
513     trace("domain name is \"%s\"\n", name);
514     HeapFree(GetProcessHeap(), 0, name);
515
516     size = 0;
517     ret = pGetComputerNameExA(ComputerNameDnsFullyQualified, (LPSTR)0xdeadbeef, &size);
518     error = GetLastError();
519     ok(ret == 0, "Expected 0, got %d\n", ret);
520     ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error);
521
522     /* size is not set in win2k */
523     if (size == 0)
524         size = MAX_COMP_NAME;
525     name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
526     ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
527     ret = pGetComputerNameExA(ComputerNameDnsFullyQualified, name, &size);
528     ok(ret, "GetComputerNameExA(ComputerNameDnsFullyQualified) failed with error %d\n", GetLastError());
529     trace("fully qualified hostname is \"%s\"\n", name);
530     HeapFree(GetProcessHeap(), 0, name);
531
532     size = 0;
533     ret = pGetComputerNameExA(ComputerNameDnsHostname, (LPSTR)0xdeadbeef, &size);
534     error = GetLastError();
535     ok(ret == 0, "Expected 0, got %d\n", ret);
536     ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error);
537
538     /* size is not set in win2k */
539     if (size == 0)
540         size = MAX_COMP_NAME;
541     name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
542     ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
543     ret = pGetComputerNameExA(ComputerNameDnsHostname, name, &size);
544     ok(ret, "GetComputerNameExA(ComputerNameDnsHostname) failed with error %d\n", GetLastError());
545     trace("hostname is \"%s\"\n", name);
546     HeapFree(GetProcessHeap(), 0, name);
547
548     size = 0;
549     ret = pGetComputerNameExA(ComputerNameNetBIOS, (LPSTR)0xdeadbeef, &size);
550     error = GetLastError();
551     ok(ret == 0, "Expected 0, got %d\n", ret);
552     ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error);
553
554     /* size is not set in win2k */
555     if (size == 0)
556         size = MAX_COMP_NAME;
557     name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
558     ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
559     ret = pGetComputerNameExA(ComputerNameNetBIOS, name, &size);
560     ok(ret, "GetComputerNameExA(ComputerNameNetBIOS) failed with error %d\n", GetLastError());
561     trace("NetBIOS name is \"%s\"\n", name);
562     HeapFree(GetProcessHeap(), 0, name);
563 }
564
565 static void test_GetComputerNameExW(void)
566 {
567     DWORD size;
568     BOOL ret;
569     LPWSTR nameW;
570     DWORD error;
571
572     if (!pGetComputerNameExW)
573     {
574         win_skip("GetComputerNameExW function not implemented\n");
575         return;
576     }
577
578     size = 0;
579     ret = pGetComputerNameExW(ComputerNameDnsDomain, (LPWSTR)0xdeadbeef, &size);
580     error = GetLastError();
581     ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
582     nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
583     ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
584     ret = pGetComputerNameExW(ComputerNameDnsDomain, nameW, &size);
585     ok(ret, "GetComputerNameExW(ComputerNameDnsDomain) failed with error %d\n", GetLastError());
586     HeapFree(GetProcessHeap(), 0, nameW);
587
588     size = 0;
589     ret = pGetComputerNameExW(ComputerNameDnsFullyQualified, (LPWSTR)0xdeadbeef, &size);
590     error = GetLastError();
591     ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
592     nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
593     ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
594     ret = pGetComputerNameExW(ComputerNameDnsFullyQualified, nameW, &size);
595     ok(ret, "GetComputerNameExW(ComputerNameDnsFullyQualified) failed with error %d\n", GetLastError());
596     HeapFree(GetProcessHeap(), 0, nameW);
597
598     size = 0;
599     ret = pGetComputerNameExW(ComputerNameDnsHostname, (LPWSTR)0xdeadbeef, &size);
600     error = GetLastError();
601     ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
602     nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
603     ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
604     ret = pGetComputerNameExW(ComputerNameDnsHostname, nameW, &size);
605     ok(ret, "GetComputerNameExW(ComputerNameDnsHostname) failed with error %d\n", GetLastError());
606     HeapFree(GetProcessHeap(), 0, nameW);
607
608     size = 0;
609     ret = pGetComputerNameExW(ComputerNameNetBIOS, (LPWSTR)0xdeadbeef, &size);
610     error = GetLastError();
611     ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
612     nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
613     ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
614     ret = pGetComputerNameExW(ComputerNameNetBIOS, nameW, &size);
615     ok(ret, "GetComputerNameExW(ComputerNameNetBIOS) failed with error %d\n", GetLastError());
616     HeapFree(GetProcessHeap(), 0, nameW);
617 }
618
619 START_TEST(environ)
620 {
621     init_functionpointers();
622
623     test_Predefined();
624     test_GetSetEnvironmentVariableA();
625     test_GetSetEnvironmentVariableW();
626     test_ExpandEnvironmentStringsA();
627     test_GetComputerName();
628     test_GetComputerNameExA();
629     test_GetComputerNameExW();
630 }