Author: tfaber
Date: Thu Nov 12 13:13:54 2015
New Revision: 69878
URL:
http://svn.reactos.org/svn/reactos?rev=69878&view=rev
Log:
[KMTESTS:IO]
- Add a test trying assorted path variations to open files
CORE-10483
Modified:
trunk/rostests/kmtests/ntos_io/IoFilesystem.c
Modified: trunk/rostests/kmtests/ntos_io/IoFilesystem.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoFilesys…
==============================================================================
--- trunk/rostests/kmtests/ntos_io/IoFilesystem.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_io/IoFilesystem.c [iso-8859-1] Thu Nov 12 13:13:54 2015
@@ -8,6 +8,275 @@
#include <kmt_test.h>
/* FIXME: Test this stuff on non-FAT volumes */
+
+static
+VOID
+Substitute(
+ _Out_writes_bytes_(BufferSize) PWCHAR Buffer,
+ _In_ ULONG BufferSize,
+ _In_ PCWSTR Template,
+ _In_ PCWSTR SystemDriveName,
+ _In_ PCWSTR SystemRootName)
+{
+ UNICODE_STRING SystemDriveTemplate = RTL_CONSTANT_STRING(L"C:");
+ UNICODE_STRING SystemRootTemplate = RTL_CONSTANT_STRING(L"ReactOS");
+ ULONG SystemDriveLength;
+ ULONG SystemRootLength;
+ PWCHAR Dest = Buffer;
+ UNICODE_STRING String;
+
+ SystemDriveLength = wcslen(SystemDriveName) * sizeof(WCHAR);
+ SystemRootLength = wcslen(SystemRootName) * sizeof(WCHAR);
+
+ RtlInitUnicodeString(&String, Template);
+ ASSERT(String.Length % sizeof(WCHAR) == 0);
+ while (String.Length)
+ {
+ if (RtlPrefixUnicodeString(&SystemDriveTemplate, &String, TRUE))
+ {
+ ASSERT((Dest - Buffer) * sizeof(WCHAR) + SystemDriveLength < BufferSize);
+ RtlCopyMemory(Dest,
+ SystemDriveName,
+ SystemDriveLength);
+ Dest += SystemDriveLength / sizeof(WCHAR);
+
+ String.Buffer += SystemDriveTemplate.Length / sizeof(WCHAR);
+ String.Length -= SystemDriveTemplate.Length;
+ String.MaximumLength -= SystemDriveTemplate.Length;
+ continue;
+ }
+
+ if (RtlPrefixUnicodeString(&SystemRootTemplate, &String, TRUE))
+ {
+ ASSERT((Dest - Buffer) * sizeof(WCHAR) + SystemRootLength < BufferSize);
+ RtlCopyMemory(Dest,
+ SystemRootName,
+ SystemRootLength);
+ Dest += SystemRootLength / sizeof(WCHAR);
+
+ String.Buffer += SystemRootTemplate.Length / sizeof(WCHAR);
+ String.Length -= SystemRootTemplate.Length;
+ String.MaximumLength -= SystemRootTemplate.Length;
+ continue;
+ }
+
+ ASSERT(Dest - Buffer < BufferSize / sizeof(WCHAR));
+ *Dest++ = String.Buffer[0];
+
+ String.Buffer++;
+ String.Length -= sizeof(WCHAR);
+ String.MaximumLength -= sizeof(WCHAR);
+ }
+ ASSERT(Dest - Buffer < BufferSize / sizeof(WCHAR));
+ *Dest = UNICODE_NULL;
+}
+
+static
+VOID
+TestRelativeNames(VOID)
+{
+ NTSTATUS Status;
+ struct
+ {
+ PCWSTR ParentPathTemplate;
+ PCWSTR RelativePathTemplate;
+ BOOLEAN IsDirectory;
+ NTSTATUS Status;
+ } Tests[] =
+ {
+ { NULL, L"C:\\",
TRUE, STATUS_SUCCESS },
+ { NULL, L"C:\\\\",
TRUE, STATUS_SUCCESS },
+ { NULL, L"C:\\\\\\",
TRUE, STATUS_OBJECT_NAME_INVALID },
+ { NULL, L"C:\\ReactOS",
TRUE, STATUS_SUCCESS },
+ { NULL, L"C:\\ReactOS\\",
TRUE, STATUS_SUCCESS },
+ { NULL, L"C:\\ReactOS\\\\",
TRUE, STATUS_SUCCESS },
+ { NULL, L"C:\\ReactOS\\\\\\",
TRUE, STATUS_OBJECT_NAME_INVALID },
+ { NULL, L"C:\\\\ReactOS",
TRUE, STATUS_SUCCESS },
+ { NULL, L"C:\\\\ReactOS\\",
TRUE, STATUS_SUCCESS },
+ { NULL, L"C:\\ReactOS\\explorer.exe",
FALSE, STATUS_SUCCESS },
+ { NULL, L"C:\\ReactOS\\\\explorer.exe",
FALSE, STATUS_OBJECT_NAME_INVALID },
+ { NULL, L"C:\\ReactOS\\explorer.exe\\",
FALSE, STATUS_OBJECT_NAME_INVALID },
+ { NULL, L"C:\\ReactOS\\explorer.exe\\\\",
FALSE, STATUS_OBJECT_NAME_INVALID },
+ /* This will never return STATUS_NOT_A_DIRECTORY. IsDirectory=TRUE is a little
hacky but achieves that without special handling */
+ { NULL, L"C:\\ReactOS\\explorer.exe\\\\\\",
TRUE, STATUS_OBJECT_NAME_INVALID },
+ { L"C:\\", L"",
TRUE, STATUS_SUCCESS },
+ { L"C:\\", L"\\",
TRUE, STATUS_OBJECT_NAME_INVALID },
+ { L"C:\\", L"ReactOS",
TRUE, STATUS_SUCCESS },
+ { L"C:\\", L"\\ReactOS",
TRUE, STATUS_OBJECT_NAME_INVALID },
+ { L"C:\\", L"ReactOS\\",
TRUE, STATUS_SUCCESS },
+ { L"C:\\", L"\\ReactOS\\",
TRUE, STATUS_OBJECT_NAME_INVALID },
+ { L"C:\\ReactOS", L"",
TRUE, STATUS_SUCCESS },
+ { L"C:\\ReactOS", L"explorer.exe",
FALSE, STATUS_SUCCESS },
+ { L"C:\\ReactOS\\explorer.exe", L"",
FALSE, STATUS_SUCCESS },
+ /* Let's try some nonexistent things */
+ { NULL, L"C:\\ReactOS\\IDoNotExist",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ { NULL, L"C:\\ReactOS\\IDoNotExist\\file",
FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
+ { NULL, L"C:\\ReactOS\\IDoNotExist\\file?",
FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
+ { NULL,
L"C:\\ReactOS\\IDoNotExist\\file\\\\",TRUE,STATUS_OBJECT_PATH_NOT_FOUND },
+ { NULL,
L"C:\\ReactOS\\IDoNotExist\\file\\\\\\",TRUE,STATUS_OBJECT_PATH_NOT_FOUND },
+ { NULL, L"C:\\ReactOS\\AmIInvalid?",
FALSE, STATUS_OBJECT_NAME_INVALID },
+ { NULL, L"C:\\ReactOS\\.",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ { NULL, L"C:\\ReactOS\\..",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ { NULL, L"C:\\ReactOS\\...",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ { L"C:\\", L".",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ { L"C:\\", L"..",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ { L"C:\\", L"...",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ { L"C:\\ReactOS", L".",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ { L"C:\\ReactOS", L"..",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ { L"C:\\ReactOS", L"...",
FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
+ };
+ ULONG i;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatus;
+ UNICODE_STRING ParentPath;
+ UNICODE_STRING RelativePath;
+ HANDLE ParentHandle;
+ HANDLE FileHandle;
+ UNICODE_STRING SystemRoot = RTL_CONSTANT_STRING(L"\\SystemRoot");
+ HANDLE SymbolicLinkHandle = NULL;
+ WCHAR LinkNameBuffer[128];
+ UNICODE_STRING SymbolicLinkName;
+ PWSTR SystemDriveName;
+ PWSTR SystemRootName;
+ PWCHAR Buffer = NULL;
+ BOOLEAN TrailingBackslash;
+
+ /* Query \SystemRoot */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SystemRoot,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = ZwOpenSymbolicLinkObject(&SymbolicLinkHandle,
+ GENERIC_READ,
+ &ObjectAttributes);
+ if (skip(NT_SUCCESS(Status), "Failed to open SystemRoot, %lx\n", Status))
+ return;
+
+ RtlInitEmptyUnicodeString(&SymbolicLinkName,
+ LinkNameBuffer,
+ sizeof(LinkNameBuffer));
+ Status = ZwQuerySymbolicLinkObject(SymbolicLinkHandle,
+ &SymbolicLinkName,
+ NULL);
+ ObCloseHandle(SymbolicLinkHandle, KernelMode);
+ if (skip(NT_SUCCESS(Status), "Failed to query SystemRoot, %lx\n", Status))
+ return;
+
+ /* Split SymbolicLinkName into drive and path */
+ SystemDriveName = SymbolicLinkName.Buffer;
+ SystemRootName = SymbolicLinkName.Buffer + SymbolicLinkName.Length / sizeof(WCHAR);
+ *SystemRootName-- = UNICODE_NULL;
+ while (*SystemRootName != L'\\')
+ {
+ ASSERT(SystemRootName > SymbolicLinkName.Buffer);
+ SystemRootName--;
+ }
+ *SystemRootName++ = UNICODE_NULL;
+ trace("System Drive: '%ls'\n", SystemDriveName);
+ trace("System Root: '%ls'\n", SystemRootName);
+
+ /* Allocate path buffer */
+ Buffer = ExAllocatePoolWithTag(PagedPool, MAXUSHORT, 'sFmK');
+ if (skip(Buffer != NULL, "No buffer\n"))
+ return;
+
+ /* Finally run some tests! */
+ for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
+ {
+ /* Open parent directory first */
+ ParentHandle = NULL;
+ if (Tests[i].ParentPathTemplate)
+ {
+ Substitute(Buffer,
+ MAXUSHORT,
+ Tests[i].ParentPathTemplate,
+ SystemDriveName,
+ SystemRootName);
+ RtlInitUnicodeString(&ParentPath, Buffer);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ParentPath,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = ZwOpenFile(&ParentHandle,
+ GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatus,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ 0);
+ ok(Status == STATUS_SUCCESS,
+ "[%lu] Status = %lx, expected STATUS_SUCCESS\n", i, Status);
+ if (skip(NT_SUCCESS(Status), "No parent handle %lu\n", i))
+ continue;
+ }
+
+ /* Now open the relative file: */
+ Substitute(Buffer,
+ MAXUSHORT,
+ Tests[i].RelativePathTemplate,
+ SystemDriveName,
+ SystemRootName);
+ RtlInitUnicodeString(&RelativePath, Buffer);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &RelativePath,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ ParentHandle,
+ NULL);
+ TrailingBackslash = FALSE;
+ if (wcslen(Buffer) && Buffer[wcslen(Buffer) - 1] == L'\\')
+ TrailingBackslash = TRUE;
+
+ /* (1) No flags */
+ Status = ZwOpenFile(&FileHandle,
+ GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatus,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ 0);
+ ok(Status == Tests[i].Status,
+ "[%lu] Status = %lx, expected %lx\n", i, Status, Tests[i].Status);
+ if (NT_SUCCESS(Status))
+ ObCloseHandle(FileHandle, KernelMode);
+
+ /* (2) Directory File */
+ Status = ZwOpenFile(&FileHandle,
+ GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatus,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_DIRECTORY_FILE);
+ if (Tests[i].IsDirectory || (!TrailingBackslash &&
!NT_SUCCESS(Tests[i].Status)))
+ ok(Status == Tests[i].Status,
+ "[%lu] Status = %lx, expected %lx\n", i, Status,
Tests[i].Status);
+ else
+ ok(Status == STATUS_NOT_A_DIRECTORY,
+ "[%lu] Status = %lx, expected STATUS_NOT_A_DIRECTORY\n", i,
Status);
+ if (NT_SUCCESS(Status))
+ ObCloseHandle(FileHandle, KernelMode);
+
+ /* (3) Non-Directory File */
+ Status = ZwOpenFile(&FileHandle,
+ GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatus,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_NON_DIRECTORY_FILE);
+ if (Tests[i].IsDirectory && NT_SUCCESS(Tests[i].Status))
+ ok(Status == STATUS_FILE_IS_A_DIRECTORY,
+ "[%lu] Status = %lx, expected STATUS_FILE_IS_A_DIRECTORY\n", i,
Status);
+ else
+ ok(Status == Tests[i].Status,
+ "[%lu] Status = %lx, expected %lx\n", i, Status,
Tests[i].Status);
+ if (NT_SUCCESS(Status))
+ ObCloseHandle(FileHandle, KernelMode);
+
+ /* And close */
+ ObCloseHandle(ParentHandle, KernelMode);
+ }
+
+ ExFreePoolWithTag(Buffer, 'sFmK');
+}
static
VOID
@@ -174,5 +443,6 @@
START_TEST(IoFilesystem)
{
+ TestRelativeNames();
TestSharedCacheMap();
}