12 # pragma clang diagnostic push
13 # pragma clang diagnostic ignored "-Wswitch"
21 BOOL result = CopyFileA(src, dst, FALSE);
24 return GetLastError();
33 if (access & eOsAccessRead) { result |= GENERIC_READ; }
34 if (access & eOsAccessWrite) { result |= GENERIC_WRITE; }
43 DWORD attr = GetFileAttributesA(path);
44 if (attr == INVALID_FILE_ATTRIBUTES)
46 DWORD error = GetLastError();
50 return (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND)
66 case (eOsAccessWrite | eOsAccessRead):
69 case (eOsAccessWrite | eOsAccessTruncate):
70 case (eOsAccessWrite | eOsAccessRead | eOsAccessTruncate):
80 DWORD dw_access = get_access(access);
81 DWORD dw_disp = get_disp(access);
89 FILE_ATTRIBUTE_NORMAL,
99 DWORD result = GetTempPathA(MAX_PATH, path);
102 return GetLastError();
106 result = GetTempFileNameA(path,
"ctu", 0, name);
109 return GetLastError();
117 return CloseHandle(impl) != 0;
126 CTASSERTF(
size <= UINT32_MAX,
"cannot read more than %u bytes at once (%zu is too big)", UINT32_MAX,
size);
129 BOOL result = ReadFile(file->
impl, buffer, (DWORD)
size, &read_size, NULL);
131 size_t read = read_size;
135 return GetLastError();
148 CTASSERTF(
size <= UINT32_MAX,
"cannot write more than %u bytes at once (%zu is too big)", UINT32_MAX,
size);
150 DWORD written_size = 0;
151 BOOL result = WriteFile(file->
impl, buffer, (DWORD)
size, &written_size, NULL);
153 size_t written = written_size;
157 return GetLastError();
161 return ERROR_SUCCESS;
171 BOOL result = GetFileSizeEx(file->
impl, &
size);
172 *actual =
size.QuadPart;
176 return GetLastError();
179 return ERROR_SUCCESS;
188 LARGE_INTEGER it = { .QuadPart = (LONGLONG)offset };
189 LARGE_INTEGER out = { 0 };
190 BOOL result = SetFilePointerEx(file->
impl, it, &out, FILE_BEGIN);
191 *actual = out.QuadPart;
195 return GetLastError();
198 return ERROR_SUCCESS;
206 LARGE_INTEGER offset = { 0 };
207 LARGE_INTEGER zero = { 0 };
208 BOOL result = SetFilePointerEx(file->
impl, zero, &offset, FILE_CURRENT);
209 *actual = offset.QuadPart;
213 return GetLastError();
216 return ERROR_SUCCESS;
224 LARGE_INTEGER it = { .QuadPart = (LONGLONG)
size };
225 BOOL result = SetFilePointerEx(file->
impl, it, NULL, FILE_BEGIN);
228 return GetLastError();
231 result = SetEndOfFile(file->
impl);
234 return GetLastError();
237 return ERROR_SUCCESS;
246 case eOsProtectNone:
return PAGE_NOACCESS;
247 case eOsProtectRead:
return PAGE_READONLY;
248 case eOsProtectExecute:
return PAGE_EXECUTE;
252 case eOsProtectWrite:
253 case (eOsProtectRead | eOsProtectWrite):
254 return PAGE_READWRITE;
256 case (eOsProtectRead | eOsProtectExecute):
257 return PAGE_EXECUTE_READ;
261 case (eOsProtectWrite | eOsProtectExecute):
262 case (eOsProtectRead | eOsProtectWrite | eOsProtectExecute):
263 return PAGE_EXECUTE_READWRITE;
275 if (protect & eOsProtectRead) { result |= FILE_MAP_READ; }
276 if (protect & eOsProtectWrite) { result |= FILE_MAP_WRITE; }
277 if (protect & eOsProtectExecute) { result |= FILE_MAP_EXECUTE; }
283 DWORD prot = get_protect(protect);
284 DWORD access = get_map_access(protect);
286 DWORD high = (DWORD)(
size >> 32);
287 DWORD low = (DWORD)(
size & 0xFFFFFFFF);
289 HANDLE handle = CreateFileMappingA(
302 LPVOID view = MapViewOfFile(
322 if (!UnmapViewOfFile(map->
view))
324 return GetLastError();
327 if (!CloseHandle(map->
handle))
329 return GetLastError();
332 return ERROR_SUCCESS;
CT_NODISCARD CT_CONSTFN STA_RET_STRING CT_OS_API const char * os_protect_string(os_protect_t protect)
get the string representation of a file mapping memory protection
os_protect_t
file mapping memory protection
CT_NODISCARD CT_CONSTFN STA_RET_STRING CT_OS_API const char * os_access_string(os_access_t access)
get the string representation of a file access mode
os_access_t
file access mode
#define STA_DECL
sal2 annotation on function implementations to copy annotations from the declaration
#define CT_NEVER(...)
assert that a code path is never reached
#define CTASSERT(expr)
assert a condition, prints the condition as a message
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
STA_DECL os_error_t os_file_resize(os_file_t *file, size_t size)
truncate/expand a file to a specific size
CT_LOCAL os_error_t impl_unmap(os_mapping_t *map)
STA_DECL os_error_t os_file_read(os_file_t *file, void *buffer, size_t size, size_t *actual)
STA_DECL os_error_t os_file_seek(os_file_t *file, size_t offset, size_t *actual)
STA_DECL os_error_t os_file_write(os_file_t *file, const void *buffer, size_t size, size_t *actual)
STA_DECL os_error_t os_file_size(os_file_t *file, size_t *actual)
STA_DECL os_error_t os_tmpfile_open(os_file_t *file)
STA_DECL os_error_t os_file_exists(const char *path)
check if a file exists
STA_DECL os_error_t os_file_tell(os_file_t *file, size_t *actual)
CT_LOCAL bool impl_file_close(os_file_impl_t file)
CT_LOCAL void * impl_file_map(os_file_t *file, os_protect_t protect, size_t size, os_mapping_t *mapping)
CT_LOCAL os_file_impl_t impl_file_open(const char *path, os_access_t access)
CT_LOCAL os_error_t impl_copyfile(const char *dst, const char *src)
CT_OS_API os_error_t os_file_open(const char *path, os_access_t access, OUT_NOTNULL os_file_t *file)
file api