Implement file_truncate for Windows and add missing Quakey mocks

file_truncate had a stub `return -1` on Windows, causing all
chunk_store_write calls to fail (every PUT returned TRANSFER_FAILED).
Implement it using SetFilePointer + SetEndOfFile.

Add mock_SetEndOfFile and mock_GetFileAttributesA to Quakey so the
simulation can exercise the Windows code paths against the mock
filesystem. Without these, SetEndOfFile was unmocked (link error) and
GetFileAttributesA called the real Win32 API on mock paths, making
chunk_store_exists always return false.

Verified: seeds 1-100 pass with 2000s simulation time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 13:33:18 +01:00
co-authored by Claude Opus 4.6
parent db2ef299bf
commit 6b4f773052
3 changed files with 68 additions and 1 deletions
+58
View File
@@ -4371,6 +4371,25 @@ HANDLE mock_CreateFileW(WCHAR *lpFileName,
return (HANDLE)(long long)desc_idx;
}
DWORD mock_GetFileAttributesA(char *lpFileName)
{
Host *host = host___;
if (host == NULL)
abort_("Call to mock_GetFileAttributesA() with no node scheduled\n");
// Try opening the file read-only to check existence
int ret = host_open_file(host, lpFileName, MOCKFS_O_RDONLY);
if (ret < 0) {
*host_errno_ptr(host) = ERROR_FILE_NOT_FOUND;
return INVALID_FILE_ATTRIBUTES;
}
// File exists — close it and return normal attributes
host_close(host, ret, false);
*host_errno_ptr(host) = ERROR_SUCCESS;
return FILE_ATTRIBUTE_NORMAL;
}
BOOL mock_CloseHandle(HANDLE handle)
{
Host *host = host___;
@@ -4574,6 +4593,45 @@ DWORD mock_SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceTo
return (DWORD)(new_pos & 0xFFFFFFFF);
}
BOOL mock_SetEndOfFile(HANDLE hFile)
{
Host *host = host___;
if (host == NULL)
abort_("Call to mock_SetEndOfFile() with no node scheduled\n");
if (hFile == INVALID_HANDLE_VALUE || hFile == NULL) {
*host_errno_ptr(host) = ERROR_INVALID_HANDLE;
return 0; // FALSE
}
int desc_idx = (int)(long long)hFile;
// Get current file position to use as the new size
int cur_pos = host_lseek(host, desc_idx, 0, HOST_SEEK_CUR);
if (cur_pos < 0) {
*host_errno_ptr(host) = ERROR_INVALID_HANDLE;
return 0; // FALSE
}
int ret = host_ftruncate(host, desc_idx, cur_pos);
if (ret < 0) {
switch (ret) {
case HOST_ERROR_BADIDX:
*host_errno_ptr(host) = ERROR_INVALID_HANDLE;
return 0;
case HOST_ERROR_NOSPC:
*host_errno_ptr(host) = ERROR_DISK_FULL;
return 0;
default:
*host_errno_ptr(host) = ERROR_INVALID_PARAMETER;
return 0;
}
}
*host_errno_ptr(host) = ERROR_SUCCESS;
return 1; // TRUE
}
BOOL mock_GetFileSizeEx(HANDLE handle, LARGE_INTEGER *buf)
{
Host *host = host___;