lib_LTLIBRARIES = libwim.la
-libwim_la_LDFLAGS = -version-info 4:0:2 $(CYGWIN_EXTRA_LDFLAGS)
+libwim_la_LDFLAGS = -version-info 4:0:2 $(WINDOWS_EXTRA_LDFLAGS)
libwim_la_SOURCES = \
src/add_image.c \
$(LTLIBICONV) \
$(LIBCRYPTO_LDADD) \
$(SSSE3_SHA1_OBJ) \
- $(PTHREAD_LDADD)
+ $(PTHREAD_LDADD) \
+ $(WINDOWS_LDADD)
libwim_la_CFLAGS = \
$(AM_CFLAGS) \
imagex_SOURCES = programs/imagex.c
imagex_LDADD = $(top_builddir)/libwim.la
+if WINDOWS_BUILD
+imagex_SOURCES += programs/imagex-win32.c programs/imagex-win32.h
+endif
+
dist_bin_SCRIPTS = programs/mkwinpeimg
include_HEADERS = src/wimlib.h
])
AC_PROG_CC
AM_PROG_CC_C_O
+AC_CANONICAL_HOST
AC_CHECK_FUNCS([utimensat lutimes utime flock])
AC_CHECK_HEADERS([endian.h byteswap.h sys/byteorder.h sys/endian.h \
sys/param.h machine/endian.h alloca.h stdlib.h stdarg.h \
- errno.h attr/xattr.h utime.h sys/file.h])
+ errno.h attr/xattr.h utime.h sys/file.h glob.h])
AC_CHECK_MEMBER([struct stat.st_mtim],
[AC_DEFINE([HAVE_STAT_NANOSECOND_PRECISION], [1],
[],
[[#include <sys/stat.h>]])
-AM_ICONV
-if test "x$am_cv_func_iconv" != "xyes"; then
- AC_MSG_ERROR([Cannot find the iconv() function.
- iconv() is used to convert between UTF-8 and UTF-16 encodings of WIM
- filenames and XML data. Wimlib cannot be compiled without it. iconv()
- is available in the latest version of glibc and sometimes in other
- libraries.])
-fi
-
AC_ARG_WITH(pkgconfigdir,
[ --with-pkgconfigdir=DIR pkgconfig file in DIR @<:@LIBDIR/pkgconfig@:>@],
AC_SUBST([PTHREAD_LDADD], [$PTHREAD_LDADD])
case "$host" in
- *-*-cygwin*)
- dnl -no-undefined is needed to build a DLL in a Cygwin environment.
- CYGWIN_EXTRA_LDFLAGS="-no-undefined"
-
- dnl -fvisibility=hidden should not be used when building PE
- dnl binaries on Windows
+ *-*-mingw*)
+ # Native Windows
+ WINDOWS_EXTRA_LDFLAGS="-no-undefined"
VISIBILITY_CFLAGS=""
-
WITH_NTFS_3G_DEFAULT="no"
WITH_FUSE_DEFAULT="no"
WINDOWS_BUILD="yes"
+ WINDOWS_LDADD="-lshlwapi"
+ ;;
+ *-*-cygwin*)
+ # Cygwin (WARNING: not well supported)
+ WINDOWS_EXTRA_LDFLAGS="-no-undefined"
+ VISIBILITY_CFLAGS=""
+ WITH_NTFS_3G_DEFAULT="no"
+ WITH_FUSE_DEFAULT="no"
+ WINDOWS_BUILD="yes"
+ WINDOWS_LDADD=""
;;
*)
- CYGWIN_EXTRA_LDFLAGS=""
+ # UNIX / other
+ WINDOWS_EXTRA_LDFLAGS=""
VISIBILITY_CFLAGS="-fvisibility=hidden"
WITH_NTFS_3G_DEFAULT="yes"
WITH_FUSE_DEFAULT="yes"
WINDOWS_BUILD="no"
+ WINDOWS_LDADD=""
;;
esac
-AC_SUBST([CYGWIN_EXTRA_LDFLAGS], [$CYGWIN_EXTRA_LDFLAGS])
+AC_SUBST([WINDOWS_EXTRA_LDFLAGS], [$WINDOWS_EXTRA_LDFLAGS])
AC_SUBST([VISIBILITY_CFLAGS], [$VISIBILITY_CFLAGS])
+AC_SUBST([WINDOWS_LDADD], [$WINDOWS_LDADD])
AM_CONDITIONAL([WINDOWS_BUILD], [test "x$WINDOWS_BUILD" = "xyes"])
AC_MSG_CHECKING([whether to include support for ntfs-3g])
else
LIBNTFS_3G_LDADD=
LIBNTFS_3G_CFLAGS=
+
+ if test "x$WINDOWS_BUILD" != "xyes"; then
+ AM_ICONV
+ if test "x$am_cv_func_iconv" != "xyes"; then
+ AC_MSG_ERROR([Cannot find the iconv() function.
+ iconv() is used to convert between UTF-8 and UTF-16 encodings of WIM
+ filenames and XML data. Wimlib cannot be compiled without it. iconv()
+ is available in the latest version of glibc and sometimes in other
+ libraries.])
+ fi
+ fi
fi
AM_CONDITIONAL([WITH_NTFS_3G], [test "x$WITH_NTFS_3G" = "xyes"])
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
-#include <glob.h>
+
#include <inttypes.h>
#include <libgen.h>
#include <limits.h>
#include <alloca.h>
#endif
+#ifdef __WIN32__
+# include "imagex-win32.h"
+#else
+# include <glob.h>
+#endif
+
#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
#define for_opt(c, opts) while ((c = getopt_long_only(argc, (char**)argv, "", \
glob_t globbuf;
int ret;
+ /* Warning: glob() is replaced in Windows native builds */
ret = glob(swm_glob, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf);
if (ret != 0) {
if (ret == GLOB_NOMATCH) {
wim_is_new = false;
/* Destination file exists. */
- if (!S_ISREG(stbuf.st_mode) && !S_ISLNK(stbuf.st_mode)) {
+
+ if (!S_ISREG(stbuf.st_mode)) {
imagex_error("`%s' is not a regular file",
- dest_wimfile);
+ dest_wimfile);
ret = -1;
goto out;
}
# include "timestamp.h"
#endif
+#ifdef __WIN32__
+#include <shlwapi.h>
+#endif
+
#include "wimlib_internal.h"
#include "dentry.h"
#include "lookup_table.h"
#include "xml.h"
#include <ctype.h>
#include <errno.h>
+
+#ifndef __WIN32__
#include <fnmatch.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
DWORD len = lenNeeded;
char buf[len];
if (GetFileSecurityW(path_utf16, requestedInformation,
- buf, len, &lenNeeded))
+ (PSECURITY_DESCRIPTOR)buf, len, &lenNeeded))
{
int security_id = sd_set_add_sd(sd_set, buf, len);
if (security_id < 0)
return 0;
}
+static bool path_matches_pattern(const char *path, const char *pattern)
+{
+#ifdef __WIN32__
+ return PathMatchSpecA(path, pattern);
+#else
+ return fnmatch(pattern, path, FNM_PATHNAME
+ #ifdef FNM_CASEFOLD
+ | FNM_CASEFOLD
+ #endif
+ ) == 0;
+#endif
+}
+
static bool match_pattern(const char *path, const char *path_basename,
const struct pattern_list *list)
{
/* A file name pattern */
string = path_basename;
}
- if (fnmatch(pat, string, FNM_PATHNAME
- #ifdef FNM_CASEFOLD
- | FNM_CASEFOLD
- #endif
- ) == 0)
- {
+
+ if (path_matches_pattern(string, pat)) {
DEBUG("`%s' matches the pattern \"%s\"",
string, pat);
return true;
inode->i_num_ads--;
}
+#ifndef __WIN32__
int inode_get_unix_data(const struct wim_inode *inode,
struct wimlib_unix_data *unix_data,
u16 *stream_idx_ret)
inode_remove_ads(inode, stream_idx, lookup_table);
return ret;
}
+#endif /* !__WIN32__ */
/*
* Reads the alternate data stream entries of a WIM dentry.
u16 gid;
u16 mode;
} PACKED;
+
+#ifndef __WIN32__
+
#define NO_UNIX_DATA (-1)
#define BAD_UNIX_DATA (-2)
extern int inode_get_unix_data(const struct wim_inode *inode,
uid_t uid, gid_t gid, mode_t mode,
struct wim_lookup_table *lookup_table,
int which);
+#endif
extern int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len,
u64 offset, struct wim_dentry *dentry);
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
+#include "config.h"
#include "wimlib.h"
#include "util.h"
#include "endianness.h"
#include <errno.h>
#ifdef WITH_NTFS_3G
-#include <ntfs-3g/volume.h>
-#include <ntfs-3g/unistr.h>
+# include <ntfs-3g/volume.h>
+# include <ntfs-3g/unistr.h>
+#elif defined(__WIN32__)
+# include <wchar.h>
+# include <stdlib.h>
#else
-#include <iconv.h>
+# include <iconv.h>
#endif
/*
* libntfs-3g/unistr.c in the NTFS-3g sources. (Modified slightly to remove
* unneeded functionality.)
*/
-#ifndef WITH_NTFS_3G
+#if !defined(WITH_NTFS_3G) && !defined(__WIN32__)
/*
* Return the amount of 8-bit elements in UTF-8 needed (without the terminating
* null) to store a given UTF-16LE string.
}
return count;
}
-#endif /* !WITH_NTFS_3G */
-#ifndef WITH_NTFS_3G
static iconv_t cd_utf8_to_utf16 = (iconv_t)(-1);
static iconv_t cd_utf16_to_utf8 = (iconv_t)(-1);
if (cd_utf16_to_utf8 != (iconv_t)(-1))
iconv_close(cd_utf16_to_utf8);
}
-#endif
+#endif /* !WITH_NTFS_3G && !__WIN32__ */
/* Converts a string in the UTF-16LE encoding to a newly allocated string in the
* UTF-8 encoding.
else
ret = WIMLIB_ERR_INVALID_UTF16_STRING;
}
-#else /* !WITH_NTFS_3G */
-
+#elif defined(__WIN32__)
+ char *utf8_str;
+ size_t utf8_nbytes;
+ utf8_nbytes = wcstombs(NULL, (const wchar_t*)utf16_str, 0);
+ if (utf8_nbytes == (size_t)(-1)) {
+ ret = WIMLIB_ERR_INVALID_UTF16_STRING;
+ } else {
+ utf8_str = MALLOC(utf8_nbytes + 1);
+ if (!utf8_str) {
+ ret = WIMLIB_ERR_NOMEM;
+ } else {
+ wcstombs(utf8_str, (const wchar_t*)utf16_str, utf8_nbytes + 1);
+ *utf8_str_ret = utf8_str;
+ *utf8_nbytes_ret = utf8_nbytes;
+ ret = 0;
+ }
+ }
+#else
ret = iconv_global_init();
if (ret != 0)
return ret;
else
ret = WIMLIB_ERR_INVALID_UTF8_STRING;
}
-#else /* !WITH_NTFS_3G */
+#elif defined(__WIN32__)
+ char *utf16_str;
+ size_t utf16_nchars;
+ utf16_nchars = mbstowcs(NULL, utf8_str, 0);
+ if (utf16_nchars == (size_t)(-1)) {
+ ret = WIMLIB_ERR_INVALID_UTF8_STRING;
+ } else {
+ utf16_str = MALLOC((utf16_nchars + 1) * sizeof(wchar_t));
+ if (!utf16_str) {
+ ret = WIMLIB_ERR_NOMEM;
+ } else {
+ mbstowcs((wchar_t*)utf16_str, utf8_str,
+ utf16_nchars + 1);
+ *utf16_str_ret = utf16_str;
+ *utf16_nbytes_ret = utf16_nchars * sizeof(wchar_t);
+ ret = 0;
+ }
+ }
+
+#else
ret = iconv_global_init();
if (ret != 0)
return ret;
#include <alloca.h>
#endif
+#if defined(__WIN32__)
+# define swprintf _snwprintf
+# define mkdir(path, mode) (!CreateDirectoryA(path, NULL))
+#endif
+
#if defined(__CYGWIN__) || defined(__WIN32__)
static int win32_set_reparse_data(HANDLE h,
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
+#include "config.h"
+
+#define MINGW_HAS_SECURE_API
+
#undef _GNU_SOURCE
/* Make sure the POSIX-compatible strerror_r() is declared, rather than the GNU
* version, which has a different return type. */
#include <unistd.h> /* for getpid() */
+/* Windoze compatibility */
+#ifdef __WIN32__
+# define strerror_r(errnum, buf, bufsize) strerror_s(buf, bufsize, errnum)
+#endif
+
/* 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
vfprintf(stderr, format, va);
if (perror && errno_save != 0) {
char buf[50];
- int res = strerror_r(errno_save, buf, sizeof(buf));
+ int res;
+ res = strerror_r(errno_save, buf, sizeof(buf));
if (res) {
snprintf(buf, sizeof(buf),
"unknown error (errno=%d)", errno_save);
/* encoding.c */
-#ifdef WITH_NTFS_3G
+#if defined(WITH_NTFS_3G) || defined(__WIN32__)
static inline int iconv_global_init()
{
return 0;
*/
#include "config.h"
+
+#ifdef __WIN32__
+# include <windows.h>
+# ifdef ERROR
+# undef ERROR
+# endif
+#endif
+
#include <limits.h>
#include <stdlib.h>
#include <stdarg.h>
#include "lookup_table.h"
#include "xml.h"
+#ifdef __WIN32__
+static char *realpath(const char *path, char *resolved_path)
+{
+ DWORD ret;
+ wimlib_assert(resolved_path == NULL);
+
+ ret = GetFullPathNameA(path, 0, NULL, NULL);
+ if (!ret)
+ goto fail_win32;
+
+ resolved_path = MALLOC(ret + 1);
+ if (!resolved_path)
+ goto fail;
+ ret = GetFullPathNameA(path, ret, resolved_path, NULL);
+ if (!ret) {
+ free(resolved_path);
+ goto fail_win32;
+ }
+ return resolved_path;
+fail_win32:
+ win32_error(GetLastError());
+fail:
+ return NULL;
+}
+#endif
+
static int image_print_metadata(WIMStruct *w)
{
DEBUG("Printing metadata for image %d", w->current_image);
#include <sys/file.h>
#endif
+#ifdef __WIN32__
+# include <windows.h>
+# ifdef ERROR
+# undef ERROR
+# endif
+#endif
+
#include "list.h"
#include "wimlib_internal.h"
#include "buffer_io.h"
#include <stdlib.h>
#endif
+#ifdef __WIN32__
+# ifdef fsync
+# undef fsync
+# endif
+# define fsync(fd) 0
+#endif
+
static int fflush_and_ftruncate(FILE *fp, off_t size)
{
int ret;
return ret;
}
+static long get_default_num_threads()
+{
+#ifdef __WIN32__
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ return sysinfo.dwNumberOfProcessors;
+#else
+ return sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+}
static int write_stream_list_parallel(struct list_head *stream_list,
FILE *out_fp,
pthread_t *compressor_threads = NULL;
if (num_threads == 0) {
- long nthreads = sysconf(_SC_NPROCESSORS_ONLN);
- if (nthreads < 1) {
+ long nthreads = get_default_num_threads();
+ if (nthreads < 1 || nthreads > UINT_MAX) {
WARNING("Could not determine number of processors! Assuming 1");
goto out_serial;
} else {