#include "../CgeFs.h" #include #include static int utf8ToWchar(const char *utf8, wchar_t *out, int size) { int len; if (!utf8 || !out || size <= 0) return 0; len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, out, size); if (len <= 0 || len > size) { out[0] = L'\0'; return 0; } return 1; } static int mapWinError(DWORD err) { switch (err) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: return CGE_FS_ENOENT; case ERROR_ALREADY_EXISTS: return CGE_FS_EEXIST; case ERROR_ACCESS_DENIED: return CGE_FS_EACCES; case ERROR_DIRECTORY: return CGE_FS_ENOTDIR; case ERROR_TOO_MANY_OPEN_FILES: return CGE_FS_EMFILE; case ERROR_FILENAME_EXCED_RANGE: return CGE_FS_ENAMETOOLONG; default: return CGE_FS_EUNKNOWN; } } static uint64_t fileTimeToUint64(const FILETIME *ft) { ULARGE_INTEGER u; u.LowPart = ft->dwLowDateTime; u.HighPart = ft->dwHighDateTime; return u.QuadPart / 10000000ULL - 11644473600ULL; } int CgeFsStat(const char *path, CgeFsInfo *info, int *result) { wchar_t wpath[MAX_PATH]; WIN32_FIND_DATAW fd; HANDLE handle; const char *p; const char *base; if (!utf8ToWchar(path, wpath, MAX_PATH)) { if (result) *result = CGE_FS_EUNKNOWN; return 0; } handle = FindFirstFileW(wpath, &fd); if (handle == INVALID_HANDLE_VALUE) { if (result) *result = mapWinError(GetLastError()); return 0; } base = NULL; for (p = path; *p; p++) if (*p == '/' || *p == '\\') base = p + 1; if (!base) base = path; strncpy(info->name, base, CGE_FS_NAME_MAX - 1); info->name[CGE_FS_NAME_MAX - 1] = '\0'; info->type = (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? CGE_FS_DIR : CGE_FS_FILE; info->size = ((uint64_t)fd.nFileSizeHigh << 32) | fd.nFileSizeLow; info->mtime = (uint64_t)(fileTimeToUint64(&fd.ftLastWriteTime)); FindClose(handle); return 1; } int CgeFsDelete(const char *path, int *result) { wchar_t wpath[MAX_PATH]; if (!utf8ToWchar(path, wpath, MAX_PATH)) { if (result) *result = CGE_FS_EUNKNOWN; return 0; } if (DeleteFileW(wpath) == 0) { if (result) *result = mapWinError(GetLastError()); return 0; } return 1; } int CgeFsRename(const char *from, const char *to, int *result) { wchar_t wfrom[MAX_PATH], wto[MAX_PATH]; if (!utf8ToWchar(from, wfrom, MAX_PATH)) { if (result) *result = CGE_FS_EUNKNOWN; return 0; } if (!utf8ToWchar(to, wto, MAX_PATH)) { if (result) *result = CGE_FS_EUNKNOWN; return 0; } if (MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING) == 0) { if (result) *result = mapWinError(GetLastError()); return 0; } return 1; } int CgeFsCopy(const char *from, const char *to, int *result) { wchar_t wfrom[MAX_PATH], wto[MAX_PATH]; if (!utf8ToWchar(from, wfrom, MAX_PATH)) { if (result) *result = CGE_FS_EUNKNOWN; return 0; } if (!utf8ToWchar(to, wto, MAX_PATH)) { if (result) *result = CGE_FS_EUNKNOWN; return 0; } if (CopyFileW(wfrom, wto, FALSE) == 0) { if (result) *result = mapWinError(GetLastError()); return 0; } return 1; }