ACLOCAL_AMFLAGS = -I m4
-AM_CPPFLAGS = -I$(top_srcdir)/src $(WINDOWS_CPPFLAGS) \
+AM_CPPFLAGS = -I$(top_srcdir)/include $(WINDOWS_CPPFLAGS) \
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
-AM_CFLAGS = -std=gnu99 -fno-strict-aliasing
+AM_CFLAGS = -std=gnu99 -fno-strict-aliasing \
+ -Wmissing-prototypes -Wstrict-prototypes
lib_LTLIBRARIES = libwim.la
libwim_la_SOURCES = \
src/add_image.c \
- src/buffer_io.h \
src/capture_common.c \
src/compress.c \
- src/compress.h \
src/decompress.c \
- src/decompress.h \
src/delete_image.c \
src/dentry.c \
- src/dentry.h \
src/encoding.c \
- src/endianness.h \
src/export_image.c \
- src/extract_image.c \
+ src/extract.c \
+ src/file_io.c \
src/hardlink.c \
src/header.c \
src/integrity.c \
src/join.c \
- src/list.h \
src/lookup_table.c \
- src/lookup_table.h \
src/lz77.c \
src/lzx-common.c \
src/lzx-compress.c \
src/lzx-decompress.c \
- src/lzx.h \
src/metadata_resource.c \
src/mount_image.c \
+ src/paths.c \
src/resource.c \
src/rbtree.c \
- src/rbtree.h \
src/security.c \
- src/security.h \
src/sha1.c \
- src/sha1.h \
src/split.c \
src/reparse.c \
- src/timestamp.h \
+ src/timestamp.c \
src/update_image.c \
src/util.c \
- src/util.h \
src/verify.c \
src/wim.c \
- src/wimlib.h \
- wimlib_tchar.h \
- src/wimlib_internal.h \
src/write.c \
src/xml.c \
- src/xml.h \
src/xpress-compress.c \
- src/xpress-decompress.c \
- src/xpress.h
+ src/xpress-decompress.c \
+ include/wimlib/apply.h \
+ include/wimlib/assert.h \
+ include/wimlib/buffer_io.h \
+ include/wimlib/callback.h \
+ include/wimlib/capture.h \
+ include/wimlib/compiler.h \
+ include/wimlib/compress.h \
+ include/wimlib/decompress.h \
+ include/wimlib/dentry.h \
+ include/wimlib/encoding.h \
+ include/wimlib/endianness.h \
+ include/wimlib/error.h \
+ include/wimlib/file_io.h \
+ include/wimlib/header.h \
+ include/wimlib/integrity.h \
+ include/wimlib/list.h \
+ include/wimlib/lookup_table.h \
+ include/wimlib/lzx.h \
+ include/wimlib/metadata.h \
+ include/wimlib/ntfs_3g.h \
+ include/wimlib/paths.h \
+ include/wimlib/rbtree.h \
+ include/wimlib/reparse.h \
+ include/wimlib/resource.h \
+ include/wimlib/security.h \
+ include/wimlib/sha1.h \
+ include/wimlib/swm.h \
+ include/wimlib/timestamp.h \
+ include/wimlib/types.h \
+ include/wimlib/util.h \
+ include/wimlib/version.h \
+ include/wimlib/wim.h \
+ include/wimlib/write.h \
+ include/wimlib/xml.h \
+ include/wimlib/xpress.h
if WITH_NTFS_3G
-libwim_la_SOURCES += src/ntfs-apply.c \
- src/ntfs-capture.c
+libwim_la_SOURCES += src/ntfs-3g_apply.c \
+ src/ntfs-3g_capture.c \
+ include/wimlib/ntfs_3g.h
+endif
+
+if WINDOWS_NATIVE_BUILD
+libwim_la_SOURCES += src/win32_common.c \
+ src/win32_apply.c \
+ src/win32_capture.c \
+ src/win32_replacements.c \
+ include/wimlib/win32_common.h \
+ include/wimlib/win32.h
+else
+libwim_la_SOURCES += src/unix_apply.c \
+ src/unix_capture.c
endif
+
EXTRA_libwim_la_SOURCES = src/sha1-ssse3.asm
libwim_la_DEPENDENCIES = $(SSSE3_SHA1_OBJ)
STRIP_FPIC = sh $(top_srcdir)/build-aux/strip_fPIC.sh
bin_PROGRAMS = imagex
-imagex_SOURCES = programs/imagex.c wimlib_tchar.h
+imagex_SOURCES = programs/imagex.c \
+ include/wimlib.h \
+ include/wimlib_tchar.h
imagex_LDADD = $(top_builddir)/libwim.la
imagex_CFLAGS = $(AM_CFLAGS) $(WINDOWS_CFLAGS)
programs/imagex-win32.h \
programs/wgetopt.c \
programs/wgetopt.h
-
-libwim_la_SOURCES += src/win32_common.c \
- src/win32_apply.c \
- src/win32_capture.c \
- src/win32.h \
- src/win32_common.h
-else
-libwim_la_SOURCES += src/unix_apply.c \
- src/unix_capture.c
endif
install-exec-hook:
dist_bin_SCRIPTS = programs/mkwinpeimg
-include_HEADERS = src/wimlib.h
+include_HEADERS = include/wimlib.h
EXTRA_DIST = \
build-aux/strip_fPIC.sh \
as it exists in reality and not as it exists in Microsoft's poorly written
documentation.
-The code in ntfs-apply.c and ntfs-capture.c uses the NTFS-3g library, which is a
-library for reading and writing to NTFS filesystems (the filesystem used by
-recent versions of Windows). See
+The code in ntfs-3g_apply.c and ntfs-3g_capture.c uses the NTFS-3g library,
+which is a library for reading and writing to NTFS filesystems (the filesystem
+used by recent versions of Windows). See
http://www.tuxera.com/community/ntfs-3g-download/ for more information.
lzx-decompress.c, the code to decompress WIM file resources that are compressed
AC_MSG_CHECKING([whether to include support for ntfs-3g])
AC_ARG_WITH([ntfs-3g],
AS_HELP_STRING([--without-ntfs-3g], [build without NTFS-3g.
- This will disable the ability to use NTFS-specific
+ On UNIX, this will disable the ability to use NTFS-specific
information when capturing or applying WIMs to a
NTFS filesystem.]),
[WITH_NTFS_3G=$withval],
)
AC_MSG_RESULT([$WITH_NTFS_3G])
if test "x$WITH_NTFS_3G" = "xyes"; then
- AC_DEFINE([WITH_NTFS_3G], [1], [Define to 1 to enable support for
- NTFS-specific information])
+ AC_DEFINE([WITH_NTFS_3G], [1], [On UNIX, define to 1 to enable support
+ for NTFS-specific information])
dnl This effectively checks for NTFS-3g 2011.4.12 or later
AC_CHECK_LIB([ntfs-3g], [ntfs_xattr_system_setxattr], [],
--- /dev/null
+./configure --host=i686-w64-mingw32 "$@"
JAVADOC_AUTOBRIEF = YES
OPTIMIZE_OUTPUT_FOR_C = YES
SHOW_USED_FILES = YES
-INPUT = @top_srcdir@/src/wimlib.h
+INPUT = @top_srcdir@/include/wimlib.h
FULL_PATH_NAMES = NO
OPTIMIZE_FOR_C = YES
GENERATE_HTML = YES
* Use wimlib_write() or wimlib_overwrite() to actually write an on-disk WIM
* file from a ::WIMStruct.
*/
+#ifndef WIMLIB_WIMSTRUCT_DECLARED
typedef struct WIMStruct WIMStruct;
+#define WIMLIB_WIMSTRUCT_DECLARED
+#endif
#ifdef __WIN32__
typedef wchar_t wimlib_tchar;
* memory allocated by the library.
*/
extern void
-wimlib_global_cleanup();
+wimlib_global_cleanup(void);
/**
* Returns true if the WIM has an integrity table.
--- /dev/null
+#ifndef _WIMLIB_APPLY_H
+#define _WIMLIB_APPLY_H
+
+#include "wimlib.h"
+#include "wimlib/types.h"
+
+#ifdef WITH_NTFS_3G
+struct _ntfs_volume;
+#endif
+
+struct apply_args {
+ WIMStruct *w;
+ const tchar *target;
+ unsigned target_nchars;
+ unsigned wim_source_path_nchars;
+ struct wim_dentry *extract_root;
+ tchar *target_realpath;
+ unsigned target_realpath_len;
+ int extract_flags;
+ union wimlib_progress_info progress;
+ wimlib_progress_func_t progress_func;
+ int (*apply_dentry)(struct wim_dentry *, void *);
+ union {
+ #ifdef WITH_NTFS_3G
+ struct {
+ /* NTFS apply only */
+ struct _ntfs_volume *vol;
+ };
+ #endif
+ #ifdef __WIN32__
+ struct {
+ /* Normal apply only (Win32) */
+ unsigned long num_set_sacl_priv_notheld;
+ unsigned long num_set_sd_access_denied;
+ unsigned vol_flags;
+ unsigned long num_hard_links_failed;
+ unsigned long num_soft_links_failed;
+ bool have_vol_flags;
+ };
+ #else
+ struct {
+ /* Normal apply only (UNIX) */
+ unsigned long num_utime_warnings;
+ };
+ #endif
+ };
+};
+
+#ifdef WITH_NTFS_3G
+extern int
+apply_dentry_ntfs(struct wim_dentry *dentry, void *arg);
+
+extern int
+apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg);
+#endif
+
+#ifdef __WIN32__
+extern int
+win32_do_apply_dentry(const tchar *output_path,
+ size_t output_path_nbytes,
+ struct wim_dentry *dentry,
+ struct apply_args *args);
+
+extern int
+win32_do_apply_dentry_timestamps(const tchar *output_path,
+ size_t output_path_nbytes,
+ struct wim_dentry *dentry,
+ struct apply_args *args);
+#else /* __WIN32__ */
+extern int
+unix_do_apply_dentry(const tchar *output_path, size_t output_path_nbytes,
+ struct wim_dentry *dentry, struct apply_args *args);
+extern int
+unix_do_apply_dentry_timestamps(const tchar *output_path,
+ size_t output_path_nbytes,
+ struct wim_dentry *dentry,
+ struct apply_args *args);
+#endif /* !__WIN32__ */
+
+/* Internal use only */
+#define WIMLIB_EXTRACT_FLAG_MULTI_IMAGE 0x80000000
+#define WIMLIB_EXTRACT_FLAG_NO_STREAMS 0x40000000
+#define WIMLIB_EXTRACT_MASK_PUBLIC 0x3fffffff
+
+
+#endif /* _WIMLIB_APPLY_H */
--- /dev/null
+#ifndef _WIMLIB_ASSERT_H
+#define _WIMLIB_ASSERT_H
+
+#ifdef ENABLE_ASSERTIONS
+#include <assert.h>
+# define wimlib_assert(expr) assert(expr)
+#else
+# define wimlib_assert(expr)
+#endif
+
+#ifdef ENABLE_MORE_ASSERTIONS
+# define wimlib_assert2(expr) wimlib_assert(expr)
+#else
+# define wimlib_assert2(expr)
+#endif
+
+#endif /* _WIMLIB_ASSERT_H */
#ifndef _WIMLIB_BUFFER_IO_H
#define _WIMLIB_BUFFER_IO_H
-#include "util.h"
+#include "wimlib/types.h"
#include "endianness.h"
#include <string.h>
{
return memcpy(p, input, num_bytes) + num_bytes;
}
+
#endif /* _WIMLIB_BUFFER_IO_H */
--- /dev/null
+#ifndef _WIMLIB_CALLBACK_H
+#define _WIMLIB_CALLBACK_H
+
+#include <stddef.h>
+
+typedef int (*consume_data_callback_t)(const void *buf, size_t len, void *ctx);
+
+#endif
--- /dev/null
+#ifndef _WIMLIB_CAPTURE_H
+#define _WIMLIB_CAPTURE_H
+
+#include "wimlib.h"
+#include "wimlib/list.h"
+#include "wimlib/security.h"
+#include "wimlib/util.h"
+
+struct wim_lookup_table;
+struct wim_dentry;
+
+/* Hash table to find inodes, given an inode number (in the case of reading
+ * a WIM images), or both an inode number and a device number (in the case of
+ * capturing a WIM image). */
+struct wim_inode_table {
+ /* Fields for the hash table */
+ struct hlist_head *array;
+ u64 num_entries;
+ u64 capacity;
+
+ /*
+ * Linked list of "extra" inodes. These may be:
+ *
+ * - inodes with link count 1, which are all allowed to have 0 for their
+ * inode number, meaning we cannot insert them into the hash table.
+ *
+ * - Groups we create ourselves by splitting a nominal inode due to
+ * inconsistencies in the dentries. These inodes will share an inode
+ * number with some other inode until assign_inode_numbers() is
+ * called.
+ */
+ struct list_head extra_inodes;
+};
+
+/* Common parameters to implementations of building an in-memory dentry tree
+ * from an on-disk directory structure. */
+struct add_image_params {
+ /* Pointer to the lookup table of the WIM. */
+ struct wim_lookup_table *lookup_table;
+
+ /* Hash table of inodes that have been captured for this tree so far. */
+ struct wim_inode_table inode_table;
+
+ /* The set of security descriptors that have been captured for this
+ * image so far. */
+ struct wim_sd_set sd_set;
+
+ /* Pointer to the capture configuration, which indicates whether any
+ * files should be excluded from capture or not. */
+ const struct wimlib_capture_config *config;
+
+ /* Flags that affect the capture operation (WIMLIB_ADD_FLAG_*) */
+ int add_flags;
+
+ /* If non-NULL, the user-supplied progress function. */
+ wimlib_progress_func_t progress_func;
+
+ /* Extra argument; set to point to a pointer to the ntfs_volume for
+ * libntfs-3g capture. */
+ void *extra_arg;
+
+ u64 capture_root_ino;
+ u64 capture_root_dev;
+};
+
+
+/* capture_common.c */
+
+extern bool
+exclude_path(const tchar *path, size_t path_len,
+ const struct wimlib_capture_config *config,
+ bool exclude_prefix);
+
+extern struct wimlib_capture_config *
+copy_capture_config(const struct wimlib_capture_config *config);
+
+extern int
+copy_and_canonicalize_capture_config(const struct wimlib_capture_config *config,
+ struct wimlib_capture_config **config_copy_ret);
+
+extern void
+free_capture_config(struct wimlib_capture_config *config);
+
+/* hardlink.c */
+
+extern int
+init_inode_table(struct wim_inode_table *table, size_t capacity);
+
+extern int
+inode_table_new_dentry(struct wim_inode_table *table, const tchar *name,
+ u64 ino, u64 devno, bool noshare,
+ struct wim_dentry **dentry_ret);
+
+extern void
+inode_table_prepare_inode_list(struct wim_inode_table *table,
+ struct list_head *head);
+
+static inline void
+destroy_inode_table(struct wim_inode_table *table)
+{
+ FREE(table->array);
+}
+
+
+#ifdef WITH_NTFS_3G
+/* ntfs-3g_capture.c */
+extern int
+build_dentry_tree_ntfs(struct wim_dentry **root_p,
+ const tchar *device,
+ struct add_image_params *params);
+#endif
+
+#ifdef __WIN32__
+/* win32_capture.c */
+extern int
+win32_build_dentry_tree(struct wim_dentry **root_ret,
+ const tchar *root_disk_path,
+ struct add_image_params *params);
+#else
+/* unix_capture.c */
+extern int
+unix_build_dentry_tree(struct wim_dentry **root_ret,
+ const tchar *root_disk_path,
+ struct add_image_params *params);
+#endif
+
+#define WIMLIB_ADD_FLAG_ROOT 0x80000000
+
+#endif /* _WIMLIB_CAPTURE_H */
--- /dev/null
+#ifndef _WIMLIB_COMPILER_H
+#define _WIMLIB_COMPILER_H
+
+#ifdef __GNUC__
+# if defined(__CYGWIN__) || defined(__WIN32__)
+# define WIMLIBAPI __declspec(dllexport)
+# else
+# define WIMLIBAPI __attribute__((visibility("default")))
+# endif
+# define ALWAYS_INLINE inline __attribute__((always_inline))
+# define PACKED __attribute__((packed))
+# define FORMAT(type, format_str, args_start) \
+ /*__attribute__((format(type, format_str, args_start))) */
+# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+# define COLD __attribute__((cold))
+# else
+# define COLD
+# endif
+#else
+# define WIMLIBAPI
+# define ALWAYS_INLINE inline
+# define FORMAT(type, format_str, args_start)
+# define COLD
+# define PACKED
+#endif /* __GNUC__ */
+
+#endif /* _WIMLIB_COMPILER_H */
#ifndef _WIMLIB_COMPRESS_H
#define _WIMLIB_COMPRESS_H
-#include "util.h"
-#include "endianness.h"
+#include "wimlib/endianness.h"
+#include "wimlib/types.h"
typedef u16 output_bitbuf_t;
* Functions useful for decompression, mainly bitstreams.
*/
-#ifndef _WIMLIB_DECOMP_H
-#define _WIMLIB_DECOMP_H
+#ifndef _WIMLIB_DECOMPRESS_H
+#define _WIMLIB_DECOMPRESS_H
-#include "util.h"
-#include "endianness.h"
+#include "wimlib/assert.h"
+#include "wimlib/endianness.h"
+#include "wimlib/error.h"
+#include "wimlib/types.h"
/* Must be at least 32 bits. */
typedef unsigned long input_bitbuf_t;
};
/* Initializes a bitstream to receive its input from @data. */
-static inline void init_input_bitstream(struct input_bitstream *istream,
- const void *data, unsigned num_data_bytes)
+static inline void
+init_input_bitstream(struct input_bitstream *istream,
+ const void *data, unsigned num_data_bytes)
{
istream->bitbuf = 0;
istream->bitsleft = 0;
*
* If there are at least @num_bits bits remaining in the bitstream, 0 is
* returned. Otherwise, -1 is returned. */
-static inline int bitstream_ensure_bits(struct input_bitstream *istream,
- unsigned num_bits)
+static inline int
+bitstream_ensure_bits(struct input_bitstream *istream, unsigned num_bits)
{
wimlib_assert2(num_bits <= 16);
/* Removes @num_bits bits from the buffer variable, which must contain at least
* @num_bits bits, for the bitstream. */
-static inline void bitstream_remove_bits(struct input_bitstream *istream,
- unsigned num_bits)
+static inline void
+bitstream_remove_bits(struct input_bitstream *istream, unsigned num_bits)
{
wimlib_assert2(istream->bitsleft >= num_bits);
istream->bitbuf <<= num_bits;
/* Reads @num_bits bits from the input bitstream. @num_bits must be 16 or fewer.
* On success, returns 0 and returns the requested bits in @n. If there are
* fewer than @num_bits remaining in the bitstream, -1 is returned. */
-static inline int bitstream_read_bits(struct input_bitstream *istream,
- unsigned num_bits, unsigned *n)
+static inline int
+bitstream_read_bits(struct input_bitstream *istream,
+ unsigned num_bits, unsigned *n)
{
wimlib_assert2(num_bits <= 16);
int ret = bitstream_ensure_bits(istream, num_bits);
*
* This function returns the next such literal byte, or -1 if there are no more.
*/
-static inline int bitstream_read_byte(struct input_bitstream *istream)
+static inline int
+bitstream_read_byte(struct input_bitstream *istream)
{
wimlib_assert2(istream->bitsleft < 32);
int ret;
return n;
}
-extern int read_huffsym_near_end_of_input(struct input_bitstream *istream,
- const u16 decode_table[],
- const u8 lens[],
- unsigned num_syms,
- unsigned table_bits,
- unsigned *n);
+extern int
+read_huffsym_near_end_of_input(struct input_bitstream *istream,
+ const u16 decode_table[],
+ const u8 lens[],
+ unsigned num_syms,
+ unsigned table_bits,
+ unsigned *n);
/*
* Reads a Huffman-encoded symbol from a bitstream.
* directory in the decode_table, as the
* decode_table contains 2**table_bits entries.
*/
-static inline int read_huffsym(struct input_bitstream *istream,
- const u16 decode_table[],
- const u8 lens[],
- unsigned num_syms,
- unsigned table_bits,
- unsigned *n,
- unsigned max_codeword_len)
+static inline int
+read_huffsym(struct input_bitstream *istream,
+ const u16 decode_table[],
+ const u8 lens[],
+ unsigned num_syms,
+ unsigned table_bits,
+ unsigned *n,
+ unsigned max_codeword_len)
{
int ret;
unsigned num_bits, const u8 lengths[],
unsigned max_codeword_len);
-#endif /* _WIMLIB_DECOMP_H */
+#endif /* _WIMLIB_DECOMPRESS_H */
#ifndef _WIMLIB_DENTRY_H
#define _WIMLIB_DENTRY_H
-#include "util.h"
-#include "config.h"
-#include "list.h"
-#include "sha1.h"
-#include "rbtree.h"
+#include "wimlib/list.h"
+#include "wimlib/rbtree.h"
+#include "wimlib/sha1.h"
+#include "wimlib/types.h"
+
#include <string.h>
+#include <sys/types.h> /* uid_t, gid_t */
#ifdef WITH_FUSE
-#include <pthread.h>
+# include <pthread.h>
#endif
-struct stat;
struct wim_lookup_table;
-struct WIMStruct;
struct wim_lookup_table_entry;
struct wimfs_fd;
struct wim_inode;
-struct wim_dentry;
/* Size of the struct wim_dentry up to and including the file_name_len. */
#define WIM_DENTRY_DISK_SIZE 102
dentry_full_path(struct wim_dentry *dentry);
extern struct wim_inode *
-new_timeless_inode();
+new_timeless_inode(void);
extern int
new_dentry(const tchar *name, struct wim_dentry **dentry_ret);
return dentry->file_name_nbytes != 0;
}
+extern void
+inode_ref_streams(struct wim_inode *inode);
+
+extern int
+dentry_tree_fix_inodes(struct wim_dentry *root, struct list_head *inode_list);
+
+extern int
+verify_dentry(struct wim_dentry *dentry, void *wim);
+
#endif
--- /dev/null
+#ifndef _WIMLIB_ENCODING_H
+#define _WIMLIB_ENCODING_H
+
+#include "wimlib/types.h"
+
+extern void
+iconv_global_cleanup(void);
+
+extern bool wimlib_mbs_is_utf8;
+
+#define DECLARE_CHAR_CONVERSION_FUNCTIONS(varname1, varname2, \
+ chartype1, chartype2) \
+ \
+extern int \
+varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes, \
+ chartype2 **out_ret, \
+ size_t *out_nbytes_ret); \
+ \
+extern int \
+varname1##_to_##varname2##_nbytes(const chartype1 *in, size_t in_nbytes,\
+ size_t *out_nbytes_ret); \
+ \
+extern int \
+varname1##_to_##varname2##_buf(const chartype1 *in, size_t in_nbytes, \
+ chartype2 *out);
+
+
+#if !TCHAR_IS_UTF16LE
+DECLARE_CHAR_CONVERSION_FUNCTIONS(utf16le, tstr, utf16lechar, tchar);
+DECLARE_CHAR_CONVERSION_FUNCTIONS(tstr, utf16le, tchar, utf16lechar);
+#endif
+
+extern int
+utf8_to_tstr_simple(const char *utf8str, tchar **out);
+
+extern int
+tstr_to_utf8_simple(const tchar *tstr, char **out);
+
+#endif /* _WIMLIB_ENCODING_H */
#ifndef _WIMLIB_ENDIANNESS_H
#define _WIMLIB_ENDIANNESS_H
+#include "wimlib/types.h"
-#include "config.h"
-#include <inttypes.h>
+/* Watch out for conflict with ntfs-3g/endian.h ... */
-/* Watch out for conflicts with ntfs-3g headers... */
+#ifndef _NTFS_ENDIANS_H
-#ifndef bswap16
-static inline uint16_t
-bswap16(uint16_t n)
+static inline u16
+bswap16(u16 n)
{
return (n << 8) | (n >> 8);
}
-#endif /* ifndef bswap16 */
-#ifndef bswap32
-static inline uint32_t
-bswap32(uint32_t n)
+static inline u32
+bswap32(u32 n)
{
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
return __builtin_bswap32(n);
(n >> 24);
#endif
}
-#endif /* ifndef bswap32 */
-#ifndef bswap64
-static inline uint64_t
-bswap64(uint64_t n)
+static inline u64
+bswap64(u64 n)
{
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
return __builtin_bswap64(n);
((n & 0xff000000000000) >> 40) | (n >> 56);
#endif
}
-#endif /* ifndef bswap64 */
-
-#ifndef _NTFS_ENDIANS_H
-# ifdef WORDS_BIGENDIAN
-# define le16_to_cpu(n) bswap16(n)
-# define le32_to_cpu(n) bswap32(n)
-# define le64_to_cpu(n) bswap64(n)
-# define cpu_to_le16(n) bswap16(n)
-# define cpu_to_le32(n) bswap32(n)
-# define cpu_to_le64(n) bswap64(n)
-# else
-# define cpu_to_le16(n) (n)
-# define cpu_to_le32(n) (n)
-# define cpu_to_le64(n) (n)
-# define le16_to_cpu(n) (n)
-# define le32_to_cpu(n) (n)
-# define le64_to_cpu(n) (n)
-# endif
-#endif
+# ifdef WORDS_BIGENDIAN
+# define le16_to_cpu(n) bswap16(n)
+# define le32_to_cpu(n) bswap32(n)
+# define le64_to_cpu(n) bswap64(n)
+# define cpu_to_le16(n) bswap16(n)
+# define cpu_to_le32(n) bswap32(n)
+# define cpu_to_le64(n) bswap64(n)
+# else
+# define cpu_to_le16(n) (n)
+# define cpu_to_le32(n) (n)
+# define cpu_to_le64(n) (n)
+# define le16_to_cpu(n) (n)
+# define le32_to_cpu(n) (n)
+# define le64_to_cpu(n) (n)
+# endif
+#endif /* _NTFS_ENDIANS_H */
static inline void
-array_cpu_to_le32(uint32_t *p, size_t n)
+array_cpu_to_le32(u32 *p, size_t n)
{
for (size_t i = 0; i < n; i++)
p[i] = cpu_to_le32(p[i]);
}
static inline void
-array_le32_to_cpu(uint32_t *p, size_t n)
+array_le32_to_cpu(u32 *p, size_t n)
{
for (size_t i = 0; i < n; i++)
p[i] = le32_to_cpu(p[i]);
}
static inline void
-array_cpu_to_le64(uint64_t *p, size_t n)
+array_cpu_to_le64(u64 *p, size_t n)
{
for (size_t i = 0; i < n; i++)
p[i] = cpu_to_le64(p[i]);
}
static inline void
-array_le64_to_cpu(uint64_t *p, size_t n)
+array_le64_to_cpu(u64 *p, size_t n)
{
for (size_t i = 0; i < n; i++)
p[i] = le64_to_cpu(p[i]);
}
-
#endif /* _WIMLIB_ENDIANNESS_H */
--- /dev/null
+#ifndef _WIMLIB_ERROR_H
+#define _WIMLIB_ERROR_H
+
+#include "wimlib.h" /* Get error code definitions */
+#include "wimlib/compiler.h"
+#include "wimlib/types.h"
+
+#include <stdio.h>
+
+#ifdef __WIN32__
+# define wimlib_fprintf fwprintf
+# define wimlib_printf wprintf
+#else /* __WIN32__ */
+extern int
+wimlib_fprintf(FILE *fp, const tchar *format, ...) FORMAT(printf, 2, 3);
+
+extern int
+wimlib_printf(const tchar *format, ...) FORMAT(printf, 1, 2);
+#endif /* !__WIN32__ */
+
+
+static inline int dummy_tprintf(const tchar *format, ...)
+{
+ return 0;
+}
+
+#ifdef ENABLE_ERROR_MESSAGES
+extern void
+wimlib_error(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
+
+extern void
+wimlib_error_with_errno(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
+
+extern void
+wimlib_warning(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
+
+extern void
+wimlib_warning_with_errno(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
+# define ERROR(format, ...) wimlib_error(T(format), ## __VA_ARGS__)
+# define ERROR_WITH_ERRNO(format, ...) wimlib_error_with_errno(T(format), ## __VA_ARGS__)
+# define WARNING(format, ...) wimlib_warning(T(format), ## __VA_ARGS__)
+# define WARNING_WITH_ERRNO(format, ...) wimlib_warning_with_errno(T(format), ## __VA_ARGS__)
+#else /* ENABLE_ERROR_MESSAGES */
+# define ERROR(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
+# define ERROR_WITH_ERRNO(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
+# define WARNING(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
+# define WARNING_WITH_ERRNO(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
+#endif /* !ENABLE_ERROR_MESSAGES */
+
+#if defined(ENABLE_MORE_DEBUG) && !defined(ENABLE_DEBUG)
+# define ENABLE_DEBUG 1
+#endif
+
+#if defined(ENABLE_MORE_ASSERTIONS) && !defined(ENABLE_ASSERTIONS)
+# define ENABLE_ASSERTIONS 1
+#endif
+
+#ifdef ENABLE_DEBUG
+extern void
+wimlib_debug(const tchar *file, int line, const char *func,
+ const tchar *format, ...);
+# define DEBUG(format, ...) \
+ wimlib_debug(T(__FILE__), __LINE__, __func__, T(format), ## __VA_ARGS__)
+
+#else
+# define DEBUG(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
+#endif /* !ENABLE_DEBUG */
+
+#ifdef ENABLE_MORE_DEBUG
+# define DEBUG2(format, ...) DEBUG(format, ## __VA_ARGS__)
+#else
+# define DEBUG2(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
+#endif /* !ENABLE_MORE_DEBUG */
+
+#endif /* _WIMLIB_ERROR_H */
--- /dev/null
+#ifndef _WIMLIB_FILE_IO_H
+#define _WIMLIB_FILE_IO_H
+
+#include <stddef.h>
+#include <sys/types.h>
+
+extern size_t
+full_read(int fd, void *buf, size_t n);
+
+extern size_t
+full_write(int fd, const void *buf, size_t n);
+
+extern size_t
+full_pread(int fd, void *buf, size_t nbyte, off_t offset);
+
+extern size_t
+full_pwrite(int fd, const void *buf, size_t count, off_t offset);
+
+
+#ifdef __WIN32__
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+#else
+struct iovec;
+#endif
+
+extern size_t
+full_writev(int fd, struct iovec *iov, int iovcnt);
+
+extern off_t
+filedes_offset(int fd);
+
+#ifndef __WIN32__
+# define O_BINARY 0
+#endif
+
+#endif /* _WIMLIB_FILE_IO_H */
--- /dev/null
+#ifndef _WIMLIB_HEADER_H
+#define _WIMLIB_HEADER_H
+
+#include "wimlib/resource.h"
+#include "wimlib/types.h"
+
+#define WIM_MAGIC_LEN 8
+#define WIM_GID_LEN 16
+#define WIM_UNUSED_LEN 60
+
+/* Length of the WIM header on disk. */
+#define WIM_HEADER_DISK_SIZE (148 + WIM_UNUSED_LEN)
+
+/* Compressed resources in the WIM are divided into separated compressed chunks
+ * of this size. */
+#define WIM_CHUNK_SIZE 32768
+
+/* Version of the WIM file. There is an older version, but we don't support it
+ * yet. The differences between the versions are undocumented. */
+#define WIM_VERSION 0x10d00
+
+/* Header at the very beginning of the WIM file. */
+struct wim_header {
+ /* Identifies the file as WIM file. Must be exactly
+ * {'M', 'S', 'W', 'I', 'M', 0, 0, 0} */
+ //u8 magic[WIM_MAGIC_LEN];
+
+ /* size of WIM header in bytes. */
+ //u32 hdr_size;
+
+ /* Version of the WIM file. Microsoft provides no documentation about
+ * exactly what this field affects about the file format, other than the
+ * fact that more recent versions have a higher value. */
+ //u32 version;
+
+ /* Bitwise OR of one or more of the WIM_HDR_FLAG_* defined below. */
+ u32 flags;
+
+ /* The size of the pieces that the uncompressed files were split up into
+ * when they were compressed. This should be the same as
+ * WIM_CHUNK_SIZE. Microsoft incorrectly documents this as "the size of
+ * the compressed .wim file in bytes".*/
+ //u32 chunk_size;
+
+ /* A unique identifier for the WIM file. */
+ u8 guid[WIM_GID_LEN];
+
+ /* Part number of the WIM file in a spanned set. */
+ u16 part_number;
+
+ /* Total number of parts in a spanned set. */
+ u16 total_parts;
+
+ /* Number of images in the WIM file. */
+ u32 image_count;
+
+ /* Location, size, and flags of the lookup table of the WIM. */
+ struct resource_entry lookup_table_res_entry;
+
+ /* Location, size, and flags for the XML data of the WIM. */
+ struct resource_entry xml_res_entry;
+
+ /* Location, size, and flags for the boot metadata. This means the
+ * metadata resource for the image specified by boot_idx below. Should
+ * be zeroed out if boot_idx is 0. */
+ struct resource_entry boot_metadata_res_entry;
+
+ /* The index of the bootable image in the WIM file. If 0, there are no
+ * bootable images available. */
+ u32 boot_idx;
+
+ /* The location of the optional integrity table used to verify the
+ * integrity WIM. Zeroed out if there is no integrity table.*/
+ struct resource_entry integrity;
+
+ /* Reserved for future disuse */
+ //u8 unused[WIM_UNUSED_LEN];
+};
+
+/* Flags for the `flags' field of the struct wim_header: */
+
+/* Reserved for future use */
+#define WIM_HDR_FLAG_RESERVED 0x00000001
+
+/* Files and metadata in the WIM are compressed. */
+#define WIM_HDR_FLAG_COMPRESSION 0x00000002
+
+/* WIM is read-only (wimlib ignores this because it's pretty much pointless) */
+#define WIM_HDR_FLAG_READONLY 0x00000004
+
+/* Resource data specified by images in this WIM may be contained in a different
+ * WIM. Or in other words, this WIM is part of a split WIM. */
+#define WIM_HDR_FLAG_SPANNED 0x00000008
+
+/* The WIM contains resources only; no filesystem metadata. wimlib ignores this
+ * flag, as it looks for resources in all the WIMs anyway. */
+#define WIM_HDR_FLAG_RESOURCE_ONLY 0x00000010
+
+/* The WIM contains metadata only. wimlib ignores this flag. Note that all the
+ * metadata resources for a split WIM should be in the first part. */
+#define WIM_HDR_FLAG_METADATA_ONLY 0x00000020
+
+/* Lock field to prevent multiple writers from writing the WIM concurrently.
+ * wimlib ignores this flag as it uses flock() to acquire a real lock on the
+ * file (if supported by the underlying filesystem). */
+#define WIM_HDR_FLAG_WRITE_IN_PROGRESS 0x00000040
+
+/* Reparse point fixup flag. See docs for --rpfix and --norpfix in imagex, or
+ * WIMLIB_ADD_FLAG_{RPFIX,NORPFIX} in wimlib.h. Note that
+ * WIM_HDR_FLAG_RP_FIX is a header flag and just sets the default behavior for
+ * the WIM; it can still be overridder on a per-image basis. But there is no
+ * flag to set the default behavior for a specific image. */
+#define WIM_HDR_FLAG_RP_FIX 0x00000080
+
+/* Unused, reserved flag for another compression type */
+#define WIM_HDR_FLAG_COMPRESS_RESERVED 0x00010000
+
+/* Resources within the WIM are compressed using "XPRESS" compression, which is
+ * a LZ77-based compression algorithm. */
+#define WIM_HDR_FLAG_COMPRESS_XPRESS 0x00020000
+
+/* Resources within the WIM are compressed using "LZX" compression. This is also
+ * a LZ77-based algorithm. */
+#define WIM_HDR_FLAG_COMPRESS_LZX 0x00040000
+
+#endif /* _WIMLIB_HEADER_H */
--- /dev/null
+#ifndef _WIMLIB_INTEGRITY_H
+#define _WIMLIB_INTEGRITY_H
+
+#include "wimlib.h"
+#include <sys/types.h>
+
+#define WIM_INTEGRITY_OK 0
+#define WIM_INTEGRITY_NOT_OK -1
+#define WIM_INTEGRITY_NONEXISTENT -2
+
+struct resource_entry;
+
+extern int
+write_integrity_table(int fd,
+ struct resource_entry *integrity_res_entry,
+ off_t new_lookup_table_end,
+ off_t old_lookup_table_end,
+ wimlib_progress_func_t progress_func);
+
+extern int
+check_wim_integrity(WIMStruct *w, wimlib_progress_func_t progress_func);
+
+#endif /* _WIMLIB_INTEGRITY_H */
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#ifdef LIST_HEAD /* BSD sys/queue.h defines this... */
-#undef LIST_HEAD
+# undef LIST_HEAD
#endif
#define LIST_HEAD(name) \
#ifndef _WIMLIB_LOOKUP_TABLE_H
#define _WIMLIB_LOOKUP_TABLE_H
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "sha1.h"
-#include <sys/types.h>
-/* Size of each lookup table entry in the WIM file. */
-#define WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE 50
+#include "wimlib/assert.h"
+#include "wimlib/dentry.h"
+#include "wimlib/list.h"
+#include "wimlib/sha1.h"
+#include "wimlib/types.h"
+#include "wimlib/wim.h"
#define LOOKUP_FLAG_ADS_OK 0x00000001
#define LOOKUP_FLAG_DIRECTORY_OK 0x00000002
-#ifdef __WIN32__
-#include <windef.h>
-#endif
-
/* The lookup table of a WIM file maps SHA1 message digests to streams of data.
* Here, the in-memory structure is implemented as a hash table.
};
#ifdef WITH_NTFS_3G
+
+struct _ntfs_volume;
+
struct ntfs_location {
tchar *path;
utf16lechar *stream_name;
return lte->resource_entry.size;
}
-/*
- * XXX Probably should store the compression type directly in the lookup table
- * entry
- */
-static inline int
-wim_resource_compression_type(const struct wim_lookup_table_entry *lte)
-{
- if (!(lte->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED)
- || lte->resource_location != RESOURCE_IN_WIM)
- return WIMLIB_COMPRESSION_TYPE_NONE;
- return wimlib_get_compression_type(lte->wim);
-}
+extern int
+wim_resource_compression_type(const struct wim_lookup_table_entry *lte);
static inline bool
lte_filename_valid(const struct wim_lookup_table_entry *lte)
}
extern struct wim_lookup_table_entry *
-new_lookup_table_entry();
+new_lookup_table_entry(void);
extern struct wim_lookup_table_entry *
clone_lookup_table_entry(const struct wim_lookup_table_entry *lte);
extern struct wim_lookup_table_entry **
retrieve_lte_pointer(struct wim_lookup_table_entry *lte);
-#endif
+#endif /* _WIMLIB_LOOKUP_TABLE_H */
#ifndef _WIMLIB_LZX_H
#define _WIMLIB_LZX_H
-#include "util.h"
+#include "wimlib/assert.h"
+#include "wimlib/types.h"
//#define ENABLE_LZX_DEBUG
#ifdef ENABLE_LZX_DEBUG
--- /dev/null
+#ifndef _WIMLIB_METADATA_H
+#define _WIMLIB_METADATA_H
+
+#include "wimlib/list.h"
+#include "wimlib/types.h"
+#include "wimlib/wim.h"
+
+#ifdef WITH_NTFS_3G
+struct _ntfs_volume;
+#endif
+
+/* Metadata for a WIM image */
+struct wim_image_metadata {
+
+ /* Number of WIMStruct's that are sharing this image metadata (from
+ * calls to wimlib_export_image().) */
+ unsigned long refcnt;
+
+ /* Pointer to the root dentry of the image. */
+ struct wim_dentry *root_dentry;
+
+ /* Pointer to the security data of the image. */
+ struct wim_security_data *security_data;
+
+ /* Pointer to the lookup table entry for this image's metadata resource
+ */
+ struct wim_lookup_table_entry *metadata_lte;
+
+ /* Linked list of 'struct wim_inode's for this image. */
+ struct list_head inode_list;
+
+ /* Linked list of 'struct wim_lookup_table_entry's for this image that
+ * are referred to in the dentry tree, but have not had a SHA1 message
+ * digest calculated yet and therefore have not been inserted into the
+ * WIM's lookup table. This list is added to during wimlib_add_image()
+ * and wimlib_mount_image() (read-write only). */
+ struct list_head unhashed_streams;
+
+ /* 1 iff the dentry tree has been modified. If this is the case, the
+ * memory for the dentry tree should not be freed when switching to a
+ * different WIM image. */
+ u8 modified : 1;
+
+#ifdef WITH_NTFS_3G
+ struct _ntfs_volume *ntfs_vol;
+#endif
+};
+
+static inline struct wim_image_metadata *
+wim_get_current_image_metadata(WIMStruct *w)
+{
+ return w->image_metadata[w->current_image - 1];
+}
+
+static inline const struct wim_image_metadata *
+wim_get_const_current_image_metadata(const WIMStruct *w)
+{
+ return w->image_metadata[w->current_image - 1];
+}
+
+static inline struct wim_dentry *
+wim_root_dentry(WIMStruct *w)
+{
+ return wim_get_current_image_metadata(w)->root_dentry;
+}
+
+static inline struct wim_security_data *
+wim_security_data(WIMStruct *w)
+{
+ return wim_get_current_image_metadata(w)->security_data;
+}
+
+static inline const struct wim_security_data *
+wim_const_security_data(const WIMStruct *w)
+{
+ return wim_get_const_current_image_metadata(w)->security_data;
+}
+
+/* Iterate over each inode in a WIM image that has not yet been hashed */
+#define image_for_each_inode(inode, imd) \
+ list_for_each_entry(inode, &imd->inode_list, i_list)
+
+/* Iterate over each stream in a WIM image that has not yet been hashed */
+#define image_for_each_unhashed_stream(lte, imd) \
+ list_for_each_entry(lte, &imd->unhashed_streams, unhashed_list)
+
+/* Iterate over each stream in a WIM image that has not yet been hashed (safe
+ * against stream removal) */
+#define image_for_each_unhashed_stream_safe(lte, tmp, imd) \
+ list_for_each_entry_safe(lte, tmp, &imd->unhashed_streams, unhashed_list)
+
+extern void
+destroy_image_metadata(struct wim_image_metadata *imd,
+ struct wim_lookup_table *table,
+ bool free_metadata_lte);
+
+extern void
+put_image_metadata(struct wim_image_metadata *imd,
+ struct wim_lookup_table *table);
+
+extern int
+append_image_metadata(WIMStruct *w, struct wim_image_metadata *imd);
+
+extern struct wim_image_metadata *
+new_image_metadata(void);
+
+extern struct wim_image_metadata **
+new_image_metadata_array(unsigned num_images);
+
+
+#endif /* _WIMLIB_METADATA_H */
--- /dev/null
+#ifndef _WIMLIB_NTFS_3G_H
+#define _WIMLIB_NTFS_3G_H
+
+#include "wimlib/callback.h"
+#include "wimlib/types.h"
+
+struct wim_lookup_table_entry;
+struct _ntfs_volume;
+
+extern void
+libntfs3g_global_init(void);
+
+extern int
+read_ntfs_file_prefix(const struct wim_lookup_table_entry *lte,
+ u64 size,
+ consume_data_callback_t cb,
+ void *ctx_or_buf,
+ int _ignored_flags);
+
+
+extern int
+do_ntfs_umount(struct _ntfs_volume *vol);
+
+#endif
--- /dev/null
+#ifndef _WIMLIB_PATHS_H
+#define _WIMLIB_PATHS_H
+
+#include "wimlib/types.h"
+
+const tchar *
+path_basename(const tchar *path);
+
+const tchar *
+path_basename_with_len(const tchar *path, size_t len);
+
+extern const tchar *
+path_stream_name(const tchar *path);
+
+extern void
+zap_backslashes(tchar *s);
+
+extern tchar *
+canonicalize_wim_path(const tchar *wim_path);
+
+extern tchar *
+canonicalize_fs_path(const tchar *fs_path);
+
+#endif /* _WIMLIB_PATHS_H */
#ifndef _LINUX_RBTREE_H
#define _LINUX_RBTREE_H
-#include "util.h"
#include <stdint.h>
+#include <stddef.h>
struct rb_node {
uintptr_t __rb_parent_color;
--- /dev/null
+#ifndef _WIMLIB_REPARSE_H
+#define _WIMLIB_REPARSE_H
+
+#include "wimlib/types.h"
+
+struct wim_inode;
+struct wim_lookup_table;
+
+#define REPARSE_POINT_MAX_SIZE (16 * 1024)
+
+/* Structured format for symbolic link, junction point, or mount point reparse
+ * data. */
+struct reparse_data {
+ /* Reparse point tag (see WIM_IO_REPARSE_TAG_* values) */
+ u32 rptag;
+
+ /* Length of reparse data, not including the 8-byte header (ReparseTag,
+ * ReparseDataLength, ReparseReserved) */
+ u16 rpdatalen;
+
+ /* ReparseReserved */
+ u16 rpreserved;
+
+ /* Flags (only for WIM_IO_REPARSE_TAG_SYMLINK reparse points).
+ * SYMBOLIC_LINK_RELATIVE means this is a relative symbolic link;
+ * otherwise should be set to 0. */
+#define SYMBOLIC_LINK_RELATIVE 0x00000001
+ u32 rpflags;
+
+ /* Pointer to the substitute name of the link (UTF-16LE). */
+ utf16lechar *substitute_name;
+
+ /* Pointer to the print name of the link (UTF-16LE). */
+ utf16lechar *print_name;
+
+ /* Number of bytes of the substitute name, not including null terminator
+ * if present */
+ u16 substitute_name_nbytes;
+
+ /* Number of bytes of the print name, not including null terminator if
+ * present */
+ u16 print_name_nbytes;
+};
+
+enum {
+ SUBST_NAME_IS_RELATIVE_LINK = -1,
+ SUBST_NAME_IS_VOLUME_JUNCTION = -2,
+ SUBST_NAME_IS_UNKNOWN = -3,
+};
+extern int
+parse_substitute_name(const utf16lechar *substitute_name,
+ u16 substitute_name_nbytes,
+ u32 rptag);
+
+extern int
+parse_reparse_data(const u8 *rpbuf, u16 rpbuflen, struct reparse_data *rpdata);
+
+extern int
+make_reparse_buffer(const struct reparse_data *rpdata, u8 *buf);
+
+extern int
+wim_inode_get_reparse_data(const struct wim_inode *inode, u8 *rpbuf);
+
+#ifndef __WIN32__
+ssize_t
+wim_inode_readlink(const struct wim_inode *inode, char *buf, size_t buf_len);
+
+extern int
+wim_inode_set_symlink(struct wim_inode *inode, const char *target,
+ struct wim_lookup_table *lookup_table);
+#endif
+
+extern tchar *
+capture_fixup_absolute_symlink(tchar *dest,
+ u64 capture_root_ino, u64 capture_root_dev);
+
+#endif /* _WIMLIB_REPARSE_H */
--- /dev/null
+#ifndef _WIMLIB_RESOURCE_H
+#define _WIMLIB_RESOURCE_H
+
+#include "wimlib/types.h"
+#include "wimlib/callback.h"
+
+struct wim_lookup_table_entry;
+struct wim_image_metadata;
+
+/* Metadata for a resource in a WIM file. */
+struct resource_entry {
+ /* Size, in bytes, of the resource in the WIM file. */
+ u64 size : 56;
+
+ /* Bitwise or of one or more of the WIM_RESHDR_FLAG_* flags. */
+ u64 flags : 8;
+
+ /* Offset, in bytes, of the resource in the WIM file. */
+ u64 offset;
+
+ /* Uncompressed size of the resource in the WIM file. Is the same as
+ * @size if the resource is uncompressed. */
+ u64 original_size;
+};
+
+
+/* Flags for the `flags' field of the struct resource_entry structure. */
+
+/* I haven't seen this flag used in any of the WIMs I have examined. I assume
+ * it means that there are no references to the stream, so the space is free.
+ * However, even after deleting files from a WIM mounted with `imagex.exe
+ * /mountrw', I could not see this flag being used. Either way, we don't
+ * actually use this flag for anything. */
+#define WIM_RESHDR_FLAG_FREE 0x01
+
+/* Indicates that the stream is a metadata resource for a WIM image. */
+#define WIM_RESHDR_FLAG_METADATA 0x02
+
+/* Indicates that the stream is compressed. */
+#define WIM_RESHDR_FLAG_COMPRESSED 0x04
+
+/* I haven't seen this flag used in any of the WIMs I have examined. Perhaps it
+ * means that a stream could possibly be split among multiple split WIM parts.
+ * However, `imagex.exe /split' does not seem to create any WIMs like this.
+ * Either way, we don't actually use this flag for anything. */
+#define WIM_RESHDR_FLAG_SPANNED 0x08
+
+/* Nonzero if a struct resource_entry indicates a compressed resource. */
+static inline int
+resource_is_compressed(const struct resource_entry *entry)
+{
+ return (entry->flags & WIM_RESHDR_FLAG_COMPRESSED);
+}
+
+#if 1
+# define copy_resource_entry(dst, src) memcpy(dst, src, sizeof(struct resource_entry))
+# define zero_resource_entry(entry) memset(entry, 0, sizeof(struct resource_entry))
+#else
+static inline void
+copy_resource_entry(struct resource_entry *dst,
+ const struct resource_entry *src)
+{
+ BUILD_BUG_ON(sizeof(struct resource_entry) != 24);
+ ((u64*)dst)[0] = ((u64*)src)[0];
+ ((u64*)dst)[1] = ((u64*)src)[1];
+ ((u64*)dst)[2] = ((u64*)src)[2];
+}
+
+static inline void
+zero_resource_entry(struct resource_entry *entry)
+{
+ BUILD_BUG_ON(sizeof(struct resource_entry) != 24);
+ ((u64*)entry)[0] = 0;
+ ((u64*)entry)[1] = 0;
+ ((u64*)entry)[2] = 0;
+}
+#endif
+
+#define WIMLIB_RESOURCE_FLAG_RAW 0x1
+#define WIMLIB_RESOURCE_FLAG_RECOMPRESS 0x2
+
+extern int
+read_resource_prefix(const struct wim_lookup_table_entry *lte,
+ u64 size, consume_data_callback_t cb, void *ctx_or_buf,
+ int flags);
+
+extern const void *
+get_resource_entry(const void *p, struct resource_entry *entry);
+
+extern void *
+put_resource_entry(void *p, const struct resource_entry *entry);
+
+extern int
+read_partial_wim_resource_into_buf(const struct wim_lookup_table_entry *lte,
+ size_t size, u64 offset, void *buf);
+extern int
+read_full_resource_into_buf(const struct wim_lookup_table_entry *lte, void *buf);
+
+extern int
+write_wim_resource(struct wim_lookup_table_entry *lte, int out_fd,
+ int out_ctype, struct resource_entry *out_res_entry,
+ int flags);
+
+extern int
+extract_wim_resource(const struct wim_lookup_table_entry *lte,
+ u64 size,
+ consume_data_callback_t extract_chunk,
+ void *extract_chunk_arg);
+
+extern int
+extract_wim_resource_to_fd(const struct wim_lookup_table_entry *lte,
+ int fd, u64 size);
+
+extern int
+sha1_resource(struct wim_lookup_table_entry *lte);
+
+extern int
+copy_resource(struct wim_lookup_table_entry *lte, void *w);
+
+extern int
+read_metadata_resource(WIMStruct *w,
+ struct wim_image_metadata *image_metadata);
+
+extern int
+write_metadata_resource(WIMStruct *w);
+
+#endif /* _WIMLIB_RESOURCE_H */
--- /dev/null
+#ifndef _WIMLIB_SECURITY_H
+#define _WIMLIB_SECURITY_H
+
+#include "wimlib/rbtree.h"
+#include "wimlib/types.h"
+
+/* Red-black tree that maps SHA1 message digests of security descriptors to
+ * security IDs, which are themselves indices into the table of security
+ * descriptors in the 'struct wim_security_data'. */
+struct wim_sd_set {
+ struct wim_security_data *sd;
+ struct rb_root rb_root;
+ int32_t orig_num_entries;
+};
+
+/* Table of security descriptors for a WIM image. */
+struct wim_security_data {
+ /* The total length of the security data, in bytes. If there are no
+ * security descriptors, this field, when read from the on-disk metadata
+ * resource, may be either 8 (which is correct) or 0 (which is
+ * interpreted as 0). */
+ u32 total_length;
+
+ /* The number of security descriptors in the array @descriptors, below.
+ * It is really an unsigned int on-disk, but it must fit into an int
+ * because the security ID's are signed. (Not like you would ever have
+ * more than a few hundred security descriptors anyway.) */
+ int32_t num_entries;
+
+ /* Array of sizes of the descriptors in the array @descriptors. */
+ u64 *sizes;
+
+ /* Array of descriptors. */
+ u8 **descriptors;
+};
+
+extern void
+destroy_sd_set(struct wim_sd_set *sd_set, bool rollback);
+
+extern int
+lookup_sd(struct wim_sd_set *set, const u8 hash[]);
+
+extern int
+sd_set_add_sd(struct wim_sd_set *sd_set, const char descriptor[],
+ size_t size);
+
+extern int
+init_sd_set(struct wim_sd_set *sd_set, struct wim_security_data *sd);
+
+extern struct wim_security_data *
+new_wim_security_data(void);
+
+extern int
+read_security_data(const u8 metadata_resource[],
+ u64 metadata_resource_len, struct wim_security_data **sd_p);
+extern void
+print_security_data(const struct wim_security_data *sd);
+
+extern u8 *
+write_security_data(const struct wim_security_data *sd, u8 *p);
+
+extern void
+free_security_data(struct wim_security_data *sd);
+
+#endif /* _WIMLIB_SECURITY_H */
#ifndef _WIMLIB_SHA1_H
#define _WIMLIB_SHA1_H
-#include "config.h"
-#include <stdio.h>
-#include <stddef.h>
+#include "wimlib/types.h"
+#include "wimlib/util.h"
+
#include <string.h>
-#include "util.h"
#define SHA1_HASH_SIZE 20
--- /dev/null
+#ifndef _WIMLIB_SWM_H
+#define _WIMLIB_SWM_H
+
+#include "wimlib/types.h"
+
+extern int
+verify_swm_set(WIMStruct *w,
+ WIMStruct **additional_swms, unsigned num_additional_swms);
+
+extern void
+merge_lookup_tables(WIMStruct *w,
+ WIMStruct **additional_swms, unsigned num_additional_swms);
+
+extern void
+unmerge_lookup_table(WIMStruct *wim);
+
+#endif
#ifndef _WIMLIB_TIMESTAMP_H
#define _WIMLIB_TIMESTAMP_H
-#include "util.h"
+#include "wimlib/types.h"
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
}
extern u64
-get_wim_timestamp();
+get_wim_timestamp(void);
extern void
wim_timestamp_to_str(u64 timestamp, tchar *buf, size_t len);
--- /dev/null
+#ifndef _WIMLIB_TYPES_H
+#define _WIMLIB_TYPES_H
+
+#include "wimlib_tchar.h"
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#ifndef _NTFS_TYPES_H
+/* Unsigned integer types of exact size in bits */
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+/* Signed integer types of exact size in bits */
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+#endif
+
+/* A pointer to 'utf16lechar' indicates a UTF-16LE encoded string */
+typedef u16 utf16lechar;
+
+#ifndef WIMLIB_WIMSTRUCT_DECLARED
+typedef struct WIMStruct WIMStruct;
+# define WIMLIB_WIMSTRUCT_DECLARED
+#endif
+
+#endif
--- /dev/null
+#ifndef _WIMLIB_UTIL_H
+#define _WIMLIB_UTIL_H
+
+#include "wimlib/types.h"
+#include "wimlib/compiler.h"
+
+#include <stdio.h>
+#include <stddef.h>
+
+#ifndef min
+#define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
+ (__a < __b) ? __a : __b; })
+#endif
+
+#ifndef max
+#define max(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
+ (__a > __b) ? __a : __b; })
+#endif
+
+#ifndef swap
+#define swap(a, b) ({typeof(a) _a = a; (a) = (b); (b) = _a;})
+#endif
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#define DIV_ROUND_UP(numerator, denominator) \
+ (((numerator) + (denominator) - 1) / (denominator))
+
+#define MODULO_NONZERO(numerator, denominator) \
+ (((numerator) % (denominator)) ? ((numerator) % (denominator)) : (denominator))
+
+#define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
+
+#define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
+
+/* Used for buffering FILE IO in a few places */
+#define BUFFER_SIZE 32768
+
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+
+#ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR
+extern void *(*wimlib_malloc_func)(size_t);
+extern void (*wimlib_free_func)(void *);
+extern void *(*wimlib_realloc_func)(void *, size_t);
+extern void *wimlib_calloc(size_t nmemb, size_t size);
+#ifdef __WIN32__
+extern wchar_t *wimlib_wcsdup(const wchar_t *str);
+#endif
+extern char *wimlib_strdup(const char *str);
+# define MALLOC wimlib_malloc_func
+# define FREE wimlib_free_func
+# define REALLOC wimlib_realloc_func
+# define CALLOC wimlib_calloc
+# define STRDUP wimlib_strdup
+# define WSTRDUP wimlib_wcsdup
+#else /* ENABLE_CUSTOM_MEMORY_ALLOCATOR */
+# include <stdlib.h>
+# include <string.h>
+# define MALLOC malloc
+# define FREE free
+# define REALLOC realloc
+# define CALLOC calloc
+# define STRDUP strdup
+# define WSTRDUP wcsdup
+#endif /* !ENABLE_CUSTOM_MEMORY_ALLOCATOR */
+
+
+/* util.c */
+extern void
+randomize_byte_array(u8 *p, size_t n);
+
+extern void
+randomize_char_array_with_alnum(tchar p[], size_t n);
+
+extern void
+print_byte_field(const u8 field[], size_t len, FILE *out);
+
+static inline u32
+bsr32(u32 n)
+{
+#if defined(__x86__) || defined(__x86_64__)
+ asm("bsrl %0, %0;"
+ : "=r"(n)
+ : "0" (n));
+ return n;
+#else
+ u32 pow = 0;
+ while ((n >>= 1) != 0)
+ pow++;
+ return pow;
+#endif
+}
+
+static inline u64
+hash_u64(u64 n)
+{
+ return n * 0x9e37fffffffc0001ULL;
+}
+
+#endif /* _WIMLIB_UTIL_H */
--- /dev/null
+#ifndef _WIMLIB_VERSION_H
+#define _WIMLIB_VERSION_H
+
+#include "wimlib.h"
+
+#define WIMLIB_MAKEVERSION(major, minor, patch) \
+ ((major << 20) | (minor << 10) | patch)
+
+
+#define WIMLIB_VERSION_CODE \
+ WIMLIB_MAKEVERSION(WIMLIB_MAJOR_VERSION,\
+ WIMLIB_MINOR_VERSION,\
+ WIMLIB_PATCH_VERSION)
+
+#define WIMLIB_GET_PATCH_VERSION(version) \
+ ((version >> 0) & ((1 << 10) - 1))
+#define WIMLIB_GET_MINOR_VERSION(version) \
+ ((version >> 10) & ((1 << 10) - 1))
+#define WIMLIB_GET_MAJOR_VERSION(version) \
+ ((version >> 20) & ((1 << 10) - 1))
+
+#endif /* _WIMLIB_VERSION_H */
--- /dev/null
+#ifndef _WIMLIB_WIM_H
+#define _WIMLIB_WIM_H
+
+#include "wimlib/header.h"
+#include "wimlib/types.h"
+
+struct wim_info;
+struct wim_lookup_table;
+struct wim_image_metadata;
+
+/* The opaque structure exposed to the wimlib API. */
+struct WIMStruct {
+
+ /* File descriptor for the WIM file, opened for reading, or -1 if it has
+ * not been opened or there is no associated file backing it yet. */
+ int in_fd;
+
+ /* File descriptor, opened either for writing only or for
+ * reading+writing, for the WIM file (if any) currently being written.
+ * */
+ int out_fd;
+
+ /* The name of the WIM file (if any) that has been opened. */
+ tchar *filename;
+
+ /* The lookup table for the WIM file. */
+ struct wim_lookup_table *lookup_table;
+
+ /* Information retrieved from the XML data, arranged in an orderly
+ * manner. */
+ struct wim_info *wim_info;
+
+ /* Array of the image metadata, one for each image in the WIM. */
+ struct wim_image_metadata **image_metadata;
+
+ /* The header of the WIM file. */
+ struct wim_header hdr;
+
+ /* Temporary field */
+ void *private;
+
+ /* The currently selected image, indexed starting at 1. If not 0,
+ * subtract 1 from this to get the index of the current image in the
+ * image_metadata array. */
+ int current_image;
+
+ /* Have any images been deleted? */
+ u8 deletion_occurred : 1;
+
+ u8 all_images_verified : 1;
+ u8 wim_locked : 1;
+};
+
+extern int
+wim_run_full_verifications(WIMStruct *w);
+
+extern int
+read_header(const tchar *filename, int in_fd, struct wim_header *hdr,
+ int split_ok);
+
+extern int
+write_header(const struct wim_header *hdr, int out_fd);
+
+extern int
+init_header(struct wim_header *hdr, int ctype);
+
+
+extern int
+rename_wim_path(WIMStruct *wim, const tchar *from, const tchar *to);
+
+extern int
+select_wim_image(WIMStruct *w, int image);
+
+extern int
+for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *));
+
+extern int
+wim_checksum_unhashed_streams(WIMStruct *w);
+
+extern int
+reopen_wim(WIMStruct *w);
+
+extern int
+close_wim(WIMStruct *w);
+
+#endif /* _WIMLIB_WIM_H */
#ifndef _WIMLIB_WIN32_H
#define _WIMLIB_WIN32_H
-#include "wimlib_internal.h"
+#ifdef __WIN32__
+
+#include "wimlib/callback.h"
+#include "wimlib/types.h"
#include <direct.h>
#include <windef.h>
-extern int
-win32_build_dentry_tree(struct wim_dentry **root_ret,
- const tchar *root_disk_path,
- struct add_image_params *params);
-
-extern int
-win32_get_file_and_vol_ids(const wchar_t *path, u64 *ino_ret, u64 *dev_ret);
-
-extern int
-win32_read_file(const tchar *filename, HANDLE handle,
- u64 offset, size_t size, void *buf);
+struct wim_lookup_table_entry;
+struct iovec;
extern int
read_win32_file_prefix(const struct wim_lookup_table_entry *lte,
void *ctx_or_buf,
int _ignored_flags);
+
+extern void
+win32_global_init(void);
+
+extern void
+win32_global_cleanup(void);
+
#define FNM_PATHNAME 0x1
#define FNM_NOESCAPE 0x2
#define FNM_NOMATCH 1
extern int
fnmatch(const tchar *pattern, const tchar *string, int flags);
-extern int
-win32_do_apply_dentry(const tchar *output_path,
- size_t output_path_nbytes,
- struct wim_dentry *dentry,
- struct apply_args *args);
-
-extern int
-win32_do_apply_dentry_timestamps(const tchar *output_path,
- size_t output_path_nbytes,
- struct wim_dentry *dentry,
- struct apply_args *args);
-
extern int
fsync(int fd);
extern unsigned
-win32_get_number_of_processors();
+win32_get_number_of_processors(void);
extern tchar *
realpath(const tchar *path, tchar *resolved_path);
extern int
win32_truncate_replacement(const tchar *path, off_t size);
-extern void
-win32_global_init();
-
-extern void
-win32_global_cleanup();
-
extern int
win32_strerror_r_replacement(int errnum, tchar *buf, size_t buflen);
+extern int
+win32_get_file_and_vol_ids(const wchar_t *path, u64 *ino_ret, u64 *dev_ret);
+
+
extern ssize_t
-win32_pread(int fd, void *buf, size_t count, off_t offset);
+pread(int fd, void *buf, size_t count, off_t offset);
extern ssize_t
-win32_pwrite(int fd, const void *buf, size_t count, off_t offset);
+pwrite(int fd, const void *buf, size_t count, off_t offset);
extern ssize_t
-win32_writev(int fd, const struct iovec *iov, int iovcnt);
+writev(int fd, const struct iovec *iov, int iovcnt);
+
+#endif /* __WIN32__ */
#endif /* _WIMLIB_WIN32_H */
# undef ERROR
#endif
-#include "util.h"
-#include "win32.h"
+#include "wimlib/types.h"
+#include "wimlib/win32.h"
#ifdef ENABLE_ERROR_MESSAGES
#endif
extern void
-set_errno_from_GetLastError();
+set_errno_from_GetLastError(void);
extern int
win32_error_to_errno(DWORD err_code);
--- /dev/null
+#ifndef _WIMLIB_WRITE_H
+#define _WIMLIB_WRITE_H
+
+#include "wimlib.h"
+#include "wimlib/types.h"
+
+/* Internal use only */
+#define WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE 0x80000000
+#define WIMLIB_WRITE_FLAG_REUSE_INTEGRITY_TABLE 0x40000000
+#define WIMLIB_WRITE_FLAG_CHECKPOINT_AFTER_XML 0x20000000
+#define WIMLIB_WRITE_MASK_PUBLIC 0x1fffffff
+
+extern int
+begin_write(WIMStruct *w, const tchar *path, int write_flags);
+
+extern void
+close_wim_writable(WIMStruct *w);
+
+extern int
+finish_write(WIMStruct *w, int image, int write_flags,
+ wimlib_progress_func_t progress_func);
+
+#if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK)
+extern int
+lock_wim(WIMStruct *w, int fd);
+#else
+static inline int
+lock_wim(WIMStruct *w, int fd)
+{
+ return 0;
+}
+#endif
+
+#endif /* _WIMLIB_WRITE_H */
#ifndef _WIMLIB_XML_H
#define _WIMLIB_XML_H
-#include "util.h"
+#include "wimlib/types.h"
+
+struct image_info;
+struct resource_entry;
/* A struct wim_info structure corresponds to the entire XML data for a WIM file. */
struct wim_info {
u64 total_bytes, struct resource_entry *out_res_entry);
extern void
-libxml_global_init();
+libxml_global_init(void);
extern void
-libxml_global_cleanup();
+libxml_global_cleanup(void);
static inline u64
wim_info_get_total_bytes(const struct wim_info *info)
return info->num_images;
}
+#ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR
+extern void
+xml_set_memory_allocator(void *(*malloc_func)(size_t),
+ void (*free_func)(void *),
+ void *(*realloc_func)(void *, size_t));
+#endif
+
#endif
#ifndef _WIMLIB_XPRESS_H
#define _WIMLIB_XPRESS_H
-#include "util.h"
-
/* See the comments in xpress-decompress.c about the XPRESS format. */
//#define ENABLE_XPRESS_DEBUG
}
void
-win32_acquire_capture_privileges()
+win32_acquire_capture_privileges(void)
{
win32_modify_capture_privileges(true);
}
void
-win32_release_capture_privileges()
+win32_release_capture_privileges(void)
{
win32_modify_capture_privileges(false);
}
void
-win32_acquire_restore_privileges()
+win32_acquire_restore_privileges(void)
{
win32_modify_restore_privileges(true);
}
void
-win32_release_restore_privileges()
+win32_release_restore_privileges(void)
{
win32_modify_restore_privileges(false);
}
#define GLOB_NOMATCH 3 /* No matches found. */
extern void
-win32_acquire_capture_privileges();
+win32_acquire_capture_privileges(void);
extern void
-win32_release_capture_privileges();
+win32_release_capture_privileges(void);
extern void
-win32_acquire_restore_privileges();
+win32_acquire_restore_privileges(void);
extern void
-win32_release_restore_privileges();
+win32_release_restore_privileges(void);
extern wchar_t *
win32_mbs_to_wcs(const char *mbs, size_t mbs_nbytes, size_t *num_wchars_ret);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* Need for PACKAGE_VERSION, etc. */
+#endif
+
#include "wimlib.h"
#include "wimlib_tchar.h"
#include <locale.h>
#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
+# include <alloca.h>
#endif
#ifdef __WIN32__
};
static void usage(int cmd_type);
-static void usage_all();
+static void usage_all(void);
static bool imagex_be_quiet = false;
};
static void
-version()
+version(void)
{
static const tchar *s =
T(
}
static void
-usage_all()
+usage_all(void)
{
tfputs(T("Usage:\n"), stdout);
for (int i = 0; i < ARRAY_LEN(usage_strings); i++)
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
long-named options. */
-int
+static int
_wgetopt_internal (int argc, wchar_t *const *argv, const wchar_t *optstring,
const struct woption *longopts, int *longind, int long_only)
{
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "lookup_table.h"
-#include "xml.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/capture.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/xml.h"
/*
* Adds the dentry tree and security data for a new image to the image metadata
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
-#include <string.h>
+#include "wimlib/assert.h"
+#include "wimlib/capture.h"
+#include "wimlib/error.h"
+#include "wimlib/paths.h"
#ifdef __WIN32__
-# include "win32.h"
+# include "wimlib/win32.h" /* for fnmatch() equivalent */
#else
# include <fnmatch.h>
#endif
+#include <string.h>
+
static int
canonicalize_pattern(const tchar *pat, tchar **canonical_pat_ret)
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "compress.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include "wimlib/assert.h"
+#include "wimlib/compress.h"
+#include "wimlib/util.h"
+
#include <stdlib.h>
#include <string.h>
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "decompress.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/decompress.h"
+#include "wimlib/util.h"
+
#include <string.h>
/*
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "xml.h"
-#include <string.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/error.h"
+#include "wimlib/metadata.h"
+#include "wimlib/util.h"
+#include "wimlib/wim.h"
+#include "wimlib/xml.h"
/*
* Deletes an image from the WIM.
* wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "buffer_io.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "timestamp.h"
-#include "wimlib_internal.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/buffer_io.h"
+#include "wimlib/dentry.h"
+#include "wimlib/encoding.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/resource.h"
+#include "wimlib/timestamp.h"
+
#include <errno.h>
/* Calculates the unaligned length, in bytes, of an on-disk WIM dentry that has
}
struct wim_inode *
-new_timeless_inode()
+new_timeless_inode(void)
{
struct wim_inode *inode = CALLOC(1, sizeof(struct wim_inode));
if (inode) {
}
static struct wim_inode *
-new_inode()
+new_inode(void)
{
struct wim_inode *inode = new_timeless_inode();
if (inode) {
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/encoding.h"
+#include "wimlib/error.h"
+#include "wimlib/list.h"
+#include "wimlib/util.h"
#include <errno.h>
#include <iconv.h>
}
void
-iconv_global_cleanup()
+iconv_global_cleanup(void)
{
iconv_cleanup(&iconv_utf8_to_tstr);
iconv_cleanup(&iconv_tstr_to_utf8);
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "xml.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/swm.h"
+#include "wimlib/xml.h"
static int
inode_allocate_needed_ltes(struct wim_inode *inode,
/*
- * extract_image.c
+ * extract.c
*
- * Support for extracting WIM files.
+ * Support for extracting WIM images, or files or directories contained in a WIM
+ * image.
*/
/*
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "config.h"
-
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <unistd.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "wimlib/apply.h"
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/paths.h"
+#include "wimlib/resource.h"
+#include "wimlib/swm.h"
#ifdef __WIN32__
-# include "win32.h"
+# include "wimlib/win32.h" /* for realpath() equivalent */
#endif
+#include "wimlib/xml.h"
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "xml.h"
-
+#include <errno.h>
+#include <limits.h>
#ifdef WITH_NTFS_3G
-# include <ntfs-3g/volume.h>
+# include <ntfs-3g/volume.h> /* for ntfs_mount(), ntfs_umount() */
#endif
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
static int
do_apply_op(struct wim_dentry *dentry, struct apply_args *args,
--- /dev/null
+/*
+ * file_io.c - Helper functions for reading and writing to file descriptors.
+ */
+
+/*
+ * Copyright (C) 2013 Eric Biggers
+ *
+ * This file is part of wimlib, a library for working with WIM files.
+ *
+ * wimlib is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/file_io.h"
+#ifdef __WIN32__
+# include "wimlib/win32.h" /* For pread(), pwrite() replacements */
+#else
+# include <sys/uio.h> /* for writev() and `struct iovec' */
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+
+
+/* Like read(), but keep trying until everything has been written or we know for
+ * sure that there was an error (or end-of-file). */
+size_t
+full_read(int fd, void *buf, size_t count)
+{
+ ssize_t bytes_read;
+ size_t bytes_remaining;
+
+ for (bytes_remaining = count;
+ bytes_remaining != 0;
+ bytes_remaining -= bytes_read, buf += bytes_read)
+ {
+ bytes_read = read(fd, buf, bytes_remaining);
+ if (bytes_read <= 0) {
+ if (bytes_read == 0)
+ errno = EIO;
+ else if (errno == EINTR)
+ continue;
+ break;
+ }
+ }
+ return count - bytes_remaining;
+}
+
+/* Like write(), but keep trying until everything has been written or we know
+ * for sure that there was an error. */
+size_t
+full_write(int fd, const void *buf, size_t count)
+{
+ ssize_t bytes_written;
+ size_t bytes_remaining;
+
+ for (bytes_remaining = count;
+ bytes_remaining != 0;
+ bytes_remaining -= bytes_written, buf += bytes_written)
+ {
+ bytes_written = write(fd, buf, bytes_remaining);
+ if (bytes_written < 0) {
+ if (errno == EINTR)
+ continue;
+ break;
+ }
+ }
+ return count - bytes_remaining;
+}
+
+/* Like pread(), but keep trying until everything has been read or we know for
+ * sure that there was an error (or end-of-file) */
+size_t
+full_pread(int fd, void *buf, size_t count, off_t offset)
+{
+ ssize_t bytes_read;
+ size_t bytes_remaining;
+
+ for (bytes_remaining = count;
+ bytes_remaining != 0;
+ bytes_remaining -= bytes_read, buf += bytes_read,
+ offset += bytes_read)
+ {
+ bytes_read = pread(fd, buf, bytes_remaining, offset);
+ if (bytes_read <= 0) {
+ if (bytes_read == 0)
+ errno = EIO;
+ else if (errno == EINTR)
+ continue;
+ break;
+ }
+ }
+ return count - bytes_remaining;
+}
+
+/* Like pwrite(), but keep trying until everything has been written or we know
+ * for sure that there was an error. */
+size_t
+full_pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+ ssize_t bytes_written;
+ size_t bytes_remaining;
+
+ for (bytes_remaining = count;
+ bytes_remaining != 0;
+ bytes_remaining -= bytes_written, buf += bytes_written,
+ offset += bytes_written)
+ {
+ bytes_written = pwrite(fd, buf, bytes_remaining, offset);
+ if (bytes_written < 0) {
+ if (errno == EINTR)
+ continue;
+ break;
+ }
+ }
+ return count - bytes_remaining;
+}
+
+/* Like writev(), but keep trying until everything has been written or we know
+ * for sure that there was an error. */
+size_t
+full_writev(int fd, struct iovec *iov, int iovcnt)
+{
+ size_t total_bytes_written = 0;
+ while (iovcnt > 0) {
+ ssize_t bytes_written;
+
+ bytes_written = writev(fd, iov, iovcnt);
+ if (bytes_written < 0) {
+ if (errno == EINTR)
+ continue;
+ break;
+ }
+ total_bytes_written += bytes_written;
+ while (bytes_written) {
+ if (bytes_written >= iov[0].iov_len) {
+ bytes_written -= iov[0].iov_len;
+ iov++;
+ iovcnt--;
+ } else {
+ iov[0].iov_base += bytes_written;
+ iov[0].iov_len -= bytes_written;
+ bytes_written = 0;
+ }
+ }
+ }
+ return total_bytes_written;
+}
+
+off_t
+filedes_offset(int fd)
+{
+ return lseek(fd, 0, SEEK_CUR);
+}
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "list.h"
-#include "lookup_table.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/capture.h"
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
/* NULL NULL
* ^ ^
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "buffer_io.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/assert.h"
+#include "wimlib/buffer_io.h"
+#include "wimlib/error.h"
+#include "wimlib/file_io.h"
+#include "wimlib/header.h"
+#include "wimlib/util.h"
+#include "wimlib/wim.h"
+
#include <limits.h>
/* First 8 bytes in every WIM file. */
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "buffer_io.h"
-#include "sha1.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/assert.h"
+#include "wimlib/buffer_io.h"
+#include "wimlib/error.h"
+#include "wimlib/file_io.h"
+#include "wimlib/integrity.h"
+#include "wimlib/resource.h"
+#include "wimlib/sha1.h"
+#include "wimlib/wim.h"
/* Size, in bytes, of each SHA1-summed chunk, when wimlib writes integrity
* information. */
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "lookup_table.h"
-#include "xml.h"
-#include <stdlib.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/resource.h"
+#include "wimlib/swm.h"
+#include "wimlib/wim.h"
+#include "wimlib/write.h"
+#include "wimlib/xml.h"
+
+#include <stdlib.h> /* for qsort() */
static int
move_lte_to_table(struct wim_lookup_table_entry *lte, void *combined_table)
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "lookup_table.h"
-#include "buffer_io.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/buffer_io.h"
+#include "wimlib/error.h"
+#include "wimlib/file_io.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/paths.h"
+#include "wimlib/resource.h"
+#include "wimlib/util.h"
+
#include <errno.h>
#include <stdlib.h>
-
#ifdef WITH_FUSE
-#include <unistd.h>
+# include <unistd.h> /* for unlink() */
#endif
+/* Size of each lookup table entry in the WIM file. */
+#define WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE 50
+
struct wim_lookup_table *
new_lookup_table(size_t capacity)
{
}
struct wim_lookup_table_entry *
-new_lookup_table_entry()
+new_lookup_table_entry(void)
{
struct wim_lookup_table_entry *lte;
}
#endif
+/*
+ * XXX Probably should store the compression type directly in the lookup table
+ * entry
+ */
+int
+wim_resource_compression_type(const struct wim_lookup_table_entry *lte)
+{
+ if (!(lte->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED)
+ || lte->resource_location != RESOURCE_IN_WIM)
+ return WIMLIB_COMPRESSION_TYPE_NONE;
+ return wimlib_get_compression_type(lte->wim);
+}
+
/* Resolve an inode's lookup table entries
*
* This replaces the SHA1 hash fields (which are used to lookup an entry in the
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "compress.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/compress.h"
+#include "wimlib/util.h"
+
#include <string.h>
#define LZ_MIN_MATCH 3
-#include "lzx.h"
+/*
+ * lzx-common.c - Common data for LZX compression and decompression.
+ */
+
+/*
+ * Copyright (C) 2012, 2013 Eric Biggers
+ *
+ * This file is part of wimlib, a library for working with WIM files.
+ *
+ * wimlib is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/lzx.h"
#ifdef USE_LZX_EXTRA_BITS_ARRAY
/* LZX uses what it calls 'position slots' to represent match offsets.
* blocks from one input chunk is not yet implemented.
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include "wimlib.h"
-#include "lzx.h"
-#include "compress.h"
+#include "wimlib/compress.h"
+#include "wimlib/lzx.h"
+#include "wimlib/util.h"
+
#include <stdlib.h>
#include <string.h>
static void
do_call_insn_translation(u32 *call_insn_target, int input_pos,
- int32_t file_size)
+ s32 file_size)
{
- int32_t abs_offset;
- int32_t rel_offset;
+ s32 abs_offset;
+ s32 rel_offset;
rel_offset = le32_to_cpu(*call_insn_target);
if (rel_offset >= -input_pos && rel_offset < file_size) {
* succeed.
*/
-#include "util.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include "wimlib.h"
-#include "lzx.h"
-#include "decompress.h"
+#include "wimlib/decompress.h"
+#include "wimlib/lzx.h"
+#include "wimlib/util.h"
+
#include <string.h>
/* Huffman decoding tables and maps from symbols to code lengths. */
static void
undo_call_insn_translation(u32 *call_insn_target, int input_pos,
- int32_t file_size)
+ s32 file_size)
{
- int32_t abs_offset;
- int32_t rel_offset;
+ s32 abs_offset;
+ s32 rel_offset;
abs_offset = le32_to_cpu(*call_insn_target);
if (abs_offset >= -input_pos && abs_offset < file_size) {
* wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/file_io.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/resource.h"
+#include "wimlib/security.h"
/*
* Reads a metadata resource for an image in the WIM file. The metadata
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/error.h"
#ifdef WITH_FUSE
# error "FUSE mount not supported on Win32! Please configure --without-fuse"
#endif
-#include "buffer_io.h"
-#include "lookup_table.h"
-#include "sha1.h"
-#include "timestamp.h"
-#include "xml.h"
+#include "wimlib/encoding.h"
+#include "wimlib/file_io.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/paths.h"
+#include "wimlib/reparse.h"
+#include "wimlib/resource.h"
+#include "wimlib/swm.h"
+#include "wimlib/timestamp.h"
+#include "wimlib/version.h"
+#include "wimlib/write.h"
+#include "wimlib/xml.h"
#include <errno.h>
#include <ftw.h>
#define WIMFS_CTX(fuse_ctx) ((struct wimfs_context*)(fuse_ctx)->private_data)
static inline struct wimfs_context *
-wimfs_get_context()
+wimfs_get_context(void)
{
return WIMFS_CTX(fuse_get_context());
}
static inline WIMStruct *
-wimfs_get_WIMStruct()
+wimfs_get_WIMStruct(void)
{
return wimfs_get_context()->wim;
}
struct msg_unmount_finished {
struct unmount_msg_hdr hdr;
- int32_t status;
+ s32 status;
} PACKED;
struct msg_write_streams_progress {
static int
-mount_unsupported_error()
+mount_unsupported_error(void)
{
#if defined(__WIN32__)
ERROR("Sorry-- Mounting WIM images is not supported on Windows!");
/*
- * ntfs-apply.c
+ * ntfs-3g_apply.c
*
- * Apply a WIM image to a NTFS volume. Restore as much information as possible,
- * including security data, file attributes, DOS names, and alternate data
- * streams.
+ * Apply a WIM image directly to a NTFS volume using libntfs-3g. Restore as
+ * much information as possible, including security data, file attributes, DOS
+ * names, and alternate data streams.
*/
/*
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
-#include "config.h"
+#ifdef WITH_NTFS_3G
-#include <ntfs-3g/endians.h>
-#include <ntfs-3g/types.h>
-
-#include "wimlib_internal.h"
-#include "buffer_io.h"
-#include "dentry.h"
-#include "lookup_table.h"
+#include <locale.h>
+#include <string.h>
+#include <time.h> /* NTFS-3g headers are missing <time.h> include */
#include <ntfs-3g/attrib.h>
-#include <ntfs-3g/security.h> /* security.h before xattrs.h */
+#include <ntfs-3g/endians.h>
#include <ntfs-3g/reparse.h>
+#include <ntfs-3g/security.h>
+#include <ntfs-3g/types.h>
#include <ntfs-3g/xattrs.h>
-#include <string.h>
-#include <locale.h>
+
+#include "wimlib/apply.h"
+#include "wimlib/buffer_io.h"
+#include "wimlib/dentry.h"
+#include "wimlib/encoding.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/ntfs_3g.h"
+#include "wimlib/reparse.h"
+#include "wimlib/security.h"
struct ntfs_attr_extract_ctx {
u64 offset;
}
void
-libntfs3g_global_init()
+libntfs3g_global_init(void)
{
ntfs_set_char_encoding(setlocale(LC_ALL, ""));
}
+
+#endif /* WITH_NTFS_3G */
/*
- * ntfs-capture.c
+ * ntfs-3g_capture.c
*
- * Capture a WIM image from a NTFS volume. We capture everything we can,
- * including security data and alternate data streams.
+ * Capture a WIM image directly from a NTFS volume using libntfs-3g. We capture
+ * everything we can, including security data and alternate data streams.
*/
/*
*/
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
-#include <ntfs-3g/endians.h>
-#include <ntfs-3g/types.h>
+#ifdef WITH_NTFS_3G
-#include "buffer_io.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "security.h"
-#include "wimlib_internal.h"
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+
+#endif
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h> /* NTFS-3g headers are missing <time.h> include */
+#include <unistd.h>
-#include <ntfs-3g/layout.h>
-#include <ntfs-3g/acls.h>
#include <ntfs-3g/attrib.h>
+#include <ntfs-3g/endians.h>
+#include <ntfs-3g/layout.h>
#include <ntfs-3g/misc.h>
#include <ntfs-3g/reparse.h>
#include <ntfs-3g/security.h> /* ntfs-3g/security.h before ntfs-3g/xattrs.h */
-#include <ntfs-3g/xattrs.h>
+#include <ntfs-3g/types.h>
#include <ntfs-3g/volume.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
+#include <ntfs-3g/xattrs.h>
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
+#include <ntfs-3g/acls.h> /* This should be included last as it requires
+ definitions from above not included by itself */
+
+#include "wimlib/buffer_io.h"
+#include "wimlib/capture.h"
+#include "wimlib/dentry.h"
+#include "wimlib/encoding.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/ntfs_3g.h"
+#include "wimlib/paths.h"
+#include "wimlib/security.h"
static inline ntfschar *
attr_record_name(ATTR_RECORD *ar)
}
return ret;
}
+#endif /* WITH_NTFS_3G */
--- /dev/null
+/*
+ * paths.c - Path manipulation routines
+ */
+
+/*
+ * Copyright (C) 2012, 2013 Eric Biggers
+ *
+ * This file is part of wimlib, a library for working with WIM files.
+ *
+ * wimlib is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/paths.h"
+#include "wimlib/util.h"
+
+#include <string.h>
+
+/* Like the basename() function, but does not modify @path; it just returns a
+ * pointer to it. */
+const tchar *
+path_basename(const tchar *path)
+{
+ return path_basename_with_len(path, tstrlen(path));
+}
+
+/* Like path_basename(), but take an explicit string length. */
+const tchar *
+path_basename_with_len(const tchar *path, size_t len)
+{
+ const tchar *p = &path[len] - 1;
+
+ /* Trailing slashes. */
+ while (1) {
+ if (p == path - 1)
+ return T("");
+ if (*p != T('/'))
+ break;
+ p--;
+ }
+
+ while ((p != path - 1) && *p != T('/'))
+ p--;
+
+ return p + 1;
+}
+
+
+/*
+ * Returns a pointer to the part of @path following the first colon in the last
+ * path component, or NULL if the last path component does not contain a colon.
+ */
+const tchar *
+path_stream_name(const tchar *path)
+{
+ const tchar *base = path_basename(path);
+ const tchar *stream_name = tstrchr(base, T(':'));
+ if (!stream_name)
+ return NULL;
+ else
+ return stream_name + 1;
+}
+
+
+/* Translate backslashes to forward slashes in-place. */
+void
+zap_backslashes(tchar *s)
+{
+ if (s) {
+ while (*s != T('\0')) {
+ if (*s == T('\\'))
+ *s = T('/');
+ s++;
+ }
+ }
+}
+
+/* Duplicate a path, with backslashes translated into forward slashes; return
+ * empty string for NULL input. */
+tchar *
+canonicalize_fs_path(const tchar *fs_path)
+{
+ tchar *canonical_path;
+
+ if (!fs_path)
+ fs_path = T("");
+ canonical_path = TSTRDUP(fs_path);
+ zap_backslashes(canonical_path);
+ return canonical_path;
+}
+
+/* Duplicate a path, with backslashes translated into forward slashes; return
+ * empty string for NULL input; also strip leading and trailing slashes. */
+tchar *
+canonicalize_wim_path(const tchar *wim_path)
+{
+ tchar *p;
+ tchar *canonical_path;
+
+ if (wim_path == NULL) {
+ wim_path = T("");
+ } else {
+ while (*wim_path == T('/') || *wim_path == T('\\'))
+ wim_path++;
+ }
+ canonical_path = TSTRDUP(wim_path);
+ if (canonical_path) {
+ zap_backslashes(canonical_path);
+ for (p = tstrchr(canonical_path, T('\0')) - 1;
+ p >= canonical_path && *p == T('/');
+ p--)
+ {
+ *p = T('\0');
+ }
+ }
+ return canonical_path;
+}
linux/lib/rbtree.c
*/
-#include "rbtree.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/rbtree.h"
+#include <stdbool.h>
/*
* red-black trees properties: http://en.wikipedia.org/wiki/Rbtree
/*
- * reparse.c
- *
- * Handle reparse data.
+ * reparse.c - Handle reparse data.
*/
/*
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "dentry.h"
-#include "buffer_io.h"
-#include "lookup_table.h"
-#include "sha1.h"
-#include <errno.h>
-#include <stdlib.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/assert.h"
+#include "wimlib/buffer_io.h"
+#include "wimlib/dentry.h"
+#include "wimlib/encoding.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/reparse.h"
+#include "wimlib/resource.h"
+
+#ifdef __WIN32__
+# include "wimlib/win32.h" /* for win32_get_file_and_vol_ids() */
+#endif
+
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
+#include <errno.h>
+#include <stdlib.h>
static const utf16lechar volume_junction_prefix[11] = {
cpu_to_le16('\\'),
#endif /* !defined(__WIN32__) */
#ifdef __WIN32__
-# include "win32.h"
# define RP_PATH_SEPARATOR L'\\'
# define is_rp_path_separator(c) ((c) == L'\\' || (c) == L'/')
# define os_get_ino_and_dev win32_get_file_and_vol_ids
* wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "buffer_io.h"
-#include "sha1.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/buffer_io.h"
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/file_io.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/resource.h"
+#include "wimlib/sha1.h"
#ifdef __WIN32__
-# include "win32.h"
+/* for read_win32_file_prefix(), read_win32_encrypted_file_prefix() */
+# include "wimlib/win32.h"
#endif
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
+#ifdef WITH_NTFS_3G
+/* for read_ntfs_file_prefix() */
+# include "wimlib/ntfs_3g.h"
+#endif
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
/*
* Reads all or part of a compressed WIM resource.
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "buffer_io.h"
-#include "security.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/assert.h"
+#include "wimlib/buffer_io.h"
+#include "wimlib/error.h"
+#include "wimlib/security.h"
+#include "wimlib/sha1.h"
+#include "wimlib/util.h"
/* At the start of each type of access control entry. */
typedef struct {
}
struct wim_security_data *
-new_wim_security_data()
+new_wim_security_data(void)
{
return CALLOC(1, sizeof(struct wim_security_data));
}
/* Frees a security descriptor index set. */
void
-destroy_sd_set(struct sd_set *sd_set, bool rollback)
+destroy_sd_set(struct wim_sd_set *sd_set, bool rollback)
{
if (rollback) {
struct wim_security_data *sd = sd_set->sd;
- int32_t i;
- for (i = sd_set->orig_num_entries; i < sd->num_entries; i++)
+ for (s32 i = sd_set->orig_num_entries; i < sd->num_entries; i++)
FREE(sd->descriptors[i]);
sd->num_entries = sd_set->orig_num_entries;
}
/* Inserts a a new node into the security descriptor index tree. */
static bool
-insert_sd_node(struct sd_set *set, struct sd_node *new)
+insert_sd_node(struct wim_sd_set *set, struct sd_node *new)
{
struct rb_root *root = &set->rb_root;
struct rb_node **p = &(root->rb_node);
/* Returns the index of the security descriptor having a SHA1 message digest of
* @hash. If not found, return -1. */
int
-lookup_sd(struct sd_set *set, const u8 hash[SHA1_HASH_SIZE])
+lookup_sd(struct wim_sd_set *set, const u8 hash[SHA1_HASH_SIZE])
{
struct rb_node *node = set->rb_root.rb_node;
* return -1.
*/
int
-sd_set_add_sd(struct sd_set *sd_set, const char descriptor[], size_t size)
+sd_set_add_sd(struct wim_sd_set *sd_set, const char descriptor[], size_t size)
{
u8 hash[SHA1_HASH_SIZE];
int security_id;
* descriptors to indices into the security descriptors table of the WIM image
* (security IDs). */
int
-init_sd_set(struct sd_set *sd_set, struct wim_security_data *sd)
+init_sd_set(struct wim_sd_set *sd_set, struct wim_security_data *sd)
{
int ret;
/* Remember the original number of security descriptors so that newly
* added ones can be rolled back if needed. */
sd_set->orig_num_entries = sd->num_entries;
- for (int32_t i = 0; i < sd->num_entries; i++) {
+ for (s32 i = 0; i < sd->num_entries; i++) {
struct sd_node *new;
new = MALLOC(sizeof(struct sd_node));
+++ /dev/null
-#include "util.h"
-#include "rbtree.h"
-#include "sha1.h"
-
-#ifndef _WIMLIB_SECURITY_H
-#define _WIMLIB_SECURITY_H
-
-/* Red-black tree that maps SHA1 message digests of security descriptors to
- * security IDs, which are themselves indices into the table of security
- * descriptors in the 'struct wim_security_data'. */
-struct sd_set {
- struct wim_security_data *sd;
- struct rb_root rb_root;
- int32_t orig_num_entries;
-};
-extern void
-destroy_sd_set(struct sd_set *sd_set, bool rollback);
-
-extern int
-lookup_sd(struct sd_set *set, const u8 hash[SHA1_HASH_SIZE]);
-
-extern int
-sd_set_add_sd(struct sd_set *sd_set, const char descriptor[],
- size_t size);
-
-extern int
-init_sd_set(struct sd_set *sd_set, struct wim_security_data *sd);
-
-#endif /* _WIMLIB_SECURITY_H */
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "util.h"
-#include "wimlib.h"
-#include "sha1.h"
-#include "endianness.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/sha1.h"
+
#include <string.h>
/* The SHA1 support in wimlib can use an external libcrypto (part of openssl) or
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "lookup_table.h"
-#include "xml.h"
-#include "buffer_io.h"
-#include <unistd.h>
-#include <fcntl.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/buffer_io.h"
+#include "wimlib/error.h"
+#include "wimlib/file_io.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/types.h"
+#include "wimlib/write.h"
+#include "wimlib/list.h"
+
+#include <fcntl.h> /* for open() */
+#include <unistd.h> /* for close() */
struct split_args {
WIMStruct *w;
--- /dev/null
+/*
+ * timestamp.c
+ */
+
+/*
+ * Copyright (C) 2012, 2013 Eric Biggers
+ *
+ * This file is part of wimlib, a library for working with WIM files.
+ *
+ * wimlib is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/types.h"
+#include "wimlib/timestamp.h"
+
+#include <time.h>
+#include <sys/time.h>
+
+u64
+get_wim_timestamp(void)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return timeval_to_wim_timestamp(tv);
+}
+
+void
+wim_timestamp_to_str(u64 timestamp, tchar *buf, size_t len)
+{
+ struct tm tm;
+ time_t t = wim_timestamp_to_unix(timestamp);
+ gmtime_r(&t, &tm);
+ tstrftime(buf, len, T("%a %b %d %H:%M:%S %Y UTC"), &tm);
+}
+
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "config.h"
+#ifndef __WIN32__
-#ifdef HAVE_UTIME_H
-# include <utime.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
#endif
+
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
+#ifdef HAVE_UTIME_H
+# include <utime.h>
+#endif
-#include "timestamp.h"
-#include "wimlib_internal.h"
-#include "lookup_table.h"
+#include "wimlib/apply.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/reparse.h"
+#include "wimlib/timestamp.h"
/* Returns the number of components of @path. */
static unsigned
}
return 0;
}
+
+#endif /* !__WIN32__ */
#ifndef __WIN32__
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "timestamp.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
+#include "wimlib/capture.h"
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/paths.h"
+#include "wimlib/reparse.h"
+#include "wimlib/timestamp.h"
+
static int
unix_capture_regular_file(const char *path,
u64 size,
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "security.h"
-#include "xml.h"
-#include <errno.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
-#ifdef __WIN32__
-# include "win32.h"
+#include "wimlib/capture.h"
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#ifdef WITH_NTFS_3G
+# include "wimlib/ntfs_3g.h" /* for do_ntfs_umount() */
#endif
+#include "wimlib/paths.h"
+#include "wimlib/xml.h"
+
+#include <errno.h>
/* Overlays @branch onto @target, both of which must be directories. */
static int
return T("rename");
default:
wimlib_assert(0);
+ return NULL;
}
}
}
-extern void
+static void
free_update_commands(struct wimlib_update_command *cmds, size_t num_cmds)
{
if (cmds) {
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "config.h"
-
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
-#undef _GNU_SOURCE
+#ifdef _GNU_SOURCE
+# define _GNU_SOURCE_DEFINED 1
+# undef _GNU_SOURCE
+#endif
/* Make sure the POSIX-compatible strerror_r() is declared, rather than the GNU
* version, which has a different return type. */
#include <string.h>
+#ifdef _GNU_SOURCE_DEFINED
+# define _GNU_SOURCE
+#endif
-#define _GNU_SOURCE
+#include "wimlib.h"
+#include "wimlib/compiler.h"
+#include "wimlib/encoding.h"
+#include "wimlib/error.h"
+#include "wimlib/types.h"
+#include "wimlib/util.h"
+#include "wimlib/xml.h"
-#include "endianness.h"
-#include "timestamp.h"
-#include "wimlib_internal.h"
+#ifdef __WIN32__
+# include "wimlib/win32.h" /* win32_strerror_r_replacement */
+#endif
-#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <time.h>
#include <unistd.h>
-
-#ifdef __WIN32__
-# include "win32.h"
-# define pread win32_pread
-# define pwrite win32_pwrite
-# define writev win32_writev
-#else
-# include <sys/uio.h> /* for writev() and `struct iovec' */
-#endif
-
static size_t
utf16le_strlen(const utf16lechar *s)
{
va_end(va);
return ret;
}
+
+#endif /* __WIN32__ */
+
+#ifdef ENABLE_ERROR_MESSAGES
+static bool wimlib_print_errors = false;
#endif
#if defined(ENABLE_ERROR_MESSAGES) || defined(ENABLE_DEBUG)
/* True if wimlib is to print an informational message when an error occurs.
* This can be turned off by calling wimlib_set_print_errors(false). */
#ifdef ENABLE_ERROR_MESSAGES
-static bool wimlib_print_errors = false;
-
-
void
wimlib_error(const tchar *format, ...)
{
}
#endif
-extern void
-xml_set_memory_allocator(void *(*malloc_func)(size_t),
- void (*free_func)(void *),
- void *(*realloc_func)(void *, size_t));
-#endif
+#endif /* ENABLE_CUSTOM_MEMORY_ALLOCATOR */
WIMLIBAPI int
wimlib_set_memory_allocator(void *(*malloc_func)(size_t),
static bool seeded = false;
static void
-seed_random()
+seed_random(void)
{
srand(time(NULL) * getpid());
seeded = true;
*p++ = rand();
}
-const tchar *
-path_basename_with_len(const tchar *path, size_t len)
-{
- const tchar *p = &path[len] - 1;
-
- /* Trailing slashes. */
- while (1) {
- if (p == path - 1)
- return T("");
- if (*p != T('/'))
- break;
- p--;
- }
-
- while ((p != path - 1) && *p != T('/'))
- p--;
-
- return p + 1;
-}
-
-/* Like the basename() function, but does not modify @path; it just returns a
- * pointer to it. */
-const tchar *
-path_basename(const tchar *path)
-{
- return path_basename_with_len(path, tstrlen(path));
-}
-
-/*
- * Returns a pointer to the part of @path following the first colon in the last
- * path component, or NULL if the last path component does not contain a colon.
- */
-const tchar *
-path_stream_name(const tchar *path)
-{
- const tchar *base = path_basename(path);
- const tchar *stream_name = tstrchr(base, T(':'));
- if (!stream_name)
- return NULL;
- else
- return stream_name + 1;
-}
-
-u64
-get_wim_timestamp()
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return timeval_to_wim_timestamp(tv);
-}
-
-void
-wim_timestamp_to_str(u64 timestamp, tchar *buf, size_t len)
-{
- struct tm tm;
- time_t t = wim_timestamp_to_unix(timestamp);
- gmtime_r(&t, &tm);
- tstrftime(buf, len, T("%a %b %d %H:%M:%S %Y UTC"), &tm);
-}
-
-void
-zap_backslashes(tchar *s)
-{
- if (s) {
- while (*s != T('\0')) {
- if (*s == T('\\'))
- *s = T('/');
- s++;
- }
- }
-}
-
-tchar *
-canonicalize_fs_path(const tchar *fs_path)
-{
- tchar *canonical_path;
-
- if (!fs_path)
- fs_path = T("");
- canonical_path = TSTRDUP(fs_path);
- zap_backslashes(canonical_path);
- return canonical_path;
-}
-
-/* Strip leading and trailing slashes from a string. Also translates
- * backslashes into forward slashes. */
-tchar *
-canonicalize_wim_path(const tchar *wim_path)
-{
- tchar *p;
- tchar *canonical_path;
-
- if (wim_path == NULL) {
- wim_path = T("");
- } else {
- while (*wim_path == T('/') || *wim_path == T('\\'))
- wim_path++;
- }
- canonical_path = TSTRDUP(wim_path);
- if (canonical_path) {
- zap_backslashes(canonical_path);
- for (p = tstrchr(canonical_path, T('\0')) - 1;
- p >= canonical_path && *p == T('/');
- p--)
- {
- *p = T('\0');
- }
- }
- return canonical_path;
-}
-
-/* Like read(), but keep trying until everything has been written or we know for
- * sure that there was an error (or end-of-file). */
-size_t
-full_read(int fd, void *buf, size_t count)
-{
- ssize_t bytes_read;
- size_t bytes_remaining;
-
- for (bytes_remaining = count;
- bytes_remaining != 0;
- bytes_remaining -= bytes_read, buf += bytes_read)
- {
- bytes_read = read(fd, buf, bytes_remaining);
- if (bytes_read <= 0) {
- if (bytes_read == 0)
- errno = EIO;
- else if (errno == EINTR)
- continue;
- break;
- }
- }
- return count - bytes_remaining;
-}
-
-/* Like write(), but keep trying until everything has been written or we know
- * for sure that there was an error. */
-size_t
-full_write(int fd, const void *buf, size_t count)
-{
- ssize_t bytes_written;
- size_t bytes_remaining;
-
- for (bytes_remaining = count;
- bytes_remaining != 0;
- bytes_remaining -= bytes_written, buf += bytes_written)
- {
- bytes_written = write(fd, buf, bytes_remaining);
- if (bytes_written < 0) {
- if (errno == EINTR)
- continue;
- break;
- }
- }
- return count - bytes_remaining;
-}
-
-/* Like pread(), but keep trying until everything has been read or we know for
- * sure that there was an error (or end-of-file) */
-size_t
-full_pread(int fd, void *buf, size_t count, off_t offset)
-{
- ssize_t bytes_read;
- size_t bytes_remaining;
-
- for (bytes_remaining = count;
- bytes_remaining != 0;
- bytes_remaining -= bytes_read, buf += bytes_read,
- offset += bytes_read)
- {
- bytes_read = pread(fd, buf, bytes_remaining, offset);
- if (bytes_read <= 0) {
- if (bytes_read == 0)
- errno = EIO;
- else if (errno == EINTR)
- continue;
- break;
- }
- }
- return count - bytes_remaining;
-}
-
-/* Like pwrite(), but keep trying until everything has been written or we know
- * for sure that there was an error. */
-size_t
-full_pwrite(int fd, const void *buf, size_t count, off_t offset)
-{
- ssize_t bytes_written;
- size_t bytes_remaining;
-
- for (bytes_remaining = count;
- bytes_remaining != 0;
- bytes_remaining -= bytes_written, buf += bytes_written,
- offset += bytes_written)
- {
- bytes_written = pwrite(fd, buf, bytes_remaining, offset);
- if (bytes_written < 0) {
- if (errno == EINTR)
- continue;
- break;
- }
- }
- return count - bytes_remaining;
-}
-
-/* Like writev(), but keep trying until everything has been written or we know
- * for sure that there was an error. */
-size_t
-full_writev(int fd, struct iovec *iov, int iovcnt)
-{
- size_t total_bytes_written = 0;
- while (iovcnt > 0) {
- ssize_t bytes_written;
-
- bytes_written = writev(fd, iov, iovcnt);
- if (bytes_written < 0) {
- if (errno == EINTR)
- continue;
- break;
- }
- total_bytes_written += bytes_written;
- while (bytes_written) {
- if (bytes_written >= iov[0].iov_len) {
- bytes_written -= iov[0].iov_len;
- iov++;
- iovcnt--;
- } else {
- iov[0].iov_base += bytes_written;
- iov[0].iov_len -= bytes_written;
- bytes_written = 0;
- }
- }
- }
- return total_bytes_written;
-}
-off_t
-filedes_offset(int fd)
+void print_byte_field(const u8 field[], size_t len, FILE *out)
{
- return lseek(fd, 0, SEEK_CUR);
+ while (len--)
+ tfprintf(out, T("%02hhx"), *field++);
}
+++ /dev/null
-#ifndef _WIMLIB_UTIL_H
-#define _WIMLIB_UTIL_H
-
-#include "config.h"
-#include "wimlib_tchar.h"
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <inttypes.h>
-#include <sys/types.h>
-
-#ifdef __GNUC__
-# if defined(__CYGWIN__) || defined(__WIN32__)
-# define WIMLIBAPI __declspec(dllexport)
-# else
-# define WIMLIBAPI __attribute__((visibility("default")))
-# endif
-# define ALWAYS_INLINE inline __attribute__((always_inline))
-# define PACKED __attribute__((packed))
-# define FORMAT(type, format_str, args_start) \
- /*__attribute__((format(type, format_str, args_start))) */
-# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
-# define COLD __attribute__((cold))
-# else
-# define COLD
-# endif
-#else
-# define WIMLIBAPI
-# define ALWAYS_INLINE inline
-# define FORMAT(type, format_str, args_start)
-# define COLD
-# define PACKED
-#endif /* __GNUC__ */
-
-
-#if 0
-#ifdef WITH_FUSE
-#define atomic_inc(ptr) \
- __sync_fetch_and_add(ptr, 1)
-
-#define atomic_dec(ptr) \
- __sync_sub_and_fetch(ptr, 1)
-#endif
-#endif
-
-#ifndef _NTFS_TYPES_H
-typedef uint8_t u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-#endif
-
-
-/* A pointer to 'utf16lechar' indicates a UTF-16LE encoded string */
-typedef u16 utf16lechar;
-
-#define TMALLOC(n) MALLOC((n) * sizeof(tchar))
-
-/* encoding.c */
-extern void
-iconv_global_cleanup();
-
-extern bool wimlib_mbs_is_utf8;
-
-#define DECLARE_CHAR_CONVERSION_FUNCTIONS(varname1, varname2, \
- chartype1, chartype2) \
- \
-extern int \
-varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes, \
- chartype2 **out_ret, \
- size_t *out_nbytes_ret); \
- \
-extern int \
-varname1##_to_##varname2##_nbytes(const chartype1 *in, size_t in_nbytes,\
- size_t *out_nbytes_ret); \
- \
-extern int \
-varname1##_to_##varname2##_buf(const chartype1 *in, size_t in_nbytes, \
- chartype2 *out);
-
-
-#if !TCHAR_IS_UTF16LE
-DECLARE_CHAR_CONVERSION_FUNCTIONS(utf16le, tstr, utf16lechar, tchar);
-DECLARE_CHAR_CONVERSION_FUNCTIONS(tstr, utf16le, tchar, utf16lechar);
-#endif
-
-extern int
-utf8_to_tstr_simple(const char *utf8str, tchar **out);
-
-extern int
-tstr_to_utf8_simple(const tchar *tstr, char **out);
-
-#ifndef min
-#define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
- (__a < __b) ? __a : __b; })
-#endif
-
-#ifndef max
-#define max(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
- (__a > __b) ? __a : __b; })
-#endif
-
-#ifndef swap
-#define swap(a, b) ({typeof(a) _a = a; (a) = (b); (b) = _a;})
-#endif
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
-#define DIV_ROUND_UP(numerator, denominator) \
- (((numerator) + (denominator) - 1) / (denominator))
-
-#define MODULO_NONZERO(numerator, denominator) \
- (((numerator) % (denominator)) ? ((numerator) % (denominator)) : (denominator))
-
-#define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
-
-#define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
-
-/* Used for buffering FILE IO in a few places */
-#define BUFFER_SIZE 32768
-
-static inline void FORMAT(printf, 1, 2)
-dummy_tprintf(const tchar *format, ...)
-{
-}
-
-#ifdef ENABLE_ERROR_MESSAGES
-extern void
-wimlib_error(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
-
-extern void
-wimlib_error_with_errno(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
-
-extern void
-wimlib_warning(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
-
-extern void
-wimlib_warning_with_errno(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
-# define ERROR(format, ...) wimlib_error(T(format), ## __VA_ARGS__)
-# define ERROR_WITH_ERRNO(format, ...) wimlib_error_with_errno(T(format), ## __VA_ARGS__)
-# define WARNING(format, ...) wimlib_warning(T(format), ## __VA_ARGS__)
-# define WARNING_WITH_ERRNO(format, ...) wimlib_warning_with_errno(T(format), ## __VA_ARGS__)
-#else /* ENABLE_ERROR_MESSAGES */
-# define ERROR(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
-# define ERROR_WITH_ERRNO(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
-# define WARNING(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
-# define WARNING_WITH_ERRNO(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
-#endif /* !ENABLE_ERROR_MESSAGES */
-
-#if defined(ENABLE_MORE_DEBUG) && !defined(ENABLE_DEBUG)
-# define ENABLE_DEBUG 1
-#endif
-
-#if defined(ENABLE_MORE_ASSERTIONS) && !defined(ENABLE_ASSERTIONS)
-# define ENABLE_ASSERTIONS 1
-#endif
-
-#ifdef ENABLE_DEBUG
-extern void
-wimlib_debug(const tchar *file, int line, const char *func,
- const tchar *format, ...);
-# define DEBUG(format, ...) \
- wimlib_debug(T(__FILE__), __LINE__, __func__, T(format), ## __VA_ARGS__)
-
-#else
-# define DEBUG(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
-#endif /* !ENABLE_DEBUG */
-
-#ifdef ENABLE_MORE_DEBUG
-# define DEBUG2(format, ...) DEBUG(format, ## __VA_ARGS__)
-#else
-# define DEBUG2(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
-#endif /* !ENABLE_MORE_DEBUG */
-
-#ifdef ENABLE_ASSERTIONS
-#include <assert.h>
-# define wimlib_assert(expr) assert(expr)
-#else
-# define wimlib_assert(expr)
-#endif /* !ENABLE_ASSERTIONS */
-
-#ifdef ENABLE_MORE_ASSERTIONS
-# define wimlib_assert2(expr) wimlib_assert(expr)
-#else
-# define wimlib_assert2(expr)
-#endif /* !ENABLE_MORE_ASSERTIONS */
-
-#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
-
-#ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR
-extern void *(*wimlib_malloc_func)(size_t);
-extern void (*wimlib_free_func)(void *);
-extern void *(*wimlib_realloc_func)(void *, size_t);
-extern void *wimlib_calloc(size_t nmemb, size_t size);
-#ifdef __WIN32__
-extern wchar_t *wimlib_wcsdup(const wchar_t *str);
-#endif
-extern char *wimlib_strdup(const char *str);
-# define MALLOC wimlib_malloc_func
-# define FREE wimlib_free_func
-# define REALLOC wimlib_realloc_func
-# define CALLOC wimlib_calloc
-# define STRDUP wimlib_strdup
-# define WSTRDUP wimlib_wcsdup
-#else /* ENABLE_CUSTOM_MEMORY_ALLOCATOR */
-# include <stdlib.h>
-# include <string.h>
-# define MALLOC malloc
-# define FREE free
-# define REALLOC realloc
-# define CALLOC calloc
-# define STRDUP strdup
-# define WSTRDUP wcsdup
-#endif /* !ENABLE_CUSTOM_MEMORY_ALLOCATOR */
-
-
-/* util.c */
-extern void
-randomize_byte_array(u8 *p, size_t n);
-
-extern void
-randomize_char_array_with_alnum(tchar p[], size_t n);
-
-const tchar *
-path_basename_with_len(const tchar *path, size_t len);
-
-const tchar *
-path_basename(const tchar *path);
-
-extern const tchar *
-path_stream_name(const tchar *path);
-
-static inline void
-print_byte_field(const u8 field[], size_t len, FILE *out)
-{
- while (len--)
- tfprintf(out, T("%02hhx"), *field++);
-}
-
-static inline u32
-bsr32(u32 n)
-{
-#if defined(__x86__) || defined(__x86_64__)
- asm("bsrl %0, %0;"
- : "=r"(n)
- : "0" (n));
- return n;
-#else
- u32 pow = 0;
- while ((n >>= 1) != 0)
- pow++;
- return pow;
-#endif
-}
-
-#ifdef __WIN32__
-# define wimlib_fprintf fwprintf
-# define wimlib_printf wprintf
-#else /* __WIN32__ */
-extern int
-wimlib_fprintf(FILE *fp, const tchar *format, ...) FORMAT(printf, 2, 3);
-
-extern int
-wimlib_printf(const tchar *format, ...) FORMAT(printf, 1, 2);
-#endif /* !__WIN32__ */
-
-extern void
-zap_backslashes(tchar *s);
-
-extern tchar *
-canonicalize_wim_path(const tchar *wim_path);
-
-extern tchar *
-canonicalize_fs_path(const tchar *fs_path);
-
-static inline u64
-hash_u64(u64 n)
-{
- return n * 0x9e37fffffffc0001ULL;
-}
-
-extern size_t
-full_read(int fd, void *buf, size_t n);
-
-extern size_t
-full_write(int fd, const void *buf, size_t n);
-
-extern size_t
-full_pread(int fd, void *buf, size_t nbyte, off_t offset);
-
-extern size_t
-full_pwrite(int fd, const void *buf, size_t count, off_t offset);
-
-#ifdef __WIN32__
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-#else
-struct iovec;
-#endif
-
-extern size_t
-full_writev(int fd, struct iovec *iov, int iovcnt);
-
-extern off_t
-filedes_offset(int fd);
-
-#ifndef __WIN32__
-# define O_BINARY 0
-#endif
-
-#endif /* _WIMLIB_UTIL_H */
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/security.h"
+#include "wimlib/swm.h"
static int
verify_inode(struct wim_inode *inode, const WIMStruct *w)
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/error.h"
+#include "wimlib/dentry.h"
+#include "wimlib/encoding.h"
+#include "wimlib/file_io.h"
+#include "wimlib/integrity.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#ifdef WITH_NTFS_3G
+# include "wimlib/ntfs_3g.h" /* for do_ntfs_umount() */
+#endif
+#include "wimlib/security.h"
+#include "wimlib/wim.h"
+#include "wimlib/xml.h"
+
+#ifdef __WIN32__
+# include "wimlib/win32.h" /* for realpath() replacement */
+#endif
#include <errno.h>
#include <fcntl.h>
+#ifndef __WIN32__
+# include <langinfo.h>
+#endif
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
-#ifdef __WIN32__
-# include "win32.h"
-#else
-# include <langinfo.h>
-#endif
-
-#include "buffer_io.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "wimlib_internal.h"
-#include "xml.h"
-
static int
image_print_metadata(WIMStruct *w)
{
}
static WIMStruct *
-new_wim_struct()
+new_wim_struct(void)
{
WIMStruct *w = CALLOC(1, sizeof(WIMStruct));
if (w) {
struct wim_image_metadata *
-new_image_metadata()
+new_image_metadata(void)
{
struct wim_image_metadata *imd;
}
static bool
-test_locale_ctype_utf8()
+test_locale_ctype_utf8(void)
{
#ifdef __WIN32__
return false;
/* Free global memory allocations. Not strictly necessary if the process using
* wimlib is just about to exit (as is the case for 'imagex'). */
WIMLIBAPI void
-wimlib_global_cleanup()
+wimlib_global_cleanup(void)
{
libxml_global_cleanup();
iconv_global_cleanup();
+++ /dev/null
-/*
- * wimlib_internal.h
- *
- * Internal header for wimlib.
- */
-
-/*
- * Copyright (C) 2012, 2013 Eric Biggers
- *
- * This file is part of wimlib, a library for working with WIM files.
- *
- * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version.
- *
- * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with wimlib; if not, see http://www.gnu.org/licenses/.
- */
-
-#ifndef _WIMLIB_INTERNAL_H
-#define _WIMLIB_INTERNAL_H
-
-#include "config.h"
-#include "util.h"
-#include "list.h"
-#include "wimlib.h"
-#include "security.h"
-
-#define WIMLIB_MAKEVERSION(major, minor, patch) \
- ((major << 20) | (minor << 10) | patch)
-
-
-#define WIMLIB_VERSION_CODE \
- WIMLIB_MAKEVERSION(WIMLIB_MAJOR_VERSION,\
- WIMLIB_MINOR_VERSION,\
- WIMLIB_PATCH_VERSION)
-
-#define WIMLIB_GET_PATCH_VERSION(version) \
- ((version >> 0) & ((1 << 10) - 1))
-#define WIMLIB_GET_MINOR_VERSION(version) \
- ((version >> 10) & ((1 << 10) - 1))
-#define WIMLIB_GET_MAJOR_VERSION(version) \
- ((version >> 20) & ((1 << 10) - 1))
-
-
-struct stat;
-struct wim_dentry;
-struct wim_inode;
-struct sd_set;
-
-#define WIM_MAGIC_LEN 8
-#define WIM_GID_LEN 16
-#define WIM_UNUSED_LEN 60
-
-/* Length of the WIM header on disk. */
-#define WIM_HEADER_DISK_SIZE (148 + WIM_UNUSED_LEN)
-
-/* Compressed resources in the WIM are divided into separated compressed chunks
- * of this size. */
-#define WIM_CHUNK_SIZE 32768
-
-/* Version of the WIM file. There is an older version, but we don't support it
- * yet. The differences between the versions are undocumented. */
-#define WIM_VERSION 0x10d00
-
-#define REPARSE_POINT_MAX_SIZE (16 * 1024)
-
-/* Metadata for a resource in a WIM file. */
-struct resource_entry {
- /* Size, in bytes, of the resource in the WIM file. */
- u64 size : 56;
-
- /* Bitwise or of one or more of the WIM_RESHDR_FLAG_* flags. */
- u64 flags : 8;
-
- /* Offset, in bytes, of the resource in the WIM file. */
- u64 offset;
-
- /* Uncompressed size of the resource in the WIM file. Is the same as
- * @size if the resource is uncompressed. */
- u64 original_size;
-};
-
-/* Flags for the `flags' field of the struct resource_entry structure. */
-
-/* I haven't seen this flag used in any of the WIMs I have examined. I assume
- * it means that there are no references to the stream, so the space is free.
- * However, even after deleting files from a WIM mounted with `imagex.exe
- * /mountrw', I could not see this flag being used. Either way, we don't
- * actually use this flag for anything. */
-#define WIM_RESHDR_FLAG_FREE 0x01
-
-/* Indicates that the stream is a metadata resource for a WIM image. */
-#define WIM_RESHDR_FLAG_METADATA 0x02
-
-/* Indicates that the stream is compressed. */
-#define WIM_RESHDR_FLAG_COMPRESSED 0x04
-
-/* I haven't seen this flag used in any of the WIMs I have examined. Perhaps it
- * means that a stream could possibly be split among multiple split WIM parts.
- * However, `imagex.exe /split' does not seem to create any WIMs like this.
- * Either way, we don't actually use this flag for anything. */
-#define WIM_RESHDR_FLAG_SPANNED 0x08
-
-/* Header at the very beginning of the WIM file. */
-struct wim_header {
- /* Identifies the file as WIM file. Must be exactly
- * {'M', 'S', 'W', 'I', 'M', 0, 0, 0} */
- //u8 magic[WIM_MAGIC_LEN];
-
- /* size of WIM header in bytes. */
- //u32 hdr_size;
-
- /* Version of the WIM file. Microsoft provides no documentation about
- * exactly what this field affects about the file format, other than the
- * fact that more recent versions have a higher value. */
- //u32 version;
-
- /* Bitwise OR of one or more of the WIM_HDR_FLAG_* defined below. */
- u32 flags;
-
- /* The size of the pieces that the uncompressed files were split up into
- * when they were compressed. This should be the same as
- * WIM_CHUNK_SIZE. Microsoft incorrectly documents this as "the size of
- * the compressed .wim file in bytes".*/
- //u32 chunk_size;
-
- /* A unique identifier for the WIM file. */
- u8 guid[WIM_GID_LEN];
-
- /* Part number of the WIM file in a spanned set. */
- u16 part_number;
-
- /* Total number of parts in a spanned set. */
- u16 total_parts;
-
- /* Number of images in the WIM file. */
- u32 image_count;
-
- /* Location, size, and flags of the lookup table of the WIM. */
- struct resource_entry lookup_table_res_entry;
-
- /* Location, size, and flags for the XML data of the WIM. */
- struct resource_entry xml_res_entry;
-
- /* Location, size, and flags for the boot metadata. This means the
- * metadata resource for the image specified by boot_idx below. Should
- * be zeroed out if boot_idx is 0. */
- struct resource_entry boot_metadata_res_entry;
-
- /* The index of the bootable image in the WIM file. If 0, there are no
- * bootable images available. */
- u32 boot_idx;
-
- /* The location of the optional integrity table used to verify the
- * integrity WIM. Zeroed out if there is no integrity table.*/
- struct resource_entry integrity;
-
- /* Reserved for future disuse */
- //u8 unused[WIM_UNUSED_LEN];
-};
-
-/* Flags for the `flags' field of the struct wim_header: */
-
-/* Reserved for future use */
-#define WIM_HDR_FLAG_RESERVED 0x00000001
-
-/* Files and metadata in the WIM are compressed. */
-#define WIM_HDR_FLAG_COMPRESSION 0x00000002
-
-/* WIM is read-only (wimlib ignores this because it's pretty much pointless) */
-#define WIM_HDR_FLAG_READONLY 0x00000004
-
-/* Resource data specified by images in this WIM may be contained in a different
- * WIM. Or in other words, this WIM is part of a split WIM. */
-#define WIM_HDR_FLAG_SPANNED 0x00000008
-
-/* The WIM contains resources only; no filesystem metadata. wimlib ignores this
- * flag, as it looks for resources in all the WIMs anyway. */
-#define WIM_HDR_FLAG_RESOURCE_ONLY 0x00000010
-
-/* The WIM contains metadata only. wimlib ignores this flag. Note that all the
- * metadata resources for a split WIM should be in the first part. */
-#define WIM_HDR_FLAG_METADATA_ONLY 0x00000020
-
-/* Lock field to prevent multiple writers from writing the WIM concurrently.
- * wimlib ignores this flag as it uses flock() to acquire a real lock on the
- * file (if supported by the underlying filesystem). */
-#define WIM_HDR_FLAG_WRITE_IN_PROGRESS 0x00000040
-
-/* Reparse point fixup flag. See docs for --rpfix and --norpfix in imagex, or
- * WIMLIB_ADD_FLAG_{RPFIX,NORPFIX} in wimlib.h. Note that
- * WIM_HDR_FLAG_RP_FIX is a header flag and just sets the default behavior for
- * the WIM; it can still be overridder on a per-image basis. But there is no
- * flag to set the default behavior for a specific image. */
-#define WIM_HDR_FLAG_RP_FIX 0x00000080
-
-/* Unused, reserved flag for another compression type */
-#define WIM_HDR_FLAG_COMPRESS_RESERVED 0x00010000
-
-/* Resources within the WIM are compressed using "XPRESS" compression, which is
- * a LZ77-based compression algorithm. */
-#define WIM_HDR_FLAG_COMPRESS_XPRESS 0x00020000
-
-/* Resources within the WIM are compressed using "LZX" compression. This is also
- * a LZ77-based algorithm. */
-#define WIM_HDR_FLAG_COMPRESS_LZX 0x00040000
-
-#ifdef WITH_NTFS_3G
-struct _ntfs_volume;
-#endif
-
-/* Table of security descriptors for a WIM image. */
-struct wim_security_data {
- /* The total length of the security data, in bytes. If there are no
- * security descriptors, this field, when read from the on-disk metadata
- * resource, may be either 8 (which is correct) or 0 (which is
- * interpreted as 0). */
- u32 total_length;
-
- /* The number of security descriptors in the array @descriptors, below.
- * It is really an unsigned int on-disk, but it must fit into an int
- * because the security ID's are signed. (Not like you would ever have
- * more than a few hundred security descriptors anyway.) */
- int32_t num_entries;
-
- /* Array of sizes of the descriptors in the array @descriptors. */
- u64 *sizes;
-
- /* Array of descriptors. */
- u8 **descriptors;
-};
-
-/* Metadata for a WIM image */
-struct wim_image_metadata {
-
- /* Number of WIMStruct's that are sharing this image metadata (from
- * calls to wimlib_export_image().) */
- unsigned long refcnt;
-
- /* Pointer to the root dentry of the image. */
- struct wim_dentry *root_dentry;
-
- /* Pointer to the security data of the image. */
- struct wim_security_data *security_data;
-
- /* Pointer to the lookup table entry for this image's metadata resource
- */
- struct wim_lookup_table_entry *metadata_lte;
-
- /* Linked list of 'struct wim_inode's for this image. */
- struct list_head inode_list;
-
- /* Linked list of 'struct wim_lookup_table_entry's for this image that
- * are referred to in the dentry tree, but have not had a SHA1 message
- * digest calculated yet and therefore have not been inserted into the
- * WIM's lookup table. This list is added to during wimlib_add_image()
- * and wimlib_mount_image() (read-write only). */
- struct list_head unhashed_streams;
-
- /* 1 iff the dentry tree has been modified. If this is the case, the
- * memory for the dentry tree should not be freed when switching to a
- * different WIM image. */
- u8 modified : 1;
-
-#ifdef WITH_NTFS_3G
- struct _ntfs_volume *ntfs_vol;
-#endif
-};
-
-/* The opaque structure exposed to the wimlib API. */
-struct WIMStruct {
-
- /* File descriptor for the WIM file, opened for reading, or -1 if it has
- * not been opened or there is no associated file backing it yet. */
- int in_fd;
-
- /* File descriptor, opened either for writing only or for
- * reading+writing, for the WIM file (if any) currently being written.
- * */
- int out_fd;
-
- /* The name of the WIM file (if any) that has been opened. */
- tchar *filename;
-
- /* The lookup table for the WIM file. */
- struct wim_lookup_table *lookup_table;
-
- /* Information retrieved from the XML data, arranged in an orderly
- * manner. */
- struct wim_info *wim_info;
-
- /* Array of the image metadata, one for each image in the WIM. */
- struct wim_image_metadata **image_metadata;
-
- /* The header of the WIM file. */
- struct wim_header hdr;
-
- /* Temporary field */
- void *private;
-
- /* The currently selected image, indexed starting at 1. If not 0,
- * subtract 1 from this to get the index of the current image in the
- * image_metadata array. */
- int current_image;
-
- /* Have any images been deleted? */
- u8 deletion_occurred : 1;
-
- u8 all_images_verified : 1;
- u8 wim_locked : 1;
-};
-
-/* Inline utility functions for WIMStructs. */
-
-static inline struct wim_image_metadata *
-wim_get_current_image_metadata(WIMStruct *w)
-{
- return w->image_metadata[w->current_image - 1];
-}
-
-static inline const struct wim_image_metadata *
-wim_get_const_current_image_metadata(const WIMStruct *w)
-{
- return w->image_metadata[w->current_image - 1];
-}
-
-static inline struct wim_dentry *
-wim_root_dentry(WIMStruct *w)
-{
- return wim_get_current_image_metadata(w)->root_dentry;
-}
-
-static inline struct wim_security_data *
-wim_security_data(WIMStruct *w)
-{
- return wim_get_current_image_metadata(w)->security_data;
-}
-
-static inline const struct wim_security_data *
-wim_const_security_data(const WIMStruct *w)
-{
- return wim_get_const_current_image_metadata(w)->security_data;
-}
-
-/* Nonzero if a struct resource_entry indicates a compressed resource. */
-static inline int
-resource_is_compressed(const struct resource_entry *entry)
-{
- return (entry->flags & WIM_RESHDR_FLAG_COMPRESSED);
-}
-
-/* Iterate over each inode in a WIM image that has not yet been hashed */
-#define image_for_each_inode(inode, imd) \
- list_for_each_entry(inode, &imd->inode_list, i_list)
-
-/* Iterate over each stream in a WIM image that has not yet been hashed */
-#define image_for_each_unhashed_stream(lte, imd) \
- list_for_each_entry(lte, &imd->unhashed_streams, unhashed_list)
-
-/* Iterate over each stream in a WIM image that has not yet been hashed (safe
- * against stream removal) */
-#define image_for_each_unhashed_stream_safe(lte, tmp, imd) \
- list_for_each_entry_safe(lte, tmp, &imd->unhashed_streams, unhashed_list)
-
-#if 1
-# define copy_resource_entry(dst, src) memcpy(dst, src, sizeof(struct resource_entry))
-# define zero_resource_entry(entry) memset(entry, 0, sizeof(struct resource_entry))
-#else
-static inline void
-copy_resource_entry(struct resource_entry *dst,
- const struct resource_entry *src)
-{
- BUILD_BUG_ON(sizeof(struct resource_entry) != 24);
- ((u64*)dst)[0] = ((u64*)src)[0];
- ((u64*)dst)[1] = ((u64*)src)[1];
- ((u64*)dst)[2] = ((u64*)src)[2];
-}
-
-static inline void
-zero_resource_entry(struct resource_entry *entry)
-{
- BUILD_BUG_ON(sizeof(struct resource_entry) != 24);
- ((u64*)entry)[0] = 0;
- ((u64*)entry)[1] = 0;
- ((u64*)entry)[2] = 0;
-}
-#endif
-
-/* add_image.c */
-
-/* Hash table to find inodes, given an inode number (in the case of reading
- * a WIM images), or both an inode number and a device number (in the case of
- * capturing a WIM image). */
-struct wim_inode_table {
- /* Fields for the hash table */
- struct hlist_head *array;
- u64 num_entries;
- u64 capacity;
-
- /*
- * Linked list of "extra" inodes. These may be:
- *
- * - inodes with link count 1, which are all allowed to have 0 for their
- * inode number, meaning we cannot insert them into the hash table.
- *
- * - Groups we create ourselves by splitting a nominal inode due to
- * inconsistencies in the dentries. These inodes will share an inode
- * number with some other inode until assign_inode_numbers() is
- * called.
- */
- struct list_head extra_inodes;
-};
-
-/* Common parameters to implementations of building an in-memory dentry tree
- * from an on-disk directory structure. */
-struct add_image_params {
- /* Pointer to the lookup table of the WIM. */
- struct wim_lookup_table *lookup_table;
-
- /* Hash table of inodes that have been captured for this tree so far. */
- struct wim_inode_table inode_table;
-
- /* The set of security descriptors that have been captured for this
- * image so far. */
- struct sd_set sd_set;
-
- /* Pointer to the capture configuration, which indicates whether any
- * files should be excluded from capture or not. */
- const struct wimlib_capture_config *config;
-
- /* Flags that affect the capture operation (WIMLIB_ADD_FLAG_*) */
- int add_flags;
-
- /* If non-NULL, the user-supplied progress function. */
- wimlib_progress_func_t progress_func;
-
- /* Extra argument; set to point to a pointer to the ntfs_volume for
- * libntfs-3g capture. */
- void *extra_arg;
-
- u64 capture_root_ino;
- u64 capture_root_dev;
-};
-
-
-/* capture_common.c */
-
-extern bool
-exclude_path(const tchar *path, size_t path_len,
- const struct wimlib_capture_config *config,
- bool exclude_prefix);
-
-extern struct wimlib_capture_config *
-copy_capture_config(const struct wimlib_capture_config *config);
-
-extern int
-copy_and_canonicalize_capture_config(const struct wimlib_capture_config *config,
- struct wimlib_capture_config **config_copy_ret);
-
-extern void
-free_capture_config(struct wimlib_capture_config *config);
-
-/* extract_image.c */
-
-/* Internal use only */
-#define WIMLIB_EXTRACT_FLAG_MULTI_IMAGE 0x80000000
-#define WIMLIB_EXTRACT_FLAG_NO_STREAMS 0x40000000
-#define WIMLIB_EXTRACT_MASK_PUBLIC 0x3fffffff
-
-/* hardlink.c */
-
-extern int
-init_inode_table(struct wim_inode_table *table, size_t capacity);
-
-extern int
-inode_table_new_dentry(struct wim_inode_table *table, const tchar *name,
- u64 ino, u64 devno, bool noshare,
- struct wim_dentry **dentry_ret);
-
-extern void
-inode_ref_streams(struct wim_inode *inode);
-
-extern void
-inode_table_prepare_inode_list(struct wim_inode_table *table,
- struct list_head *head);
-
-static inline void
-destroy_inode_table(struct wim_inode_table *table)
-{
- FREE(table->array);
-}
-
-
-extern int
-dentry_tree_fix_inodes(struct wim_dentry *root, struct list_head *inode_list);
-
-/* header.c */
-
-extern int
-read_header(const tchar *filename, int in_fd, struct wim_header *hdr,
- int split_ok);
-
-extern int
-write_header(const struct wim_header *hdr, int out_fd);
-
-extern int
-init_header(struct wim_header *hdr, int ctype);
-
-/* integrity.c */
-
-#define WIM_INTEGRITY_OK 0
-#define WIM_INTEGRITY_NOT_OK -1
-#define WIM_INTEGRITY_NONEXISTENT -2
-
-extern int
-write_integrity_table(int fd,
- struct resource_entry *integrity_res_entry,
- off_t new_lookup_table_end,
- off_t old_lookup_table_end,
- wimlib_progress_func_t progress_func);
-
-extern int
-check_wim_integrity(WIMStruct *w, wimlib_progress_func_t progress_func);
-
-/* join.c */
-
-extern void
-merge_lookup_tables(WIMStruct *w,
- WIMStruct **additional_swms, unsigned num_additional_swms);
-
-extern void
-unmerge_lookup_table(WIMStruct *wim);
-
-/* metadata_resource.c */
-
-extern int
-read_metadata_resource(WIMStruct *w,
- struct wim_image_metadata *image_metadata);
-
-extern int
-write_metadata_resource(WIMStruct *w);
-
-/* ntfs-apply.c */
-
-struct apply_args {
- WIMStruct *w;
- const tchar *target;
- unsigned target_nchars;
- unsigned wim_source_path_nchars;
- struct wim_dentry *extract_root;
- tchar *target_realpath;
- unsigned target_realpath_len;
- int extract_flags;
- union wimlib_progress_info progress;
- wimlib_progress_func_t progress_func;
- int (*apply_dentry)(struct wim_dentry *, void *);
- union {
- #ifdef WITH_NTFS_3G
- struct {
- /* NTFS apply only */
- struct _ntfs_volume *vol;
- };
- #endif
- #ifdef __WIN32__
- struct {
- /* Normal apply only (Win32) */
- unsigned long num_set_sacl_priv_notheld;
- unsigned long num_set_sd_access_denied;
- unsigned vol_flags;
- unsigned long num_hard_links_failed;
- unsigned long num_soft_links_failed;
- bool have_vol_flags;
- };
- #else
- struct {
- /* Normal apply only (UNIX) */
- unsigned long num_utime_warnings;
- };
- #endif
- };
-};
-
-extern int
-apply_dentry_ntfs(struct wim_dentry *dentry, void *arg);
-
-extern int
-apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg);
-
-extern void
-libntfs3g_global_init();
-
-/* ntfs-capture.c */
-
-typedef int (*consume_data_callback_t)(const void *buf, size_t len, void *ctx);
-
-extern int
-read_ntfs_file_prefix(const struct wim_lookup_table_entry *lte,
- u64 size,
- consume_data_callback_t cb,
- void *ctx_or_buf,
- int _ignored_flags);
-extern int
-build_dentry_tree_ntfs(struct wim_dentry **root_p,
- const tchar *device,
- struct add_image_params *ctx);
-
-#ifdef WITH_NTFS_3G
-extern int
-do_ntfs_umount(struct _ntfs_volume *vol);
-#endif
-
-/* reparse.c */
-
-/* Structured format for symbolic link, junction point, or mount point reparse
- * data. */
-struct reparse_data {
- /* Reparse point tag (see WIM_IO_REPARSE_TAG_* values) */
- u32 rptag;
-
- /* Length of reparse data, not including the 8-byte header (ReparseTag,
- * ReparseDataLength, ReparseReserved) */
- u16 rpdatalen;
-
- /* ReparseReserved */
- u16 rpreserved;
-
- /* Flags (only for WIM_IO_REPARSE_TAG_SYMLINK reparse points).
- * SYMBOLIC_LINK_RELATIVE means this is a relative symbolic link;
- * otherwise should be set to 0. */
-#define SYMBOLIC_LINK_RELATIVE 0x00000001
- u32 rpflags;
-
- /* Pointer to the substitute name of the link (UTF-16LE). */
- utf16lechar *substitute_name;
-
- /* Pointer to the print name of the link (UTF-16LE). */
- utf16lechar *print_name;
-
- /* Number of bytes of the substitute name, not including null terminator
- * if present */
- u16 substitute_name_nbytes;
-
- /* Number of bytes of the print name, not including null terminator if
- * present */
- u16 print_name_nbytes;
-};
-
-enum {
- SUBST_NAME_IS_RELATIVE_LINK = -1,
- SUBST_NAME_IS_VOLUME_JUNCTION = -2,
- SUBST_NAME_IS_UNKNOWN = -3,
-};
-extern int
-parse_substitute_name(const utf16lechar *substitute_name,
- u16 substitute_name_nbytes,
- u32 rptag);
-
-extern int
-parse_reparse_data(const u8 *rpbuf, u16 rpbuflen, struct reparse_data *rpdata);
-
-extern int
-make_reparse_buffer(const struct reparse_data *rpdata, u8 *buf);
-
-extern int
-wim_inode_get_reparse_data(const struct wim_inode *inode, u8 *rpbuf);
-
-#ifndef __WIN32__
-ssize_t
-wim_inode_readlink(const struct wim_inode *inode, char *buf, size_t buf_len);
-
-extern int
-wim_inode_set_symlink(struct wim_inode *inode, const char *target,
- struct wim_lookup_table *lookup_table);
-#endif
-extern tchar *
-capture_fixup_absolute_symlink(tchar *dest,
- u64 capture_root_ino, u64 capture_root_dev);
-
-
-/* resource.c */
-
-#define WIMLIB_RESOURCE_FLAG_RAW 0x1
-#define WIMLIB_RESOURCE_FLAG_RECOMPRESS 0x4
-
-extern int
-read_resource_prefix(const struct wim_lookup_table_entry *lte,
- u64 size, consume_data_callback_t cb, void *ctx_or_buf,
- int flags);
-
-extern const void *
-get_resource_entry(const void *p, struct resource_entry *entry);
-
-extern void *
-put_resource_entry(void *p, const struct resource_entry *entry);
-
-extern int
-read_partial_wim_resource_into_buf(const struct wim_lookup_table_entry *lte,
- size_t size, u64 offset, void *buf);
-extern int
-read_full_resource_into_buf(const struct wim_lookup_table_entry *lte, void *buf);
-
-extern int
-write_wim_resource(struct wim_lookup_table_entry *lte, int out_fd,
- int out_ctype, struct resource_entry *out_res_entry,
- int flags);
-
-extern int
-extract_wim_resource(const struct wim_lookup_table_entry *lte,
- u64 size,
- consume_data_callback_t extract_chunk,
- void *extract_chunk_arg);
-
-extern int
-extract_wim_resource_to_fd(const struct wim_lookup_table_entry *lte,
- int fd, u64 size);
-
-extern int
-sha1_resource(struct wim_lookup_table_entry *lte);
-
-extern int
-copy_resource(struct wim_lookup_table_entry *lte, void *w);
-
-/* security.c */
-extern struct wim_security_data *
-new_wim_security_data();
-
-extern int
-read_security_data(const u8 metadata_resource[],
- u64 metadata_resource_len, struct wim_security_data **sd_p);
-extern void
-print_security_data(const struct wim_security_data *sd);
-
-extern u8 *
-write_security_data(const struct wim_security_data *sd, u8 *p);
-
-extern void
-free_security_data(struct wim_security_data *sd);
-
-/* unix_apply.c */
-#ifndef __WIN32__
-extern int
-unix_do_apply_dentry(const char *output_path, size_t output_path_len,
- struct wim_dentry *dentry, struct apply_args *args);
-extern int
-unix_do_apply_dentry_timestamps(const char *output_path,
- size_t output_path_len,
- struct wim_dentry *dentry,
- struct apply_args *args);
-#endif
-
-/* unix_capture.c */
-#ifndef __WIN32__
-extern int
-unix_build_dentry_tree(struct wim_dentry **root_ret,
- const char *root_disk_path,
- struct add_image_params *params);
-#endif
-
-/* update_image.c */
-extern int
-rename_wim_path(WIMStruct *wim, const tchar *from, const tchar *to);
-
-/* verify.c */
-
-extern int
-verify_dentry(struct wim_dentry *dentry, void *wim);
-
-extern int
-wim_run_full_verifications(WIMStruct *w);
-
-extern int
-verify_swm_set(WIMStruct *w,
- WIMStruct **additional_swms, unsigned num_additional_swms);
-
-/* wim.c */
-
-extern int
-select_wim_image(WIMStruct *w, int image);
-
-extern int
-for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *));
-
-extern void
-destroy_image_metadata(struct wim_image_metadata *imd,
- struct wim_lookup_table *table,
- bool free_metadata_lte);
-
-extern void
-put_image_metadata(struct wim_image_metadata *imd,
- struct wim_lookup_table *table);
-
-extern int
-append_image_metadata(WIMStruct *w, struct wim_image_metadata *imd);
-
-extern struct wim_image_metadata *
-new_image_metadata();
-
-extern struct wim_image_metadata **
-new_image_metadata_array(unsigned num_images);
-
-extern int
-wim_checksum_unhashed_streams(WIMStruct *w);
-
-extern int
-reopen_wim(WIMStruct *w);
-
-extern int
-close_wim(WIMStruct *w);
-
-/* write.c */
-
-/* Internal use only */
-#define WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE 0x80000000
-#define WIMLIB_WRITE_FLAG_REUSE_INTEGRITY_TABLE 0x40000000
-#define WIMLIB_WRITE_FLAG_CHECKPOINT_AFTER_XML 0x20000000
-#define WIMLIB_WRITE_MASK_PUBLIC 0x1fffffff
-
-/* We are capturing a tree to be placed in the root of the WIM image */
-#define WIMLIB_ADD_FLAG_ROOT 0x80000000
-
-extern int
-begin_write(WIMStruct *w, const tchar *path, int write_flags);
-
-extern void
-close_wim_writable(WIMStruct *w);
-
-extern int
-finish_write(WIMStruct *w, int image, int write_flags,
- wimlib_progress_func_t progress_func);
-
-#if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK)
-extern int
-lock_wim(WIMStruct *w, int fd);
-#else
-static inline int
-lock_wim(WIMStruct *w, int fd)
-{
- return 0;
-}
-#endif
-
-#endif /* _WIMLIB_INTERNAL_H */
-
#ifdef __WIN32__
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <aclapi.h> /* for SetSecurityInfo() */
-#include "win32_common.h"
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "endianness.h"
+#include "wimlib/win32_common.h"
+
+#include "wimlib/apply.h"
+#include "wimlib/dentry.h"
+#include "wimlib/endianness.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/reparse.h"
+#include "wimlib/security.h"
#define MAX_CREATE_HARD_LINK_WARNINGS 5
#define MAX_CREATE_SOFT_LINK_WARNINGS 5
#ifdef __WIN32__
-#include "win32_common.h"
-#include "wimlib_internal.h"
-#include "lookup_table.h"
-#include "security.h"
-#include "endianness.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib/win32_common.h"
+
+#include "wimlib/capture.h"
+#include "wimlib/endianness.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/paths.h"
+#include "wimlib/reparse.h"
#define MAX_GET_SD_ACCESS_DENIED_WARNINGS 1
#define MAX_GET_SACL_PRIV_NOTHELD_WARNINGS 1
static int
win32_get_security_descriptor(struct wim_dentry *dentry,
- struct sd_set *sd_set,
+ struct wim_sd_set *sd_set,
const wchar_t *path,
struct win32_capture_state *state,
int add_flags)
return ret;
}
-int
-win32_get_file_and_vol_ids(const wchar_t *path, u64 *ino_ret, u64 *dev_ret)
-{
- HANDLE hFile;
- DWORD err;
- BY_HANDLE_FILE_INFORMATION file_info;
- int ret;
-
- hFile = win32_open_existing_file(path, FILE_READ_ATTRIBUTES);
- if (hFile == INVALID_HANDLE_VALUE) {
- err = GetLastError();
- if (err != ERROR_FILE_NOT_FOUND) {
- WARNING("Failed to open \"%ls\" to get file "
- "and volume IDs", path);
- win32_error(err);
- }
- return WIMLIB_ERR_OPEN;
- }
-
- if (!GetFileInformationByHandle(hFile, &file_info)) {
- err = GetLastError();
- ERROR("Failed to get file information for \"%ls\"", path);
- win32_error(err);
- ret = WIMLIB_ERR_STAT;
- } else {
- *ino_ret = ((u64)file_info.nFileIndexHigh << 32) |
- (u64)file_info.nFileIndexLow;
- *dev_ret = file_info.dwVolumeSerialNumber;
- ret = 0;
- }
- CloseHandle(hFile);
- return ret;
-}
-
/* Reparse point fixup status code */
enum rp_status {
/* Reparse point corresponded to an absolute symbolic link or junction
/*
- * win32_common.c - Windows code common to applying and capturing images, as
- * well as replacements for various functions not available on Windows, such as
- * fsync().
+ * win32_common.c - Windows code common to applying and capturing images.
*/
/*
#ifdef __WIN32__
-#include <shlwapi.h> /* for PathMatchSpecW() */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <errno.h>
-#include <pthread.h>
-#include "win32_common.h"
+#include "wimlib/win32_common.h"
+
+#include "wimlib/assert.h"
+#include "wimlib/error.h"
#ifdef ENABLE_ERROR_MESSAGES
void
}
void
-set_errno_from_GetLastError()
+set_errno_from_GetLastError(void)
{
errno = win32_error_to_errno(GetLastError());
}
-/* Replacement for POSIX fsync() */
-int
-fsync(int fd)
-{
- HANDLE h;
-
- h = (HANDLE)_get_osfhandle(fd);
- if (h == INVALID_HANDLE_VALUE)
- goto err;
- if (!FlushFileBuffers(h))
- goto err_set_errno;
- return 0;
-err_set_errno:
- set_errno_from_GetLastError();
-err:
- return -1;
-}
-
-/* Use the Win32 API to get the number of processors */
-unsigned
-win32_get_number_of_processors()
-{
- SYSTEM_INFO sysinfo;
- GetSystemInfo(&sysinfo);
- return sysinfo.dwNumberOfProcessors;
-}
-
-/* Replacement for POSIX-2008 realpath(). Warning: partial functionality only
- * (resolved_path must be NULL). Also I highly doubt that GetFullPathName
- * really does the right thing under all circumstances. */
-wchar_t *
-realpath(const wchar_t *path, wchar_t *resolved_path)
-{
- DWORD ret;
- DWORD err;
- wimlib_assert(resolved_path == NULL);
-
- ret = GetFullPathNameW(path, 0, NULL, NULL);
- if (!ret) {
- err = GetLastError();
- goto fail_win32;
- }
-
- resolved_path = TMALLOC(ret);
- if (!resolved_path)
- goto out;
- ret = GetFullPathNameW(path, ret, resolved_path, NULL);
- if (!ret) {
- err = GetLastError();
- free(resolved_path);
- resolved_path = NULL;
- goto fail_win32;
- }
- goto out;
-fail_win32:
- errno = win32_error_to_errno(err);
-out:
- return resolved_path;
-}
-
-/* rename() on Windows fails if the destination file exists. And we need to
- * make it work on wide characters. Fix it. */
-int
-win32_rename_replacement(const wchar_t *oldpath, const wchar_t *newpath)
-{
- if (MoveFileExW(oldpath, newpath, MOVEFILE_REPLACE_EXISTING)) {
- return 0;
- } else {
- set_errno_from_GetLastError();
- return -1;
- }
-}
-
-/* Replacement for POSIX fnmatch() (partial functionality only) */
-int
-fnmatch(const wchar_t *pattern, const wchar_t *string, int flags)
-{
- if (PathMatchSpecW(string, pattern))
- return 0;
- else
- return FNM_NOMATCH;
-}
-
-/* truncate() replacement */
-int
-win32_truncate_replacement(const wchar_t *path, off_t size)
-{
- DWORD err = NO_ERROR;
- LARGE_INTEGER liOffset;
-
- HANDLE h = win32_open_existing_file(path, GENERIC_WRITE);
- if (h == INVALID_HANDLE_VALUE)
- goto fail;
-
- liOffset.QuadPart = size;
- if (!SetFilePointerEx(h, liOffset, NULL, FILE_BEGIN))
- goto fail_close_handle;
-
- if (!SetEndOfFile(h))
- goto fail_close_handle;
- CloseHandle(h);
- return 0;
-
-fail_close_handle:
- err = GetLastError();
- CloseHandle(h);
-fail:
- if (err == NO_ERROR)
- err = GetLastError();
- errno = win32_error_to_errno(err);
- return -1;
-}
-
-
-/* This really could be replaced with _wcserror_s, but this doesn't seem to
- * actually be available in MSVCRT.DLL on Windows XP (perhaps it's statically
- * linked in by Visual Studio...?). */
-extern int
-win32_strerror_r_replacement(int errnum, wchar_t *buf, size_t buflen)
-{
- static pthread_mutex_t strerror_lock = PTHREAD_MUTEX_INITIALIZER;
-
- pthread_mutex_lock(&strerror_lock);
- mbstowcs(buf, strerror(errnum), buflen);
- buf[buflen - 1] = '\0';
- pthread_mutex_unlock(&strerror_lock);
- return 0;
-}
-
-static int
-do_pread_or_pwrite(int fd, void *buf, size_t count, off_t offset,
- bool is_pwrite)
-{
- HANDLE h;
- LARGE_INTEGER orig_offset;
- DWORD bytes_read_or_written;
- LARGE_INTEGER relative_offset;
- OVERLAPPED overlapped;
- BOOL bret;
-
- wimlib_assert(count <= 0xffffffff);
-
- h = (HANDLE)_get_osfhandle(fd);
- if (h == INVALID_HANDLE_VALUE)
- goto err;
-
- /* Get original position */
- relative_offset.QuadPart = 0;
- if (!SetFilePointerEx(h, relative_offset, &orig_offset, FILE_CURRENT))
- goto err_set_errno;
-
- memset(&overlapped, 0, sizeof(overlapped));
- overlapped.Offset = offset;
- overlapped.OffsetHigh = offset >> 32;
-
- /* Do the read or write at the specified offset */
- if (is_pwrite)
- bret = WriteFile(h, buf, count, &bytes_read_or_written, &overlapped);
- else
- bret = ReadFile(h, buf, count, &bytes_read_or_written, &overlapped);
- if (!bret)
- goto err_set_errno;
-
- /* Restore the original position */
- if (!SetFilePointerEx(h, orig_offset, NULL, FILE_BEGIN))
- goto err_set_errno;
-
- return bytes_read_or_written;
-err_set_errno:
- set_errno_from_GetLastError();
-err:
- return -1;
-}
-
-/* Dumb Windows implementation of pread(). It temporarily changes the file
- * offset, so it is not safe to use with readers/writers on the same file
- * descriptor. */
-extern ssize_t
-win32_pread(int fd, void *buf, size_t count, off_t offset)
-{
- return do_pread_or_pwrite(fd, buf, count, offset, false);
-}
-
-/* Dumb Windows implementation of pwrite(). It temporarily changes the file
- * offset, so it is not safe to use with readers/writers on the same file
- * descriptor. */
-extern ssize_t
-win32_pwrite(int fd, const void *buf, size_t count, off_t offset)
-{
- return do_pread_or_pwrite(fd, (void*)buf, count, offset, true);
-}
-
-/* Dumb Windows implementation of writev(). It writes the vectors one at a
- * time. */
-extern ssize_t
-win32_writev(int fd, const struct iovec *iov, int iovcnt)
-{
- ssize_t total_bytes_written = 0;
-
- if (iovcnt <= 0) {
- errno = EINVAL;
- return -1;
- }
- for (int i = 0; i < iovcnt; i++) {
- ssize_t bytes_written;
-
- bytes_written = write(fd, iov[i].iov_base, iov[i].iov_len);
- if (bytes_written >= 0)
- total_bytes_written += bytes_written;
- if (bytes_written != iov[i].iov_len) {
- if (total_bytes_written == 0)
- total_bytes_written = -1;
- break;
- }
- }
- return total_bytes_written;
-}
-
/* Given a path, which may not yet exist, get a set of flags that describe the
* features of the volume the path is on. */
int
/* Try to dynamically load some functions */
void
-win32_global_init()
+win32_global_init(void)
{
DWORD err;
}
void
-win32_global_cleanup()
+win32_global_cleanup(void)
{
if (hKernel32 != NULL) {
DEBUG("Closing Kernel32.dll");
--- /dev/null
+/*
+ * win32_replacements.c - Replacements for various functions not available on
+ * Windows, such as fsync().
+ */
+
+/*
+ * Copyright (C) 2013 Eric Biggers
+ *
+ * This file is part of wimlib, a library for working with WIM files.
+ *
+ * wimlib is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ */
+
+#ifdef __WIN32__
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <pthread.h>
+#include <shlwapi.h> /* for PathMatchSpecW() */
+#include "wimlib/win32_common.h"
+
+#include "wimlib/assert.h"
+#include "wimlib/file_io.h"
+#include "wimlib/error.h"
+#include "wimlib/util.h"
+
+/* Replacement for POSIX fsync() */
+int
+fsync(int fd)
+{
+ HANDLE h;
+
+ h = (HANDLE)_get_osfhandle(fd);
+ if (h == INVALID_HANDLE_VALUE)
+ goto err;
+ if (!FlushFileBuffers(h))
+ goto err_set_errno;
+ return 0;
+err_set_errno:
+ set_errno_from_GetLastError();
+err:
+ return -1;
+}
+
+/* Use the Win32 API to get the number of processors */
+unsigned
+win32_get_number_of_processors(void)
+{
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ return sysinfo.dwNumberOfProcessors;
+}
+
+/* Replacement for POSIX-2008 realpath(). Warning: partial functionality only
+ * (resolved_path must be NULL). Also I highly doubt that GetFullPathName
+ * really does the right thing under all circumstances. */
+wchar_t *
+realpath(const wchar_t *path, wchar_t *resolved_path)
+{
+ DWORD ret;
+ DWORD err;
+ wimlib_assert(resolved_path == NULL);
+
+ ret = GetFullPathNameW(path, 0, NULL, NULL);
+ if (!ret) {
+ err = GetLastError();
+ goto fail_win32;
+ }
+
+ resolved_path = MALLOC(ret * sizeof(wchar_t));
+ if (!resolved_path)
+ goto out;
+ ret = GetFullPathNameW(path, ret, resolved_path, NULL);
+ if (!ret) {
+ err = GetLastError();
+ free(resolved_path);
+ resolved_path = NULL;
+ goto fail_win32;
+ }
+ goto out;
+fail_win32:
+ errno = win32_error_to_errno(err);
+out:
+ return resolved_path;
+}
+
+/* rename() on Windows fails if the destination file exists. And we need to
+ * make it work on wide characters. Fix it. */
+int
+win32_rename_replacement(const wchar_t *oldpath, const wchar_t *newpath)
+{
+ if (MoveFileExW(oldpath, newpath, MOVEFILE_REPLACE_EXISTING)) {
+ return 0;
+ } else {
+ set_errno_from_GetLastError();
+ return -1;
+ }
+}
+
+/* Replacement for POSIX fnmatch() (partial functionality only) */
+int
+fnmatch(const wchar_t *pattern, const wchar_t *string, int flags)
+{
+ if (PathMatchSpecW(string, pattern))
+ return 0;
+ else
+ return FNM_NOMATCH;
+}
+
+/* truncate() replacement */
+int
+win32_truncate_replacement(const wchar_t *path, off_t size)
+{
+ DWORD err = NO_ERROR;
+ LARGE_INTEGER liOffset;
+
+ HANDLE h = win32_open_existing_file(path, GENERIC_WRITE);
+ if (h == INVALID_HANDLE_VALUE)
+ goto fail;
+
+ liOffset.QuadPart = size;
+ if (!SetFilePointerEx(h, liOffset, NULL, FILE_BEGIN))
+ goto fail_close_handle;
+
+ if (!SetEndOfFile(h))
+ goto fail_close_handle;
+ CloseHandle(h);
+ return 0;
+
+fail_close_handle:
+ err = GetLastError();
+ CloseHandle(h);
+fail:
+ if (err == NO_ERROR)
+ err = GetLastError();
+ errno = win32_error_to_errno(err);
+ return -1;
+}
+
+
+/* This really could be replaced with _wcserror_s, but this doesn't seem to
+ * actually be available in MSVCRT.DLL on Windows XP (perhaps it's statically
+ * linked in by Visual Studio...?). */
+extern int
+win32_strerror_r_replacement(int errnum, wchar_t *buf, size_t buflen)
+{
+ static pthread_mutex_t strerror_lock = PTHREAD_MUTEX_INITIALIZER;
+
+ pthread_mutex_lock(&strerror_lock);
+ mbstowcs(buf, strerror(errnum), buflen);
+ buf[buflen - 1] = '\0';
+ pthread_mutex_unlock(&strerror_lock);
+ return 0;
+}
+
+static int
+do_pread_or_pwrite(int fd, void *buf, size_t count, off_t offset,
+ bool is_pwrite)
+{
+ HANDLE h;
+ LARGE_INTEGER orig_offset;
+ DWORD bytes_read_or_written;
+ LARGE_INTEGER relative_offset;
+ OVERLAPPED overlapped;
+ BOOL bret;
+
+ wimlib_assert(count <= 0xffffffff);
+
+ h = (HANDLE)_get_osfhandle(fd);
+ if (h == INVALID_HANDLE_VALUE)
+ goto err;
+
+ /* Get original position */
+ relative_offset.QuadPart = 0;
+ if (!SetFilePointerEx(h, relative_offset, &orig_offset, FILE_CURRENT))
+ goto err_set_errno;
+
+ memset(&overlapped, 0, sizeof(overlapped));
+ overlapped.Offset = offset;
+ overlapped.OffsetHigh = offset >> 32;
+
+ /* Do the read or write at the specified offset */
+ if (is_pwrite)
+ bret = WriteFile(h, buf, count, &bytes_read_or_written, &overlapped);
+ else
+ bret = ReadFile(h, buf, count, &bytes_read_or_written, &overlapped);
+ if (!bret)
+ goto err_set_errno;
+
+ /* Restore the original position */
+ if (!SetFilePointerEx(h, orig_offset, NULL, FILE_BEGIN))
+ goto err_set_errno;
+
+ return bytes_read_or_written;
+err_set_errno:
+ set_errno_from_GetLastError();
+err:
+ return -1;
+}
+
+/* Dumb Windows implementation of pread(). It temporarily changes the file
+ * offset, so it is not safe to use with readers/writers on the same file
+ * descriptor. */
+ssize_t
+pread(int fd, void *buf, size_t count, off_t offset)
+{
+ return do_pread_or_pwrite(fd, buf, count, offset, false);
+}
+
+/* Dumb Windows implementation of pwrite(). It temporarily changes the file
+ * offset, so it is not safe to use with readers/writers on the same file
+ * descriptor. */
+ssize_t
+pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+ return do_pread_or_pwrite(fd, (void*)buf, count, offset, true);
+}
+
+/* Dumb Windows implementation of writev(). It writes the vectors one at a
+ * time. */
+ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
+{
+ ssize_t total_bytes_written = 0;
+
+ if (iovcnt <= 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ for (int i = 0; i < iovcnt; i++) {
+ ssize_t bytes_written;
+
+ bytes_written = write(fd, iov[i].iov_base, iov[i].iov_len);
+ if (bytes_written >= 0)
+ total_bytes_written += bytes_written;
+ if (bytes_written != iov[i].iov_len) {
+ if (total_bytes_written == 0)
+ total_bytes_written = -1;
+ break;
+ }
+ }
+ return total_bytes_written;
+}
+
+int
+win32_get_file_and_vol_ids(const wchar_t *path, u64 *ino_ret, u64 *dev_ret)
+{
+ HANDLE hFile;
+ DWORD err;
+ BY_HANDLE_FILE_INFORMATION file_info;
+ int ret;
+
+ hFile = win32_open_existing_file(path, FILE_READ_ATTRIBUTES);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ err = GetLastError();
+ if (err != ERROR_FILE_NOT_FOUND) {
+ WARNING("Failed to open \"%ls\" to get file "
+ "and volume IDs", path);
+ win32_error(err);
+ }
+ return WIMLIB_ERR_OPEN;
+ }
+
+ if (!GetFileInformationByHandle(hFile, &file_info)) {
+ err = GetLastError();
+ ERROR("Failed to get file information for \"%ls\"", path);
+ win32_error(err);
+ ret = WIMLIB_ERR_STAT;
+ } else {
+ *ino_ret = ((u64)file_info.nFileIndexHigh << 32) |
+ (u64)file_info.nFileIndexLow;
+ *dev_ret = file_info.dwVolumeSerialNumber;
+ ret = 0;
+ }
+ CloseHandle(hFile);
+ return ret;
+}
+
+
+#endif /* __WIN32__ */
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
#if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK)
-/* On BSD, this should be included before "list.h" so that "list.h" can
+/* On BSD, this should be included before "wimlib/list.h" so that "wimlib/list.h" can
* overwrite the LIST_HEAD macro. */
# include <sys/file.h>
#endif
+#include "wimlib/endianness.h"
+#include "wimlib/error.h"
+#include "wimlib/file_io.h"
+#include "wimlib/header.h"
+#include "wimlib/integrity.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/resource.h"
+#include "wimlib/write.h"
+#include "wimlib/xml.h"
+
#ifdef __WIN32__
-# include "win32.h"
+# include "wimlib/win32.h" /* win32_get_number_of_processors() */
#endif
-#include "list.h"
-#include "wimlib_internal.h"
-#include "buffer_io.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "xml.h"
-
#ifdef ENABLE_MULTITHREADED_COMPRESSION
# include <pthread.h>
#endif
}
static long
-get_default_num_threads()
+get_default_num_threads(void)
{
#ifdef __WIN32__
return win32_get_number_of_processors();
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "dentry.h"
-#include "lookup_table.h"
-#include "timestamp.h"
-#include "wimlib_internal.h"
-#include "xml.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
-#include <string.h>
+#include "wimlib/dentry.h"
+#include "wimlib/encoding.h"
+#include "wimlib/metadata.h"
+#include "wimlib/error.h"
+#include "wimlib/file_io.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/resource.h"
+#include "wimlib/timestamp.h"
+#include "wimlib/xml.h"
+
+#include <libxml/encoding.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlwriter.h>
-#include <libxml/encoding.h>
#include <limits.h>
+#include <string.h>
/* Structures used to form an in-memory representation of the XML data (other
* than the raw parse tree from libxml). */
if (!image_info->name) {
tchar *empty_name;
WARNING("Image with index %d has no name", image_info->index);
- empty_name = TMALLOC(1);
+ empty_name = MALLOC(sizeof(tchar));
if (!empty_name)
return WIMLIB_ERR_NOMEM;
*empty_name = T('\0');
}
void
-libxml_global_init()
+libxml_global_init(void)
{
xmlInitParser();
xmlInitCharEncodingHandlers();
}
void
-libxml_global_cleanup()
+libxml_global_cleanup(void)
{
xmlCleanupParser();
xmlCleanupCharEncodingHandlers();
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "xpress.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include "wimlib.h"
-#include "compress.h"
+#include "wimlib/assert.h"
+#include "wimlib/compress.h"
+#include "wimlib/util.h"
+#include "wimlib/xpress.h"
#include <stdlib.h>
#include <string.h>
* extra symbol is there or not.
*/
-#include "util.h"
-#include "xpress.h"
-#include "wimlib.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "wimlib.h"
+#include "wimlib/assert.h"
#define XPRESS_DECOMP
-#include "decompress.h"
+#include "wimlib/decompress.h"
+#include "wimlib/util.h"
+#include "wimlib/xpress.h"
/*
* Decodes a symbol @huffsym that begins an XPRESS match.
echo 888 > file3'
msg "C source code of wimlib"
-do_test 'cp $srcdir/src/*.{c,h} .'
+do_test 'cp $srcdir/src/*.c .'
msg "tons of random stuff"
do_test 'echo -n 8 > file;
# Make test directory
mkdir dir
-cp $srcdir/src/*.c $srcdir/src/*.h dir
+cp $srcdir/src/*.c dir
mkdir dir/subdir
echo 'hello' > dir/subdir/hello
echo 'hello' > dir/subdir/hello2
init() {
mkdir dir
- cp $srcdir/src/*.c $srcdir/src/*.h dir
+ cp $srcdir/src/*.c dir
mkdir dir/subdir
echo 'hello' > dir/subdir/hello
echo 'hello' > dir/subdir/hello2
#setfattr -v DOSNAME -n system.ntfs_dos_name file;'
msg "C source code of wimlib"
-do_test 'cp $srcdir/src/*.{c,h} .'
+do_test 'cp $srcdir/src/*.c .'
msg "file with security descriptor"
do_test 'touch file;