mirror of
https://github.com/reactos/reactos.git
synced 2025-05-28 13:38:19 +00:00
[NTDLL_APITEST]
- Add a test for NtReadFile, also covering buffer size too large for an MDL CORE-12132 svn path=/trunk/; revision=73071
This commit is contained in:
parent
0a11d5e9a2
commit
a51ac2be8c
3 changed files with 252 additions and 0 deletions
|
@ -18,6 +18,7 @@ list(APPEND SOURCE
|
|||
NtQueryKey.c
|
||||
NtQuerySystemEnvironmentValue.c
|
||||
NtQueryVolumeInformationFile.c
|
||||
NtReadFile.c
|
||||
NtSaveKey.c
|
||||
NtSetValueKey.c
|
||||
NtWriteFile.c
|
||||
|
|
249
rostests/apitests/ntdll/NtReadFile.c
Normal file
249
rostests/apitests/ntdll/NtReadFile.c
Normal file
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
||||
* PURPOSE: Test for NtReadFile
|
||||
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <winreg.h>
|
||||
#include <ndk/cmfuncs.h>
|
||||
#include <ndk/iofuncs.h>
|
||||
#include <ndk/mmfuncs.h>
|
||||
#include <ndk/obfuncs.h>
|
||||
#include <ndk/psfuncs.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
||||
static
|
||||
BOOL
|
||||
Is64BitSystem(VOID)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
return TRUE;
|
||||
#else
|
||||
NTSTATUS Status;
|
||||
ULONG_PTR IsWow64;
|
||||
|
||||
Status = NtQueryInformationProcess(NtCurrentProcess(),
|
||||
ProcessWow64Information,
|
||||
&IsWow64,
|
||||
sizeof(IsWow64),
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
return IsWow64 != 0;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
ULONG
|
||||
SizeOfMdl(VOID)
|
||||
{
|
||||
return Is64BitSystem() ? 48 : 28;
|
||||
}
|
||||
|
||||
START_TEST(NtReadFile)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE FileHandle;
|
||||
UNICODE_STRING FileName = RTL_CONSTANT_STRING(L"\\SystemRoot\\ntdll-apitest-NtReadFile-test.bin");
|
||||
PVOID Buffer;
|
||||
SIZE_T BufferSize;
|
||||
LARGE_INTEGER ByteOffset;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
FILE_DISPOSITION_INFORMATION DispositionInfo;
|
||||
ULONG TooLargeDataSize = (MAXUSHORT + 1 - SizeOfMdl()) / sizeof(ULONG_PTR) * PAGE_SIZE; // 0x3FF9000 on x86
|
||||
ULONG LargeMdlMaxDataSize = TooLargeDataSize - PAGE_SIZE;
|
||||
|
||||
trace("System is %d bits, Size of MDL: %lu\n", Is64BitSystem() ? 64 : 32, SizeOfMdl());
|
||||
trace("Max MDL data size: 0x%lx bytes\n", LargeMdlMaxDataSize);
|
||||
|
||||
ByteOffset.QuadPart = 0;
|
||||
|
||||
Buffer = NULL;
|
||||
BufferSize = TooLargeDataSize;
|
||||
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
|
||||
&Buffer,
|
||||
0,
|
||||
&BufferSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
skip("Failed to allocate memory, status %lx\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&FileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtCreateFile(&FileHandle,
|
||||
FILE_READ_DATA | FILE_WRITE_DATA | DELETE | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatus,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
FILE_SUPERSEDE,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
|
||||
FILE_NO_INTERMEDIATE_BUFFERING,
|
||||
NULL,
|
||||
0);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
ByteOffset.QuadPart = 0x10000;
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
BufferSize - 0x10000,
|
||||
&ByteOffset,
|
||||
NULL);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
ByteOffset.QuadPart = 0;
|
||||
|
||||
/* non-cached, max size -- succeeds */
|
||||
Status = NtReadFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
LargeMdlMaxDataSize - PAGE_SIZE,
|
||||
&ByteOffset,
|
||||
NULL);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
/* non-cached, max size -- succeeds */
|
||||
Status = NtReadFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
LargeMdlMaxDataSize,
|
||||
&ByteOffset,
|
||||
NULL);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
/* non-cached, too large -- fails to allocate MDL
|
||||
* Note: this returns STATUS_SUCCESS on Win7 -- higher MDL size limit */
|
||||
Status = NtReadFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
LargeMdlMaxDataSize + PAGE_SIZE,
|
||||
&ByteOffset,
|
||||
NULL);
|
||||
ok_hex(Status, STATUS_INSUFFICIENT_RESOURCES);
|
||||
|
||||
/* non-cached, unaligned -- fails with invalid parameter */
|
||||
Status = NtReadFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
LargeMdlMaxDataSize + 1,
|
||||
&ByteOffset,
|
||||
NULL);
|
||||
ok_hex(Status, STATUS_INVALID_PARAMETER);
|
||||
|
||||
DispositionInfo.DeleteFile = TRUE;
|
||||
Status = NtSetInformationFile(FileHandle,
|
||||
&IoStatus,
|
||||
&DispositionInfo,
|
||||
sizeof(DispositionInfo),
|
||||
FileDispositionInformation);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
Status = NtClose(FileHandle);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = NtCreateFile(&FileHandle,
|
||||
FILE_READ_DATA | FILE_WRITE_DATA | DELETE | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatus,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
FILE_SUPERSEDE,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
NULL,
|
||||
0);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
ByteOffset.QuadPart = 0x10000;
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
BufferSize - 0x10000,
|
||||
&ByteOffset,
|
||||
NULL);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
ByteOffset.QuadPart = 0;
|
||||
|
||||
/* cached: succeeds with arbitrary length */
|
||||
Status = NtReadFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
LargeMdlMaxDataSize,
|
||||
&ByteOffset,
|
||||
NULL);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = NtReadFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
LargeMdlMaxDataSize + 1,
|
||||
&ByteOffset,
|
||||
NULL);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = NtReadFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
TooLargeDataSize,
|
||||
&ByteOffset,
|
||||
NULL);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
DispositionInfo.DeleteFile = TRUE;
|
||||
Status = NtSetInformationFile(FileHandle,
|
||||
&IoStatus,
|
||||
&DispositionInfo,
|
||||
sizeof(DispositionInfo),
|
||||
FileDispositionInformation);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
Status = NtClose(FileHandle);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = NtFreeVirtualMemory(NtCurrentProcess(),
|
||||
&Buffer,
|
||||
&BufferSize,
|
||||
MEM_RELEASE);
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
}
|
|
@ -21,6 +21,7 @@ extern void func_NtQueryInformationProcess(void);
|
|||
extern void func_NtQueryKey(void);
|
||||
extern void func_NtQuerySystemEnvironmentValue(void);
|
||||
extern void func_NtQueryVolumeInformationFile(void);
|
||||
extern void func_NtReadFile(void);
|
||||
extern void func_NtSaveKey(void);
|
||||
extern void func_NtSetValueKey(void);
|
||||
extern void func_NtSystemInformation(void);
|
||||
|
@ -68,6 +69,7 @@ const struct test winetest_testlist[] =
|
|||
{ "NtQueryKey", func_NtQueryKey },
|
||||
{ "NtQuerySystemEnvironmentValue", func_NtQuerySystemEnvironmentValue },
|
||||
{ "NtQueryVolumeInformationFile", func_NtQueryVolumeInformationFile },
|
||||
{ "NtReadFile", func_NtReadFile },
|
||||
{ "NtSaveKey", func_NtSaveKey},
|
||||
{ "NtSetValueKey", func_NtSetValueKey},
|
||||
{ "NtSystemInformation", func_NtSystemInformation },
|
||||
|
|
Loading…
Reference in a new issue