Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Cygwin build #106

Draft
wants to merge 18 commits into
base: edge
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -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
==============
Expand Down
3 changes: 3 additions & 0 deletions include/ntfs-3g/device_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion include/ntfs-3g/ntfstime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions libntfs-3g/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
2 changes: 2 additions & 0 deletions libntfs-3g/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
Expand Down
56 changes: 37 additions & 19 deletions libntfs-3g/win32_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <windows.h>
#undef BOOL
#undef _NO_BOOL_TYPEDEF
#endif

#ifdef HAVE_STDLIB_H
Expand All @@ -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 <winioctl.h>

#ifdef HAVE_STDIO_H
Expand All @@ -70,7 +61,9 @@ typedef struct {
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#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

Expand Down Expand Up @@ -134,6 +127,30 @@ static LPFN_SETFILEPOINTEREX fnSetFilePointerEx = NULL;
#define FNPOSTFIX "A"
#endif

/*
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to just skip this enum when any constant is already defined (instead of doing this bunch of undef's)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it may not be safe to do this. The first compiler error occurs with STATUS_INVALID_HANDLE (as opposed to STATUS_SUCCESS or STATUS_BUFFER_OVERFLOW), which suggests to me that the included header is not ntstatus.h, but rather winnt.h. The later is a rather incomplete group of status codes, missing STATUS_BUFFER_OVERFLOW, so it can't be used as-is.

What I can do, however, is include ntstatus.h, which does provide a comprehensive set of status codes. The remaining questions, then, are:

  • Should use ntstatus's defines no matter what, or still do it depending on whether STATUS_SUCCESS is defined?
  • Will this header reliable be available, or should I guard it for Cygwin-only?

I'm not aware of any non-Cygwin Windows setups that are supposed to be working, but I could take the conservative route and do it conditionally, if preferred.

* 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,
Expand All @@ -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 <windows.h>
Expand Down Expand Up @@ -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 :
Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
4 changes: 4 additions & 0 deletions ntfsprogs/ntfsclone.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,14 @@
#endif

#ifdef HAVE_WINDOWS_H
#ifdef __CYGWIN__
#include <io.h>
#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)
Expand Down
10 changes: 10 additions & 0 deletions ntfsprogs/ntfssecaudit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <windows.h> leads to numerous conflicts with layout.h
* so define a few needed Windows calls unrelated to ntfs-3g
Expand Down
15 changes: 15 additions & 0 deletions ntfsprogs/ntfsusermap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <windows.h> leads to numerous conflicts with layout.h
* so define a few needed Windows calls unrelated to ntfs-3g
Expand Down Expand Up @@ -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, 777);
#else
mkdir(fullname);
#endif
}

strcat(fullname, DIRSEP);
Expand Down
21 changes: 0 additions & 21 deletions ntfsprogs/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down