diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-10-11 12:53:47 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-10-11 13:03:18 +0200 |
commit | acb4156bd5c730d0c62585eb78b2b6ff21a12fe4 (patch) | |
tree | fbcdec272ecd6dde779866ccb30ea1ee265c16fc | |
parent | bd94eccbdf17c17faf8c0bc96177a497fd9d2655 (diff) |
Add Windows implementation for sqfs_file_t
This commit moves the generic unix implementation into a "unix"
subdirectory and adds a "win32" subdirectory with a winapi based
implementation.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r-- | lib/sqfs/Makemodule.am | 8 | ||||
-rw-r--r-- | lib/sqfs/unix/io_file.c (renamed from lib/sqfs/io_file.c) | 0 | ||||
-rw-r--r-- | lib/sqfs/win32/io_file.c | 170 |
3 files changed, 177 insertions, 1 deletions
diff --git a/lib/sqfs/Makemodule.am b/lib/sqfs/Makemodule.am index 3742f7f..821f22a 100644 --- a/lib/sqfs/Makemodule.am +++ b/lib/sqfs/Makemodule.am @@ -10,7 +10,7 @@ LIBSQFS_HEARDS = include/sqfs/meta_writer.h \ include/sqfs/xattr_reader.h include/sqfs/xattr_writer.h libsquashfs_la_SOURCES = $(LIBSQFS_HEARDS) lib/sqfs/id_table.c lib/sqfs/super.c -libsquashfs_la_SOURCES += lib/sqfs/readdir.c lib/sqfs/io_file.c lib/sqfs/xattr.c +libsquashfs_la_SOURCES += lib/sqfs/readdir.c lib/sqfs/xattr.c libsquashfs_la_SOURCES += lib/sqfs/write_table.c lib/sqfs/meta_writer.c libsquashfs_la_SOURCES += lib/sqfs/read_super.c lib/sqfs/meta_reader.c libsquashfs_la_SOURCES += lib/sqfs/read_inode.c lib/sqfs/write_inode.c @@ -30,6 +30,12 @@ libsquashfs_la_CFLAGS += $(ZSTD_CFLAGS) $(PTHREAD_CFLAGS) libsquashfs_la_LIBADD = $(XZ_LIBS) $(ZLIB_LIBS) $(LZO_LIBS) $(LZ4_LIBS) libsquashfs_la_LIBADD += $(ZSTD_LIBS) $(PTHREAD_LIBS) libutil.la +if WINDOWS +libsquashfs_la_SOURCES += lib/sqfs/win32/io_file.c +else +libsquashfs_la_SOURCES += lib/sqfs/unix/io_file.c +endif + if HAVE_PTHREAD libsquashfs_la_SOURCES += lib/sqfs/data_writer/pthread.c libsquashfs_la_CPPFLAGS += -DWITH_PTHREAD diff --git a/lib/sqfs/io_file.c b/lib/sqfs/unix/io_file.c index f93af4d..f93af4d 100644 --- a/lib/sqfs/io_file.c +++ b/lib/sqfs/unix/io_file.c diff --git a/lib/sqfs/win32/io_file.c b/lib/sqfs/win32/io_file.c new file mode 100644 index 0000000..c3de1fd --- /dev/null +++ b/lib/sqfs/win32/io_file.c @@ -0,0 +1,170 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* + * io_file.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#define SQFS_BUILDING_DLL +#include "config.h" + +#include "sqfs/io.h" +#include "sqfs/error.h" + +#include <stdlib.h> + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + + +typedef struct { + sqfs_file_t base; + + sqfs_u64 size; + HANDLE fd; +} sqfs_file_stdio_t; + + +static void stdio_destroy(sqfs_file_t *base) +{ + sqfs_file_stdio_t *file = (sqfs_file_stdio_t *)base; + + CloseHandle(file->fd); + free(file); +} + +static int stdio_read_at(sqfs_file_t *base, sqfs_u64 offset, + void *buffer, size_t size) +{ + sqfs_file_stdio_t *file = (sqfs_file_stdio_t *)base; + DWORD actually_read; + LARGE_INTEGER pos; + + if (offset >= file->size) + return SQFS_ERROR_OUT_OF_BOUNDS; + + if (size == 0) + return 0; + + if ((offset + size - 1) >= file->size) + return SQFS_ERROR_OUT_OF_BOUNDS; + + pos.QuadPart = offset; + + if (!SetFilePointerEx(file->fd, pos, NULL, FILE_BEGIN)) + return SQFS_ERROR_IO; + + while (size > 0) { + if (!ReadFile(file->fd, buffer, size, &actually_read, NULL)) + return SQFS_ERROR_IO; + + size -= actually_read; + buffer = (char *)buffer + actually_read; + } + + return 0; +} + +static int stdio_write_at(sqfs_file_t *base, sqfs_u64 offset, + const void *buffer, size_t size) +{ + sqfs_file_stdio_t *file = (sqfs_file_stdio_t *)base; + DWORD actually_read; + LARGE_INTEGER pos; + + if (size == 0) + return 0; + + pos.QuadPart = offset; + + if (!SetFilePointerEx(file->fd, pos, NULL, FILE_BEGIN)) + return SQFS_ERROR_IO; + + while (size > 0) { + if (!WriteFile(file->fd, buffer, size, &actually_read, NULL)) + return SQFS_ERROR_IO; + + size -= actually_read; + buffer = (char *)buffer + actually_read; + offset += actually_read; + + if (offset > file->size) + file->size = offset; + } + + return 0; +} + +static sqfs_u64 stdio_get_size(const sqfs_file_t *base) +{ + const sqfs_file_stdio_t *file = (const sqfs_file_stdio_t *)base; + + return file->size; +} + +static int stdio_truncate(sqfs_file_t *base, sqfs_u64 size) +{ + sqfs_file_stdio_t *file = (sqfs_file_stdio_t *)base; + LARGE_INTEGER pos; + + pos.QuadPart = size; + + if (!SetFilePointerEx(file->fd, pos, NULL, FILE_BEGIN)) + return SQFS_ERROR_IO; + + if (!SetEndOfFile(file->fd)) + return SQFS_ERROR_IO; + + file->size = size; + return 0; +} + + +sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags) +{ + int access_flags, creation_mode; + sqfs_file_stdio_t *file; + LARGE_INTEGER size; + sqfs_file_t *base; + + if (flags & ~SQFS_FILE_OPEN_ALL_FLAGS) + return NULL; + + file = calloc(1, sizeof(*file)); + base = (sqfs_file_t *)file; + if (file == NULL) + return NULL; + + if (flags & SQFS_FILE_OPEN_READ_ONLY) { + access_flags = GENERIC_READ; + creation_mode = OPEN_EXISTING; + } else { + access_flags = GENERIC_READ | GENERIC_WRITE; + + if (flags & SQFS_FILE_OPEN_OVERWRITE) { + creation_mode = TRUNCATE_EXISTING; + } else { + creation_mode = CREATE_NEW; + } + } + + file->fd = CreateFile(filename, access_flags, 0, NULL, creation_mode, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (file->fd == INVALID_HANDLE_VALUE) { + free(file); + return NULL; + } + + if (!GetFileSizeEx(file->fd, &size)) { + free(file); + return NULL; + } + + file->size = size.QuadPart; + base->destroy = stdio_destroy; + base->read_at = stdio_read_at; + base->write_at = stdio_write_at; + base->get_size = stdio_get_size; + base->truncate = stdio_truncate; + return base; +} |