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; +} | 
