Author: tfaber Date: Sun Jul 3 08:31:28 2016 New Revision: 71770
URL: http://svn.reactos.org/svn/reactos?rev=71770&view=rev Log: [KMTESTS:OB] - Add a test for ZwCreateSymbolicLinkObject/ZwQuerySymbolicLinkObject CORE-11509
Added: trunk/rostests/kmtests/ntos_ob/ObSymbolicLink.c (with props) Modified: trunk/rostests/kmtests/CMakeLists.txt
Modified: trunk/rostests/kmtests/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/CMakeLists.txt?rev... ============================================================================== --- trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] Sun Jul 3 08:31:28 2016 @@ -79,6 +79,7 @@ ntos_mm/ZwMapViewOfSection.c ntos_ob/ObHandle.c ntos_ob/ObReference.c + ntos_ob/ObSymbolicLink.c ntos_ob/ObType.c ntos_ob/ObTypes.c ntos_ob/ObWait.c
Added: trunk/rostests/kmtests/ntos_ob/ObSymbolicLink.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ob/ObSymbolic... ============================================================================== --- trunk/rostests/kmtests/ntos_ob/ObSymbolicLink.c (added) +++ trunk/rostests/kmtests/ntos_ob/ObSymbolicLink.c [iso-8859-1] Sun Jul 3 08:31:28 2016 @@ -0,0 +1,282 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Kernel-Mode Test for Zw*SymbolicLinkObject + * PROGRAMMER: Thomas Faber thomas.faber@reactos.org + */ + +#include <kmt_test.h> + +#define NDEBUG +#include <debug.h> + +static +VOID +TestQueryLink( + _In_ HANDLE LinkHandle, + _In_ PCUNICODE_STRING ExpectedTarget) +{ + NTSTATUS Status; + WCHAR QueriedTargetBuffer[32]; + UNICODE_STRING QueriedTarget; + ULONG ResultLength; + PULONG pResultLength; + ULONG i; + + for (i = 0; i < 2; i++) + { + if (i == 0) + { + pResultLength = &ResultLength; + } + else + { + pResultLength = NULL; + } + + /* Query with NULL Buffer just gives us the length */ + RtlInitEmptyUnicodeString(&QueriedTarget, NULL, 0); + if (pResultLength) ResultLength = 0x55555555; + Status = ZwQuerySymbolicLinkObject(LinkHandle, + &QueriedTarget, + pResultLength); + ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL); + ok_eq_uint(QueriedTarget.Length, 0); + ok_eq_uint(QueriedTarget.MaximumLength, 0); + ok_eq_pointer(QueriedTarget.Buffer, NULL); + if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); + + /* Query with Length-1 buffer */ + RtlInitEmptyUnicodeString(&QueriedTarget, + QueriedTargetBuffer, + ExpectedTarget->Length - 1); + RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); + if (pResultLength) ResultLength = 0x55555555; + Status = ZwQuerySymbolicLinkObject(LinkHandle, + &QueriedTarget, + pResultLength); + ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL); + ok_eq_uint(QueriedTarget.Length, 0); + ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length - 1); + ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); + ok_eq_uint(QueriedTarget.Buffer[0], 0x5555); + if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); + + /* Query with Length buffer */ + RtlInitEmptyUnicodeString(&QueriedTarget, + QueriedTargetBuffer, + ExpectedTarget->Length); + RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); + if (pResultLength) ResultLength = 0x55555555; + Status = ZwQuerySymbolicLinkObject(LinkHandle, + &QueriedTarget, + pResultLength); + ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length); + ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); + if (pResultLength && + QueriedTarget.MaximumLength < ExpectedTarget->MaximumLength) + { + ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL); + ok_eq_uint(QueriedTarget.Length, 0); + ok_eq_uint(QueriedTarget.Buffer[0], 0x5555); + if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); + } + else + { + ok_eq_hex(Status, STATUS_SUCCESS); + ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length); + ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget); + ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555); + } + + /* Query with Length+1 buffer */ + RtlInitEmptyUnicodeString(&QueriedTarget, + QueriedTargetBuffer, + ExpectedTarget->Length + 1); + RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); + if (pResultLength) ResultLength = 0x55555555; + Status = ZwQuerySymbolicLinkObject(LinkHandle, + &QueriedTarget, + pResultLength); + ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length + 1); + ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); + if (pResultLength && + QueriedTarget.MaximumLength < ExpectedTarget->MaximumLength) + { + ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL); + ok_eq_uint(QueriedTarget.Length, 0); + ok_eq_uint(QueriedTarget.Buffer[0], 0x5555); + if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); + } + else + { + ok_eq_hex(Status, STATUS_SUCCESS); + ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length); + ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget); + ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555); + } + + /* Query with Length+2 buffer */ + RtlInitEmptyUnicodeString(&QueriedTarget, + QueriedTargetBuffer, + ExpectedTarget->Length + sizeof(WCHAR)); + RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); + if (pResultLength) ResultLength = 0x55555555; + Status = ZwQuerySymbolicLinkObject(LinkHandle, + &QueriedTarget, + pResultLength); + ok_eq_hex(Status, STATUS_SUCCESS); + ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length); + ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length + sizeof(WCHAR)); + ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); + ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget); + if (pResultLength) + { + if (ExpectedTarget->MaximumLength >= ExpectedTarget->Length + sizeof(UNICODE_NULL)) + ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0); + ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); + } + else + { + ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555); + } + + /* Query with full-sized buffer */ + RtlInitEmptyUnicodeString(&QueriedTarget, + QueriedTargetBuffer, + sizeof(QueriedTargetBuffer)); + RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); + if (pResultLength) ResultLength = 0x55555555; + Status = ZwQuerySymbolicLinkObject(LinkHandle, + &QueriedTarget, + pResultLength); + ok_eq_hex(Status, STATUS_SUCCESS); + ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length); + ok_eq_uint(QueriedTarget.MaximumLength, sizeof(QueriedTargetBuffer)); + ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); + ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget); + if (pResultLength) + { + if (ExpectedTarget->MaximumLength >= ExpectedTarget->Length + sizeof(UNICODE_NULL)) + ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0); + ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); + } + else + { + ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555); + } + } +} + +START_TEST(ObSymbolicLink) +{ + NTSTATUS Status; + HANDLE LinkHandle; + HANDLE LinkHandle2; + UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\Device\ObSymbolicLinkKmtestNamedPipe"); + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING DefaultLinkTarget = RTL_CONSTANT_STRING(L"\Device\NamedPipe"); + UNICODE_STRING LinkTarget = DefaultLinkTarget; + + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, + NULL, + NULL); + LinkHandle = KmtInvalidPointer; + Status = ZwOpenSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes); + ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); + ok_eq_pointer(LinkHandle, NULL); + if (NT_SUCCESS(Status)) ObCloseHandle(LinkHandle, KernelMode); + + /* Create it */ + LinkHandle = KmtInvalidPointer; + Status = ZwCreateSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes, + &LinkTarget); + ok_eq_hex(Status, STATUS_SUCCESS); + ok(LinkHandle != NULL && LinkHandle != KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle); + if (skip(NT_SUCCESS(Status), "Failed to create link\n")) + { + return; + } + + /* Now we should be able to open it */ + LinkHandle2 = KmtInvalidPointer; + Status = ZwOpenSymbolicLinkObject(&LinkHandle2, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes); + ok_eq_hex(Status, STATUS_SUCCESS); + ok(LinkHandle2 != NULL && LinkHandle2 != KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle2); + if (!skip(NT_SUCCESS(Status), "Failed to open symlink\n")) + { + TestQueryLink(LinkHandle2, &LinkTarget); + ObCloseHandle(LinkHandle2, KernelMode); + } + + /* Close it */ + ObCloseHandle(LinkHandle, KernelMode); + + /* Open fails again */ + LinkHandle = KmtInvalidPointer; + Status = ZwOpenSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes); + ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); + ok_eq_pointer(LinkHandle, NULL); + if (NT_SUCCESS(Status)) ObCloseHandle(LinkHandle, KernelMode); + + /* Create with broken LinkTarget */ + LinkHandle = KmtInvalidPointer; + LinkTarget.Buffer = NULL; + Status = ZwCreateSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes, + &LinkTarget); + ok_eq_hex(Status, STATUS_ACCESS_VIOLATION); + ok(LinkHandle == KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle); + if (NT_SUCCESS(Status)) ObCloseHandle(LinkHandle, KernelMode); + + /* Since it failed, open should also fail */ + LinkHandle = KmtInvalidPointer; + Status = ZwOpenSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes); + ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); + ok_eq_pointer(LinkHandle, NULL); + if (NT_SUCCESS(Status)) ObCloseHandle(LinkHandle, KernelMode); + + /* Create with valid, but not null-terminated LinkTarget */ + LinkTarget = DefaultLinkTarget; + LinkTarget.MaximumLength = LinkTarget.Length; + LinkHandle = KmtInvalidPointer; + Status = ZwCreateSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes, + &LinkTarget); + ok_eq_hex(Status, STATUS_SUCCESS); + ok(LinkHandle != NULL && LinkHandle != KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle); + if (skip(NT_SUCCESS(Status), "Failed to create link\n")) + { + return; + } + + /* Now we should be able to open it */ + LinkHandle2 = KmtInvalidPointer; + Status = ZwOpenSymbolicLinkObject(&LinkHandle2, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes); + ok_eq_hex(Status, STATUS_SUCCESS); + ok(LinkHandle2 != NULL && LinkHandle2 != KmtInvalidPointer, "LinkHandle = %p\n", LinkHandle2); + if (!skip(NT_SUCCESS(Status), "Failed to open symlink\n")) + { + TestQueryLink(LinkHandle2, &LinkTarget); + ObCloseHandle(LinkHandle2, KernelMode); + } + + /* Close it */ + ObCloseHandle(LinkHandle, KernelMode); +}
Propchange: trunk/rostests/kmtests/ntos_ob/ObSymbolicLink.c ------------------------------------------------------------------------------ svn:eol-style = native