ReactOS  0.4.13-dev-249-gcba1a2f
RtlRegistry.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS kernel-mode tests
3  * LICENSE: GPLv2+ - See COPYING in the top level directory
4  * PURPOSE: Test for RtlQueryRegistryValues
5  * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #define KMT_EMULATE_KERNEL
9 #include <kmt_test.h>
10 
11 #ifndef RTL_NUMBER_OF
12 #define RTL_NUMBER_OF(x) (sizeof(x) / sizeof(x[0]))
13 #endif
14 
15 typedef struct
16 {
22 
23 typedef struct
24 {
27  EXPECTED_VALUE Values[20];
29 
30 //static RTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
31 static
33 NTAPI
41 {
42  PEXPECTED_VALUES ExpectedValues = Context;
44  SIZE_T EqualBytes;
45 
46  ok(ExpectedValues->CurrentIndex < ExpectedValues->Count,
47  "Call number %lu, expected only %lu\n",
48  ExpectedValues->CurrentIndex, ExpectedValues->Count);
49  if (!skip(ExpectedValues->CurrentIndex < ExpectedValues->Count, "Out of bounds\n"))
50  {
51  Expected = &ExpectedValues->Values[ExpectedValues->CurrentIndex];
52  if (EntryContext)
54  ok_eq_wstr(ValueName, Expected->ValueName);
55  ok_eq_ulong(ValueType, Expected->ValueType);
56  ok_eq_ulong(ValueLength, Expected->ValueLength);
57  EqualBytes = RtlCompareMemory(ValueData,
58  Expected->ValueData,
59  min(ValueLength, Expected->ValueLength));
60  ok_eq_size(EqualBytes, Expected->ValueLength);
61  }
62 
63  ExpectedValues->CurrentIndex++;
64  return STATUS_SUCCESS;
65 }
66 
67 static
68 VOID
71 {
75  {
76  { QueryRoutine, 0, L"TestValue", NULL, REG_NONE, NULL, 0 },
77  { NULL }
78  };
80  typedef struct
81  {
82  PWSTR Str;
83  ULONG Len;
84  } STR_AND_LEN;
85 #define CONST_STR_AND_LEN(d) { (d), sizeof(d) }
86 #define CSAL CONST_STR_AND_LEN
87 
88 #define NO_AUTO_LEN 1
89 #define NO_DEFAULT 2
90 #define AUTO_DIFFERS 4
91 #define DEFAULT_DIFFERS 8
92  struct
93  {
94  STR_AND_LEN Value;
95  ULONG ExpectedCount;
96  STR_AND_LEN Expected[20];
97  ULONG Flags;
98  ULONG DefaultExpectedCount;
99  STR_AND_LEN DefaultExpected[20];
100 
101  } Tests[] =
102  {
103  { { NULL, 0 }, 0, { { NULL, 0 } }, NO_AUTO_LEN | NO_DEFAULT },
104  { CSAL(L""), 0, { { NULL, 0 } }, NO_AUTO_LEN },
105  { CSAL(L"\0"), 1, { CSAL(L"") },
106  AUTO_DIFFERS | DEFAULT_DIFFERS, 0, { { NULL, 0 } } },
107  { CSAL(L"String"), 1, { CSAL(L"String") }, NO_AUTO_LEN },
108  { CSAL(L"String\0"), 1, { CSAL(L"String") } },
109  { CSAL(L"String1\0String2"), 2, { CSAL(L"String1"), CSAL(L"String2") }, NO_AUTO_LEN },
110  { CSAL(L"String1\0String2\0"), 2, { CSAL(L"String1"), CSAL(L"String2") } },
111  { CSAL(L"String1\0\0String3"), 3, { CSAL(L"String1"), CSAL(L""), CSAL(L"String3") }, NO_AUTO_LEN },
112  { CSAL(L"String1\0\0String3\0"), 3, { CSAL(L"String1"), CSAL(L""), CSAL(L"String3") },
113  AUTO_DIFFERS, 1, { CSAL(L"String1") } },
114  };
115 
116 #define DO_QUERY(ExpectedArray, ExpectedCount) do \
117  { \
118  ULONG _i; \
119  ULONG _ExpectedCount = (ExpectedCount); \
120  for (_i = 0; _i < _ExpectedCount; _i++) \
121  { \
122  Expected.Values[_i].ValueName = ValueName.Buffer; \
123  Expected.Values[_i].ValueType = REG_SZ; \
124  Expected.Values[_i].ValueData = (ExpectedArray)[_i].Str; \
125  Expected.Values[_i].ValueLength = (ExpectedArray)[_i].Len; \
126  } \
127  Expected.CurrentIndex = 0; \
128  Expected.Count = _ExpectedCount; \
129  if (_ExpectedCount == 1) \
130  QueryTable[0].EntryContext = &Expected.Values[0]; \
131  else \
132  QueryTable[0].EntryContext = NULL; \
133  Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, \
134  (PCWSTR)KeyHandle, \
135  QueryTable, \
136  &Expected, \
137  NULL); \
138  ok_eq_hex(Status, STATUS_SUCCESS); \
139  ok_eq_ulong(Expected.CurrentIndex, Expected.Count); \
140  } while(0)
141 
142  ULONG TestCount = RTL_NUMBER_OF(Tests);
143  ULONG i;
144 
145  for (i = 0; i < TestCount; i++)
146  {
147  trace("Set: %lu\n", i);
148  Status = ZwSetValueKey(KeyHandle,
149  &ValueName,
150  0,
151  REG_MULTI_SZ,
152  Tests[i].Value.Str,
153  Tests[i].Value.Len);
155 
156  DO_QUERY(Tests[i].Expected, Tests[i].ExpectedCount);
157  }
158 
159  /* Delete value to test default values */
160  Status = ZwDeleteValueKey(KeyHandle, &ValueName);
162  "ZwDeleteValueKey returned %lx\n", Status);
163 
164  /* Default: REG_NONE */
165  DO_QUERY((STR_AND_LEN *)NULL, 0);
166 
167  for (i = 0; i < TestCount; i++)
168  {
169  if (Tests[i].Flags & NO_DEFAULT)
170  continue;
171  trace("Default: %lu\n", i);
173  QueryTable[0].DefaultData = Tests[i].Value.Str;
174  QueryTable[0].DefaultLength = Tests[i].Value.Len;
175 
176  if (Tests[i].Flags & DEFAULT_DIFFERS)
177  DO_QUERY(Tests[i].DefaultExpected, Tests[i].DefaultExpectedCount);
178  else
179  DO_QUERY(Tests[i].Expected, Tests[i].ExpectedCount);
180  }
181 
182  for (i = 0; i < TestCount; i++)
183  {
184  if (Tests[i].Flags & NO_AUTO_LEN)
185  continue;
186  trace("Auto: %lu\n", i);
188  QueryTable[0].DefaultData = Tests[i].Value.Str;
189  QueryTable[0].DefaultLength = 0;
190 
191  if (Tests[i].Flags & AUTO_DIFFERS)
192  DO_QUERY(Tests[i].DefaultExpected, Tests[i].DefaultExpectedCount);
193  else
194  DO_QUERY(Tests[i].Expected, Tests[i].ExpectedCount);
195  }
196 }
197 
198 START_TEST(RtlRegistry)
199 {
203  HANDLE SoftwareHandle;
205 
206  RtlInitUnicodeString(&KeyName, L"\\Registry\\MACHINE\\Software");
208  &KeyName,
210  NULL,
211  NULL);
212  Status = ZwOpenKey(&SoftwareHandle,
216  if (skip(NT_SUCCESS(Status) && SoftwareHandle != NULL, "No software key\n"))
217  return;
218 
219  RtlInitUnicodeString(&KeyName, L"RtlRegistryKmtestKey");
221  &KeyName,
223  SoftwareHandle,
224  NULL);
225  Status = ZwCreateKey(&KeyHandle,
228  0,
229  NULL,
231  NULL);
233 
234  if (!skip(NT_SUCCESS(Status) && KeyHandle != NULL, "No test key\n"))
235  {
237 
238  Status = ZwDeleteKey(KeyHandle);
242  }
243 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define ok_eq_ulong(value, expected)
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define trace(...)
Definition: kmt_test.h:217
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
struct EXPECTED_VALUE * PEXPECTED_VALUE
EXPECTED_VALUE Values[20]
Definition: RtlRegistry.c:27
#define KEY_SET_VALUE
Definition: nt_native.h:1017
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define ok_eq_wstr(value, expected)
Definition: kmt_test.h:262
#define ok_eq_size(value, expected)
Definition: kmt_test.h:247
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
PCWSTR ValueName
Definition: RtlRegistry.c:17
#define ok_eq_pointer(value, expected)
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4000
LONG NTSTATUS
Definition: precomp.h:26
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define ok(value,...)
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:3988
smooth NULL
Definition: ftsmooth.c:416
ULONG CurrentIndex
Definition: RtlRegistry.c:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DEFAULT_DIFFERS
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
#define Len
Definition: deflate.h:82
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define NO_AUTO_LEN
#define AUTO_DIFFERS
static const WCHAR L[]
Definition: oid.c:1250
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
static VOID TestRtlQueryRegistryValues(_In_ HANDLE KeyHandle)
Definition: RtlRegistry.c:69
#define DO_QUERY(ExpectedArray, ExpectedCount)
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define min(a, b)
Definition: monoChain.cc:55
static NTSTATUS NTAPI QueryRoutine(_In_ PWSTR ValueName, _In_ ULONG ValueType, _In_ PVOID ValueData, _In_ ULONG ValueLength, _In_ PVOID Context, _In_ PVOID EntryContext)
Definition: RtlRegistry.c:34
#define skip(...)
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NO_DEFAULT
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG ValueLength
Definition: RtlRegistry.c:20
struct EXPECTED_VALUES * PEXPECTED_VALUES
#define ok_eq_hex(value, expected)
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define REG_NONE
Definition: nt_native.h:1492
BOOLEAN Expected
START_TEST(RtlRegistry)
Definition: RtlRegistry.c:198
#define CSAL
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
struct test_data Tests[]
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define DELETE
Definition: nt_native.h:57
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14