diff --git a/README b/README index aaa63414..66c7bc0a 100644 --- a/README +++ b/README @@ -119,6 +119,30 @@ then, as root: And, to end the test, unmount the usual way: umount /dev/sda1 +BUILDING FOR WINDOWS +==================== + +A subset of the components found in this repository may be compiled and +executed on Windows. This includes the libntfs-3g library and the ntfsprogs +programs, but NOT the actual ntfs-3g driver. + +To target Cygwin, you must install the following packages +from the Cygwin installer: + + automake + libtool + make + gcc-core + libgcrypt-devel + +Then + + ./configure --disable-ntfs-3g --disable-plugins + make + +The full set of ntfsprogs, including ntfsusermap, can be built using: + + make extra NTFS UTILITIES ============== diff --git a/include/ntfs-3g/device_io.h b/include/ntfs-3g/device_io.h index 66ad2439..12c1e370 100644 --- a/include/ntfs-3g/device_io.h +++ b/include/ntfs-3g/device_io.h @@ -69,6 +69,9 @@ struct hd_geometry { /* On Windows (and Cygwin) : use Win32 low level device operations. */ #define ntfs_device_default_io_ops ntfs_device_win32_io_ops +/* Forward declaration. */ +struct ntfs_device; + /* A few useful functions */ int ntfs_win32_set_sparse(int); int ntfs_win32_ftruncate(int fd, s64 size); diff --git a/include/ntfs-3g/ntfstime.h b/include/ntfs-3g/ntfstime.h index f3a89dd8..80e163f8 100644 --- a/include/ntfs-3g/ntfstime.h +++ b/include/ntfs-3g/ntfstime.h @@ -39,7 +39,7 @@ /* * assume "struct timespec" is not defined if st_mtime is not defined */ -#if !defined(st_mtime) & !defined(__timespec_defined) +#if !defined(st_mtime) struct timespec { time_t tv_sec; long tv_nsec; diff --git a/libntfs-3g/Makefile.am b/libntfs-3g/Makefile.am index 6feba7d7..28d873f3 100644 --- a/libntfs-3g/Makefile.am +++ b/libntfs-3g/Makefile.am @@ -14,6 +14,10 @@ libntfs_3g_la_CPPFLAGS= $(AM_CPPFLAGS) $(LIBNTFS_CPPFLAGS) -I$(top_srcdir)/inclu libntfs_3g_la_LIBADD = $(LIBNTFS_LIBS) libntfs_3g_la_LDFLAGS = -version-info $(LIBNTFS_3G_VERSION) -no-undefined +if WINDOWS +libntfs_3g_la_LDFLAGS += -lntdll +endif + libntfs_3g_la_SOURCES = \ acls.c \ attrib.c \ diff --git a/libntfs-3g/ioctl.c b/libntfs-3g/ioctl.c index b059a53f..a3a56722 100644 --- a/libntfs-3g/ioctl.c +++ b/libntfs-3g/ioctl.c @@ -48,7 +48,9 @@ #ifdef HAVE_LIMITS_H #include #endif +#ifdef HAVE_SYSLOG_H #include +#endif #ifdef HAVE_SYS_TYPES_H #include #endif diff --git a/libntfs-3g/win32_io.c b/libntfs-3g/win32_io.c index 9c72dee3..8d0d718e 100644 --- a/libntfs-3g/win32_io.c +++ b/libntfs-3g/win32_io.c @@ -27,9 +27,9 @@ #include "config.h" #ifdef HAVE_WINDOWS_H -#define BOOL WINBOOL /* avoid conflicting definitions of BOOL */ +#define _NO_BOOL_TYPEDEF /* supported by both Cygwin and MinGW-w64's w32api */ #include -#undef BOOL +#undef _NO_BOOL_TYPEDEF #endif #ifdef HAVE_STDLIB_H @@ -45,15 +45,6 @@ typedef unsigned long long DWORD64; #endif -typedef struct { - DWORD data1; /* The first eight hexadecimal digits of the GUID. */ - WORD data2; /* The first group of four hexadecimal digits. */ - WORD data3; /* The second group of four hexadecimal digits. */ - char data4[8]; /* The first two bytes are the third group of four - hexadecimal digits. The remaining six bytes are the - final 12 hexadecimal digits. */ -} GUID; - #include #ifdef HAVE_STDIO_H @@ -70,7 +61,9 @@ typedef struct { #endif #ifdef HAVE_SYS_STAT_H #include +#ifndef __CYGWIN__ /* See https://cygwin.com/faq.html#faq.programming.stat64 */ #define stat stat64 +#endif #define st_blocks st_rdev /* emulate st_blocks, missing in Windows */ #endif @@ -134,6 +127,30 @@ static LPFN_SETFILEPOINTEREX fnSetFilePointerEx = NULL; #define FNPOSTFIX "A" #endif +/* + * Since many of the ahead enum constants conflict with winnt.h defines, + * make sure that each enum constant is undefined. + */ + +#undef STATUS_UNKNOWN +#undef STATUS_SUCCESS +#undef STATUS_BUFFER_OVERFLOW +#undef STATUS_INVALID_HANDLE +#undef STATUS_INVALID_PARAMETER +#undef STATUS_INVALID_DEVICE_REQUEST +#undef STATUS_END_OF_FILE +#undef STATUS_CONFLICTING_ADDRESSES +#undef STATUS_NO_MATCH +#undef STATUS_ACCESS_DENIED +#undef STATUS_BUFFER_TOO_SMALL +#undef STATUS_OBJECT_TYPE_MISMATCH +#undef STATUS_FILE_NOT_FOUND +#undef STATUS_OBJECT_NAME_INVALID +#undef STATUS_OBJECT_NAME_NOT_FOUND +#undef STATUS_SHARING_VIOLATION +#undef STATUS_INVALID_PARAMETER_1 +#undef STATUS_IO_DEVICE_ERROR +#undef STATUS_GUARD_PAGE_VIOLATION enum { /* see http://msdn.microsoft.com/en-us/library/cc704588(v=prot.10).aspx */ STATUS_UNKNOWN = -1, STATUS_SUCCESS = 0x00000000, @@ -156,14 +173,14 @@ enum { /* see http://msdn.microsoft.com/en-us/library/cc704588(v=prot.10).aspx * STATUS_GUARD_PAGE_VIOLATION = 0x80000001 } ; -typedef u32 NTSTATUS; /* do not let the compiler choose the size */ +typedef s32 NTSTATUS; /* do not let the compiler choose the size */ #ifdef __x86_64__ typedef unsigned long long ULONG_PTR; /* an integer the same size as a pointer */ #else typedef unsigned long ULONG_PTR; /* an integer the same size as a pointer */ #endif -HANDLE get_osfhandle(int); /* from msvcrt.dll */ +HANDLE _get_osfhandle(int); /* from msvcrt.dll */ /* * A few needed definitions not included in @@ -343,7 +360,7 @@ static int ntfs_w32error_to_errno(unsigned int w32error) static int ntfs_ntstatus_to_errno(NTSTATUS status) { - ntfs_log_trace("Converting w32error 0x%x.\n",w32error); + ntfs_log_trace("Converting w32error 0x%x.\n",status); switch (status) { case STATUS_INVALID_HANDLE : case STATUS_INVALID_PARAMETER : @@ -1323,7 +1340,8 @@ static s64 ntfs_device_win32_seek(struct ntfs_device *dev, s64 offset, * @fd: win32 device descriptor obtained via ->open * @pos: at which position to do i/o from/to * @count: how many bytes should be transfered - * @b: source/destination buffer + * @rbuf: source buffer (null if writing) + * @wbuf: destination buffer (null if reading) * @write: TRUE if write transfer and FALSE if read transfer * * On success returns the number of bytes transfered (can be < @count) and on @@ -1345,7 +1363,7 @@ static s64 ntfs_device_win32_pio(win32_fd *fd, const s64 pos, s64 bytes; ntfs_log_trace("pos = 0x%llx, count = 0x%llx, direction = %s.\n", - (long long)pos, (long long)count, write ? "write" : + (long long)pos, (long long)count, wbuf ? "write" : "read"); li.QuadPart = pos; if (fd->vol_handle != INVALID_HANDLE_VALUE && pos < fd->geo_size) { @@ -1395,7 +1413,7 @@ static s64 ntfs_device_win32_pio(win32_fd *fd, const s64 pos, bytes = bt; if (!res) { errno = ntfs_w32error_to_errno(GetLastError()); - ntfs_log_trace("%sFile() failed.\n", write ? + ntfs_log_trace("%sFile() failed.\n", wbuf ? "Write" : "Read"); return -1; } @@ -1970,7 +1988,7 @@ int ntfs_win32_set_sparse(int fd) HANDLE handle; DWORD bytes; - handle = get_osfhandle(fd); + handle = _get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) ok = FALSE; else @@ -2034,7 +2052,7 @@ int ntfs_win32_ftruncate(int fd, s64 size) int ret; HANDLE handle; - handle = get_osfhandle(fd); + handle = _get_osfhandle(fd); ret = win32_ftruncate(handle, size); return (ret); } diff --git a/ntfsprogs/ntfsclone.c b/ntfsprogs/ntfsclone.c index 00876313..2aab675d 100644 --- a/ntfsprogs/ntfsclone.c +++ b/ntfsprogs/ntfsclone.c @@ -110,10 +110,14 @@ #endif #ifdef HAVE_WINDOWS_H +#ifdef __CYGWIN__ +#include +#else /* * Replacements for functions which do not exist on Windows */ int setmode(int, int); /* from msvcrt.dll */ +#endif #define getpid() (0) #define srandom(seed) srand(seed) diff --git a/ntfsprogs/ntfssecaudit.c b/ntfsprogs/ntfssecaudit.c index 9484a605..25b136b8 100644 --- a/ntfsprogs/ntfssecaudit.c +++ b/ntfsprogs/ntfssecaudit.c @@ -434,6 +434,16 @@ struct SDH { /* this is an image of an $SDH index entry */ } ; #ifdef HAVE_WINDOWS_H + +// Copied from minwindef.h. +#ifndef WINAPI +#if defined(_ARM_) +#define WINAPI +#else +#define WINAPI __stdcall +#endif +#endif + /* * Including leads to numerous conflicts with layout.h * so define a few needed Windows calls unrelated to ntfs-3g diff --git a/ntfsprogs/ntfsusermap.c b/ntfsprogs/ntfsusermap.c index 6c1f61b8..8a25b278 100644 --- a/ntfsprogs/ntfsusermap.c +++ b/ntfsprogs/ntfsusermap.c @@ -142,6 +142,16 @@ #include "misc.h" #ifdef HAVE_WINDOWS_H + +// Copied from minwindef.h. +#ifndef WINAPI +#if defined(_ARM_) +#define WINAPI +#else +#define WINAPI __stdcall +#endif +#endif + /* * Including leads to numerous conflicts with layout.h * so define a few needed Windows calls unrelated to ntfs-3g @@ -804,7 +814,12 @@ static boolean outputmap(const char *volume, const char *dir) /* build directory, if not present */ if (stat(fullname,&st) && (errno == ENOENT)) { printf("* Creating directory %s\n", fullname); + #ifdef __CYGWIN__ + // The one-argument mkdir is exclusive to msvcrt.dll. + mkdir(fullname, 0777); + #else mkdir(fullname); + #endif } strcat(fullname, DIRSEP); diff --git a/ntfsprogs/utils.h b/ntfsprogs/utils.h index 6335924e..3974da00 100644 --- a/ntfsprogs/utils.h +++ b/ntfsprogs/utils.h @@ -101,27 +101,6 @@ int mft_next_record(struct mft_search_ctx *ctx); #define MAX_PATH 1024 #endif -#ifdef HAVE_WINDOWS_H -/* - * Macroes to hide the needs to translate formats on older Windows - */ -#define MAX_FMT 1536 -char *ntfs_utils_reformat(char *out, int sz, const char *fmt); -char *ntfs_utils_unix_path(const char *in); -#define ntfs_log_redirect(fn,fi,li,le,d,fmt, args...) \ - do { char _b[MAX_FMT]; ntfs_log_redirect(fn,fi,li,le,d, \ - ntfs_utils_reformat(_b,MAX_FMT,fmt), args); } while (0) -#define printf(fmt, args...) \ - do { char _b[MAX_FMT]; \ - printf(ntfs_utils_reformat(_b,MAX_FMT,fmt), args); } while (0) -#define fprintf(str, fmt, args...) \ - do { char _b[MAX_FMT]; \ - fprintf(str, ntfs_utils_reformat(_b,MAX_FMT,fmt), args); } while (0) -#define vfprintf(file, fmt, args) \ - do { char _b[MAX_FMT]; vfprintf(file, \ - ntfs_utils_reformat(_b,MAX_FMT,fmt), args); } while (0) -#endif - /** * linux-ntfs's ntfs_mbstoucs has different semantics, so we emulate it with * ntfs-3g's.