[KERNEL32_APITEST] Add tests for ReadFile and WriteFIle

This commit is contained in:
Timo Kreuzer
2026-05-11 10:12:42 +03:00
parent 15fa25299f
commit b8bf0089de
3 changed files with 397 additions and 1 deletions

View File

@@ -37,6 +37,7 @@ list(APPEND SOURCE
Pipes.c
PrivMoveFileIdentityW.c
QueueUserAPC.c
ReadFile.c
SetComputerNameExW.c
SetConsoleWindowInfo.c
SetCurrentDirectory.c
@@ -45,7 +46,9 @@ list(APPEND SOURCE
TerminateProcess.c
TunnelCache.c
UEFIFirmware.c
WideCharToMultiByte.c)
WideCharToMultiByte.c
WriteFile.c
)
list(APPEND PCH_SKIP_SOURCE
testlist.c)

View File

@@ -0,0 +1,223 @@
/*
* PROJECT: ReactOS API tests
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: Test for ReadFile
* COPYRIGHT: Copyright 2026 Timo Kreuzer <timo.kreuzer@reactos.org>
*/
#include "precomp.h"
static void Test_ReadFile_sync(HANDLE hFile)
{
UCHAR Buffer[128];
DWORD dwBytesRead;
BOOL bResult;
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
/* Test NULL File */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
bResult = ReadFile(NULL, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), ERROR_INVALID_HANDLE);
/* Test INVALID_HANDLE_VALUE */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
bResult = ReadFile(INVALID_HANDLE_VALUE, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), ERROR_INVALID_HANDLE);
/* Read some bytes */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
bResult = ReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesRead, sizeof(Buffer));
ok_eq_ulong(GetLastError(), 0xdeadbeef);
/* Try to read at end of file */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
ok(SetFilePointer(hFile, 0, NULL, FILE_END) > 0, "SetFilePointer failed\n");
bResult = ReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
/* Try to read 0 bytes at end of file */
SetLastError(0xdeadbeef);
bResult = ReadFile(hFile, Buffer, 0, &dwBytesRead, NULL);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
/* Test with NULL lpBuffer */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
StartSeh()
bResult = ReadFile(hFile, NULL, sizeof(Buffer), &dwBytesRead, NULL);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), ERROR_NOACCESS);
EndSeh(STATUS_SUCCESS);
/* Test with NULL lpBuffer and 0 nNumberOfBytesToRead */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
StartSeh()
bResult = ReadFile(hFile, NULL, 0, &dwBytesRead, NULL);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
EndSeh(STATUS_SUCCESS);
/* Test with NULL lpNumberOfBytesRead */
SetLastError(0xdeadbeef);
StartSeh()
bResult = ReadFile(hFile, Buffer, sizeof(Buffer), NULL, NULL);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
EndSeh((GetNTVersion() >= _WIN32_WINNT_WIN8) ? STATUS_SUCCESS : EXCEPTION_ACCESS_VIOLATION);
/* Test with NULL lpNumberOfBytesRead at end of file */
ok(SetFilePointer(hFile, 0, NULL, FILE_END) > 0, "SetFilePointer failed\n");
SetLastError(0xdeadbeef);
StartSeh()
bResult = ReadFile(hFile, Buffer, sizeof(Buffer), NULL, NULL);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
EndSeh((GetNTVersion() >= _WIN32_WINNT_WIN8) ? STATUS_SUCCESS : EXCEPTION_ACCESS_VIOLATION);
}
static void Test_ReadFile_async(HANDLE hFile)
{
BOOL bResult;
UCHAR Buffer[128];
DWORD dwBytesRead;
OVERLAPPED ol = { 0 };
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
/* Test NULL File */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
bResult = ReadFile(NULL, Buffer, sizeof(Buffer), &dwBytesRead, &ol);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), ERROR_INVALID_HANDLE);
/* Test INVALID_HANDLE_VALUE */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
bResult = ReadFile(INVALID_HANDLE_VALUE, Buffer, sizeof(Buffer), &dwBytesRead, &ol);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), ERROR_INVALID_HANDLE);
/* Read some bytes */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
bResult = ReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, &ol);
ok_eq_bool(bResult, TRUE);
dwBytesRead = 0xdeadbeef;
bResult = GetOverlappedResult(hFile, &ol, &dwBytesRead, TRUE);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesRead, sizeof(Buffer));
ok_eq_ulong(GetLastError(), (GetNTVersion() >= _WIN32_WINNT_WIN10) ? 0 : 0xdeadbeef);
/* Try to read at end of file */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
ol.Offset = GetFileSize(hFile, NULL);
ok(ol.Offset > 0, "GetFileSize failed\n");
bResult = ReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, &ol);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), ERROR_HANDLE_EOF);
/* Try to read 0 bytes at end of file */
SetLastError(0xdeadbeef);
bResult = ReadFile(hFile, Buffer, 0, &dwBytesRead, &ol);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
ol.Offset = 0;
/* Test with NULL lpBuffer */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
StartSeh()
bResult = ReadFile(hFile, NULL, sizeof(Buffer), &dwBytesRead, &ol);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(GetLastError(), ERROR_NOACCESS);
EndSeh(STATUS_SUCCESS);
/* Test with NULL lpBuffer and 0 nNumberOfBytesToRead */
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
StartSeh()
bResult = ReadFile(hFile, NULL, 0, &dwBytesRead, &ol);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
bResult = GetOverlappedResult(hFile, &ol, &dwBytesRead, TRUE);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), (GetNTVersion() >= _WIN32_WINNT_WIN10) ? 0 : 0xdeadbeef);
EndSeh(STATUS_SUCCESS);
/* Test with NULL lpNumberOfBytesRead */
SetLastError(0xdeadbeef);
bResult = ReadFile(hFile, Buffer, sizeof(Buffer), NULL, &ol);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
bResult = GetOverlappedResult(hFile, &ol, &dwBytesRead, TRUE);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesRead, sizeof(Buffer));
ok_eq_ulong(GetLastError(), (GetNTVersion() >= _WIN32_WINNT_WIN10) ? 0 : 0xdeadbeef);
/* Test with NULL lpNumberOfBytesRead at end of file */
SetLastError(0xdeadbeef);
ol.Offset = GetFileSize(hFile, NULL);
ok(ol.Offset > 0, "GetFileSize failed\n");
bResult = ReadFile(hFile, Buffer, sizeof(Buffer), NULL, &ol);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(GetLastError(), ERROR_HANDLE_EOF);
SetLastError(0xdeadbeef);
dwBytesRead = 0xdeadbeef;
bResult = GetOverlappedResult(hFile, &ol, &dwBytesRead, TRUE);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesRead, 0);
ok_eq_ulong(GetLastError(), ERROR_HANDLE_EOF);
ol.Offset = 0;
}
START_TEST(ReadFile)
{
CHAR FileName[MAX_PATH];
HANDLE hFile;
/* Open the executable file */
GetModuleFileNameA(NULL, FileName, ARRAYSIZE(FileName));
hFile = CreateFileA(FileName,
FILE_READ_ACCESS,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
skip("CreateFileA failed with error %lu\n", GetLastError());
return;
}
Test_ReadFile_sync(hFile);
Test_ReadFile_async(hFile);
CloseHandle(hFile);
}

View File

@@ -0,0 +1,170 @@
/*
* PROJECT: ReactOS API tests
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: Test for WriteFile
* COPYRIGHT: Copyright 2026 Timo Kreuzer <timo.kreuzer@reactos.org>
*/
#include "precomp.h"
static void Test_WriteFile_sync(HANDLE hFile)
{
UCHAR Buffer[128];
DWORD dwBytesWritten;
BOOL bResult;
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
/* Test NULL File */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
bResult = WriteFile(NULL, Buffer, sizeof(Buffer), &dwBytesWritten, NULL);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesWritten, 0);
ok_eq_ulong(GetLastError(), ERROR_INVALID_HANDLE);
/* Test INVALID_HANDLE_VALUE */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
bResult = WriteFile(INVALID_HANDLE_VALUE, Buffer, sizeof(Buffer), &dwBytesWritten, NULL);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesWritten, 0);
ok_eq_ulong(GetLastError(), ERROR_INVALID_HANDLE);
/* Write some bytes */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
bResult = WriteFile(hFile, Buffer, sizeof(Buffer), &dwBytesWritten, NULL);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesWritten, sizeof(Buffer));
ok_eq_ulong(GetLastError(), 0xdeadbeef);
/* Test with NULL lpBuffer */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
StartSeh()
bResult = WriteFile(hFile, NULL, sizeof(Buffer), &dwBytesWritten, NULL);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesWritten, 0);
ok_eq_ulong(GetLastError(), ERROR_INVALID_USER_BUFFER);
EndSeh(STATUS_SUCCESS);
/* Test with NULL lpBuffer and 0 nNumberOfBytesToWrite */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
StartSeh()
bResult = WriteFile(hFile, NULL, 0, &dwBytesWritten, NULL);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesWritten, 0);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
EndSeh(STATUS_SUCCESS);
/* Test with NULL lpNumberOfBytesWritten */
SetLastError(0xdeadbeef);
StartSeh()
bResult = WriteFile(hFile, Buffer, sizeof(Buffer), NULL, NULL);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
EndSeh((GetNTVersion() >= _WIN32_WINNT_WIN8) ? STATUS_SUCCESS : EXCEPTION_ACCESS_VIOLATION);
}
static void Test_WriteFile_async(HANDLE hFile)
{
BOOL bResult;
UCHAR Buffer[128];
DWORD dwBytesWritten;
OVERLAPPED ol = { 0 };
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
/* Test NULL File */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
bResult = WriteFile(NULL, Buffer, sizeof(Buffer), &dwBytesWritten, &ol);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesWritten, 0);
ok_eq_ulong(GetLastError(), ERROR_INVALID_HANDLE);
/* Test INVALID_HANDLE_VALUE */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
bResult = WriteFile(INVALID_HANDLE_VALUE, Buffer, sizeof(Buffer), &dwBytesWritten, &ol);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(dwBytesWritten, 0);
ok_eq_ulong(GetLastError(), ERROR_INVALID_HANDLE);
/* Write some bytes */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
bResult = WriteFile(hFile, Buffer, sizeof(Buffer), &dwBytesWritten, &ol);
ok_eq_bool(bResult, TRUE);
dwBytesWritten = 0xdeadbeef;
bResult = GetOverlappedResult(hFile, &ol, &dwBytesWritten, TRUE);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesWritten, sizeof(Buffer));
ok_eq_ulong(GetLastError(), (GetNTVersion() >= _WIN32_WINNT_WIN10) ? 0 : 0xdeadbeef);
/* Test with NULL lpBuffer */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
StartSeh()
bResult = WriteFile(hFile, NULL, sizeof(Buffer), &dwBytesWritten, &ol);
ok_eq_bool(bResult, FALSE);
ok_eq_ulong(GetLastError(), ERROR_INVALID_USER_BUFFER);
EndSeh(STATUS_SUCCESS);
/* Test with NULL lpBuffer and 0 nNumberOfBytesToWrite */
SetLastError(0xdeadbeef);
dwBytesWritten = 0xdeadbeef;
StartSeh()
bResult = WriteFile(hFile, NULL, 0, &dwBytesWritten, &ol);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
bResult = GetOverlappedResult(hFile, &ol, &dwBytesWritten, TRUE);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesWritten, 0);
ok_eq_ulong(GetLastError(), (GetNTVersion() >= _WIN32_WINNT_WIN10) ? 0 : 0xdeadbeef);
EndSeh(STATUS_SUCCESS);
/* Test with NULL lpNumberOfBytesWritten */
SetLastError(0xdeadbeef);
bResult = WriteFile(hFile, Buffer, sizeof(Buffer), NULL, &ol);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(GetLastError(), 0xdeadbeef);
bResult = GetOverlappedResult(hFile, &ol, &dwBytesWritten, TRUE);
ok_eq_bool(bResult, TRUE);
ok_eq_ulong(dwBytesWritten, sizeof(Buffer));
ok_eq_ulong(GetLastError(), (GetNTVersion() >= _WIN32_WINNT_WIN10) ? 0 : 0xdeadbeef);
}
START_TEST(WriteFile)
{
HANDLE hFile;
/* Create a temp file name */
CHAR tempFileName[MAX_PATH];
if (!GetTempFileNameA(".", "writetest", 0, tempFileName))
{
skip("GetTempFileNameA failed with error %lu\n", GetLastError());
return;
}
/* Create a temp file to write to */
hFile = CreateFileA(tempFileName,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
skip("CreateFileA failed with error %lu\n", GetLastError());
return;
}
Test_WriteFile_sync(hFile);
Test_WriteFile_async(hFile);
CloseHandle(hFile);
}