mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:52:54 +00:00
[KMTESTS:IO]
- Add a test trying assorted path variations to open files CORE-10483 svn path=/trunk/; revision=69878
This commit is contained in:
parent
8160fdc383
commit
57dd4b34c7
1 changed files with 270 additions and 0 deletions
|
@ -9,6 +9,275 @@
|
||||||
|
|
||||||
/* FIXME: Test this stuff on non-FAT volumes */
|
/* 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
|
static
|
||||||
VOID
|
VOID
|
||||||
TestSharedCacheMap(VOID)
|
TestSharedCacheMap(VOID)
|
||||||
|
@ -174,5 +443,6 @@ Cleanup:
|
||||||
|
|
||||||
START_TEST(IoFilesystem)
|
START_TEST(IoFilesystem)
|
||||||
{
|
{
|
||||||
|
TestRelativeNames();
|
||||||
TestSharedCacheMap();
|
TestSharedCacheMap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue