diff --git a/include/ntfs-3g/cache.h b/include/ntfs-3g/cache.h index be63b1a..195222c 100644 --- a/include/ntfs-3g/cache.h +++ b/include/ntfs-3g/cache.h @@ -29,7 +29,7 @@ struct CACHED_GENERIC { struct CACHED_GENERIC *previous; void *variable; size_t varsize; - union ALIGNMENT payload[0]; + union ALIGNMENT payload[1]; } ; struct CACHED_INODE { @@ -37,7 +37,7 @@ struct CACHED_INODE { struct CACHED_INODE *previous; const char *pathname; size_t varsize; - union ALIGNMENT payload[0]; + /* zero-length generic payload omitted for MSVC */ /* above fields must match "struct CACHED_GENERIC" */ u64 inum; } ; @@ -47,7 +47,7 @@ struct CACHED_NIDATA { struct CACHED_NIDATA *previous; const char *pathname; /* not used */ size_t varsize; /* not used */ - union ALIGNMENT payload[0]; + /* zero-length generic payload omitted for MSVC */ /* above fields must match "struct CACHED_GENERIC" */ u64 inum; ntfs_inode *ni; @@ -58,7 +58,7 @@ struct CACHED_LOOKUP { struct CACHED_LOOKUP *previous; const char *name; size_t namesize; - union ALIGNMENT payload[0]; + /* zero-length generic payload omitted for MSVC */ /* above fields must match "struct CACHED_GENERIC" */ u64 parent; u64 inum; @@ -93,7 +93,7 @@ struct CACHE_HEADER { unsigned long hits; int fixed_size; int max_hash; - struct CACHED_GENERIC entry[0]; + struct CACHED_GENERIC entry[1]; } ; /* cast to generic, avoiding gcc warnings */ diff --git a/include/ntfs-3g/layout.h b/include/ntfs-3g/layout.h index ab6d453..05605c7 100644 --- a/include/ntfs-3g/layout.h +++ b/include/ntfs-3g/layout.h @@ -1,6 +1,14 @@ -#ifdef _MSC_VER -#pragma pack(push, 1) -#endif +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif +#ifdef _MSC_VER +#define NTFS_PACKED_ENUM_BEGIN(name, storage) enum +#define NTFS_PACKED_ENUM_END(name, storage) ; typedef storage name +#else +#define NTFS_PACKED_ENUM_BEGIN(name, storage) typedef enum +#define NTFS_PACKED_ENUM_END(name, storage) __attribute__((__packed__)) name +#endif + /* * layout.h - Ntfs on-disk layout structures. Originated from the Linux-NTFS project. * @@ -263,14 +271,14 @@ typedef enum { * index, that means an INDEX_ROOT and an INDEX_ALLOCATION with a name other * than "$I30". It is unknown if it is limited to metadata files only. */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(MFT_RECORD_FLAGS, u16) { MFT_RECORD_IN_USE = const_cpu_to_le16(0x0001), MFT_RECORD_IS_DIRECTORY = const_cpu_to_le16(0x0002), MFT_RECORD_IS_4 = const_cpu_to_le16(0x0004), MFT_RECORD_IS_VIEW_INDEX = const_cpu_to_le16(0x0008), MFT_REC_SPACE_FILLER = 0xffff, /* Just to make flags 16-bit. */ -} __attribute__((__packed__)) MFT_RECORD_FLAGS; +} NTFS_PACKED_ENUM_END(MFT_RECORD_FLAGS, u16); /* * mft references (aka file references or file record segment references) are @@ -631,14 +639,14 @@ typedef struct { /** * enum ATTR_FLAGS - Attribute flags (16-bit). */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(ATTR_FLAGS, u16) { ATTR_IS_COMPRESSED = const_cpu_to_le16(0x0001), ATTR_COMPRESSION_MASK = const_cpu_to_le16(0x00ff), /* Compression method mask. Also, first illegal value. */ ATTR_IS_ENCRYPTED = const_cpu_to_le16(0x4000), ATTR_IS_SPARSE = const_cpu_to_le16(0x8000), -} __attribute__((__packed__)) ATTR_FLAGS; +} NTFS_PACKED_ENUM_END(ATTR_FLAGS, u16); /* * Attribute compression. @@ -710,11 +718,11 @@ typedef enum { /** * enum RESIDENT_ATTR_FLAGS - Flags of resident attributes (8-bit). */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(RESIDENT_ATTR_FLAGS, u8) { RESIDENT_ATTR_IS_INDEXED = 0x01, /* Attribute is referenced in an index (has implications for deleting and modifying the attribute). */ -} __attribute__((__packed__)) RESIDENT_ATTR_FLAGS; +} NTFS_PACKED_ENUM_END(RESIDENT_ATTR_FLAGS, u8); /** * struct ATTR_RECORD - Attribute record header. @@ -759,7 +767,7 @@ typedef struct { /* 22 */ RESIDENT_ATTR_FLAGS resident_flags; /* See above. */ /* 23 */ s8 reservedR; /* Reserved/alignment to 8-byte boundary. */ -/* 24 */ void *resident_end[0]; /* Use offsetof(ATTR_RECORD, +/* 24 */ void *resident_end[1]; /* Use offsetof(ATTR_RECORD, resident_end) to get size of a resident attribute. */ } __attribute__((__packed__)); @@ -805,17 +813,17 @@ typedef struct { /* 56*/ sle64 initialized_size; /* Byte size of initialized portion of the attribute value. Usually equals data_size. */ -/* 64 */ void *non_resident_end[0]; /* Use offsetof(ATTR_RECORD, - non_resident_end) to get - size of a non resident - attribute. */ +/* 64 */ union { + void *non_resident_end[1]; /* Marker for offsetof(). */ + sle64 compressed_size; + }; /* sizeof(uncompressed attr) = 64*/ -/* 64*/ sle64 compressed_size; /* Byte size of the attribute +/* 64*/ /* compressed_size is overlaid above */ /* Byte size of the attribute value after compression. Only present when compressed. Always is a multiple of the cluster size. Represents the actual amount of disk space being used on the disk. */ -/* 72 */ void *compressed_end[0]; +/* 72 */ void *compressed_end[1]; /* Use offsetof(ATTR_RECORD, compressed_end) to get size of a compressed attribute. */ /* sizeof(compressed attr) = 72*/ @@ -828,7 +836,7 @@ typedef ATTR_RECORD ATTR_REC; /** * enum FILE_ATTR_FLAGS - File attribute flags (32-bit). */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(FILE_ATTR_FLAGS, u32) { /* * These flags are only present in the STANDARD_INFORMATION attribute * (in the field file_attributes). @@ -891,7 +899,7 @@ typedef enum { * $FILE_NAME attributes. */ FILE_ATTR_VIEW_INDEX_PRESENT = const_cpu_to_le32(0x20000000), -} __attribute__((__packed__)) FILE_ATTR_FLAGS; +} NTFS_PACKED_ENUM_END(FILE_ATTR_FLAGS, u32); /* * NOTE on times in NTFS: All times are in MS standard time format, i.e. they @@ -932,7 +940,7 @@ typedef struct { struct { /* 36 */ u8 reserved12[12]; /* Reserved/alignment to 8-byte boundary. */ - /* 48 */ void *v1_end[0]; /* Marker for offsetof(). */ + /* 48 */ void *v1_end[1]; /* Marker for offsetof(). */ } __attribute__((__packed__)); /* sizeof() = 48 bytes */ /* NTFS 3.0 */ @@ -986,7 +994,7 @@ typedef struct { partition. This, in contrast to disabling the journal is a very fast process, so the user won't even notice it. */ - /* 72*/ void *v3_end[0]; /* Marker for offsetof(). */ + /* 72*/ void *v3_end[1]; /* Marker for offsetof(). */ } __attribute__((__packed__)); } __attribute__((__packed__)); /* sizeof() = 72 bytes (NTFS 3.0) */ @@ -1047,7 +1055,7 @@ typedef struct { attribute value. */ /* 24*/ le16 instance; /* If lowest_vcn = 0, the instance of the attribute being referenced; otherwise 0. */ -/* 26*/ ntfschar name[0]; /* Use when creating only. When reading use +/* 26*/ ntfschar name[1]; /* Use when creating only. When reading use name_offset to determine the location of the name. */ /* sizeof() = 26 + (attribute_name_length * 2) bytes */ @@ -1062,7 +1070,7 @@ typedef struct { * enum FILE_NAME_TYPE_FLAGS - Possible namespaces for filenames in ntfs. * (8-bit). */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(FILE_NAME_TYPE_FLAGS, u8) { FILE_NAME_POSIX = 0x00, /* This is the largest namespace. It is case sensitive and allows all Unicode characters except for: '\0' and '/'. @@ -1088,7 +1096,7 @@ typedef enum { /* 3 means that both the Win32 and the DOS filenames are identical and hence have been saved in this single filename record. */ -} __attribute__((__packed__)) FILE_NAME_TYPE_FLAGS; +} NTFS_PACKED_ENUM_END(FILE_NAME_TYPE_FLAGS, u8); /** * struct FILE_NAME_ATTR - Attribute: Filename (0x30). @@ -1141,7 +1149,7 @@ typedef struct { /* 40*/ u8 file_name_length; /* Length of file name in (Unicode) characters. */ /* 41*/ FILE_NAME_TYPE_FLAGS file_name_type; /* Namespace of the file name.*/ -/* 42*/ ntfschar file_name[0]; /* File name in Unicode. */ +/* 42*/ ntfschar file_name[1]; /* File name in Unicode. */ } __attribute__((__packed__)) FILE_NAME_ATTR; /** @@ -1392,7 +1400,7 @@ typedef union { * revision = 1, * sub_authority_count = 2, * identifier_authority = {0,0,0,0,0,5}, // SECURITY_NT_AUTHORITY - * sub_authority[0] = 32, // SECURITY_BUILTIN_DOMAIN_RID + * sub_authority[1] = 32, // SECURITY_BUILTIN_DOMAIN_RID * sub_authority[1] = 544 // DOMAIN_ALIAS_RID_ADMINS */ typedef struct { @@ -1415,7 +1423,7 @@ typedef enum { /** * enum ACE_TYPES - The predefined ACE types (8-bit, see below). */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(ACE_TYPES, u8) { ACCESS_MIN_MS_ACE_TYPE = 0, ACCESS_ALLOWED_ACE_TYPE = 0, ACCESS_DENIED_ACE_TYPE = 1, @@ -1458,7 +1466,7 @@ typedef enum { /* Windows 10 and later */ SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE = 20, -} __attribute__((__packed__)) ACE_TYPES; +} NTFS_PACKED_ENUM_END(ACE_TYPES, u8); /** * enum ACE_FLAGS - The ACE flags (8-bit) for audit and inheritance. @@ -1470,7 +1478,7 @@ typedef enum { * FAILED_ACCESS_ACE_FLAG is only used with system audit and alarm ACE types * to indicate that a message is generated (in Windows!) for failed accesses. */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(ACE_FLAGS, u8) { /* The inheritance flags. */ OBJECT_INHERIT_ACE = 0x01, CONTAINER_INHERIT_ACE = 0x02, @@ -1482,7 +1490,7 @@ typedef enum { /* The audit flags. */ SUCCESSFUL_ACCESS_ACE_FLAG = 0x40, FAILED_ACCESS_ACE_FLAG = 0x80, -} __attribute__((__packed__)) ACE_FLAGS; +} NTFS_PACKED_ENUM_END(ACE_FLAGS, u8); /** * struct ACE_HEADER - @@ -1784,7 +1792,7 @@ typedef enum { * and all pointer fields are expressed as offsets from the * beginning of the security descriptor. */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(SECURITY_DESCRIPTOR_CONTROL, u16) { SE_OWNER_DEFAULTED = const_cpu_to_le16(0x0001), SE_GROUP_DEFAULTED = const_cpu_to_le16(0x0002), SE_DACL_PRESENT = const_cpu_to_le16(0x0004), @@ -1799,7 +1807,7 @@ typedef enum { SE_SACL_PROTECTED = const_cpu_to_le16(0x2000), SE_RM_CONTROL_VALID = const_cpu_to_le16(0x4000), SE_SELF_RELATIVE = const_cpu_to_le16(0x8000), -} __attribute__((__packed__)) SECURITY_DESCRIPTOR_CONTROL; +} NTFS_PACKED_ENUM_END(SECURITY_DESCRIPTOR_CONTROL, u16); /** * struct SECURITY_DESCRIPTOR_RELATIVE - @@ -2007,13 +2015,13 @@ typedef struct { * NOTE: Present only in FILE_Volume. */ typedef struct { - ntfschar name[0]; /* The name of the volume in Unicode. */ + ntfschar name[1]; /* The name of the volume in Unicode. */ } __attribute__((__packed__)) VOLUME_NAME; /** * enum VOLUME_FLAGS - Possible flags for the volume (16-bit). */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(VOLUME_FLAGS, u16) { VOLUME_IS_DIRTY = const_cpu_to_le16(0x0001), VOLUME_RESIZE_LOG_FILE = const_cpu_to_le16(0x0002), VOLUME_UPGRADE_ON_MOUNT = const_cpu_to_le16(0x0004), @@ -2023,7 +2031,7 @@ typedef enum { VOLUME_CHKDSK_UNDERWAY = const_cpu_to_le16(0x4000), VOLUME_MODIFIED_BY_CHKDSK = const_cpu_to_le16(0x8000), VOLUME_FLAGS_MASK = const_cpu_to_le16(0xc03f), -} __attribute__((__packed__)) VOLUME_FLAGS; +} NTFS_PACKED_ENUM_END(VOLUME_FLAGS, u16); /** * struct VOLUME_INFORMATION - Attribute: Volume information (0x70). @@ -2048,13 +2056,13 @@ typedef struct { * Data contents of a file (i.e. the unnamed stream) or of a named stream. */ typedef struct { - u8 data[0]; /* The file's data contents. */ + u8 data[1]; /* The file's data contents. */ } __attribute__((__packed__)) DATA_ATTR; /** * enum INDEX_HEADER_FLAGS - Index header flags (8-bit). */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(INDEX_HEADER_FLAGS, u8) { /* When index header is in an index root attribute: */ SMALL_INDEX = 0, /* The index is small enough to fit inside the index root attribute and there is no index @@ -2071,7 +2079,7 @@ typedef enum { INDEX_NODE = 1, /* This node indexes other nodes, i.e. is not a leaf node. */ NODE_MASK = 1, /* Mask for accessing the *_NODE bits. */ -} __attribute__((__packed__)) INDEX_HEADER_FLAGS; +} NTFS_PACKED_ENUM_END(INDEX_HEADER_FLAGS, u8); /** * struct INDEX_HEADER - @@ -2282,7 +2290,7 @@ typedef enum { /** * enum INDEX_ENTRY_FLAGS - Index entry flags (16-bit). */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(INDEX_ENTRY_FLAGS, u16) { INDEX_ENTRY_NODE = const_cpu_to_le16(1), /* This entry contains a sub-node, i.e. a reference to an index block in form of a virtual cluster @@ -2292,7 +2300,7 @@ typedef enum { entry does not represent a file but it can point to a sub-node. */ INDEX_ENTRY_SPACE_FILLER = 0xffff, /* Just to force 16-bit width. */ -} __attribute__((__packed__)) INDEX_ENTRY_FLAGS; +} NTFS_PACKED_ENUM_END(INDEX_ENTRY_FLAGS, u16); /** * struct INDEX_ENTRY_HEADER - This the index entry header (see below). @@ -2395,7 +2403,7 @@ typedef struct { * number of clusters in the index allocation attribute. */ typedef struct { - u8 bitmap[0]; /* Array of bits. */ + u8 bitmap[1]; /* Array of bits. */ } __attribute__((__packed__)) BITMAP_ATTR; /** @@ -2469,7 +2477,7 @@ typedef struct { le32 reparse_tag; /* Reparse point type (inc. flags). */ le16 reparse_data_length; /* Byte size of reparse data. */ le16 reserved; /* Align to 8-byte boundary. */ - u8 reparse_data[0]; /* Meaning depends on reparse_tag. */ + u8 reparse_data[1]; /* Meaning depends on reparse_tag. */ } __attribute__((__packed__)) REPARSE_POINT; /** @@ -2492,12 +2500,12 @@ typedef struct { /** * enum EA_FLAGS - Extended attribute flags (8-bit). */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(EA_FLAGS, u8) { NEED_EA = 0x80, /* Indicate that the file to which the EA belongs cannot be interpreted without understanding the associated extended attributes. */ -} __attribute__((__packed__)) EA_FLAGS; +} NTFS_PACKED_ENUM_END(EA_FLAGS, u8); /** * struct EA_ATTR - Attribute: Extended attribute (EA) (0xe0). @@ -2514,8 +2522,8 @@ typedef struct { u8 name_length; /* Length of the name of the extended attribute in bytes. */ le16 value_length; /* Byte size of the EA's value. */ - u8 name[0]; /* Name of the EA. */ - u8 value[0]; /* The value of the EA. Immediately + u8 name[1]; /* Name of the EA. */ + u8 value[1]; /* The value of the EA. Immediately follows the name. */ } __attribute__((__packed__)) EA_ATTR; @@ -2526,7 +2534,7 @@ typedef struct { * NTFS 3.0 during beta testing. */ typedef struct { - /* Irrelevant as feature unused. */ + u8 _ntlite_unused; } __attribute__((__packed__)) PROPERTY_SET; /** @@ -2541,7 +2549,7 @@ typedef struct { * attribute with the name $EFS. See below for the relevant structures. */ typedef struct { - /* Can be anything the creator chooses. */ + u8 _ntlite_unused; } __attribute__((__packed__)) LOGGED_UTILITY_STREAM; /* @@ -2684,6 +2692,15 @@ typedef struct { typedef EFS_DF_CERTIFICATE_THUMBPRINT_HEADER EFS_DF_CERT_THUMBPRINT_HEADER; +#ifdef _MSC_VER +typedef le64 INTX_FILE_TYPES; +#define INTX_SYMBOLIC_LINK \ + ((INTX_FILE_TYPES)const_cpu_to_le64(0x014B4E4C78746E49ULL)) /* "IntxLNK\1" */ +#define INTX_CHARACTER_DEVICE \ + ((INTX_FILE_TYPES)const_cpu_to_le64(0x0052484378746E49ULL)) /* "IntxCHR\0" */ +#define INTX_BLOCK_DEVICE \ + ((INTX_FILE_TYPES)const_cpu_to_le64(0x004B4C4278746E49ULL)) /* "IntxBLK\0" */ +#else typedef enum { INTX_SYMBOLIC_LINK = const_cpu_to_le64(0x014B4E4C78746E49ULL), /* "IntxLNK\1" */ @@ -2692,6 +2709,7 @@ typedef enum { INTX_BLOCK_DEVICE = const_cpu_to_le64(0x004B4C4278746E49ULL), /* "IntxBLK\0" */ } INTX_FILE_TYPES; +#endif typedef struct { INTX_FILE_TYPES magic; /* Intx file magic. */ @@ -2700,15 +2718,15 @@ typedef struct { struct { le64 major; /* Major device number. */ le64 minor; /* Minor device number. */ - void *device_end[0]; /* Marker for offsetof(). */ + void *device_end[1]; /* Marker for offsetof(). */ } __attribute__((__packed__)); /* For symbolic links. */ - ntfschar target[0]; + ntfschar target[1]; } __attribute__((__packed__)); } __attribute__((__packed__)) INTX_FILE; #endif /* defined _NTFS_LAYOUT_H */ - -#ifdef _MSC_VER -#pragma pack(pop) -#endif + +#ifdef _MSC_VER +#pragma pack(pop) +#endif diff --git a/include/ntfs-3g/logfile.h b/include/ntfs-3g/logfile.h index d1f1222..97c99c4 100644 --- a/include/ntfs-3g/logfile.h +++ b/include/ntfs-3g/logfile.h @@ -1,3 +1,6 @@ +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif /* * logfile.h - Exports for $LogFile handling. Originated from the Linux-NTFS project. * @@ -335,7 +338,7 @@ typedef struct { * * (Or is it log record pages?) */ -typedef enum { +NTFS_PACKED_ENUM_BEGIN(LOG_RECORD_FLAGS, u16) { LOG_RECORD_MULTI_PAGE = const_cpu_to_le16(0x0001), /* ??? */ /* The flags below were introduced in Windows 10 */ LOG_RECORD_DELETING = const_cpu_to_le16(0x0002), @@ -343,7 +346,7 @@ typedef enum { LOG_RECORD_SIZE_PLACE_HOLDER = 0xffff, /* This has nothing to do with the log record. It is only so gcc knows to make the flags 16-bit. */ -} __attribute__((__packed__)) LOG_RECORD_FLAGS; +} NTFS_PACKED_ENUM_END(LOG_RECORD_FLAGS, u16); /** * struct LOG_CLIENT_ID - The log client id structure identifying a log client. @@ -413,7 +416,7 @@ typedef struct { ATTRIBUTE_FLAGS attribute_flags; leVCN target_vcn; /* Now at ofs 0x50. */ - leLCN lcn_list[0]; /* Only present if lcns_to_follow + leLCN lcn_list[1]; /* Only present if lcns_to_follow is not 0. */ } __attribute__((__packed__)); struct { @@ -421,7 +424,7 @@ typedef struct { leLSN attributes_lsn; leLSN names_lsn; leLSN dirty_pages_lsn; - le64 unknown_list[0]; + le64 unknown_list[1]; } __attribute__((__packed__)); } __attribute__((__packed__)); } __attribute__((__packed__)) LOG_RECORD; @@ -468,3 +471,7 @@ extern BOOL ntfs_is_logfile_clean(ntfs_attr *log_na, RESTART_PAGE_HEADER *rp); extern int ntfs_empty_logfile(ntfs_attr *na); #endif /* defined _NTFS_LOGFILE_H */ + +#ifdef _MSC_VER +#pragma pack(pop) +#endif diff --git a/include/ntfs-3g/logging.h b/include/ntfs-3g/logging.h index 82f39fe..8c9538c 100644 --- a/include/ntfs-3g/logging.h +++ b/include/ntfs-3g/logging.h @@ -87,32 +87,28 @@ int ntfs_log_redirect(const char *function, const char *file, int line, #define NTFS_LOG_FLAG_FUNCTION (1 << 3) /* Show the function name containing the message */ #define NTFS_LOG_FLAG_ONLYNAME (1 << 4) /* Only display the filename, not the pathname */ -/* Macros to simplify logging. One for each level defined above. - * Note, ntfs_log_debug/trace have effect only if DEBUG is defined. - */ -#define ntfs_log_critical(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_CRITICAL,NULL,FORMAT,##ARGS) -#define ntfs_log_error(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_ERROR,NULL,FORMAT,##ARGS) -#define ntfs_log_info(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_INFO,NULL,FORMAT,##ARGS) -#define ntfs_log_perror(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PERROR,NULL,FORMAT,##ARGS) -#define ntfs_log_progress(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PROGRESS,NULL,FORMAT,##ARGS) -#define ntfs_log_quiet(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_QUIET,NULL,FORMAT,##ARGS) -#define ntfs_log_verbose(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_VERBOSE,NULL,FORMAT,##ARGS) -#define ntfs_log_warning(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_WARNING,NULL,FORMAT,##ARGS) - -/* By default debug and trace messages are compiled into the program, - * but not displayed. - */ +/* Macros to simplify logging. Use standard C99 variadic macros so this + * header also parses with MSVC's C front-end. */ +#define ntfs_log_critical(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_CRITICAL,NULL,__VA_ARGS__) +#define ntfs_log_error(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_ERROR,NULL,__VA_ARGS__) +#define ntfs_log_info(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_INFO,NULL,__VA_ARGS__) +#define ntfs_log_perror(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PERROR,NULL,__VA_ARGS__) +#define ntfs_log_progress(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PROGRESS,NULL,__VA_ARGS__) +#define ntfs_log_quiet(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_QUIET,NULL,__VA_ARGS__) +#define ntfs_log_verbose(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_VERBOSE,NULL,__VA_ARGS__) +#define ntfs_log_warning(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_WARNING,NULL,__VA_ARGS__) + #ifdef DEBUG -#define ntfs_log_debug(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_DEBUG,NULL,FORMAT,##ARGS) -#define ntfs_log_trace(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_TRACE,NULL,FORMAT,##ARGS) -#define ntfs_log_enter(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_ENTER,NULL,FORMAT,##ARGS) -#define ntfs_log_leave(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_LEAVE,NULL,FORMAT,##ARGS) +#define ntfs_log_debug(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_DEBUG,NULL,__VA_ARGS__) +#define ntfs_log_trace(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_TRACE,NULL,__VA_ARGS__) +#define ntfs_log_enter(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_ENTER,NULL,__VA_ARGS__) +#define ntfs_log_leave(...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_LEAVE,NULL,__VA_ARGS__) #else -#define ntfs_log_debug(FORMAT, ARGS...)do {} while (0) -#define ntfs_log_trace(FORMAT, ARGS...)do {} while (0) -#define ntfs_log_enter(FORMAT, ARGS...)do {} while (0) -#define ntfs_log_leave(FORMAT, ARGS...)do {} while (0) -#endif /* DEBUG */ +#define ntfs_log_debug(...) do {} while (0) +#define ntfs_log_trace(...) do {} while (0) +#define ntfs_log_enter(...) do {} while (0) +#define ntfs_log_leave(...) do {} while (0) +#endif void ntfs_log_early_error(const char *format, ...) __attribute__((format(printf, 1, 2))); diff --git a/include/ntfs-3g/param.h b/include/ntfs-3g/param.h index ebc8a0a..231dc76 100644 --- a/include/ntfs-3g/param.h +++ b/include/ntfs-3g/param.h @@ -22,11 +22,21 @@ #ifndef _NTFS_PARAM_H #define _NTFS_PARAM_H +#ifndef CACHE_INODE_SIZE #define CACHE_INODE_SIZE 32 /* inode cache, zero or >= 3 and not too big */ +#endif +#ifndef CACHE_NIDATA_SIZE #define CACHE_NIDATA_SIZE 64 /* idata cache, zero or >= 3 and not too big */ +#endif +#ifndef CACHE_LOOKUP_SIZE #define CACHE_LOOKUP_SIZE 64 /* lookup cache, zero or >= 3 and not too big */ +#endif +#ifndef CACHE_SECURID_SIZE #define CACHE_SECURID_SIZE 16 /* securid cache, zero or >= 3 and not too big */ +#endif +#ifndef CACHE_LEGACY_SIZE #define CACHE_LEGACY_SIZE 8 /* legacy cache size, zero or >= 3 and not too big */ +#endif #define FORCE_FORMAT_v1x 0 /* Insert security data as in NTFS v1.x */ #define OWNERFROMACL 1 /* Get the owner from ACL (not Windows owner) */ diff --git a/include/ntfs-3g/security.h b/include/ntfs-3g/security.h index c76ce9f..b747b61 100644 --- a/include/ntfs-3g/security.h +++ b/include/ntfs-3g/security.h @@ -74,7 +74,7 @@ struct CACHED_PERMISSIONS_LEGACY { struct CACHED_PERMISSIONS_LEGACY *previous; void *variable; size_t varsize; - union ALIGNMENT payload[0]; + /* zero-length generic payload omitted for MSVC */ /* above fields must match "struct CACHED_GENERIC" */ u64 mft_no; struct CACHED_PERMISSIONS perm; @@ -89,7 +89,7 @@ struct CACHED_SECURID { struct CACHED_SECURID *previous; void *variable; size_t varsize; - union ALIGNMENT payload[0]; + /* zero-length generic payload omitted for MSVC */ /* above fields must match "struct CACHED_GENERIC" */ uid_t uid; gid_t gid; @@ -164,7 +164,7 @@ struct POSIX_ACL { u8 version; u8 flags; u16 filler; - struct POSIX_ACE ace[0]; + struct POSIX_ACE ace[1]; } __attribute__((__packed__)); struct POSIX_SECURITY { diff --git a/include/ntfs-3g/support.h b/include/ntfs-3g/support.h index 6af4761..eadc08d 100644 --- a/include/ntfs-3g/support.h +++ b/include/ntfs-3g/support.h @@ -67,19 +67,13 @@ #define set_bit(bit, var) (var) |= 1 << (bit) #define clear_bit(bit, var) (var) &= ~(1 << (bit)) -#define test_and_set_bit(bit, var) \ -({ \ - const BOOL old_state = test_bit(bit, var); \ - set_bit(bit, var); \ - old_state; \ -}) +#define test_and_set_bit(bit, var) \ + (test_bit((bit), (var)) ? (set_bit((bit), (var)), TRUE) : \ + (set_bit((bit), (var)), FALSE)) -#define test_and_clear_bit(bit, var) \ -({ \ - const BOOL old_state = test_bit(bit, var); \ - clear_bit(bit, var); \ - old_state; \ -}) +#define test_and_clear_bit(bit, var) \ + (test_bit((bit), (var)) ? (clear_bit((bit), (var)), TRUE) : \ + (clear_bit((bit), (var)), FALSE)) #endif /* defined _NTFS_SUPPORT_H */ diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c index 35da32e..b1ab81e 100644 --- a/libntfs-3g/attrib.c +++ b/libntfs-3g/attrib.c @@ -6906,7 +6906,7 @@ static int stuff_hole(ntfs_attr *na, const s64 pos) if (!ret && NAttrNonResident(na)) { /* does the hole span over several compression block ? */ if ((pos ^ na->initialized_size) - & ~(na->compression_block_size - 1)) { + & ~((s64)na->compression_block_size - 1)) { begin_size = ((na->initialized_size - 1) | (na->compression_block_size - 1)) + 1 - na->initialized_size; diff --git a/libntfs-3g/attrlist.c b/libntfs-3g/attrlist.c index 29d4085..0cb8473 100644 --- a/libntfs-3g/attrlist.c +++ b/libntfs-3g/attrlist.c @@ -135,7 +135,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr) } /* Determine size and allocate memory for new attribute list. */ - entry_len = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) * + entry_len = (offsetof(ATTR_LIST_ENTRY, name) + sizeof(ntfschar) * attr->name_length + 7) & ~7; new_al = ntfs_calloc(ni->attr_list_size + entry_len); if (!new_al) diff --git a/libntfs-3g/cache.c b/libntfs-3g/cache.c index 2ad8d35..e577b52 100644 --- a/libntfs-3g/cache.c +++ b/libntfs-3g/cache.c @@ -483,7 +483,7 @@ static struct CACHE_HEADER *ntfs_create_cache(const char *name, size_t size; int i; - size = sizeof(struct CACHE_HEADER) + item_count*full_item_size; + size = offsetof(struct CACHE_HEADER, entry) + item_count*full_item_size; if (max_hash) size += item_count*sizeof(struct HASH_ENTRY) + max_hash*sizeof(struct HASH_ENTRY*); @@ -499,7 +499,7 @@ static struct CACHE_HEADER *ntfs_create_cache(const char *name, cache->dohash = (cache_hash)NULL; cache->max_hash = 0; } - cache->fixed_size = full_item_size - sizeof(struct CACHED_GENERIC); + cache->fixed_size = full_item_size - offsetof(struct CACHED_GENERIC, payload); cache->reads = 0; cache->writes = 0; cache->hits = 0; diff --git a/libntfs-3g/dir.c b/libntfs-3g/dir.c index 5cab5c5..ad82c6f 100644 --- a/libntfs-3g/dir.c +++ b/libntfs-3g/dir.c @@ -841,10 +841,6 @@ static const ntfschar dotdot[3] = { const_cpu_to_le16('.'), * union index_union - * More helpers for ntfs_readdir(). */ -typedef union { - INDEX_ROOT *ir; - INDEX_ALLOCATION *ia; -} index_union __attribute__((__transparent_union__)); /** * enum INDEX_TYPE - @@ -957,7 +953,7 @@ static u32 ntfs_dir_entry_type(ntfs_inode *dir_ni, MFT_REF mref, * callback. */ static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits, - const INDEX_TYPE index_type, index_union iu, INDEX_ENTRY *ie, + const INDEX_TYPE index_type, void *index_block, INDEX_ENTRY *ie, void *dirent, ntfs_filldir_t filldir) { FILE_NAME_ATTR *fn = &ie->key.file_name; @@ -971,11 +967,11 @@ static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits, /* Advance the position even if going to skip the entry. */ if (index_type == INDEX_TYPE_ALLOCATION) - *pos = (u8*)ie - (u8*)iu.ia + (sle64_to_cpu( - iu.ia->index_block_vcn) << ivcn_bits) + + *pos = (u8*)ie - (u8*)(INDEX_ALLOCATION*)index_block + (sle64_to_cpu( + ((INDEX_ALLOCATION*)index_block)->index_block_vcn) << ivcn_bits) + dir_ni->vol->mft_record_size; else /* if (index_type == INDEX_TYPE_ROOT) */ - *pos = (u8*)ie - (u8*)iu.ir; + *pos = (u8*)ie - (u8*)(INDEX_ROOT*)index_block; mref = le64_to_cpu(ie->indexed_file); metadata = (MREF(mref) != FILE_root) && (MREF(mref) < FILE_first_user); /* Skip root directory self reference entry. */ @@ -1500,7 +1496,7 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid, * Write STANDARD_INFORMATION v1.2 (no inheritance) or v3 */ if (securid) - si_len = sizeof(STANDARD_INFORMATION); + si_len = offsetof(STANDARD_INFORMATION, v3_end); else si_len = offsetof(STANDARD_INFORMATION, v1_end); si = ntfs_calloc(si_len); @@ -1686,7 +1682,7 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid, free(data); } /* Create FILE_NAME attribute. */ - fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar); + fn_len = offsetof(FILE_NAME_ATTR, file_name) + name_len * sizeof(ntfschar); fn = ntfs_calloc(fn_len); if (!fn) { err = errno; @@ -2223,7 +2219,7 @@ static int ntfs_link_i(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name, } /* Create FILE_NAME attribute. */ - fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar); + fn_len = offsetof(FILE_NAME_ATTR, file_name) + name_len * sizeof(ntfschar); fn = ntfs_calloc(fn_len); if (!fn) { err = errno; diff --git a/libntfs-3g/index.c b/libntfs-3g/index.c index 7b88c18..6de0e35 100644 --- a/libntfs-3g/index.c +++ b/libntfs-3g/index.c @@ -1704,7 +1704,7 @@ int ntfs_index_add_filename(ntfs_inode *ni, FILE_NAME_ATTR *fn, MFT_REF mref) } fn_size = (fn->file_name_length * sizeof(ntfschar)) + - sizeof(FILE_NAME_ATTR); + offsetof(FILE_NAME_ATTR, file_name); ie_size = (sizeof(INDEX_ENTRY_HEADER) + fn_size + 7) & ~7; ie = ntfs_calloc(ie_size); diff --git a/libntfs-3g/inode.c b/libntfs-3g/inode.c index 8819ff1..dc17a4c 100644 --- a/libntfs-3g/inode.c +++ b/libntfs-3g/inode.c @@ -857,7 +857,7 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni) err = errno; continue; } - if (ntfs_index_lookup(fn, sizeof(FILE_NAME_ATTR), ictx)) { + if (ntfs_index_lookup(fn, offsetof(FILE_NAME_ATTR, file_name), ictx)) { if (!err) { if (errno == ENOENT) err = EIO; @@ -1148,7 +1148,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni) goto put_err_out; } - ale_size = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) * + ale_size = (offsetof(ATTR_LIST_ENTRY, name) + sizeof(ntfschar) * ctx->attr->name_length + 7) & ~7; al_len += ale_size; @@ -1165,7 +1165,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni) /* Add attribute to attribute list. */ ale->type = ctx->attr->type; - ale->length = cpu_to_le16((sizeof(ATTR_LIST_ENTRY) + + ale->length = cpu_to_le16((offsetof(ATTR_LIST_ENTRY, name) + sizeof(ntfschar) * ctx->attr->name_length + 7) & ~7); ale->name_length = ctx->attr->name_length; ale->name_offset = (u8 *)ale->name - (u8 *)ale; diff --git a/libntfs-3g/ioctl.c b/libntfs-3g/ioctl.c index b059a53..be13ede 100644 --- a/libntfs-3g/ioctl.c +++ b/libntfs-3g/ioctl.c @@ -409,7 +409,11 @@ int ntfs_ioctl(ntfs_inode *ni, unsigned long cmd, } break; #else +#ifdef _MSC_VER +#pragma message("ntfs-3g: trimming not supported (FITRIM or BLKDISCARD not defined)") +#else #warning Trimming not supported : FITRIM or BLKDISCARD not defined +#endif #endif default : ret = -EINVAL; diff --git a/libntfs-3g/reparse.c b/libntfs-3g/reparse.c index 54858ca..fca18a6 100644 --- a/libntfs-3g/reparse.c +++ b/libntfs-3g/reparse.c @@ -66,7 +66,7 @@ struct MOUNT_POINT_REPARSE_DATA { /* reparse data for junctions */ le16 subst_name_length; le16 print_name_offset; le16 print_name_length; - char path_buffer[0]; /* above data assume this is char array */ + char path_buffer[1]; /* above data assume this is char array */ } ; struct SYMLINK_REPARSE_DATA { /* reparse data for symlinks */ @@ -75,12 +75,12 @@ struct SYMLINK_REPARSE_DATA { /* reparse data for symlinks */ le16 print_name_offset; le16 print_name_length; le32 flags; /* 1 for full target, otherwise 0 */ - char path_buffer[0]; /* above data assume this is char array */ + char path_buffer[1]; /* above data assume this is char array */ } ; struct WSL_LINK_REPARSE_DATA { le32 type; - char link[0]; + char link[1]; } ; struct REPARSE_INDEX { /* index entry in $Extend/$Reparse */ diff --git a/libntfs-3g/security.c b/libntfs-3g/security.c index d0e030e..6e6dc14 100644 --- a/libntfs-3g/security.c +++ b/libntfs-3g/security.c @@ -1017,7 +1017,7 @@ static int update_secur_descr(ntfs_volume *vol, if (!test_nino_flag(ni, v3_Extensions)) { /* expand standard information attribute to v3.x */ res = ntfs_attr_truncate(na, - (s64)sizeof(STANDARD_INFORMATION)); + (s64)offsetof(STANDARD_INFORMATION, v3_end)); ni->owner_id = const_cpu_to_le32(0); ni->quota_charged = const_cpu_to_le64(0); ni->usn = const_cpu_to_le64(0); @@ -1091,7 +1091,7 @@ static int upgrade_secur_desc(ntfs_volume *vol, if (na) { /* expand standard information attribute to v3.x */ res = ntfs_attr_truncate(na, - (s64)sizeof(STANDARD_INFORMATION)); + (s64)offsetof(STANDARD_INFORMATION, v3_end)); ni->owner_id = const_cpu_to_le32(0); ni->quota_charged = const_cpu_to_le64(0); ni->usn = const_cpu_to_le64(0); diff --git a/libntfs-3g/xattrs.c b/libntfs-3g/xattrs.c index 4e410de..97adb7d 100644 --- a/libntfs-3g/xattrs.c +++ b/libntfs-3g/xattrs.c @@ -75,7 +75,7 @@ struct LE_POSIX_ACL { u8 version; u8 flags; le16 filler; - struct LE_POSIX_ACE ace[0]; + struct LE_POSIX_ACE ace[1]; } __attribute__((__packed__)); #endif