Files
Elpisdev_unsegaREBORN/include/lib.h
T
2026-02-06 01:07:35 +03:00

639 lines
17 KiB
C

#ifndef LIB_H
#define LIB_H
#if defined(_WIN32) || defined(_WIN64)
#define PLATFORM_WINDOWS 1
#elif defined(__linux__) && defined(__x86_64__)
#define PLATFORM_LINUX 1
#else
#error "unsupported platform"
#endif
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#ifdef PLATFORM_WINDOWS
typedef uint64_t size_t;
typedef int64_t ssize_t;
typedef uint64_t uintptr_t;
typedef int64_t intptr_t;
#else
typedef unsigned long size_t;
typedef long ssize_t;
typedef unsigned long uintptr_t;
typedef long intptr_t;
#endif
typedef int64_t off_t;
typedef int64_t time_t;
typedef int64_t __time64_t;
#ifndef __bool_true_false_are_defined
#if __STDC_VERSION__ < 202311L
typedef _Bool bool;
#define true 1
#define false 0
#endif
#define __bool_true_false_are_defined 1
#endif
#define NULL ((void*)0)
typedef __builtin_va_list va_list;
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#ifdef __cplusplus
extern "C" {
#endif
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define EBADF 9
#define ENOMEM 12
#define EACCES 13
#define EFAULT 14
#define EEXIST 17
#define ENOTDIR 20
#define EISDIR 21
#define EINVAL 22
#define EMFILE 24
#define ENOSPC 28
#define EROFS 30
#define ERANGE 34
#ifdef PLATFORM_WINDOWS
typedef long NTSTATUS;
typedef void* HANDLE;
typedef uint16_t WCHAR;
typedef uint32_t ULONG;
typedef int32_t LONG;
typedef uint64_t ULONGLONG;
typedef int64_t LONGLONG;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_END_OF_FILE ((NTSTATUS)0xC0000011L)
#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define INVALID_HANDLE_VALUE ((HANDLE)(intptr_t)-1)
#define FILE_READ_DATA 0x0001
#define FILE_WRITE_DATA 0x0002
#define FILE_APPEND_DATA 0x0004
#define FILE_READ_ATTRIBUTES 0x0080
#define FILE_WRITE_ATTRIBUTES 0x0100
#define FILE_LIST_DIRECTORY 0x0001
#define DELETE 0x00010000L
#define SYNCHRONIZE 0x00100000L
#define FILE_SHARE_READ 0x00000001
#define FILE_SHARE_WRITE 0x00000002
#define FILE_SHARE_DELETE 0x00000004
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_OPEN_IF 0x00000003
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_SEQUENTIAL_ONLY 0x00000004
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_DELETE_ON_CLOSE 0x00001000
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#define OBJ_CASE_INSENSITIVE 0x00000040
typedef struct _UNICODE_STRING {
uint16_t Length;
uint16_t MaximumLength;
WCHAR* Buffer;
} UNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
UNICODE_STRING* ObjectName;
ULONG Attributes;
void* SecurityDescriptor;
void* SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK {
union { NTSTATUS Status; void* Pointer; };
uintptr_t Information;
} IO_STATUS_BLOCK;
typedef struct _LARGE_INTEGER {
LONGLONG QuadPart;
} LARGE_INTEGER;
typedef struct _FILE_POSITION_INFORMATION {
LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION;
typedef struct _FILE_STANDARD_INFORMATION {
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
uint8_t DeletePending;
uint8_t Directory;
} FILE_STANDARD_INFORMATION;
typedef struct _FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
ULONG FileAttributes;
} FILE_BASIC_INFORMATION;
typedef struct _FILE_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
uint8_t ShortNameLength;
WCHAR ShortName[12];
WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION;
typedef enum _FILE_INFORMATION_CLASS {
FileBasicInformation = 4,
FileStandardInformation = 5,
FilePositionInformation = 14,
FileBothDirectoryInformation = 3,
} FILE_INFORMATION_CLASS;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
uint8_t _Reserved0[0x20];
HANDLE StandardInput;
HANDLE StandardOutput;
HANDLE StandardError;
uint8_t _Reserved1[0x38];
UNICODE_STRING CommandLine;
WCHAR* Environment;
} RTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
uint8_t _Reserved0[0x20];
RTL_USER_PROCESS_PARAMETERS* ProcessParameters;
void* SubSystemData;
HANDLE ProcessHeap;
} PEB;
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitStatus;
void* PebBaseAddress;
uintptr_t AffinityMask;
int32_t BasePriority;
uintptr_t UniqueProcessId;
uintptr_t InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
uint8_t Reserved1[48];
UNICODE_STRING ImageName;
int32_t BasePriority;
uintptr_t UniqueProcessId;
} SYSTEM_PROCESS_INFORMATION;
#define ProcessBasicInformation 0
#define SystemProcessInformation 5
#define CRT_OFFSETOF(type, member) ((size_t)&(((type*)0)->member))
__declspec(dllimport) NTSTATUS __stdcall NtCreateFile(HANDLE*, ULONG, OBJECT_ATTRIBUTES*, IO_STATUS_BLOCK*, LARGE_INTEGER*, ULONG, ULONG, ULONG, ULONG, void*, ULONG);
__declspec(dllimport) NTSTATUS __stdcall NtReadFile(HANDLE, HANDLE, void*, void*, IO_STATUS_BLOCK*, void*, ULONG, LARGE_INTEGER*, ULONG*);
__declspec(dllimport) NTSTATUS __stdcall NtWriteFile(HANDLE, HANDLE, void*, void*, IO_STATUS_BLOCK*, const void*, ULONG, LARGE_INTEGER*, ULONG*);
__declspec(dllimport) NTSTATUS __stdcall NtClose(HANDLE);
__declspec(dllimport) NTSTATUS __stdcall NtQueryInformationFile(HANDLE, IO_STATUS_BLOCK*, void*, ULONG, FILE_INFORMATION_CLASS);
__declspec(dllimport) NTSTATUS __stdcall NtSetInformationFile(HANDLE, IO_STATUS_BLOCK*, void*, ULONG, FILE_INFORMATION_CLASS);
__declspec(dllimport) NTSTATUS __stdcall NtQueryDirectoryFile(HANDLE, HANDLE, void*, void*, IO_STATUS_BLOCK*, void*, ULONG, FILE_INFORMATION_CLASS, uint8_t, UNICODE_STRING*, uint8_t);
__declspec(dllimport) NTSTATUS __stdcall NtQuerySystemTime(LARGE_INTEGER*);
__declspec(dllimport) NTSTATUS __stdcall NtQueryInformationProcess(HANDLE, ULONG, void*, ULONG, ULONG*);
__declspec(dllimport) NTSTATUS __stdcall NtQuerySystemInformation(ULONG, void*, ULONG, ULONG*);
__declspec(dllimport) NTSTATUS __stdcall NtDelayExecution(uint8_t, LARGE_INTEGER*);
__declspec(dllimport) void* __stdcall RtlAllocateHeap(HANDLE, ULONG, size_t);
__declspec(dllimport) void* __stdcall RtlReAllocateHeap(HANDLE, ULONG, void*, size_t);
__declspec(dllimport) uint8_t __stdcall RtlFreeHeap(HANDLE, ULONG, void*);
__declspec(dllimport) void __stdcall RtlExitUserProcess(NTSTATUS);
__declspec(dllimport) NTSTATUS __stdcall RtlDosPathNameToNtPathName_U_WithStatus(const WCHAR*, UNICODE_STRING*, WCHAR**, void*);
__declspec(dllimport) void __stdcall RtlFreeUnicodeString(UNICODE_STRING*);
static inline PEB* lib_get_peb(void) {
PEB* peb;
__asm__ volatile ("mov %%gs:0x60, %0" : "=r"(peb));
return peb;
}
#else
#define SYS_read 0
#define SYS_write 1
#define SYS_open 2
#define SYS_close 3
#define SYS_fstat 5
#define SYS_lseek 8
#define SYS_mmap 9
#define SYS_mprotect 10
#define SYS_munmap 11
#define SYS_brk 12
#define SYS_ioctl 16
#define SYS_access 21
#define SYS_dup2 33
#define SYS_getpid 39
#define SYS_exit 60
#define SYS_uname 63
#define SYS_fcntl 72
#define SYS_fsync 74
#define SYS_ftruncate 77
#define SYS_getdents64 217
#define SYS_fadvise64 221
#define SYS_exit_group 231
#define SYS_openat 257
#define SYS_mkdirat 258
#define SYS_newfstatat 262
#define SYS_unlinkat 263
#define SYS_utimensat 280
#define O_RDONLY 0x0000
#define O_WRONLY 0x0001
#define O_RDWR 0x0002
#define O_CREAT 0x0040
#define O_EXCL 0x0080
#define O_TRUNC 0x0200
#define O_APPEND 0x0400
#define O_DIRECTORY 0x10000
#define O_CLOEXEC 0x80000
#define S_IRWXU 0700
#define S_IRUSR 0400
#define S_IWUSR 0200
#define S_IXUSR 0100
#define S_IRWXG 0070
#define S_IRGRP 0040
#define S_IXGRP 0010
#define S_IRWXO 0007
#define S_IROTH 0004
#define S_IXOTH 0001
#define S_IFMT 0170000
#define S_IFDIR 0040000
#define S_IFREG 0100000
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define MAP_PRIVATE 0x02
#define MAP_ANONYMOUS 0x20
#define MAP_FAILED ((void*)-1)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define AT_FDCWD (-100)
#define DT_DIR 4
#define DT_REG 8
struct linux_dirent64 {
uint64_t d_ino;
int64_t d_off;
uint16_t d_reclen;
uint8_t d_type;
char d_name[];
};
struct linux_stat {
uint64_t st_dev;
uint64_t st_ino;
uint64_t st_nlink;
uint32_t st_mode;
uint32_t st_uid;
uint32_t st_gid;
uint32_t __pad0;
uint64_t st_rdev;
int64_t st_size;
int64_t st_blksize;
int64_t st_blocks;
int64_t st_atime_sec;
int64_t st_atime_nsec;
int64_t st_mtime_sec;
int64_t st_mtime_nsec;
int64_t st_ctime_sec;
int64_t st_ctime_nsec;
int64_t __unused[3];
};
struct linux_timespec {
int64_t tv_sec;
int64_t tv_nsec;
};
static inline long syscall0(long n) {
long ret;
__asm__ volatile ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
return ret;
}
static inline long syscall1(long n, long a1) {
long ret;
__asm__ volatile ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
return ret;
}
static inline long syscall2(long n, long a1, long a2) {
long ret;
__asm__ volatile ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2) : "rcx", "r11", "memory");
return ret;
}
static inline long syscall3(long n, long a1, long a2, long a3) {
long ret;
__asm__ volatile ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), "d"(a3) : "rcx", "r11", "memory");
return ret;
}
static inline long syscall4(long n, long a1, long a2, long a3, long a4) {
long ret;
register long r10 __asm__("r10") = a4;
__asm__ volatile ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10) : "rcx", "r11", "memory");
return ret;
}
static inline long syscall5(long n, long a1, long a2, long a3, long a4, long a5) {
long ret;
register long r10 __asm__("r10") = a4;
register long r8 __asm__("r8") = a5;
__asm__ volatile ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory");
return ret;
}
static inline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6) {
long ret;
register long r10 __asm__("r10") = a4;
register long r8 __asm__("r8") = a5;
register long r9 __asm__("r9") = a6;
__asm__ volatile ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory");
return ret;
}
#endif
#define _IOFBF 0
#define _IOLBF 1
#define _IONBF 2
#define _A_SUBDIR 0x10
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
#define EOF (-1)
#ifdef PLATFORM_WINDOWS
extern HANDLE lib_heap;
extern HANDLE lib_stdout_handle;
extern HANDLE lib_stderr_handle;
extern HANDLE lib_stdin_handle;
#endif
extern int lib_errno_val;
void* lib_malloc(size_t size);
void* lib_calloc(size_t count, size_t size);
void* lib_realloc(void* ptr, size_t size);
void lib_free(void* ptr);
#define malloc lib_malloc
#define calloc lib_calloc
#define realloc lib_realloc
#define free lib_free
size_t lib_strlen(const char* s);
char* lib_strcpy(char* dst, const char* src);
char* lib_strncpy(char* dst, const char* src, size_t n);
int lib_strcmp(const char* s1, const char* s2);
int lib_strncmp(const char* s1, const char* s2, size_t n);
char* lib_strchr(const char* s, int c);
char* lib_strrchr(const char* s, int c);
char* lib_strstr(const char* haystack, const char* needle);
char* lib_strncat(char* dst, const char* src, size_t n);
void* lib_memcpy(void* dst, const void* src, size_t n);
void* lib_memset(void* dst, int c, size_t n);
int lib_memcmp(const void* s1, const void* s2, size_t n);
#define strlen lib_strlen
#define strcpy lib_strcpy
#define strncpy lib_strncpy
#define strcmp lib_strcmp
#define strncmp lib_strncmp
#define strchr lib_strchr
#define strrchr lib_strrchr
#define strstr lib_strstr
#define strncat lib_strncat
#define memcpy lib_memcpy
#define memset lib_memset
#define memcmp lib_memcmp
#define LIB_FILE_READ 0x01
#define LIB_FILE_WRITE 0x02
#define LIB_FILE_EOF 0x04
#define LIB_FILE_ERROR 0x08
#define LIB_FILE_APPEND 0x10
#define LIB_IOBUF_SIZE (64 * 1024)
typedef struct {
#ifdef PLATFORM_WINDOWS
HANDLE handle;
#else
int fd;
#endif
uint8_t* buffer;
uint32_t buf_cap;
uint32_t buf_pos;
uint32_t buf_fill;
int64_t file_pos;
uint32_t flags;
} FILE;
extern FILE* lib_stdout_file;
extern FILE* lib_stderr_file;
extern FILE* lib_stdin_file;
#define stdin lib_stdin_file
#define stdout lib_stdout_file
#define stderr lib_stderr_file
FILE* lib_fopen(const char* path, const char* mode);
size_t lib_fread(void* buf, size_t size, size_t count, FILE* f);
size_t lib_fwrite(const void* buf, size_t size, size_t count, FILE* f);
int lib_fseek(FILE* f, long offset, int whence);
int lib_fseeki64(FILE* f, int64_t offset, int whence);
long lib_ftell(FILE* f);
int64_t lib_ftelli64(FILE* f);
int lib_fclose(FILE* f);
int lib_fflush(FILE* f);
int lib_feof(FILE* f);
char* lib_fgets(char* buf, int n, FILE* f);
void lib_rewind(FILE* f);
void lib_setvbuf(FILE* f, char* buf, int mode, size_t size);
#define fopen lib_fopen
#define fread lib_fread
#define fwrite lib_fwrite
#define fseek lib_fseek
#define _fseeki64 lib_fseeki64
#define fseeko lib_fseeki64
#define ftell lib_ftell
#define _ftelli64 lib_ftelli64
#define ftello lib_ftelli64
#define fclose lib_fclose
#define fflush lib_fflush
#define feof lib_feof
#define fgets lib_fgets
#define rewind lib_rewind
#define setvbuf lib_setvbuf
#ifdef PLATFORM_WINDOWS
FILE* lib_wfopen(const WCHAR* path, const WCHAR* mode);
FILE* lib_wfopen_prealloc(const WCHAR* path, uint64_t size);
bool lib_set_file_times_ntfs(FILE* f, int64_t modified_time, int64_t access_time);
int lib_wutime(const WCHAR* path, const void* times);
int lib_wutime_dir(const WCHAR* path, const void* times);
#define _wfopen lib_wfopen
#define _wutime lib_wutime
#endif
size_t lib_fwrite_direct(FILE* f, const void* buf, size_t size);
int lib_printf(const char* fmt, ...);
int lib_fprintf(FILE* f, const char* fmt, ...);
int lib_snprintf(char* buf, size_t n, const char* fmt, ...);
int lib_vprintf(const char* fmt, va_list ap);
int lib_vfprintf(FILE* f, const char* fmt, va_list ap);
int lib_vsnprintf(char* buf, size_t n, const char* fmt, va_list ap);
int lib_puts(const char* s);
#define printf lib_printf
#define fprintf lib_fprintf
#define snprintf lib_snprintf
#define vprintf lib_vprintf
#define vfprintf lib_vfprintf
#define vsnprintf lib_vsnprintf
#define puts lib_puts
int lib_mkdir(const char* path);
int lib_rmdir(const char* path);
int lib_remove(const char* path);
#define mkdir lib_mkdir
#define _mkdir lib_mkdir
#define rmdir lib_rmdir
#define _rmdir lib_rmdir
#define remove lib_remove
#ifdef PLATFORM_WINDOWS
int lib_wmkdir(const WCHAR* path);
int lib_wremove(const WCHAR* path);
#define _wmkdir lib_wmkdir
#define _wremove lib_wremove
#endif
typedef struct {
uint32_t attrib;
int64_t time_create;
int64_t time_access;
int64_t time_write;
int64_t size;
char name[260];
} lib_finddata_t;
intptr_t lib_findfirst(const char* pattern, lib_finddata_t* data);
int lib_findnext(intptr_t handle, lib_finddata_t* data);
int lib_findclose(intptr_t handle);
#define _finddata_t lib_finddata_t
#define _finddata64_t lib_finddata_t
#define _findfirst lib_findfirst
#define _findfirst64 lib_findfirst
#define _findnext lib_findnext
#define _findnext64 lib_findnext
#define _findclose lib_findclose
int lib_isatty(int fd);
#define isatty lib_isatty
#define _isatty lib_isatty
time_t lib_time(time_t* t);
double lib_difftime(time_t t1, time_t t0);
#define time lib_time
#define _time64 lib_time
#define difftime lib_difftime
int lib_atoi(const char* s);
int lib_isxdigit(int c);
#define atoi lib_atoi
#define isxdigit lib_isxdigit
int* lib_errno_func(void);
#define errno (*lib_errno_func())
void lib_exit(int status);
#define exit lib_exit
#define _exit lib_exit
#ifdef PLATFORM_WINDOWS
#define PATH_SEPARATOR "\\"
#define PATH_SEP_CHAR '\\'
#else
#define PATH_SEPARATOR "/"
#define PATH_SEP_CHAR '/'
#endif
void lib_init(void);
int lib_main(int argc, char** argv);
#ifdef __cplusplus
}
#endif
#endif