SetEnvironmentVariableA(NULL, NULL) crashes on Win98 -> removed.
[wine] / dlls / kernel / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "wine/test.h"
22 #include "winbase.h"
23 #include "winerror.h"
24
25 static void test_GetSetEnvironmentVariableA(void)
26 {
27     char buf[256];
28     BOOL ret;
29     DWORD ret_size;
30     static const char name[] = "SomeWildName";
31     static const char name_cased[] = "sOMEwILDnAME";
32     static const char value[] = "SomeWildValue";
33
34     ret = SetEnvironmentVariableA(name, value);
35     ok(ret == TRUE,
36        "unexpected error in SetEnvironmentVariableA, GetLastError=%ld",
37        GetLastError());
38
39     /* Try to retrieve the environment variable we just set */
40     ret_size = GetEnvironmentVariableA(name, NULL, 0);
41     ok(ret_size == lstrlenA(value) + 1,
42        "should return length with terminating 0 ret_size=%ld", ret_size);
43
44     lstrcpyA(buf, "foo");
45     ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value));
46     ok(lstrcmpA(buf, "foo") == 0, "should not touch the buffer");
47     ok(ret_size == lstrlenA(value) + 1,
48        "should return length with terminating 0 ret_size=%ld", ret_size);
49
50     lstrcpyA(buf, "foo");
51     ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
52     ok(lstrcmpA(buf, value) == 0, "should touch the buffer");
53     ok(ret_size == lstrlenA(value),
54        "should return length without terminating 0 ret_size=%ld", ret_size);
55
56     lstrcpyA(buf, "foo");
57     ret_size = GetEnvironmentVariableA(name_cased, buf, lstrlenA(value) + 1);
58     ok(lstrcmpA(buf, value) == 0, "should touch the buffer");
59     ok(ret_size == lstrlenA(value),
60        "should return length without terminating 0 ret_size=%ld", ret_size);
61
62     /* Remove that environment variable */
63     ret = SetEnvironmentVariableA(name_cased, NULL);
64     ok(ret == TRUE, "should erase existing variable");
65
66     lstrcpyA(buf, "foo");
67     ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
68     ok(lstrcmpA(buf, "foo") == 0, "should not touch the buffer");
69     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
70        "should not find variable but ret_size=%ld GetLastError=%ld",
71        ret_size, GetLastError());
72
73     /* Check behavior of SetEnvironmentVariableA(name, "") */
74     ret = SetEnvironmentVariableA(name, value);
75     ok(ret == TRUE,
76        "unexpected error in SetEnvironmentVariableA, GetLastError=%ld",
77        GetLastError());
78
79     lstrcpyA(buf, "foo");
80     ret_size = GetEnvironmentVariableA(name_cased, buf, lstrlenA(value) + 1);
81     ok(lstrcmpA(buf, value) == 0, "should touch the buffer");
82     ok(ret_size == lstrlenA(value),
83        "should return length without terminating 0 ret_size=%ld", ret_size);
84
85     ret = SetEnvironmentVariableA(name_cased, "");
86     ok(ret == TRUE,
87        "should not fail with empty value but GetLastError=%ld", GetLastError());
88
89     lstrcpyA(buf, "foo");
90     SetLastError(0);
91     ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
92     ok(ret_size == 0 &&
93        ((GetLastError() == 0 && lstrcmpA(buf, "") == 0) ||
94         (GetLastError() == ERROR_ENVVAR_NOT_FOUND)),
95        "%s should be set to \"\" (NT) or removed (Win9x) but ret_size=%ld GetLastError=%ld and buf=%s",
96        name, ret_size, GetLastError(), buf);
97
98     /* Test the limits */
99     ret_size = GetEnvironmentVariableA(NULL, NULL, 0);
100     ok(ret_size == 0 && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
101        "should not find variable but ret_size=%ld GetLastError=%ld",
102        ret_size, GetLastError());
103
104     ret_size = GetEnvironmentVariableA(NULL, buf, lstrlenA(value) + 1);
105     ok(ret_size == 0 && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
106        "should not find variable but ret_size=%ld GetLastError=%ld",
107        ret_size, GetLastError());
108
109     ret_size = GetEnvironmentVariableA("", buf, lstrlenA(value) + 1);
110     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
111        "should not find variable but ret_size=%ld GetLastError=%ld",
112        ret_size, GetLastError());
113 }
114
115 static void test_GetSetEnvironmentVariableW(void)
116 {
117     WCHAR buf[256];
118     BOOL ret;
119     DWORD ret_size;
120     static const WCHAR name[] = {'S','o','m','e','W','i','l','d','N','a','m','e',0};
121     static const WCHAR value[] = {'S','o','m','e','W','i','l','d','V','a','l','u','e',0};
122     static const WCHAR name_cased[] = {'s','O','M','E','w','I','L','D','n','A','M','E',0};
123     static const WCHAR empty_strW[] = { 0 };
124     static const WCHAR fooW[] = {'f','o','o',0};
125
126     ret = SetEnvironmentVariableW(name, value);
127     if (ret == FALSE && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
128     {
129         /* Must be Win9x which doesn't support the Unicode functions */
130         return;
131     }
132     ok(ret == TRUE,
133        "unexpected error in SetEnvironmentVariableW, GetLastError=%ld",
134        GetLastError());
135
136     /* Try to retrieve the environment variable we just set */
137     ret_size = GetEnvironmentVariableW(name, NULL, 0);
138     ok(ret_size == lstrlenW(value) + 1,
139        "should return length with terminating 0 ret_size=%ld",
140        ret_size);
141
142     lstrcpyW(buf, fooW);
143     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value));
144     todo_wine {
145         ok(lstrcmpW(buf, fooW) == 0, "should not touch the buffer");
146     };
147     ok(ret_size == lstrlenW(value) + 1,
148        "should return length with terminating 0 ret_size=%ld", ret_size);
149
150     lstrcpyW(buf, fooW);
151     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
152     ok(lstrcmpW(buf, value) == 0, "should touch the buffer");
153     ok(ret_size == lstrlenW(value),
154        "should return length without terminating 0 ret_size=%ld", ret_size);
155
156     lstrcpyW(buf, fooW);
157     ret_size = GetEnvironmentVariableW(name_cased, buf, lstrlenW(value) + 1);
158     ok(lstrcmpW(buf, value) == 0, "should touch the buffer");
159     ok(ret_size == lstrlenW(value),
160        "should return length without terminating 0 ret_size=%ld", ret_size);
161
162     /* Remove that environment variable */
163     ret = SetEnvironmentVariableW(name_cased, NULL);
164     ok(ret == TRUE, "should erase existing variable");
165
166     lstrcpyW(buf, fooW);
167     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
168     ok(lstrcmpW(buf, fooW) == 0, "should not touch the buffer");
169     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
170        "should not find variable but ret_size=%ld GetLastError=%ld",
171        ret_size, GetLastError());
172
173     /* Check behavior of SetEnvironmentVariableW(name, "") */
174     ret = SetEnvironmentVariableW(name, value);
175     ok(ret == TRUE,
176        "unexpected error in SetEnvironmentVariableW, GetLastError=%ld",
177        GetLastError());
178
179     lstrcpyW(buf, fooW);
180     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
181     ok(lstrcmpW(buf, value) == 0, "should touch the buffer");
182     ok(ret_size == lstrlenW(value),
183        "should return length without terminating 0 ret_size=%ld", ret_size);
184
185     ret = SetEnvironmentVariableW(name_cased, empty_strW);
186     ok(ret == TRUE, "should not fail with empty value but GetLastError=%ld", GetLastError());
187
188     lstrcpyW(buf, fooW);
189     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
190     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
191        "should not find variable but ret_size=%ld GetLastError=%ld",
192        ret_size, GetLastError());
193
194     todo_wine {
195         ok(lstrcmpW(buf, empty_strW) == 0, "should copy an empty string");
196     };
197
198     /* Test the limits */
199     ret_size = GetEnvironmentVariableW(NULL, NULL, 0);
200     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
201        "should not find variable but ret_size=%ld GetLastError=%ld",
202        ret_size, GetLastError());
203
204     ret_size = GetEnvironmentVariableW(NULL, buf, lstrlenW(value) + 1);
205     ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
206        "should not find variable but ret_size=%ld GetLastError=%ld",
207        ret_size, GetLastError());
208
209     ret = SetEnvironmentVariableW(NULL, NULL);
210     ok(ret == FALSE && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
211        "should fail with NULL, NULL but ret=%d and GetLastError=%ld",
212        ret, GetLastError());
213 }
214
215 START_TEST(environ)
216 {
217     test_GetSetEnvironmentVariableA();
218     test_GetSetEnvironmentVariableW();
219 }