Enable strict checking of endian-specific types.

Strict checking of endian-specific types mean that types that have a
fixed endianness in the data representation of the value are now defined
as complex types, enabling the compiler to catch mixed usage of these
types with native-endian types. This allows us to catch most issues
relating to usage on big-endian systems since we cannot anymore assign a
fixed-endian value to a native-endian variable and vice-versa without a
compiler error.

The downside is that we aren't able to apply simple binary operators to
the fixed-endian types anymore since they are complex... so all
combining fixed-endian constants and values with |, &, etc. and
comparison with ==, !=, <=, etc. must be replaced with a macro which
unpacks the wrapped value and performs the operation. Lots of changes,
lots of work but in the interest of good code quality it's justified.
edge.strict_endians
Erik Larsson 2016-01-28 08:29:03 +01:00
parent 7e85b4ccd4
commit 1984a714e5
5 changed files with 533 additions and 2 deletions

View File

@ -52,6 +52,8 @@
#include <sys/param.h>
#endif
#include "types.h"
#ifndef __BYTE_ORDER
# if defined(_BYTE_ORDER)
# define __BYTE_ORDER _BYTE_ORDER
@ -182,6 +184,8 @@
#endif
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
/* Unsigned from LE to CPU conversion. */
#define le16_to_cpu(x) (u16)__le16_to_cpu((u16)(x))
@ -348,4 +352,273 @@
#define le64_not(a) (~(a))
#else
/* Unsigned from LE to CPU conversion. */
static inline u16 le16_to_cpu(le16 x) { return (u16) __le16_to_cpu(x.value); }
static inline u32 le32_to_cpu(le32 x) { return (u32) __le32_to_cpu(x.value); }
static inline u64 le64_to_cpu(le64 x) { return (u64) __le64_to_cpu(x.value); }
static inline u16 le16_to_cpup(const le16 *x) {
return (u16) __le16_to_cpu(x->value);
}
static inline u32 le32_to_cpup(const le32 *x) {
return (u32) __le32_to_cpu(x->value);
}
static inline u64 le64_to_cpup(const le64 *x) {
return (u64) __le64_to_cpu(x->value);
}
/* Signed from LE to CPU conversion. */
static inline s16 sle16_to_cpu(sle16 x) { return (s16) __le16_to_cpu(x.value); }
static inline s32 sle32_to_cpu(sle32 x) { return (s32) __le32_to_cpu(x.value); }
static inline s64 sle64_to_cpu(sle64 x) { return (s64) __le64_to_cpu(x.value); }
static inline s16 sle16_to_cpup(const sle16 *x) {
return (s16) __le16_to_cpu(x->value);
}
static inline s32 sle32_to_cpup(const sle32 *x) {
return (s32) __le32_to_cpu(x->value);
}
static inline s64 sle64_to_cpup(const sle64 *x) {
return (s64) __le64_to_cpu(x->value);
}
/* Unsigned from CPU to LE conversion. */
static inline le16 cpu_to_le16(u16 x) {
le16 leval; leval.value = __cpu_to_le16(x); return leval;
}
static inline le32 cpu_to_le32(u32 x) {
le32 leval; leval.value = __cpu_to_le32(x); return leval;
}
static inline le64 cpu_to_le64(u64 x) {
le64 leval; leval.value = __cpu_to_le64(x); return leval;
}
static inline le16 cpu_to_le16p(const u16 *x) {
le16 leval; leval.value = __cpu_to_le16(*x); return leval;
}
static inline le32 cpu_to_le32p(const u32 *x) {
le32 leval; leval.value = __cpu_to_le32(*x); return leval;
}
static inline le64 cpu_to_le64p(const u64 *x) {
le64 leval; leval.value = __cpu_to_le64(*x); return leval;
}
/* Signed from CPU to LE conversion. */
static inline sle16 cpu_to_sle16(s16 x) {
sle16 leval; leval.value = __cpu_to_le16(x); return leval;
}
static inline sle32 cpu_to_sle32(s32 x) {
sle32 leval; leval.value = __cpu_to_le32(x); return leval;
}
static inline sle64 cpu_to_sle64(s64 x) {
sle64 leval; leval.value = __cpu_to_le64(x); return leval;
}
static inline sle16 cpu_to_sle16p(const s16 *x) {
sle16 leval; leval.value = __cpu_to_le16(*x); return leval;
}
static inline sle32 cpu_to_sle32p(const s32 *x) {
sle32 leval; leval.value = __cpu_to_le32(*x); return leval;
}
static inline sle64 cpu_to_sle64p(const s64 *x) {
sle64 leval; leval.value = __cpu_to_le64(*x); return leval;
}
/* Unsigned from BE to CPU conversion. */
static inline u16 be16_to_cpu(be16 x) { return (u16) __be16_to_cpu(x.value); }
static inline u32 be32_to_cpu(be32 x) { return (u32) __be32_to_cpu(x.value); }
static inline u64 be64_to_cpu(be64 x) { return (u64) __be64_to_cpu(x.value); }
static inline u16 be16_to_cpup(const be16 *x) {
return (u16) __be16_to_cpu(x->value);
}
static inline u32 be32_to_cpup(const be32 *x) {
return (u32) __be32_to_cpu(x->value);
}
static inline u64 be64_to_cpup(const be64 *x) {
return (u64) __be64_to_cpu(x->value);
}
/* Signed from BE to CPU conversion. */
static inline s16 sbe16_to_cpu(sbe16 x) { return (s16) __be16_to_cpu(x.value); }
static inline s32 sbe32_to_cpu(sbe32 x) { return (s32) __be32_to_cpu(x.value); }
static inline s64 sbe64_to_cpu(sbe64 x) { return (s64) __be64_to_cpu(x.value); }
static inline s16 sbe16_to_cpup(const sbe16 *x) {
return (s16) __be16_to_cpu(x->value);
}
static inline s32 sbe32_to_cpup(const sbe32 *x) {
return (s32) __be32_to_cpu(x->value);
}
static inline s64 sbe64_to_cpup(const sbe64 *x) {
return (s64) __be64_to_cpu(x->value);
}
/* Unsigned from CPU to BE conversion. */
static inline be16 cpu_to_be16(u16 x) {
be16 beval; beval.value = __cpu_to_be16(x); return beval;
}
static inline be32 cpu_to_be32(u32 x) {
be32 beval; beval.value = __cpu_to_be32(x); return beval;
}
static inline be64 cpu_to_be64(u64 x) {
be64 beval; beval.value = __cpu_to_be64(x); return beval;
}
static inline be16 cpu_to_be16p(const u16 *x) {
be16 beval; beval.value = __cpu_to_be16(*x); return beval;
}
static inline be32 cpu_to_be32p(const u32 *x) {
be32 beval; beval.value = __cpu_to_be32(*x); return beval;
}
static inline be64 cpu_to_be64p(const u64 *x) {
be64 beval; beval.value = __cpu_to_be64(*x); return beval;
}
/* Signed from CPU to BE conversion. */
static inline sbe16 cpu_to_sbe16(s16 x) {
sbe16 beval; beval.value = __cpu_to_be16(x); return beval;
}
static inline sbe32 cpu_to_sbe32(s32 x) {
sbe32 beval; beval.value = __cpu_to_be32(x); return beval;
}
static inline sbe64 cpu_to_sbe64(s64 x) {
sbe64 beval; beval.value = __cpu_to_be64(x); return beval;
}
static inline sbe16 cpu_to_sbe16p(const s16 *x) {
sbe16 beval; beval.value = __cpu_to_be16(*x); return beval;
}
static inline sbe32 cpu_to_sbe32p(const s32 *x) {
sbe32 beval; beval.value = __cpu_to_be32(*x); return beval;
}
static inline sbe64 cpu_to_sbe64p(const s64 *x) {
sbe64 beval; beval.value = __cpu_to_be64(*x); return beval;
}
/* Constant endianness conversion defines. */
#define const_le16_to_cpu(x) __constant_le16_to_cpu((u16)(x.value))
#define const_le32_to_cpu(x) __constant_le32_to_cpu((u32)(x.value))
#define const_le64_to_cpu(x) __constant_le64_to_cpu((u64)(x.value))
#define const_cpu_to_le16(x) ((le16)(u16) __constant_cpu_to_le16((u16)(x)))
#define const_cpu_to_le32(x) ((le32) __constant_cpu_to_le32((u32)(x)))
#define const_cpu_to_le64(x) ((le64) __constant_cpu_to_le64((u64)(x)))
#define const_sle16_to_cpu(x) __constant_le16_to_cpu((u16)(x.value))
#define const_sle32_to_cpu(x) __constant_le32_to_cpu((u32)(x.value))
#define const_sle64_to_cpu(x) __constant_le64_to_cpu((u64)(x.value))
#define const_cpu_to_sle16(x) ((sle16)(u16) __constant_cpu_to_le16((u16)(x)))
#define const_cpu_to_sle32(x) ((sle32) __constant_cpu_to_le32((u32)(x)))
#define const_cpu_to_sle64(x) ((sle64) __constant_cpu_to_le64((u64)(x)))
#define const_be16_to_cpu(x) __constant_be16_to_cpu((u16)(x.value))
#define const_be32_to_cpu(x) __constant_be32_to_cpu((u32)(x.value))
#define const_be64_to_cpu(x) __constant_be64_to_cpu((u64)(x.value))
#define const_cpu_to_be16(x) ((be16)(u16) __constant_cpu_to_be16((u16)(x)))
#define const_cpu_to_be32(x) ((be32) __constant_cpu_to_be32((u32)(x)))
#define const_cpu_to_be64(x) ((be64) __constant_cpu_to_be64((u64)(x)))
#define const_sbe16_to_cpu(x) __constant_be16_to_cpu((u16)(x.value))
#define const_sbe32_to_cpu(x) __constant_be32_to_cpu((u32)(x.value))
#define const_sbe64_to_cpu(x) __constant_be64_to_cpu((u64)(x.value))
#define const_cpu_to_sbe16(x) ((sbe16)(u16) __constant_cpu_to_be16((u16)(x)))
#define const_cpu_to_sbe32(x) ((sbe32) __constant_cpu_to_be32((u32)(x)))
#define const_cpu_to_sbe64(x) ((sbe64) __constant_cpu_to_be64((u64)(x)))
static inline int le16_eq(le16 a, le16 b) { return (a.value == b.value); }
static inline int le32_eq(le32 a, le32 b) { return (a.value == b.value); }
static inline int le64_eq(le64 a, le64 b) { return (a.value == b.value); }
static inline int sle16_eq(sle16 a, sle16 b) { return (a.value == b.value); }
static inline int sle64_eq(sle64 a, sle64 b) { return (a.value == b.value); }
static inline int be16_eq(be16 a, be16 b) { return (a.value == b.value); }
static inline int be32_eq(be32 a, be32 b) { return (a.value == b.value); }
static inline int le16_cmpz(le16 a) { return !a.value; }
static inline int le32_cmpz(le32 a) { return !a.value; }
static inline int le64_cmpz(le64 a) { return !a.value; }
static inline int sle64_cmpz(sle64 a) { return !a.value; }
static inline int be16_cmpz(be16 a) { return !a.value; }
static inline int le16_andz(le16 a, le16 b) { return !(a.value & b.value); }
static inline int le32_andz(le32 a, le32 b) { return !(a.value & b.value); }
static inline le16 le16_and(le16 a, le16 b)
{
return (le16) ((u16) (a.value & b.value));
}
static inline le32 le32_and(le32 a, le32 b)
{
return (le32) (a.value & b.value);
}
static inline le64 le64_and(le64 a, le64 b)
{
return (le64) (a.value & b.value);
}
static inline le16 le16_or(le16 a, le16 b)
{
return (le16) ((u16) (a.value | b.value));
}
static inline le32 le32_or(le32 a, le32 b)
{
return (le32) (a.value | b.value);
}
static inline le64 le64_or(le64 a, le64 b)
{
return (le64) (a.value | b.value);
}
static inline le16 le16_xor(le16 a, le16 b)
{
return (le16) ((u16) (a.value ^ b.value));
}
static inline le32 le32_xor(le32 a, le32 b)
{
return (le32) (a.value ^ b.value);
}
static inline le64 le64_xor(le64 a, le64 b)
{
return (le64) (a.value ^ b.value);
}
static inline le16 le16_not(le16 a) { return (le16) ((u16) (~a.value)); }
static inline le32 le32_not(le32 a) { return (le32) (~a.value); }
static inline le64 le64_not(le64 a) { return (le64) (~a.value); }
#endif /* !ENABLE_STRICT_ENDIANNESS_CHECKING ... */
#endif /* defined _NTFS_ENDIANS_H */

View File

@ -100,7 +100,13 @@ typedef struct {
* Magic identifiers present at the beginning of all ntfs record containing
* records (like mft records for example).
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 NTFS_RECORD_TYPES;
static const le32
#else
typedef enum {
#endif
/* Found in $MFT/$DATA. */
magic_FILE = const_cpu_to_le32(0x454c4946), /* Mft entry. */
magic_INDX = const_cpu_to_le32(0x58444e49), /* Index buffer. */
@ -125,14 +131,18 @@ typedef enum {
magic_empty = const_cpu_to_le32(0xffffffff),/* Record is empty and has
to be initialized before
it can be used. */
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} NTFS_RECORD_TYPES;
#else
__NTFS_RECORD_TYPES_end;
#endif
/*
* Generic magic comparison macros. Finally found a use for the ## preprocessor
* operator! (-8
*/
#define ntfs_is_magic(x, m) ( (u32)(x) == (u32)magic_##m )
#define ntfs_is_magicp(p, m) ( *(u32*)(p) == (u32)magic_##m )
#define ntfs_is_magic(x, m) ( le32_eq(x, magic_##m) )
#define ntfs_is_magicp(p, m) ( le32_eq(*p, magic_##m) )
/*
* Specialised magic comparison macros for the NTFS_RECORD_TYPES defined above.
@ -254,14 +264,24 @@ 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.
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le16 MFT_RECORD_FLAGS;
static const MFT_RECORD_FLAGS
#else
typedef enum {
#endif
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),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
MFT_REC_SPACE_FILLER = 0xffff, /* Just to make flags
16-bit. */
} __attribute__((__packed__)) MFT_RECORD_FLAGS;
#else
__MFT_RECORD_FLAGS_end;
#endif
/*
* mft references (aka file references or file record segment references) are
@ -489,7 +509,13 @@ typedef struct {
* enum exchanging AT_ for the dollar sign ($). If that isn't a revealing
* choice of symbol... (-;
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 ATTR_TYPES;
static const ATTR_TYPES
#else
typedef enum {
#endif
AT_UNUSED = const_cpu_to_le32( 0),
AT_STANDARD_INFORMATION = const_cpu_to_le32( 0x10),
AT_ATTRIBUTE_LIST = const_cpu_to_le32( 0x20),
@ -509,7 +535,11 @@ typedef enum {
AT_LOGGED_UTILITY_STREAM = const_cpu_to_le32( 0x100),
AT_FIRST_USER_DEFINED_ATTRIBUTE = const_cpu_to_le32( 0x1000),
AT_END = const_cpu_to_le32(0xffffffff),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} ATTR_TYPES;
#else
__ATTR_TYPES_end;
#endif
/**
* enum COLLATION_RULES - The collation rules for sorting views/indexes/etc
@ -548,7 +578,13 @@ typedef enum {
* the 2nd object_id. If the first le32 values of both object_ids were
* equal then the second le32 values would be compared, etc.
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 COLLATION_RULES;
static const COLLATION_RULES
#else
typedef enum {
#endif
COLLATION_BINARY = const_cpu_to_le32(0), /* Collate by binary
compare where the first byte is most
significant. */
@ -564,7 +600,11 @@ typedef enum {
COLLATION_NTOFS_SID = const_cpu_to_le32(17),
COLLATION_NTOFS_SECURITY_HASH = const_cpu_to_le32(18),
COLLATION_NTOFS_ULONGS = const_cpu_to_le32(19),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} COLLATION_RULES;
#else
__COLLATION_RULES_end;
#endif
/**
* enum ATTR_DEF_FLAGS -
@ -576,7 +616,13 @@ typedef enum {
* name attribute has this flag set and this is the only attribute indexed in
* NT4.
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 ATTR_DEF_FLAGS;
static const ATTR_DEF_FLAGS
#else
typedef enum {
#endif
ATTR_DEF_INDEXABLE = const_cpu_to_le32(0x02), /* Attribute can be
indexed. */
ATTR_DEF_MULTIPLE = const_cpu_to_le32(0x04), /* Attribute type
@ -601,7 +647,11 @@ typedef enum {
non-resident. Without this, only log
modifications if the attribute is
resident. */
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} ATTR_DEF_FLAGS;
#else
__ATTR_DEF_FLAGS_end;
#endif
/**
* struct ATTR_DEF -
@ -631,14 +681,24 @@ typedef struct {
/**
* enum ATTR_FLAGS - Attribute flags (16-bit).
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le16 ATTR_FLAGS;
static const ATTR_FLAGS
#else
typedef enum {
#endif
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),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} __attribute__((__packed__)) ATTR_FLAGS;
#else
__ATTR_FLAGS_end;
#endif
/*
* Attribute compression.
@ -828,7 +888,13 @@ typedef ATTR_RECORD ATTR_REC;
/**
* enum FILE_ATTR_FLAGS - File attribute flags (32-bit).
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 FILE_ATTR_FLAGS;
static const FILE_ATTR_FLAGS
#else
typedef enum {
#endif
/*
* These flags are only present in the STANDARD_INFORMATION attribute
* (in the field file_attributes).
@ -889,7 +955,11 @@ typedef enum {
* $FILE_NAME attributes.
*/
FILE_ATTR_VIEW_INDEX_PRESENT = const_cpu_to_le32(0x20000000),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} __attribute__((__packed__)) FILE_ATTR_FLAGS;
#else
__FILE_ATTR_FLAGS_end;
#endif
/*
* NOTE on times in NTFS: All times are in MS standard time format, i.e. they
@ -1481,7 +1551,13 @@ typedef struct {
*
* Defines the access rights.
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 ACCESS_MASK;
static const ACCESS_MASK
#else
typedef enum {
#endif
/*
* The specific rights (bits 0 to 15). Depend on the type of the
* object being secured by the ACE.
@ -1609,7 +1685,11 @@ typedef enum {
* above for the descriptions of the rights granted.
*/
GENERIC_READ = const_cpu_to_le32(0x80000000),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} ACCESS_MASK;
#else
__ACCESS_MASK_end;
#endif
/**
* struct GENERIC_MAPPING -
@ -1649,10 +1729,20 @@ typedef struct {
/**
* enum OBJECT_ACE_FLAGS - The object ACE flags (32-bit).
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 OBJECT_ACE_FLAGS;
static const OBJECT_ACE_FLAGS
#else
typedef enum {
#endif
ACE_OBJECT_TYPE_PRESENT = const_cpu_to_le32(1),
ACE_INHERITED_OBJECT_TYPE_PRESENT = const_cpu_to_le32(2),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} OBJECT_ACE_FLAGS;
#else
__OBJECT_ACE_FLAGS_end;
#endif
/**
* struct ACCESS_ALLOWED_OBJECT_ACE -
@ -1757,7 +1847,13 @@ typedef enum {
* and all pointer fields are expressed as offsets from the
* beginning of the security descriptor.
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le16 SECURITY_DESCRIPTOR_CONTROL;
static const SECURITY_DESCRIPTOR_CONTROL
#else
typedef enum {
#endif
SE_OWNER_DEFAULTED = const_cpu_to_le16(0x0001),
SE_GROUP_DEFAULTED = const_cpu_to_le16(0x0002),
SE_DACL_PRESENT = const_cpu_to_le16(0x0004),
@ -1772,7 +1868,11 @@ 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),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} __attribute__((__packed__)) SECURITY_DESCRIPTOR_CONTROL;
#else
__SECURITY_DESCRIPTOR_CONTROL_end;
#endif
/**
* struct SECURITY_DESCRIPTOR_RELATIVE -
@ -1986,7 +2086,13 @@ typedef struct {
/**
* enum VOLUME_FLAGS - Possible flags for the volume (16-bit).
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le16 VOLUME_FLAGS;
static const VOLUME_FLAGS
#else
typedef enum {
#endif
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),
@ -1996,7 +2102,11 @@ 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),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} __attribute__((__packed__)) VOLUME_FLAGS;
#else
__VOLUME_FLAGS_end;
#endif
/**
* struct VOLUME_INFORMATION - Attribute: Volume information (0x70).
@ -2170,7 +2280,13 @@ typedef struct {
/**
* enum QUOTA_FLAGS - Quota flags (32-bit).
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 QUOTA_FLAGS;
static const QUOTA_FLAGS
#else
typedef enum {
#endif
/* The user quota flags. Names explain meaning. */
QUOTA_FLAG_DEFAULT_LIMITS = const_cpu_to_le32(0x00000001),
QUOTA_FLAG_LIMIT_REACHED = const_cpu_to_le32(0x00000002),
@ -2189,7 +2305,11 @@ typedef enum {
QUOTA_FLAG_OUT_OF_DATE = const_cpu_to_le32(0x00000200),
QUOTA_FLAG_CORRUPT = const_cpu_to_le32(0x00000400),
QUOTA_FLAG_PENDING_DELETES = const_cpu_to_le32(0x00000800),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} QUOTA_FLAGS;
#else
__QUOTA_FLAGS_end;
#endif
/**
* struct QUOTA_CONTROL_ENTRY -
@ -2246,16 +2366,32 @@ typedef struct {
/**
* enum PREDEFINED_OWNER_IDS - Predefined owner_id values (32-bit).
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 PREDEFINED_OWNER_IDS;
static const PREDEFINED_OWNER_IDS
#else
typedef enum {
#endif
QUOTA_INVALID_ID = const_cpu_to_le32(0x00000000),
QUOTA_DEFAULTS_ID = const_cpu_to_le32(0x00000001),
QUOTA_FIRST_USER_ID = const_cpu_to_le32(0x00000100),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} PREDEFINED_OWNER_IDS;
#else
__PREDEFINED_OWNER_IDS_end;
#endif
/**
* enum INDEX_ENTRY_FLAGS - Index entry flags (16-bit).
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le16 INDEX_ENTRY_FLAGS;
static const INDEX_ENTRY_FLAGS
#else
typedef enum {
#endif
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
@ -2264,8 +2400,12 @@ typedef enum {
entry in an index block. The index
entry does not represent a file but it
can point to a sub-node. */
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
INDEX_ENTRY_SPACE_FILLER = 0xffff, /* Just to force 16-bit width. */
} __attribute__((__packed__)) INDEX_ENTRY_FLAGS;
#else
__INDEX_ENTRY_FLAGS_end;
#endif
/**
* struct INDEX_ENTRY_HEADER - This the index entry header (see below).
@ -2391,7 +2531,13 @@ typedef struct {
* bit 31: Microsoft bit. If set, the tag is owned by Microsoft. User
* defined tags have to use zero here.
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 PREDEFINED_REPARSE_TAGS;
static const PREDEFINED_REPARSE_TAGS
#else
typedef enum {
#endif
IO_REPARSE_TAG_IS_ALIAS = const_cpu_to_le32(0x20000000),
IO_REPARSE_TAG_IS_HIGH_LATENCY = const_cpu_to_le32(0x40000000),
IO_REPARSE_TAG_IS_MICROSOFT = const_cpu_to_le32(0x80000000),
@ -2413,7 +2559,11 @@ typedef enum {
IO_REPARSE_TAG_WIM = const_cpu_to_le32(0x80000008),
IO_REPARSE_TAG_VALID_VALUES = const_cpu_to_le32(0xf000ffff),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} PREDEFINED_REPARSE_TAGS;
#else
__PREDEFINED_REPARSE_TAGS_end;
#endif
/**
* struct REPARSE_POINT - Attribute: Reparse point (0xc0).
@ -2639,14 +2789,24 @@ typedef struct {
typedef EFS_DF_CERTIFICATE_THUMBPRINT_HEADER EFS_DF_CERT_THUMBPRINT_HEADER;
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le64 INTX_FILE_TYPES;
static const INTX_FILE_TYPES
#else
typedef enum {
#endif
INTX_SYMBOLIC_LINK =
const_cpu_to_le64(0x014B4E4C78746E49ULL), /* "IntxLNK\1" */
INTX_CHARACTER_DEVICE =
const_cpu_to_le64(0x0052484378746E49ULL), /* "IntxCHR\0" */
INTX_BLOCK_DEVICE =
const_cpu_to_le64(0x004B4C4278746E49ULL), /* "IntxBLK\0" */
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} INTX_FILE_TYPES;
#else
__INTX_FILE_TYPES_end;
#endif
typedef struct {
INTX_FILE_TYPES magic; /* Intx file magic. */

View File

@ -108,10 +108,18 @@ typedef struct {
* These are the so far known RESTART_AREA_* flags (16-bit) which contain
* information about the log file in which they are present.
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
static const le16
#else
enum {
#endif
RESTART_VOLUME_IS_CLEAN = const_cpu_to_le16(0x0002),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
RESTART_SPACE_FILLER = 0xffff, /* gcc: Force enum bit width to 16. */
} __attribute__((__packed__));
#else
__RESTART_AREA_FLAGS_end;
#endif
typedef le16 RESTART_AREA_FLAGS;
@ -335,12 +343,22 @@ typedef struct {
*
* (Or is it log record pages?)
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le16 LOG_RECORD_FLAGS;
static const LOG_RECORD_FLAGS
#else
typedef enum {
#endif
LOG_RECORD_MULTI_PAGE = const_cpu_to_le16(0x0001), /* ??? */
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
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;
#else
__LOG_RECORD_FLAGS_end;
#endif
/**
* struct LOG_CLIENT_ID - The log client id structure identifying a log client.

View File

@ -27,6 +27,10 @@
#include "config.h"
#endif
#if !defined(ENABLE_STRICT_ENDIANNESS_CHECKING)
#define ENABLE_STRICT_ENDIANNESS_CHECKING 1
#endif /* !defined(ENABLE_STRICT_ENDIANNESS_CHECKING) */
#if HAVE_STDINT_H || !HAVE_CONFIG_H
#include <stdint.h>
#endif
@ -44,6 +48,7 @@ typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
typedef u16 le16;
typedef u32 le32;
typedef u64 le64;
@ -63,6 +68,71 @@ typedef u64 sle64;
typedef u16 sbe16;
typedef u32 sbe32;
typedef u64 sbe64;
#else
typedef union {
u8 data[2];
u16 value;
} le16;
typedef union {
u8 data[4];
u32 value;
} le32;
typedef union {
u8 data[8];
u64 value;
} le64;
typedef union {
u8 data[2];
u16 value;
} be16;
typedef union {
u8 data[4];
u32 value;
} be32;
typedef union {
u8 data[8];
u64 value;
} be64;
/*
* Declare s{l,b}e{16,32,64} to be unsigned because we do not want sign
* extension on BE architectures.
*/
typedef union {
u8 data[2];
u16 value;
} sle16;
typedef union {
u8 data[4];
u32 value;
} sle32;
typedef union {
u8 data[8];
u64 value;
} sle64;
typedef union {
u8 data[2];
u16 value;
} sbe16;
typedef union {
u8 data[4];
u32 value;
} sbe32;
typedef union {
u8 data[8];
u64 value;
} sbe64;
#endif /* !ENABLE_STRICT_ENDIANNESS_CHECKING ... */
typedef le16 ntfschar; /* 2-byte Unicode character type. */
#define UCHAR_T_SIZE_BITS 1

View File

@ -96,13 +96,23 @@ typedef enum {
* this registry key. It would be interesting to check out encryption on one
* of the "crippled" crypto Windows versions...
*/
#if ENABLE_STRICT_ENDIANNESS_CHECKING
typedef le32 NTFS_CRYPTO_ALGORITHMS;
static const le32
#else
typedef enum {
#endif
CALG_DES = const_cpu_to_le32(0x6601),
/* If not one of the below three, fall back to standard Des. */
CALG_3DES = const_cpu_to_le32(0x6603),
CALG_DESX = const_cpu_to_le32(0x6604),
CALG_AES_256 = const_cpu_to_le32(0x6610),
#if !ENABLE_STRICT_ENDIANNESS_CHECKING
} NTFS_CRYPTO_ALGORITHMS;
#else
__NTFS_CRYPTO_ALGORITHMS_end;
#endif
typedef struct {
u64 in_whitening, out_whitening;