2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test for Zw*SymbolicLinkObject
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
16 _In_ HANDLE LinkHandle
,
17 _In_ PCUNICODE_STRING ExpectedTarget
)
20 WCHAR QueriedTargetBuffer
[32];
21 UNICODE_STRING QueriedTarget
;
26 for (i
= 0; i
< 2; i
++)
30 pResultLength
= &ResultLength
;
37 /* Query with NULL Buffer just gives us the length */
38 RtlInitEmptyUnicodeString(&QueriedTarget
, NULL
, 0);
39 if (pResultLength
) ResultLength
= 0x55555555;
40 Status
= ZwQuerySymbolicLinkObject(LinkHandle
,
43 ok_eq_hex(Status
, STATUS_BUFFER_TOO_SMALL
);
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
);
49 /* Query with Length-1 buffer */
50 RtlInitEmptyUnicodeString(&QueriedTarget
,
52 ExpectedTarget
->Length
- 1);
53 RtlFillMemory(&QueriedTargetBuffer
, sizeof(QueriedTargetBuffer
), 0x55);
54 if (pResultLength
) ResultLength
= 0x55555555;
55 Status
= ZwQuerySymbolicLinkObject(LinkHandle
,
58 ok_eq_hex(Status
, STATUS_BUFFER_TOO_SMALL
);
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
);
65 /* Query with Length buffer */
66 RtlInitEmptyUnicodeString(&QueriedTarget
,
68 ExpectedTarget
->Length
);
69 RtlFillMemory(&QueriedTargetBuffer
, sizeof(QueriedTargetBuffer
), 0x55);
70 if (pResultLength
) ResultLength
= 0x55555555;
71 Status
= ZwQuerySymbolicLinkObject(LinkHandle
,
74 ok_eq_uint(QueriedTarget
.MaximumLength
, ExpectedTarget
->Length
);
75 ok_eq_pointer(QueriedTarget
.Buffer
, QueriedTargetBuffer
);
77 QueriedTarget
.MaximumLength
< ExpectedTarget
->MaximumLength
)
79 ok_eq_hex(Status
, STATUS_BUFFER_TOO_SMALL
);
80 ok_eq_uint(QueriedTarget
.Length
, 0);
81 ok_eq_uint(QueriedTarget
.Buffer
[0], 0x5555);
82 if (pResultLength
) ok_eq_ulong(ResultLength
, ExpectedTarget
->MaximumLength
);
86 ok_eq_hex(Status
, STATUS_SUCCESS
);
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);
92 /* Query with Length+1 buffer */
93 RtlInitEmptyUnicodeString(&QueriedTarget
,
95 ExpectedTarget
->Length
+ 1);
96 RtlFillMemory(&QueriedTargetBuffer
, sizeof(QueriedTargetBuffer
), 0x55);
97 if (pResultLength
) ResultLength
= 0x55555555;
98 Status
= ZwQuerySymbolicLinkObject(LinkHandle
,
101 ok_eq_uint(QueriedTarget
.MaximumLength
, ExpectedTarget
->Length
+ 1);
102 ok_eq_pointer(QueriedTarget
.Buffer
, QueriedTargetBuffer
);
104 QueriedTarget
.MaximumLength
< ExpectedTarget
->MaximumLength
)
106 ok_eq_hex(Status
, STATUS_BUFFER_TOO_SMALL
);
107 ok_eq_uint(QueriedTarget
.Length
, 0);
108 ok_eq_uint(QueriedTarget
.Buffer
[0], 0x5555);
109 if (pResultLength
) ok_eq_ulong(ResultLength
, ExpectedTarget
->MaximumLength
);
113 ok_eq_hex(Status
, STATUS_SUCCESS
);
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);
119 /* Query with Length+2 buffer */
120 RtlInitEmptyUnicodeString(&QueriedTarget
,
122 ExpectedTarget
->Length
+ sizeof(WCHAR
));
123 RtlFillMemory(&QueriedTargetBuffer
, sizeof(QueriedTargetBuffer
), 0x55);
124 if (pResultLength
) ResultLength
= 0x55555555;
125 Status
= ZwQuerySymbolicLinkObject(LinkHandle
,
128 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
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
);
141 ok_eq_uint(QueriedTarget
.Buffer
[QueriedTarget
.Length
/ sizeof(WCHAR
)], 0x5555);
144 /* Query with full-sized buffer */
145 RtlInitEmptyUnicodeString(&QueriedTarget
,
147 sizeof(QueriedTargetBuffer
));
148 RtlFillMemory(&QueriedTargetBuffer
, sizeof(QueriedTargetBuffer
), 0x55);
149 if (pResultLength
) ResultLength
= 0x55555555;
150 Status
= ZwQuerySymbolicLinkObject(LinkHandle
,
153 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
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
);
166 ok_eq_uint(QueriedTarget
.Buffer
[QueriedTarget
.Length
/ sizeof(WCHAR
)], 0x5555);
171 START_TEST(ObSymbolicLink
)
176 UNICODE_STRING LinkName
= RTL_CONSTANT_STRING(L
"\\Device\\ObSymbolicLinkKmtestNamedPipe");
177 OBJECT_ATTRIBUTES ObjectAttributes
;
178 UNICODE_STRING DefaultLinkTarget
= RTL_CONSTANT_STRING(L
"\\Device\\NamedPipe");
179 UNICODE_STRING LinkTarget
= DefaultLinkTarget
;
181 InitializeObjectAttributes(&ObjectAttributes
,
183 OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
,
186 LinkHandle
= KmtInvalidPointer
;
187 Status
= ZwOpenSymbolicLinkObject(&LinkHandle
,
190 ok_eq_hex(Status
, STATUS_OBJECT_NAME_NOT_FOUND
);
191 ok_eq_pointer(LinkHandle
, NULL
);
192 if (NT_SUCCESS(Status
)) ObCloseHandle(LinkHandle
, KernelMode
);
195 LinkHandle
= KmtInvalidPointer
;
196 Status
= ZwCreateSymbolicLinkObject(&LinkHandle
,
200 ok_eq_hex(Status
, STATUS_SUCCESS
);
201 ok(LinkHandle
!= NULL
&& LinkHandle
!= KmtInvalidPointer
, "LinkHandle = %p\n", LinkHandle
);
202 if (skip(NT_SUCCESS(Status
), "Failed to create link\n"))
207 /* Now we should be able to open it */
208 LinkHandle2
= KmtInvalidPointer
;
209 Status
= ZwOpenSymbolicLinkObject(&LinkHandle2
,
212 ok_eq_hex(Status
, STATUS_SUCCESS
);
213 ok(LinkHandle2
!= NULL
&& LinkHandle2
!= KmtInvalidPointer
, "LinkHandle = %p\n", LinkHandle2
);
214 if (!skip(NT_SUCCESS(Status
), "Failed to open symlink\n"))
216 TestQueryLink(LinkHandle2
, &LinkTarget
);
217 ObCloseHandle(LinkHandle2
, KernelMode
);
221 ObCloseHandle(LinkHandle
, KernelMode
);
223 /* Open fails again */
224 LinkHandle
= KmtInvalidPointer
;
225 Status
= ZwOpenSymbolicLinkObject(&LinkHandle
,
228 ok_eq_hex(Status
, STATUS_OBJECT_NAME_NOT_FOUND
);
229 ok_eq_pointer(LinkHandle
, NULL
);
230 if (NT_SUCCESS(Status
)) ObCloseHandle(LinkHandle
, KernelMode
);
232 /* Create with broken LinkTarget */
233 LinkHandle
= KmtInvalidPointer
;
234 LinkTarget
.Buffer
= NULL
;
235 Status
= ZwCreateSymbolicLinkObject(&LinkHandle
,
239 ok_eq_hex(Status
, STATUS_ACCESS_VIOLATION
);
240 ok(LinkHandle
== KmtInvalidPointer
, "LinkHandle = %p\n", LinkHandle
);
241 if (NT_SUCCESS(Status
)) ObCloseHandle(LinkHandle
, KernelMode
);
243 /* Since it failed, open should also fail */
244 LinkHandle
= KmtInvalidPointer
;
245 Status
= ZwOpenSymbolicLinkObject(&LinkHandle
,
248 ok_eq_hex(Status
, STATUS_OBJECT_NAME_NOT_FOUND
);
249 ok_eq_pointer(LinkHandle
, NULL
);
250 if (NT_SUCCESS(Status
)) ObCloseHandle(LinkHandle
, KernelMode
);
252 /* Create with valid, but not null-terminated LinkTarget */
253 LinkTarget
= DefaultLinkTarget
;
254 LinkTarget
.MaximumLength
= LinkTarget
.Length
;
255 LinkHandle
= KmtInvalidPointer
;
256 Status
= ZwCreateSymbolicLinkObject(&LinkHandle
,
260 ok_eq_hex(Status
, STATUS_SUCCESS
);
261 ok(LinkHandle
!= NULL
&& LinkHandle
!= KmtInvalidPointer
, "LinkHandle = %p\n", LinkHandle
);
262 if (skip(NT_SUCCESS(Status
), "Failed to create link\n"))
267 /* Now we should be able to open it */
268 LinkHandle2
= KmtInvalidPointer
;
269 Status
= ZwOpenSymbolicLinkObject(&LinkHandle2
,
272 ok_eq_hex(Status
, STATUS_SUCCESS
);
273 ok(LinkHandle2
!= NULL
&& LinkHandle2
!= KmtInvalidPointer
, "LinkHandle = %p\n", LinkHandle2
);
274 if (!skip(NT_SUCCESS(Status
), "Failed to open symlink\n"))
276 TestQueryLink(LinkHandle2
, &LinkTarget
);
277 ObCloseHandle(LinkHandle2
, KernelMode
);
281 ObCloseHandle(LinkHandle
, KernelMode
);