From 0a1d93062463133e6f40e3398c0fe53371c47ab0 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sat, 15 Jul 2023 17:13:48 +0200 Subject: Move dir_iterator_t from libio into libsquashfs Signed-off-by: David Oberhollenzer --- lib/io/src/win32/dir_iterator.c | 309 ---------------------------------------- 1 file changed, 309 deletions(-) delete mode 100644 lib/io/src/win32/dir_iterator.c (limited to 'lib/io/src/win32/dir_iterator.c') diff --git a/lib/io/src/win32/dir_iterator.c b/lib/io/src/win32/dir_iterator.c deleted file mode 100644 index 15cfbc5..0000000 --- a/lib/io/src/win32/dir_iterator.c +++ /dev/null @@ -1,309 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * dir_iterator.c - * - * Copyright (C) 2023 David Oberhollenzer - */ -#include "config.h" -#include "io/dir_iterator.h" -#include "util/util.h" -#include "sqfs/error.h" -#include "sqfs/io.h" - -#include -#include -#include - -#define UNIX_EPOCH_ON_W32 11644473600UL -#define W32_TICS_PER_SEC 10000000UL - -typedef struct { - sqfs_dir_iterator_t base; - - WIN32_FIND_DATAW ent; - HANDLE dirhnd; - int state; - bool is_first; - - WCHAR path[]; -} dir_iterator_win32_t; - -static sqfs_s64 w32time_to_unix(const FILETIME *ft) -{ - sqfs_u64 w32ts; - - w32ts = ft->dwHighDateTime; - w32ts <<= 32UL; - w32ts |= ft->dwLowDateTime; - - w32ts /= W32_TICS_PER_SEC; - - if (w32ts <= UNIX_EPOCH_ON_W32) - return -((sqfs_s64)(UNIX_EPOCH_ON_W32 - w32ts)); - - return w32ts - UNIX_EPOCH_ON_W32; -} - -static int dir_iterator_read_link(sqfs_dir_iterator_t *it, char **out) -{ - (void)it; - *out = NULL; - return SQFS_ERROR_UNSUPPORTED; -} - -static int dir_iterator_next(sqfs_dir_iterator_t *it, sqfs_dir_entry_t **out) -{ - dir_iterator_win32_t *w32 = (dir_iterator_win32_t *)it; - sqfs_dir_entry_t *ent = NULL; - DWORD length; - - if (w32->state == 0 && !w32->is_first) { - if (!FindNextFileW(w32->dirhnd, &w32->ent)) { - os_error_t err = get_os_error_state(); - - if (err.w32_errno == ERROR_NO_MORE_FILES) { - w32->state = 1; - } else { - w32->state = SQFS_ERROR_IO; - } - - set_os_error_state(err); - } - } - - w32->is_first = false; - - if (w32->state != 0) - goto out; - - length = WideCharToMultiByte(CP_UTF8, 0, w32->ent.cFileName, - -1, NULL, 0, NULL, NULL); - if (length <= 0) { - w32->state = SQFS_ERROR_ALLOC; - goto out; - } - - ent = alloc_flex(sizeof(*ent), 1, length + 1); - if (ent == NULL) { - w32->state = SQFS_ERROR_ALLOC; - goto out; - } - - WideCharToMultiByte(CP_UTF8, 0, w32->ent.cFileName, -1, - ent->name, length + 1, NULL, NULL); - - if (w32->ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - ent->mode = S_IFDIR | 0755; - } else { - ent->mode = S_IFREG | 0644; - ent->size = w32->ent.nFileSizeHigh; - ent->size <<= 32UL; - ent->size |= w32->ent.nFileSizeLow; - } - - ent->mtime = w32time_to_unix(&(w32->ent.ftLastWriteTime)); -out: - *out = ent; - return w32->state; -} - -static void dir_iterator_destroy(sqfs_object_t *obj) -{ - dir_iterator_win32_t *dir = (dir_iterator_win32_t *)obj; - - FindClose(dir->dirhnd); - free(dir); -} - -static void dir_iterator_ignore_subdir(sqfs_dir_iterator_t *it) -{ - (void)it; -} - -static int dir_iterator_open_file_ro(sqfs_dir_iterator_t *it, - sqfs_istream_t **out) -{ - dir_iterator_win32_t *dir = (dir_iterator_win32_t *)it; - size_t plen, slen; - os_error_t err; - WCHAR *str16; - DWORD length; - HANDLE hnd; - char *str8; - int ret; - - *out = NULL; - - if (dir->state != 0) - return (dir->state > 0) ? SQFS_ERROR_NO_ENTRY : dir->state; - - plen = wcslen(dir->path) - 1; - slen = wcslen(dir->ent.cFileName); - - str16 = calloc(plen + slen + 1, sizeof(WCHAR)); - if (str16 == NULL) - return SQFS_ERROR_ALLOC; - - memcpy(str16, dir->path, plen * sizeof(WCHAR)); - memcpy(str16 + plen, dir->ent.cFileName, slen * sizeof(WCHAR)); - - hnd = CreateFileW(str16, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - NULL); - - err = get_os_error_state(); - free(str16); - set_os_error_state(err); - - if (hnd == INVALID_HANDLE_VALUE) - return SQFS_ERROR_IO; - - length = WideCharToMultiByte(CP_UTF8, 0, dir->ent.cFileName, - -1, NULL, 0, NULL, NULL); - if (length <= 0) { - CloseHandle(hnd); - return SQFS_ERROR_ALLOC; - } - - str8 = calloc(1, length + 1); - if (str8 == NULL) { - CloseHandle(hnd); - return SQFS_ERROR_ALLOC; - } - - WideCharToMultiByte(CP_UTF8, 0, dir->ent.cFileName, -1, str8, - length + 1, NULL, NULL); - - ret = sqfs_istream_open_handle(out, str8, hnd, - SQFS_FILE_OPEN_READ_ONLY); - err = get_os_error_state(); - free(str8); - if (ret != 0) - CloseHandle(hnd); - set_os_error_state(err); - - return ret; -} - -static int dir_iterator_read_xattr(sqfs_dir_iterator_t *it, sqfs_xattr_t **out) -{ - (void)it; - *out = NULL; - return 0; -} - -static int dir_iterator_init(dir_iterator_win32_t *it); - -static int dir_iterator_open_subdir(sqfs_dir_iterator_t *it, - sqfs_dir_iterator_t **out) -{ - const dir_iterator_win32_t *dir = (const dir_iterator_win32_t *)it; - dir_iterator_win32_t *sub = NULL; - size_t plen, slen, total; - int ret; - - *out = NULL; - - if (dir->state != 0) - return (dir->state > 0) ? SQFS_ERROR_NO_ENTRY : dir->state; - - if (!(dir->ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - return SQFS_ERROR_NOT_DIR; - - plen = wcslen(dir->path) - 1; - slen = wcslen(dir->ent.cFileName); - total = plen + slen + 3; - - sub = alloc_flex(sizeof(*sub), sizeof(WCHAR), total); - if (sub == NULL) - return SQFS_ERROR_ALLOC; - - memcpy(sub->path, dir->path, plen * sizeof(WCHAR)); - memcpy(sub->path + plen, dir->ent.cFileName, slen * sizeof(WCHAR)); - sub->path[plen + slen ] = '\\'; - sub->path[plen + slen + 1] = '*'; - sub->path[plen + slen + 2] = '\0'; - - ret = dir_iterator_init(sub); - if (ret != 0) { - free(sub); - sub = NULL; - } - - *out = (sqfs_dir_iterator_t *)sub; - return ret; -} - -static int dir_iterator_init(dir_iterator_win32_t *it) -{ - sqfs_object_init(it, dir_iterator_destroy, NULL); - - ((sqfs_dir_iterator_t *)it)->next = dir_iterator_next; - ((sqfs_dir_iterator_t *)it)->read_link = dir_iterator_read_link; - ((sqfs_dir_iterator_t *)it)->open_subdir = dir_iterator_open_subdir; - ((sqfs_dir_iterator_t *)it)->ignore_subdir = dir_iterator_ignore_subdir; - ((sqfs_dir_iterator_t *)it)->open_file_ro = dir_iterator_open_file_ro; - ((sqfs_dir_iterator_t *)it)->read_xattr = dir_iterator_read_xattr; - it->is_first = true; - it->state = 0; - - it->dirhnd = FindFirstFileW(it->path, &it->ent); - if (it->dirhnd == INVALID_HANDLE_VALUE) - return SQFS_ERROR_IO; - - return 0; -} - -sqfs_dir_iterator_t *dir_iterator_create(const char *path) -{ - dir_iterator_win32_t *it; - size_t len, newlen; - WCHAR *wpath = NULL; - void *new = NULL; - - /* convert path to UTF-16, append "\\*" */ - wpath = path_to_windows(path); - if (wpath == NULL) - goto fail_alloc; - - len = wcslen(wpath); - newlen = len + 1; - - if (len > 0 && wpath[len - 1] != '\\') - newlen += 1; - - new = realloc(wpath, sizeof(wpath[0]) * (newlen + 1)); - if (new == NULL) - goto fail_alloc; - - wpath = new; - - if (len > 0 && wpath[len - 1] != '\\') - wpath[len++] = '\\'; - - wpath[len++] = '*'; - wpath[len++] = '\0'; - - /* create the sourrounding iterator structure */ - new = realloc(wpath, sizeof(*it) + len * sizeof(wpath[0])); - if (new == NULL) - goto fail_alloc; - - it = new; - wpath = NULL; - memmove(it->path, new, len * sizeof(wpath[0])); - - /* initialize */ - memset(it, 0, offsetof(dir_iterator_win32_t, path)); - if (dir_iterator_init(it) != 0) { - w32_perror(path); - free(it); - it = NULL; - } - - return (sqfs_dir_iterator_t *)it; -fail_alloc: - fprintf(stderr, "%s: allocation failure.\n", path); - free(wpath); - return NULL; -} -- cgit v1.2.3