ReactOS  0.4.14-dev-293-g2b39b42
ObSymbolicLink.c File Reference
#include <kmt_test.h>
#include <debug.h>
Include dependency graph for ObSymbolicLink.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static VOID TestQueryLink (_In_ HANDLE LinkHandle, _In_ PCUNICODE_STRING ExpectedTarget)
 
 START_TEST (ObSymbolicLink)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file ObSymbolicLink.c.

Function Documentation

◆ START_TEST()

START_TEST ( ObSymbolicLink  )

Definition at line 171 of file ObSymbolicLink.c.

172 {
174  HANDLE LinkHandle;
175  HANDLE LinkHandle2;
176  UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\Device\\ObSymbolicLinkKmtestNamedPipe");
178  UNICODE_STRING DefaultLinkTarget = RTL_CONSTANT_STRING(L"\\Device\\NamedPipe");
179  UNICODE_STRING LinkTarget = DefaultLinkTarget;
180 
182  &LinkName,
184  NULL,
185  NULL);
186  LinkHandle = KmtInvalidPointer;
187  Status = ZwOpenSymbolicLinkObject(&LinkHandle,
191  ok_eq_pointer(LinkHandle, NULL);
192  if (NT_SUCCESS(Status)) ObCloseHandle(LinkHandle, KernelMode);
193 
194  /* Create it */
195  LinkHandle = KmtInvalidPointer;
196  Status = ZwCreateSymbolicLinkObject(&LinkHandle,
199  &LinkTarget);
201  ok(LinkHandle != NULL && LinkHandle != KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle);
202  if (skip(NT_SUCCESS(Status), "Failed to create link\n"))
203  {
204  return;
205  }
206 
207  /* Now we should be able to open it */
208  LinkHandle2 = KmtInvalidPointer;
209  Status = ZwOpenSymbolicLinkObject(&LinkHandle2,
213  ok(LinkHandle2 != NULL && LinkHandle2 != KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle2);
214  if (!skip(NT_SUCCESS(Status), "Failed to open symlink\n"))
215  {
216  TestQueryLink(LinkHandle2, &LinkTarget);
217  ObCloseHandle(LinkHandle2, KernelMode);
218  }
219 
220  /* Close it */
221  ObCloseHandle(LinkHandle, KernelMode);
222 
223  /* Open fails again */
224  LinkHandle = KmtInvalidPointer;
225  Status = ZwOpenSymbolicLinkObject(&LinkHandle,
229  ok_eq_pointer(LinkHandle, NULL);
230  if (NT_SUCCESS(Status)) ObCloseHandle(LinkHandle, KernelMode);
231 
232  /* Create with broken LinkTarget */
233  LinkHandle = KmtInvalidPointer;
235  Status = ZwCreateSymbolicLinkObject(&LinkHandle,
238  &LinkTarget);
240  ok(LinkHandle == KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle);
241  if (NT_SUCCESS(Status)) ObCloseHandle(LinkHandle, KernelMode);
242 
243  /* Since it failed, open should also fail */
244  LinkHandle = KmtInvalidPointer;
245  Status = ZwOpenSymbolicLinkObject(&LinkHandle,
249  ok_eq_pointer(LinkHandle, NULL);
250  if (NT_SUCCESS(Status)) ObCloseHandle(LinkHandle, KernelMode);
251 
252  /* Create with valid, but not null-terminated LinkTarget */
253  LinkTarget = DefaultLinkTarget;
255  LinkHandle = KmtInvalidPointer;
256  Status = ZwCreateSymbolicLinkObject(&LinkHandle,
259  &LinkTarget);
261  ok(LinkHandle != NULL && LinkHandle != KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle);
262  if (skip(NT_SUCCESS(Status), "Failed to create link\n"))
263  {
264  return;
265  }
266 
267  /* Now we should be able to open it */
268  LinkHandle2 = KmtInvalidPointer;
269  Status = ZwOpenSymbolicLinkObject(&LinkHandle2,
273  ok(LinkHandle2 != NULL && LinkHandle2 != KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle2);
274  if (!skip(NT_SUCCESS(Status), "Failed to open symlink\n"))
275  {
276  TestQueryLink(LinkHandle2, &LinkTarget);
277  ObCloseHandle(LinkHandle2, KernelMode);
278  }
279 
280  /* Close it */
281  ObCloseHandle(LinkHandle, KernelMode);
282 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define KmtInvalidPointer
Definition: kmt_test.h:275
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define ok_eq_pointer(value, expected)
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS NTAPI ZwCreateSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ PUNICODE_STRING Name)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ok_eq_hex(value, expected)
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

◆ TestQueryLink()

static VOID TestQueryLink ( _In_ HANDLE  LinkHandle,
_In_ PCUNICODE_STRING  ExpectedTarget 
)
static

Definition at line 15 of file ObSymbolicLink.c.

18 {
20  WCHAR QueriedTargetBuffer[32];
21  UNICODE_STRING QueriedTarget;
23  PULONG pResultLength;
24  ULONG i;
25 
26  for (i = 0; i < 2; i++)
27  {
28  if (i == 0)
29  {
30  pResultLength = &ResultLength;
31  }
32  else
33  {
34  pResultLength = NULL;
35  }
36 
37  /* Query with NULL Buffer just gives us the length */
38  RtlInitEmptyUnicodeString(&QueriedTarget, NULL, 0);
39  if (pResultLength) ResultLength = 0x55555555;
40  Status = ZwQuerySymbolicLinkObject(LinkHandle,
41  &QueriedTarget,
42  pResultLength);
44  ok_eq_uint(QueriedTarget.Length, 0);
45  ok_eq_uint(QueriedTarget.MaximumLength, 0);
46  ok_eq_pointer(QueriedTarget.Buffer, NULL);
47  if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
48 
49  /* Query with Length-1 buffer */
50  RtlInitEmptyUnicodeString(&QueriedTarget,
51  QueriedTargetBuffer,
52  ExpectedTarget->Length - 1);
53  RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
54  if (pResultLength) ResultLength = 0x55555555;
55  Status = ZwQuerySymbolicLinkObject(LinkHandle,
56  &QueriedTarget,
57  pResultLength);
59  ok_eq_uint(QueriedTarget.Length, 0);
60  ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length - 1);
61  ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
62  ok_eq_uint(QueriedTarget.Buffer[0], 0x5555);
63  if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
64 
65  /* Query with Length buffer */
66  RtlInitEmptyUnicodeString(&QueriedTarget,
67  QueriedTargetBuffer,
68  ExpectedTarget->Length);
69  RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
70  if (pResultLength) ResultLength = 0x55555555;
71  Status = ZwQuerySymbolicLinkObject(LinkHandle,
72  &QueriedTarget,
73  pResultLength);
74  ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length);
75  ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
76  if (pResultLength &&
77  QueriedTarget.MaximumLength < ExpectedTarget->MaximumLength)
78  {
80  ok_eq_uint(QueriedTarget.Length, 0);
81  ok_eq_uint(QueriedTarget.Buffer[0], 0x5555);
82  if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
83  }
84  else
85  {
87  ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length);
88  ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget);
89  ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555);
90  }
91 
92  /* Query with Length+1 buffer */
93  RtlInitEmptyUnicodeString(&QueriedTarget,
94  QueriedTargetBuffer,
95  ExpectedTarget->Length + 1);
96  RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
97  if (pResultLength) ResultLength = 0x55555555;
98  Status = ZwQuerySymbolicLinkObject(LinkHandle,
99  &QueriedTarget,
100  pResultLength);
101  ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length + 1);
102  ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
103  if (pResultLength &&
104  QueriedTarget.MaximumLength < ExpectedTarget->MaximumLength)
105  {
107  ok_eq_uint(QueriedTarget.Length, 0);
108  ok_eq_uint(QueriedTarget.Buffer[0], 0x5555);
109  if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
110  }
111  else
112  {
114  ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length);
115  ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget);
116  ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555);
117  }
118 
119  /* Query with Length+2 buffer */
120  RtlInitEmptyUnicodeString(&QueriedTarget,
121  QueriedTargetBuffer,
122  ExpectedTarget->Length + sizeof(WCHAR));
123  RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
124  if (pResultLength) ResultLength = 0x55555555;
125  Status = ZwQuerySymbolicLinkObject(LinkHandle,
126  &QueriedTarget,
127  pResultLength);
129  ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length);
130  ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length + sizeof(WCHAR));
131  ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
132  ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget);
133  if (pResultLength)
134  {
135  if (ExpectedTarget->MaximumLength >= ExpectedTarget->Length + sizeof(UNICODE_NULL))
136  ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0);
137  ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
138  }
139  else
140  {
141  ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555);
142  }
143 
144  /* Query with full-sized buffer */
145  RtlInitEmptyUnicodeString(&QueriedTarget,
146  QueriedTargetBuffer,
147  sizeof(QueriedTargetBuffer));
148  RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
149  if (pResultLength) ResultLength = 0x55555555;
150  Status = ZwQuerySymbolicLinkObject(LinkHandle,
151  &QueriedTarget,
152  pResultLength);
154  ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length);
155  ok_eq_uint(QueriedTarget.MaximumLength, sizeof(QueriedTargetBuffer));
156  ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
157  ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget);
158  if (pResultLength)
159  {
160  if (ExpectedTarget->MaximumLength >= ExpectedTarget->Length + sizeof(UNICODE_NULL))
161  ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0);
162  ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
163  }
164  else
165  {
166  ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555);
167  }
168  }
169 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define ok_eq_ulong(value, expected)
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define ok_eq_pointer(value, expected)
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
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
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
Status
Definition: gdiplustypes.h:24
#define ok(value,...)
Definition: atltest.h:57
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define ok_eq_hex(value, expected)
#define ok_eq_uint(value, expected)
Definition: kmt_test.h:239
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)

Referenced by START_TEST().