ReactOS 0.4.15-dev-7924-g5949c20
env.c File Reference
#include <stdio.h>
#include "ntdll_test.h"
Include dependency graph for env.c:

Go to the source code of this file.

Functions

static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)(LPWSTR dst
 
static void (WINAPI *pRtlSetCurrentEnvironment)(PWSTR
 
static void testQuery (void)
 
static void testSetHelper (LPWSTR *env, const char *var, const char *val, NTSTATUS ret, NTSTATUS alt)
 
static void testSet (void)
 
static void testExpand (void)
 
 START_TEST (env)
 

Variables

static DWORD dstlen
 
static DWORD LPDWORD reslen
 
static DWORD LPDWORD LPCSTR src
 
static DWORD LPDWORD LPCSTR DWORD srclen
 
static PUNICODE_STRING
 
static PULONG
 
static WCHAR small_env []
 

Function Documentation

◆ NTSTATUS()

static NTSTATUS ( WINAPI pRtlMultiByteToUnicodeN)
static

◆ START_TEST()

START_TEST ( env  )

Definition at line 277 of file env.c.

278{
279 HMODULE mod = GetModuleHandleA("ntdll.dll");
280 if (!mod)
281 {
282 win_skip("Not running on NT, skipping tests\n");
283 return;
284 }
285
286 pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN");
287 pRtlCreateEnvironment = (void*)GetProcAddress(mod, "RtlCreateEnvironment");
288 pRtlDestroyEnvironment = (void*)GetProcAddress(mod, "RtlDestroyEnvironment");
289 pRtlQueryEnvironmentVariable_U = (void*)GetProcAddress(mod, "RtlQueryEnvironmentVariable_U");
290 pRtlSetCurrentEnvironment = (void*)GetProcAddress(mod, "RtlSetCurrentEnvironment");
291 pRtlSetEnvironmentVariable = (void*)GetProcAddress(mod, "RtlSetEnvironmentVariable");
292 pRtlExpandEnvironmentStrings_U = (void*)GetProcAddress(mod, "RtlExpandEnvironmentStrings_U");
293
294 if (pRtlQueryEnvironmentVariable_U)
295 testQuery();
296 if (pRtlSetEnvironmentVariable)
297 testSet();
298 if (pRtlExpandEnvironmentStrings_U)
299 testExpand();
300}
#define GetProcAddress(x, y)
Definition: compat.h:753
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
static int mod
Definition: i386-dis.c:1288
static void testExpand(void)
Definition: env.c:205
static void testSet(void)
Definition: env.c:170
static void testQuery(void)
Definition: env.c:52
#define win_skip
Definition: test.h:160

◆ testExpand()

static void testExpand ( void  )
static

Definition at line 205 of file env.c.

206{
207 static const struct test
208 {
209 const char *src;
210 const char *dst;
211 } tests[] =
212 {
213 {"hello%foo%world", "hellototoworld"},
214 {"hello%=oOH%world", "helloIIIworld"},
215 {"hello%foo", "hello%foo"},
216 {"hello%bar%world", "hello%bar%world"},
217 /*
218 * {"hello%foo%world%=oOH%eeck", "hellototoworldIIIeeck"},
219 * Interestingly enough, with a 8 WCHAR buffers, we get on 2k:
220 * helloIII
221 * so it seems like strings overflowing the buffer are written
222 * (truncated) but the write cursor is not advanced :-/
223 */
224 {NULL, NULL}
225 };
226
227 const struct test* test;
228 NTSTATUS nts;
229 UNICODE_STRING us_src, us_dst;
230 WCHAR src[256], dst[256], rst[256];
231 ULONG ul;
232
233 for (test = tests; test->src; test++)
234 {
235 pRtlMultiByteToUnicodeN(src, sizeof(src), NULL, test->src, strlen(test->src)+1);
236 pRtlMultiByteToUnicodeN(rst, sizeof(rst), NULL, test->dst, strlen(test->dst)+1);
237
238 us_src.Length = strlen(test->src) * sizeof(WCHAR);
239 us_src.MaximumLength = us_src.Length + 2;
240 us_src.Buffer = src;
241
242 us_dst.Length = 0;
243 us_dst.MaximumLength = 0;
244 us_dst.Buffer = NULL;
245
246 nts = pRtlExpandEnvironmentStrings_U(small_env, &us_src, &us_dst, &ul);
247 ok(nts == STATUS_BUFFER_TOO_SMALL, "Call failed (%u)\n", nts);
248 ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR),
249 "Wrong returned length for %s: %u\n", test->src, ul );
250
251 us_dst.Length = 0;
252 us_dst.MaximumLength = sizeof(dst);
253 us_dst.Buffer = dst;
254
255 nts = pRtlExpandEnvironmentStrings_U(small_env, &us_src, &us_dst, &ul);
256 ok(nts == STATUS_SUCCESS, "Call failed (%u)\n", nts);
257 ok(ul == us_dst.Length + sizeof(WCHAR),
258 "Wrong returned length for %s: %u\n", test->src, ul);
259 ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR),
260 "Wrong returned length for %s: %u\n", test->src, ul);
261 ok(lstrcmpW(dst, rst) == 0, "Wrong result for %s: expecting %s\n",
262 test->src, test->dst);
263
264 us_dst.Length = 0;
265 us_dst.MaximumLength = 8 * sizeof(WCHAR);
266 us_dst.Buffer = dst;
267 dst[8] = '-';
268 nts = pRtlExpandEnvironmentStrings_U(small_env, &us_src, &us_dst, &ul);
269 ok(nts == STATUS_BUFFER_TOO_SMALL, "Call failed (%u)\n", nts);
270 ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR),
271 "Wrong returned length for %s (with buffer too small): %u\n", test->src, ul);
272 ok(dst[8] == '-', "Writing too far in buffer (got %c/%d)\n", dst[8], dst[8]);
273 }
274
275}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ok(value,...)
Definition: atltest.h:57
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static struct test_info tests[]
static WCHAR small_env[]
Definition: env.c:34
static DWORD LPDWORD LPCSTR src
Definition: env.c:26
#define test
Definition: rosglue.h:37
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32_t ULONG
Definition: typedefs.h:59
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ testQuery()

static void testQuery ( void  )
static

Definition at line 52 of file env.c.

53{
54 struct test
55 {
56 const char *var;
57 int len;
59 const char *val;
60 NTSTATUS alt;
61 };
62
63 static const struct test tests[] =
64 {
65 {"foo", 256, STATUS_SUCCESS, "toto"},
66 {"FoO", 256, STATUS_SUCCESS, "toto"},
67 {"foo=", 256, STATUS_VARIABLE_NOT_FOUND, NULL},
68 {"foo ", 256, STATUS_VARIABLE_NOT_FOUND, NULL},
69 {"foo", 1, STATUS_BUFFER_TOO_SMALL, "toto"},
70 {"foo", 3, STATUS_BUFFER_TOO_SMALL, "toto"},
71 {"foo", 4, STATUS_SUCCESS, "toto", STATUS_BUFFER_TOO_SMALL},
72 {"foo", 5, STATUS_SUCCESS, "toto"},
73 {"fooo", 256, STATUS_SUCCESS, "tutu"},
75 {"g", 256, STATUS_SUCCESS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
76"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
77 {"sr=an", 256, STATUS_SUCCESS, "ouo", STATUS_VARIABLE_NOT_FOUND},
78 {"sr", 256, STATUS_SUCCESS, "an=ouo"},
79 {"=oOH", 256, STATUS_SUCCESS, "III"},
81 {"nul", 256, STATUS_SUCCESS, ""},
82 {NULL, 0, 0, NULL}
83 };
84
85 WCHAR bn[257];
86 WCHAR bv[257];
89 NTSTATUS nts;
90 unsigned int i;
91
92 for (i = 0; tests[i].var; i++)
93 {
94 const struct test *test = &tests[i];
95 name.Length = strlen(test->var) * 2;
96 name.MaximumLength = name.Length + 2;
97 name.Buffer = bn;
98 value.Length = 0;
99 value.MaximumLength = test->len * 2;
100 value.Buffer = bv;
101 bv[test->len] = '@';
102
103 pRtlMultiByteToUnicodeN( bn, sizeof(bn), NULL, test->var, strlen(test->var)+1 );
104 nts = pRtlQueryEnvironmentVariable_U(small_env, &name, &value);
105 ok( nts == test->status || (test->alt && nts == test->alt),
106 "[%d]: Wrong status for '%s', expecting %x got %x\n",
107 i, test->var, test->status, nts );
108 if (nts == test->status) switch (nts)
109 {
110 case STATUS_SUCCESS:
111 pRtlMultiByteToUnicodeN( bn, sizeof(bn), NULL, test->val, strlen(test->val)+1 );
112 ok( value.Length == strlen(test->val) * sizeof(WCHAR), "Wrong length %d for %s\n",
113 value.Length, test->var );
114 ok((value.Length == strlen(test->val) * sizeof(WCHAR) && memcmp(bv, bn, value.Length) == 0) ||
115 lstrcmpW(bv, bn) == 0,
116 "Wrong result for %s/%d\n", test->var, test->len);
117 ok(bv[test->len] == '@', "Writing too far away in the buffer for %s/%d\n", test->var, test->len);
118 break;
120 ok( value.Length == strlen(test->val) * sizeof(WCHAR),
121 "Wrong returned length %d (too small buffer) for %s\n", value.Length, test->var );
122 break;
123 }
124 }
125}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char * var
Definition: shader.c:5666
#define STATUS_VARIABLE_NOT_FOUND
Definition: ntstatus.h:492
Definition: name.c:39
Definition: ps.c:97
Definition: pdh_main.c:94

Referenced by START_TEST().

◆ testSet()

static void testSet ( void  )
static

Definition at line 170 of file env.c.

171{
172 LPWSTR env;
173 char tmp[16];
174 int i;
175
176 ok(pRtlCreateEnvironment(FALSE, &env) == STATUS_SUCCESS, "Creating environment\n");
177
178 testSetHelper(&env, "cat", "dog", STATUS_SUCCESS, 0);
179 testSetHelper(&env, "cat", "horse", STATUS_SUCCESS, 0);
180 testSetHelper(&env, "cat", "zz", STATUS_SUCCESS, 0);
181 testSetHelper(&env, "cat", NULL, STATUS_SUCCESS, 0);
183 testSetHelper(&env, "foo", "meouw", STATUS_SUCCESS, 0);
185 testSetHelper(&env, "me", "too=also", STATUS_SUCCESS, 0);
186 testSetHelper(&env, "=too", "also", STATUS_SUCCESS, 0);
187 testSetHelper(&env, "=", "also", STATUS_SUCCESS, 0);
188
189 for (i = 0; i < 128; i++)
190 {
191 sprintf(tmp, "zork%03d", i);
192 testSetHelper(&env, tmp, "is alive", STATUS_SUCCESS, 0);
193 }
194
195 for (i = 0; i < 128; i++)
196 {
197 sprintf(tmp, "zork%03d", i);
199 }
200 testSetHelper(&env, "fOo", NULL, STATUS_SUCCESS, 0);
201
202 ok(pRtlDestroyEnvironment(env) == STATUS_SUCCESS, "Destroying environment\n");
203}
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define FALSE
Definition: types.h:117
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static void testSetHelper(LPWSTR *env, const char *var, const char *val, NTSTATUS ret, NTSTATUS alt)
Definition: env.c:127
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by START_TEST(), test_hash_set(), and test_set().

◆ testSetHelper()

static void testSetHelper ( LPWSTR env,
const char var,
const char val,
NTSTATUS  ret,
NTSTATUS  alt 
)
static

Definition at line 127 of file env.c.

128{
129 WCHAR bvar[256], bval1[256], bval2[256];
130 UNICODE_STRING uvar;
131 UNICODE_STRING uval;
132 NTSTATUS nts;
133
134 uvar.Length = strlen(var) * sizeof(WCHAR);
135 uvar.MaximumLength = uvar.Length + sizeof(WCHAR);
136 uvar.Buffer = bvar;
137 pRtlMultiByteToUnicodeN( bvar, sizeof(bvar), NULL, var, strlen(var)+1 );
138 if (val)
139 {
140 uval.Length = strlen(val) * sizeof(WCHAR);
141 uval.MaximumLength = uval.Length + sizeof(WCHAR);
142 uval.Buffer = bval1;
143 pRtlMultiByteToUnicodeN( bval1, sizeof(bval1), NULL, val, strlen(val)+1 );
144 }
145 nts = pRtlSetEnvironmentVariable(env, &uvar, val ? &uval : NULL);
146 ok(nts == ret || (alt && nts == alt), "Setting var %s=%s (%x/%x)\n", var, val, nts, ret);
147 if (nts == STATUS_SUCCESS)
148 {
149 uval.Length = 0;
150 uval.MaximumLength = sizeof(bval2);
151 uval.Buffer = bval2;
152 nts = pRtlQueryEnvironmentVariable_U(*env, &uvar, &uval);
153 switch (nts)
154 {
155 case STATUS_SUCCESS:
156 ok(lstrcmpW(bval1, bval2) == 0, "Cannot get value written to environment\n");
157 break;
159 ok(val == NULL ||
160 broken(strchr(var,'=') != NULL), /* variable containing '=' may be set but not found again on NT4 */
161 "Couldn't find variable, but didn't delete it. val = %s\n", val);
162 break;
163 default:
164 ok(0, "Wrong ret %u for %s\n", nts, var);
165 break;
166 }
167 }
168}
#define broken(x)
Definition: _sntprintf.h:21
char * strchr(const char *String, int ch)
Definition: utclib.c:501
int ret

Referenced by testSet().

◆ void()

static void ( WINAPI pRtlSetCurrentEnvironment)
static

Variable Documentation

◆ dstlen

DWORD dstlen

Definition at line 25 of file env.c.

◆ PULONG

Definition at line 32 of file env.c.

◆ PUNICODE_STRING

Definition at line 29 of file env.c.

◆ reslen

DWORD LPDWORD reslen

Definition at line 25 of file env.c.

◆ small_env

WCHAR small_env[]
static
Initial value:
= {'f','o','o','=','t','o','t','o',0,
'f','o','=','t','i','t','i',0,
'f','o','o','o','=','t','u','t','u',0,
's','r','=','a','n','=','o','u','o',0,
'g','=','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0,
'=','o','O','H','=','I','I','I',0,
'n','u','l','=',0,
0}

Definition at line 34 of file env.c.

Referenced by testExpand(), and testQuery().

◆ src

Definition at line 26 of file env.c.

Referenced by testExpand().

◆ srclen

Definition at line 26 of file env.c.