mirror of
https://github.com/reactos/reactos.git
synced 2026-06-05 19:43:39 +08:00
[NTDLL_APITEST] Add tests for RtlQueryEnvironmentVariable(_U)
This commit is contained in:
@@ -129,6 +129,8 @@ list(APPEND SOURCE
|
||||
RtlNtPathNameToDosPathName.c
|
||||
RtlpApplyLengthFunction.c
|
||||
RtlpEnsureBufferSize.c
|
||||
RtlQueryEnvironmentVariable.c
|
||||
RtlQueryEnvironmentVariable_U.c
|
||||
RtlQueryTimeZoneInfo.c
|
||||
RtlReAllocateHeap.c
|
||||
RtlRemovePrivileges.c
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Tests for RtlQueryEnvironmentVariable
|
||||
* COPYRIGHT: Copyright 2026 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
typedef
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FN_RtlQueryEnvironmentVariable(
|
||||
_In_opt_ PVOID Environment,
|
||||
_In_reads_(NameLength) PWSTR Name,
|
||||
_In_ SIZE_T NameLength,
|
||||
_Out_writes_(ValueLength) PWSTR Value,
|
||||
_In_ SIZE_T ValueLength,
|
||||
_Out_ PSIZE_T ReturnLength);
|
||||
|
||||
static FN_RtlQueryEnvironmentVariable* pRtlQueryEnvironmentVariable;
|
||||
|
||||
START_TEST(RtlQueryEnvironmentVariable)
|
||||
{
|
||||
static WCHAR TestEnv[] = L"TestVar=TestVal\0Foo=4\0EmptyVar\0Bar=8\0\0";
|
||||
WCHAR Buffer[32];
|
||||
SIZE_T ReturnLength;
|
||||
NTSTATUS Status;
|
||||
|
||||
HINSTANCE hinst = GetModuleHandleA("ntdll.dll");
|
||||
pRtlQueryEnvironmentVariable = (FN_RtlQueryEnvironmentVariable*)
|
||||
GetProcAddress(hinst, "RtlQueryEnvironmentVariable");
|
||||
if (pRtlQueryEnvironmentVariable == NULL)
|
||||
{
|
||||
ok(GetNTVersion() < _WIN32_WINNT_VISTA, "RtlQueryEnvironmentVariable not available on NT6+\n");
|
||||
skip("RtlQueryEnvironmentVariable is not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Query the TestVar environment variable length */
|
||||
Status = pRtlQueryEnvironmentVariable(TestEnv, L"TestVar", 7, NULL, 0, &ReturnLength);
|
||||
ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL);
|
||||
ok_eq_size(ReturnLength, 8);
|
||||
|
||||
/* Test a buffer size that is too small */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
Status = pRtlQueryEnvironmentVariable(TestEnv, L"TestVar", 7, Buffer, 2, &ReturnLength);
|
||||
ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL);
|
||||
ok_eq_size(ReturnLength, 8);
|
||||
ok_eq_wchar(Buffer[0], UNICODE_NULL);
|
||||
ok_eq_wchar(Buffer[1], 0xABAB);
|
||||
|
||||
/* Test a buffer size that doesn't fit the terminating NULL char */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
Status = pRtlQueryEnvironmentVariable(TestEnv, L"TestVar", 7, Buffer, 7, &ReturnLength);
|
||||
ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL);
|
||||
ok_eq_size(ReturnLength, 8);
|
||||
ok_eq_wchar(Buffer[0], UNICODE_NULL);
|
||||
ok_eq_wchar(Buffer[1], 0xABAB);
|
||||
|
||||
/* Test a buffer size that is just large enough */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
Status = pRtlQueryEnvironmentVariable(TestEnv, L"TestVar", 7, Buffer, 8, &ReturnLength);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
ok_eq_size(ReturnLength, 7);
|
||||
ok_eq_wstr(Buffer, L"TestVal");
|
||||
ok_eq_wchar(Buffer[7], UNICODE_NULL);
|
||||
ok_eq_wchar(Buffer[8], 0xABAB);
|
||||
|
||||
/* Test a buffer size that is larger than needed */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
Status = pRtlQueryEnvironmentVariable(TestEnv, L"TestVar", 7, Buffer, ARRAYSIZE(Buffer), &ReturnLength);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
ok_eq_size(ReturnLength, 7);
|
||||
ok_eq_wstr(Buffer, L"TestVal");
|
||||
ok_eq_wchar(Buffer[7], UNICODE_NULL);
|
||||
ok_eq_wchar(Buffer[8], 0xABAB);
|
||||
|
||||
/* Test a too big variable Length */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
Status = pRtlQueryEnvironmentVariable(TestEnv, L"TestVar", 8, Buffer, 8, &ReturnLength);
|
||||
ok_ntstatus(Status, STATUS_VARIABLE_NOT_FOUND);
|
||||
ok_eq_wchar(Buffer[0], 0xABAB);
|
||||
|
||||
/* Query the EmptyVar environment variable */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
Status = pRtlQueryEnvironmentVariable(TestEnv, L"EmptyVar", 8, Buffer, ARRAYSIZE(Buffer), &ReturnLength);
|
||||
ok_ntstatus(Status, STATUS_VARIABLE_NOT_FOUND);
|
||||
ok_eq_wchar(Buffer[0], 0xABAB);
|
||||
|
||||
/* Query the Bar environment variable */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
Status = pRtlQueryEnvironmentVariable(TestEnv, L"Bar", 3, Buffer, 8, &ReturnLength);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
ok_eq_wchar(Buffer[0], L'8');
|
||||
ok_eq_wchar(Buffer[1], UNICODE_NULL);
|
||||
ok_eq_wchar(Buffer[2], 0xABAB);
|
||||
}
|
||||
128
modules/rostests/apitests/ntdll/RtlQueryEnvironmentVariable_U.c
Normal file
128
modules/rostests/apitests/ntdll/RtlQueryEnvironmentVariable_U.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Tests for RtlQueryEnvironmentVariable_U
|
||||
* COPYRIGHT: Copyright 2026 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
START_TEST(RtlQueryEnvironmentVariable_U)
|
||||
{
|
||||
static WCHAR TestEnvironment[] = L"TestVar=TestVal\0Foo=4\0EmptyVar\0Bar=8\0\0";
|
||||
WCHAR Buffer[32];
|
||||
UNICODE_STRING NameString, ValueString;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Query the TestVar environment variable length */
|
||||
RtlInitUnicodeString(&NameString, L"TestVar");
|
||||
RtlInitEmptyUnicodeString(&ValueString, NULL, 0);
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL);
|
||||
ok_eq_pointer(ValueString.Buffer, NULL);
|
||||
ok_eq_ulong(ValueString.Length, 7 * sizeof(WCHAR));
|
||||
ok_eq_ulong(ValueString.MaximumLength, 0);
|
||||
|
||||
/* Test passing an empty sized buffer */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
RtlInitEmptyUnicodeString(&ValueString, Buffer, 0);
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL);
|
||||
ok_eq_pointer(ValueString.Buffer, Buffer);
|
||||
ok_eq_ulong(ValueString.Length, 7 * sizeof(WCHAR));
|
||||
ok_eq_ulong(ValueString.MaximumLength, 0);
|
||||
ok_eq_wchar(Buffer[0], 0xABAB);
|
||||
|
||||
/* Test a buffer size that is too small */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
RtlInitEmptyUnicodeString(&ValueString, Buffer, 2 * sizeof(WCHAR));
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL);
|
||||
ok_eq_pointer(ValueString.Buffer, Buffer);
|
||||
ok_eq_ulong(ValueString.Length, 7 * sizeof(WCHAR));
|
||||
ok_eq_ulong(ValueString.MaximumLength, 2 * sizeof(WCHAR));
|
||||
ok(Buffer[0] == UNICODE_NULL || broken(/* Windows 2003 */ Buffer[0] == 0xABAB), "Buffer[0] = 0x%x\n", Buffer[0]);
|
||||
ok_eq_wchar(Buffer[1], 0xABAB);
|
||||
|
||||
/* Test a buffer size that doesn't fit the terminating NULL char */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
RtlInitEmptyUnicodeString(&ValueString, Buffer, 7 * sizeof(WCHAR));
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok(Status == STATUS_BUFFER_TOO_SMALL || broken(/* Windows 2003 */ Status == STATUS_SUCCESS), "Status = 0x%lx\n", Status);
|
||||
ok_eq_pointer(ValueString.Buffer, Buffer);
|
||||
ok_eq_ulong(ValueString.Length, 7 * sizeof(WCHAR));
|
||||
ok_eq_ulong(ValueString.MaximumLength, 7 * sizeof(WCHAR));
|
||||
if (Status == STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
ok_eq_wchar(Buffer[0], UNICODE_NULL);
|
||||
ok_eq_wchar(Buffer[1], 0xABAB);
|
||||
}
|
||||
|
||||
/* Test a buffer size that is just large enough */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
RtlInitEmptyUnicodeString(&ValueString, Buffer, 8 * sizeof(WCHAR));
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
ok_eq_pointer(ValueString.Buffer, Buffer);
|
||||
ok_eq_ulong(ValueString.Length, 7 * sizeof(WCHAR));
|
||||
ok_eq_ulong(ValueString.MaximumLength, 8 * sizeof(WCHAR));
|
||||
ok_eq_wstr(Buffer, L"TestVal");
|
||||
ok_eq_wchar(Buffer[7], UNICODE_NULL);
|
||||
ok_eq_wchar(Buffer[8], 0xABAB);
|
||||
|
||||
/* Test a buffer size that is larger than needed */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
RtlInitEmptyUnicodeString(&ValueString, Buffer, sizeof(Buffer));
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
ok_eq_pointer(ValueString.Buffer, Buffer);
|
||||
ok_eq_ulong(ValueString.Length, 7 * sizeof(WCHAR));
|
||||
ok_eq_ulong(ValueString.MaximumLength, sizeof(Buffer));
|
||||
ok_eq_wstr(Buffer, L"TestVal");
|
||||
ok_eq_wchar(Buffer[7], UNICODE_NULL);
|
||||
ok_eq_wchar(Buffer[8], 0xABAB);
|
||||
|
||||
/* Test a too big variable Length */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
NameString.Length += sizeof(WCHAR);
|
||||
RtlInitEmptyUnicodeString(&ValueString, Buffer, sizeof(Buffer));
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok_ntstatus(Status, STATUS_VARIABLE_NOT_FOUND);
|
||||
ok_eq_wchar(Buffer[0], 0xABAB);
|
||||
|
||||
/* Query the EmptyVar environment variable */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
RtlInitUnicodeString(&NameString, L"EmptyVar");
|
||||
RtlInitEmptyUnicodeString(&ValueString, Buffer, sizeof(Buffer));
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok_ntstatus(Status, STATUS_VARIABLE_NOT_FOUND);
|
||||
ok_eq_pointer(ValueString.Buffer, Buffer);
|
||||
ok_eq_ulong(ValueString.Length, 0);
|
||||
ok_eq_ulong(ValueString.MaximumLength, sizeof(Buffer));
|
||||
ok_eq_wchar(Buffer[0], 0xABAB);
|
||||
|
||||
/* Query the Bar environment variable */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
RtlInitUnicodeString(&NameString, L"Bar");
|
||||
RtlInitEmptyUnicodeString(&ValueString, Buffer, sizeof(Buffer));
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
ok_eq_pointer(ValueString.Buffer, Buffer);
|
||||
ok_eq_ulong(ValueString.Length, 1 * sizeof(WCHAR));
|
||||
ok_eq_ulong(ValueString.MaximumLength, sizeof(Buffer));
|
||||
ok_eq_wstr(Buffer, L"8");
|
||||
ok_eq_wchar(Buffer[1], UNICODE_NULL);
|
||||
ok_eq_wchar(Buffer[2], 0xABAB);
|
||||
|
||||
/* Test NULL Variable name */
|
||||
memset(Buffer, 0xAB, sizeof(Buffer));
|
||||
RtlInitEmptyUnicodeString(&NameString, NULL, 0);
|
||||
RtlInitEmptyUnicodeString(&ValueString, Buffer, sizeof(Buffer));
|
||||
Status = RtlQueryEnvironmentVariable_U(TestEnvironment, &NameString, &ValueString);
|
||||
ok_ntstatus(Status, STATUS_VARIABLE_NOT_FOUND);
|
||||
ok_eq_pointer(ValueString.Buffer, Buffer);
|
||||
ok_eq_ulong(ValueString.Length, 0);
|
||||
ok_eq_ulong(ValueString.MaximumLength, sizeof(Buffer));
|
||||
ok_eq_wchar(Buffer[0], 0xABAB);
|
||||
|
||||
}
|
||||
@@ -117,6 +117,8 @@ extern void func_RtlMultipleAllocateHeap(void);
|
||||
extern void func_RtlNtPathNameToDosPathName(void);
|
||||
extern void func_RtlpApplyLengthFunction(void);
|
||||
extern void func_RtlpEnsureBufferSize(void);
|
||||
extern void func_RtlQueryEnvironmentVariable(void);
|
||||
extern void func_RtlQueryEnvironmentVariable_U(void);
|
||||
extern void func_RtlQueryTimeZoneInformation(void);
|
||||
extern void func_RtlReAllocateHeap(void);
|
||||
extern void func_RtlRemovePrivileges(void);
|
||||
@@ -250,6 +252,8 @@ const struct test winetest_testlist[] =
|
||||
{ "RtlNtPathNameToDosPathName", func_RtlNtPathNameToDosPathName },
|
||||
{ "RtlpApplyLengthFunction", func_RtlpApplyLengthFunction },
|
||||
{ "RtlpEnsureBufferSize", func_RtlpEnsureBufferSize },
|
||||
{ "RtlQueryEnvironmentVariable", func_RtlQueryEnvironmentVariable },
|
||||
{ "RtlQueryEnvironmentVariable_U", func_RtlQueryEnvironmentVariable_U },
|
||||
{ "RtlQueryTimeZoneInformation", func_RtlQueryTimeZoneInformation },
|
||||
{ "RtlReAllocateHeap", func_RtlReAllocateHeap },
|
||||
{ "RtlRemovePrivileges", func_RtlRemovePrivileges },
|
||||
|
||||
Reference in New Issue
Block a user