implement logging in libntfs
fix whitespace fix build problems tidy source code and more...edge.strict_endians
parent
8c53ea8d4f
commit
f4e427e91a
|
@ -33,6 +33,7 @@ typedef struct _ntfs_attr_search_ctx ntfs_attr_search_ctx;
|
|||
#include "runlist.h"
|
||||
#include "volume.h"
|
||||
#include "debug.h"
|
||||
#include "logging.h"
|
||||
|
||||
extern ntfschar AT_UNNAMED[];
|
||||
|
||||
|
@ -135,7 +136,7 @@ static __inline__ int ntfs_attrs_walk(ntfs_attr_search_ctx *ctx)
|
|||
* @allocated_size: copy from the attribute record
|
||||
* @data_size: copy from the attribute record
|
||||
* @initialized_size: copy from the attribute record
|
||||
* @compressed_size: copy from the attribute record
|
||||
* @compressed_size: copy from the attribute record
|
||||
* @compression_block_size: size of a compression block (cb)
|
||||
* @compression_block_size_bits: log2 of the size of a cb
|
||||
* @compression_block_clusters: number of clusters per cb
|
||||
|
@ -214,9 +215,8 @@ static inline void NAttrSet##flag(ntfs_attr *na) \
|
|||
if (na->type == AT_DATA && na->name == AT_UNNAMED) \
|
||||
NInoSet##flag(na->ni); \
|
||||
else \
|
||||
Dprintf("%s(): BUG! Should be called only for " \
|
||||
"unnamed data attribute.\n", \
|
||||
__FUNCTION__); \
|
||||
ntfs_log_trace("BUG! Should be called only for "\
|
||||
"unnamed data attribute.\n"); \
|
||||
} \
|
||||
static inline void NAttrClear##flag(ntfs_attr *na) \
|
||||
{ \
|
||||
|
|
|
@ -150,15 +150,15 @@ struct ntfs_bmp {
|
|||
};
|
||||
|
||||
|
||||
int ntfs_bmp_rollback (struct ntfs_bmp *bmp);
|
||||
int ntfs_bmp_commit (struct ntfs_bmp *bmp);
|
||||
void ntfs_bmp_free (struct ntfs_bmp *bmp);
|
||||
struct ntfs_bmp * ntfs_bmp_create (ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len);
|
||||
int ntfs_bmp_add_data (struct ntfs_bmp *bmp, VCN vcn, u8 *data);
|
||||
u8 * ntfs_bmp_get_data (struct ntfs_bmp *bmp, VCN vcn);
|
||||
int ntfs_bmp_set_range (struct ntfs_bmp *bmp, VCN vcn, s64 length, int value);
|
||||
s64 ntfs_bmp_find_last_set (struct ntfs_bmp *bmp);
|
||||
int ntfs_bmp_find_space (struct ntfs_bmp *bmp, LCN start, long size);
|
||||
int ntfs_bmp_rollback(struct ntfs_bmp *bmp);
|
||||
int ntfs_bmp_commit(struct ntfs_bmp *bmp);
|
||||
void ntfs_bmp_free(struct ntfs_bmp *bmp);
|
||||
struct ntfs_bmp * ntfs_bmp_create(ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len);
|
||||
int ntfs_bmp_add_data(struct ntfs_bmp *bmp, VCN vcn, u8 *data);
|
||||
u8 * ntfs_bmp_get_data(struct ntfs_bmp *bmp, VCN vcn);
|
||||
int ntfs_bmp_set_range(struct ntfs_bmp *bmp, VCN vcn, s64 length, int value);
|
||||
s64 ntfs_bmp_find_last_set(struct ntfs_bmp *bmp);
|
||||
int ntfs_bmp_find_space(struct ntfs_bmp *bmp, LCN start, long size);
|
||||
|
||||
#endif /* NTFS_RICH */
|
||||
|
||||
|
|
|
@ -25,26 +25,31 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
# include <stdio.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDARG_H
|
||||
# include <stdarg.h>
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
struct _runlist_element;
|
||||
|
||||
extern void __Sprintf(const int silent, const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
#define Sprintf(silent, f, a...) __Sprintf(silent, f, ##a)
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/* Debug output to stderr. To get it run ./configure --enable-debug. */
|
||||
|
||||
extern void __ntfs_debug (const char *file, int line, const char *function,
|
||||
extern void __ntfs_debug(const char *file, int line, const char *function,
|
||||
const char *format, ...) __attribute__((format(printf, 4, 5)));
|
||||
#define ntfs_debug(f, a...) \
|
||||
__ntfs_debug(__FILE__, __LINE__, __FUNCTION__, f, ##a)
|
||||
|
@ -54,7 +59,7 @@ extern void __ntfs_error(const char *function,
|
|||
#define ntfs_error(sb, f, a...) __ntfs_error(__FUNCTION__, f, ##a)
|
||||
|
||||
extern void __Dprintf(const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
__attribute__((format(printf, 1, 2)));
|
||||
#define Dprintf(f, a...) __Dprintf(f, ##a)
|
||||
|
||||
extern void __Dputs(const char *s);
|
||||
|
@ -63,8 +68,6 @@ extern void __Dputs(const char *s);
|
|||
extern void __Dperror(const char *s);
|
||||
#define Dperror(s) __Dperror(s)
|
||||
|
||||
extern void ntfs_debug_runlist_dump(const struct _runlist_element *rl);
|
||||
|
||||
#else /* if !DEBUG */
|
||||
|
||||
#define ntfs_debug(f, a...) do {} while (0)
|
||||
|
@ -74,10 +77,14 @@ extern void ntfs_debug_runlist_dump(const struct _runlist_element *rl);
|
|||
#define Dputs(s) do {} while (0)
|
||||
#define Dperror(s) do {} while (0)
|
||||
|
||||
static __inline__ void ntfs_debug_runlist_dump(const struct _runlist_element *rl __attribute__((unused))) {}
|
||||
|
||||
#endif /* !DEBUG */
|
||||
|
||||
#ifdef NTFS_DISABLE_DEBUG_LOGGING
|
||||
static __inline__ void ntfs_debug_runlist_dump(const struct _runlist_element *rl __attribute__((unused))) {}
|
||||
#else
|
||||
extern void ntfs_debug_runlist_dump(const struct _runlist_element *rl);
|
||||
#endif
|
||||
|
||||
#define NTFS_BUG(msg) \
|
||||
{ \
|
||||
int ___i; \
|
||||
|
|
|
@ -102,13 +102,13 @@ struct ntfs_dir {
|
|||
};
|
||||
|
||||
|
||||
int ntfs_dir_rollback (struct ntfs_dir *dir);
|
||||
int ntfs_dir_truncate (ntfs_volume *vol, struct ntfs_dir *dir);
|
||||
int ntfs_dir_commit (struct ntfs_dir *dir);
|
||||
void ntfs_dir_free (struct ntfs_dir *dir);
|
||||
struct ntfs_dir * ntfs_dir_create (ntfs_volume *vol, MFT_REF mft_num);
|
||||
void ntfs_dir_add (struct ntfs_dir *parent, struct ntfs_dir *child);
|
||||
struct ntfs_dir * ntfs_dir_find2 (struct ntfs_dir *dir, ntfschar *name, int name_len);
|
||||
int ntfs_dir_rollback(struct ntfs_dir *dir);
|
||||
int ntfs_dir_truncate(ntfs_volume *vol, struct ntfs_dir *dir);
|
||||
int ntfs_dir_commit(struct ntfs_dir *dir);
|
||||
void ntfs_dir_free(struct ntfs_dir *dir);
|
||||
struct ntfs_dir * ntfs_dir_create(ntfs_volume *vol, MFT_REF mft_num);
|
||||
void ntfs_dir_add(struct ntfs_dir *parent, struct ntfs_dir *child);
|
||||
struct ntfs_dir * ntfs_dir_find2(struct ntfs_dir *dir, ntfschar *name, int name_len);
|
||||
|
||||
#endif /* NTFS_RICH */
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
/*
|
||||
* Notes:
|
||||
*
|
||||
* We define the conversion functions including typecasts since the
|
||||
* defaults don't necessarily perform appropriate typecasts.
|
||||
* Also, using our own functions means that we can change them if it
|
||||
|
@ -38,20 +37,21 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#include <endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_MACHINE_ENDIAN_H
|
||||
# include <machine/endian.h>
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_BYTEORDER_H
|
||||
# include <sys/byteorder.h>
|
||||
#include <sys/byteorder.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifndef __BYTE_ORDER
|
||||
# if defined(_BYTE_ORDER)
|
||||
# define __BYTE_ORDER _BYTE_ORDER
|
||||
|
|
|
@ -127,14 +127,14 @@ static inline void ntfs_index_entry_mark_dirty(ntfs_index_context *ictx)
|
|||
|
||||
#include "layout.h"
|
||||
|
||||
void ntfs_ie_free (INDEX_ENTRY *ie);
|
||||
INDEX_ENTRY * ntfs_ie_create (void);
|
||||
VCN ntfs_ie_get_vcn (INDEX_ENTRY *ie);
|
||||
INDEX_ENTRY * ntfs_ie_copy (INDEX_ENTRY *ie);
|
||||
INDEX_ENTRY * ntfs_ie_set_vcn (INDEX_ENTRY *ie, VCN vcn);
|
||||
INDEX_ENTRY * ntfs_ie_remove_vcn (INDEX_ENTRY *ie);
|
||||
INDEX_ENTRY * ntfs_ie_set_name (INDEX_ENTRY *ie, ntfschar *name, int namelen, FILE_NAME_TYPE_FLAGS nametype);
|
||||
INDEX_ENTRY * ntfs_ie_remove_name (INDEX_ENTRY *ie);
|
||||
void ntfs_ie_free(INDEX_ENTRY *ie);
|
||||
INDEX_ENTRY * ntfs_ie_create(void);
|
||||
VCN ntfs_ie_get_vcn(INDEX_ENTRY *ie);
|
||||
INDEX_ENTRY * ntfs_ie_copy(INDEX_ENTRY *ie);
|
||||
INDEX_ENTRY * ntfs_ie_set_vcn(INDEX_ENTRY *ie, VCN vcn);
|
||||
INDEX_ENTRY * ntfs_ie_remove_vcn(INDEX_ENTRY *ie);
|
||||
INDEX_ENTRY * ntfs_ie_set_name(INDEX_ENTRY *ie, ntfschar *name, int namelen, FILE_NAME_TYPE_FLAGS nametype);
|
||||
INDEX_ENTRY * ntfs_ie_remove_name(INDEX_ENTRY *ie);
|
||||
|
||||
#endif /* NTFS_RICH */
|
||||
|
||||
|
|
|
@ -187,9 +187,9 @@ extern int ntfs_inode_free_space(ntfs_inode *ni, int size);
|
|||
|
||||
#ifdef NTFS_RICH
|
||||
|
||||
int ntfs_inode_close2 (ntfs_inode *ni);
|
||||
ntfs_inode * ntfs_inode_open2 (ntfs_volume *vol, const MFT_REF mref);
|
||||
ntfs_inode * ntfs_inode_open3 (ntfs_volume *vol, const MFT_REF mref);
|
||||
int ntfs_inode_close2(ntfs_inode *ni);
|
||||
ntfs_inode * ntfs_inode_open2(ntfs_volume *vol, const MFT_REF mref);
|
||||
ntfs_inode * ntfs_inode_open3(ntfs_volume *vol, const MFT_REF mref);
|
||||
|
||||
#endif /* NTFS_RICH */
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ typedef struct {
|
|||
Required to boot Windows. */
|
||||
/*0x15*/u32 large_sectors; /* zero */
|
||||
/* sizeof() = 25 (0x19) bytes */
|
||||
} __attribute__ ((__packed__)) BIOS_PARAMETER_BLOCK;
|
||||
} __attribute__((__packed__)) BIOS_PARAMETER_BLOCK;
|
||||
|
||||
/*
|
||||
* NTFS boot sector structure.
|
||||
|
@ -95,7 +95,7 @@ typedef struct {
|
|||
u16 end_of_sector_marker; /* End of bootsector magic. Always is
|
||||
0xaa55 in little endian. */
|
||||
/* sizeof() = 512 (0x200) bytes */
|
||||
} __attribute__ ((__packed__)) NTFS_BOOT_SECTOR;
|
||||
} __attribute__((__packed__)) NTFS_BOOT_SECTOR;
|
||||
|
||||
/*
|
||||
* Magic identifiers present at the beginning of all ntfs record containing
|
||||
|
@ -190,7 +190,7 @@ typedef struct {
|
|||
including the Update Sequence Number (usn),
|
||||
thus the number of fixups is the usa_count
|
||||
minus 1. */
|
||||
} __attribute__ ((__packed__)) NTFS_RECORD;
|
||||
} __attribute__((__packed__)) NTFS_RECORD;
|
||||
|
||||
/*
|
||||
* System files mft record numbers. All these files are always marked as used
|
||||
|
@ -241,7 +241,7 @@ typedef enum {
|
|||
/*
|
||||
* These are the so far known MFT_RECORD_* flags (16-bit) which contain
|
||||
* information about the mft record in which they are present.
|
||||
* _4 and _8 are needed by $Extend sub-files (don't know what to
|
||||
* _4 and _8 are needed by $Extend sub-files (don't know what to
|
||||
* call them yet...)
|
||||
*/
|
||||
|
||||
|
@ -251,7 +251,7 @@ typedef enum {
|
|||
MFT_RECORD_IS_4 = const_cpu_to_le16(0x0004),
|
||||
MFT_RECORD_IS_8 = const_cpu_to_le16(0x0008),
|
||||
MFT_REC_SPACE_FILLER = 0xffff /* Just to make flags 16-bit. */
|
||||
} __attribute__ ((__packed__)) MFT_RECORD_FLAGS;
|
||||
} __attribute__((__packed__)) MFT_RECORD_FLAGS;
|
||||
|
||||
/*
|
||||
* mft references (aka file references or file record segment references) are
|
||||
|
@ -390,7 +390,7 @@ typedef struct {
|
|||
* by overwriting it since you then can't get it back...
|
||||
* When reading we obviously use the data from the ntfs record header.
|
||||
*/
|
||||
} __attribute__ ((__packed__)) MFT_RECORD;
|
||||
} __attribute__((__packed__)) MFT_RECORD;
|
||||
|
||||
/* This is the version without the NTFS 3.1+ specific fields. */
|
||||
typedef struct {
|
||||
|
@ -457,7 +457,7 @@ typedef struct {
|
|||
* by overwriting it since you then can't get it back...
|
||||
* When reading we obviously use the data from the ntfs record header.
|
||||
*/
|
||||
} __attribute__ ((__packed__)) MFT_RECORD_OLD;
|
||||
} __attribute__((__packed__)) MFT_RECORD_OLD;
|
||||
|
||||
/*
|
||||
* System defined attributes (32-bit). Each attribute type has a corresponding
|
||||
|
@ -599,7 +599,7 @@ typedef struct {
|
|||
/* 90*/ s64 min_size; /* Optional minimum attribute size. */
|
||||
/* 98*/ s64 max_size; /* Maximum size of attribute. */
|
||||
/* sizeof() = 0xa0 or 160 bytes */
|
||||
} __attribute__ ((__packed__)) ATTR_DEF;
|
||||
} __attribute__((__packed__)) ATTR_DEF;
|
||||
|
||||
/*
|
||||
* Attribute flags (16-bit).
|
||||
|
@ -611,7 +611,7 @@ typedef enum {
|
|||
illegal value. */
|
||||
ATTR_IS_ENCRYPTED = const_cpu_to_le16(0x4000),
|
||||
ATTR_IS_SPARSE = const_cpu_to_le16(0x8000),
|
||||
} __attribute__ ((__packed__)) ATTR_FLAGS;
|
||||
} __attribute__((__packed__)) ATTR_FLAGS;
|
||||
|
||||
/*
|
||||
* Attribute compression.
|
||||
|
@ -687,7 +687,7 @@ typedef enum {
|
|||
RESIDENT_ATTR_IS_INDEXED = 0x01, /* Attribute is referenced in an index
|
||||
(has implications for deleting and
|
||||
modifying the attribute). */
|
||||
} __attribute__ ((__packed__)) RESIDENT_ATTR_FLAGS;
|
||||
} __attribute__((__packed__)) RESIDENT_ATTR_FLAGS;
|
||||
|
||||
/*
|
||||
* Attribute record header. Always aligned to 8-byte boundary.
|
||||
|
@ -733,7 +733,7 @@ typedef struct {
|
|||
/* 24 */ void *resident_end[0]; /* Use offsetof(ATTR_RECORD,
|
||||
resident_end) to get size of
|
||||
a resident attribute. */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
/* Non-resident attributes. */
|
||||
struct {
|
||||
/* 16*/ VCN lowest_vcn; /* Lowest valid virtual cluster number
|
||||
|
@ -790,9 +790,9 @@ typedef struct {
|
|||
/* Use offsetof(ATTR_RECORD, compressed_end) to
|
||||
get size of a compressed attribute. */
|
||||
/* sizeof(compressed attr) = 72*/
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__ ((__packed__)) ATTR_RECORD;
|
||||
} __attribute__((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
} __attribute__((__packed__)) ATTR_RECORD;
|
||||
|
||||
typedef ATTR_RECORD ATTR_REC;
|
||||
|
||||
|
@ -848,7 +848,7 @@ typedef enum {
|
|||
us whether this file has a view index present (eg. object id index,
|
||||
quota index, one of the security indexes or the encrypting file
|
||||
system related indexes). */
|
||||
} __attribute__ ((__packed__)) FILE_ATTR_FLAGS;
|
||||
} __attribute__((__packed__)) FILE_ATTR_FLAGS;
|
||||
|
||||
/*
|
||||
* NOTE on times in NTFS: All times are in MS standard time format, i.e. they
|
||||
|
@ -890,7 +890,7 @@ typedef struct {
|
|||
/* 36 */ u8 reserved12[12]; /* Reserved/alignment to 8-byte
|
||||
boundary. */
|
||||
/* 48 */ void *v1_end[0]; /* Marker for offsetof(). */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
/* sizeof() = 48 bytes */
|
||||
/* NTFS 3.0 */
|
||||
struct {
|
||||
|
@ -944,10 +944,10 @@ typedef struct {
|
|||
journal is a very fast process, so the user
|
||||
won't even notice it. */
|
||||
/* 72*/ void *v3_end[0]; /* Marker for offsetof(). */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
/* sizeof() = 72 bytes (NTFS 3.0) */
|
||||
} __attribute__ ((__packed__)) STANDARD_INFORMATION;
|
||||
} __attribute__((__packed__)) STANDARD_INFORMATION;
|
||||
|
||||
/*
|
||||
* Attribute: Attribute list (0x20).
|
||||
|
@ -1008,7 +1008,7 @@ typedef struct {
|
|||
name_offset to determine the location of the
|
||||
name. */
|
||||
/* sizeof() = 26 + (attribute_name_length * 2) bytes */
|
||||
} __attribute__ ((__packed__)) ATTR_LIST_ENTRY;
|
||||
} __attribute__((__packed__)) ATTR_LIST_ENTRY;
|
||||
|
||||
/*
|
||||
* The maximum allowed length for a file name.
|
||||
|
@ -1039,7 +1039,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;
|
||||
} __attribute__((__packed__)) FILE_NAME_TYPE_FLAGS;
|
||||
|
||||
/*
|
||||
* Attribute: Filename (0x30).
|
||||
|
@ -1077,17 +1077,17 @@ typedef struct {
|
|||
pack the extended attributes
|
||||
(EAs), if such are present.*/
|
||||
/* 3e*/ u16 reserved; /* Reserved for alignment. */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
/* 3c*/ u32 reparse_point_tag; /* Type of reparse point,
|
||||
present only in reparse
|
||||
points and only if there are
|
||||
no EAs. */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
/* 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. */
|
||||
} __attribute__ ((__packed__)) FILE_NAME_ATTR;
|
||||
} __attribute__((__packed__)) FILE_NAME_ATTR;
|
||||
|
||||
/*
|
||||
* GUID structures store globally unique identifiers (GUID). A GUID is a
|
||||
|
@ -1105,7 +1105,7 @@ typedef struct {
|
|||
u8 data4[8]; /* The first two bytes are the third group of four
|
||||
hexadecimal digits. The remaining six bytes are the
|
||||
final 12 hexadecimal digits. */
|
||||
} __attribute__ ((__packed__)) GUID;
|
||||
} __attribute__((__packed__)) GUID;
|
||||
|
||||
/*
|
||||
* FILE_Extend/$ObjId contains an index named $O. This index contains all
|
||||
|
@ -1126,10 +1126,10 @@ typedef struct {
|
|||
GUID birth_volume_id;
|
||||
GUID birth_object_id;
|
||||
GUID domain_id;
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
u8 extended_info[48];
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__ ((__packed__)) OBJ_ID_INDEX_DATA;
|
||||
} __attribute__((__packed__));
|
||||
} __attribute__((__packed__)) OBJ_ID_INDEX_DATA;
|
||||
|
||||
/*
|
||||
* Attribute: Object id (NTFS 3.0+) (0x40).
|
||||
|
@ -1153,10 +1153,10 @@ typedef struct {
|
|||
GUID birth_object_id; /* Unique id of file when it was
|
||||
first created. */
|
||||
GUID domain_id; /* Reserved, zero. */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
u8 extended_info[48];
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__ ((__packed__)) OBJECT_ID_ATTR;
|
||||
} __attribute__((__packed__));
|
||||
} __attribute__((__packed__)) OBJECT_ID_ATTR;
|
||||
|
||||
/*
|
||||
* The pre-defined IDENTIFIER_AUTHORITIES used as SID_IDENTIFIER_AUTHORITY in
|
||||
|
@ -1297,9 +1297,9 @@ typedef union {
|
|||
struct {
|
||||
u16 high_part; /* High 16-bits. */
|
||||
u32 low_part; /* Low 32-bits. */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
u8 value[6]; /* Value as individual bytes. */
|
||||
} __attribute__ ((__packed__)) SID_IDENTIFIER_AUTHORITY;
|
||||
} __attribute__((__packed__)) SID_IDENTIFIER_AUTHORITY;
|
||||
|
||||
/*
|
||||
* The SID structure is a variable-length structure used to uniquely identify
|
||||
|
@ -1332,7 +1332,7 @@ typedef struct {
|
|||
u8 sub_authority_count;
|
||||
SID_IDENTIFIER_AUTHORITY identifier_authority;
|
||||
u32 sub_authority[1]; /* At least one sub_authority. */
|
||||
} __attribute__ ((__packed__)) SID;
|
||||
} __attribute__((__packed__)) SID;
|
||||
|
||||
/*
|
||||
* Current constants for SIDs.
|
||||
|
@ -1370,7 +1370,7 @@ typedef enum {
|
|||
|
||||
/* This one is for WinNT&2k. */
|
||||
ACCESS_MAX_MS_ACE_TYPE = 8,
|
||||
} __attribute__ ((__packed__)) ACE_TYPES;
|
||||
} __attribute__((__packed__)) ACE_TYPES;
|
||||
|
||||
/*
|
||||
* The ACE flags (8-bit) for audit and inheritance (see below).
|
||||
|
@ -1394,7 +1394,7 @@ typedef enum {
|
|||
/* The audit flags. */
|
||||
SUCCESSFUL_ACCESS_ACE_FLAG = 0x40,
|
||||
FAILED_ACCESS_ACE_FLAG = 0x80,
|
||||
} __attribute__ ((__packed__)) ACE_FLAGS;
|
||||
} __attribute__((__packed__)) ACE_FLAGS;
|
||||
|
||||
/*
|
||||
* An ACE is an access-control entry in an access-control list (ACL).
|
||||
|
@ -1411,7 +1411,7 @@ typedef struct {
|
|||
ACE_TYPES type; /* Type of the ACE. */
|
||||
ACE_FLAGS flags; /* Flags describing the ACE. */
|
||||
u16 size; /* Size in bytes of the ACE. */
|
||||
} __attribute__ ((__packed__)) ACE_HEADER;
|
||||
} __attribute__((__packed__)) ACE_HEADER;
|
||||
|
||||
/*
|
||||
* The access mask (32-bit). Defines the access rights.
|
||||
|
@ -1557,7 +1557,7 @@ typedef struct {
|
|||
ACCESS_MASK generic_write;
|
||||
ACCESS_MASK generic_execute;
|
||||
ACCESS_MASK generic_all;
|
||||
} __attribute__ ((__packed__)) GENERIC_MAPPING;
|
||||
} __attribute__((__packed__)) GENERIC_MAPPING;
|
||||
|
||||
/*
|
||||
* The predefined ACE type structures are as defined below.
|
||||
|
@ -1574,7 +1574,7 @@ typedef struct {
|
|||
|
||||
/* 4*/ ACCESS_MASK mask; /* Access mask associated with the ACE. */
|
||||
/* 8*/ SID sid; /* The SID associated with the ACE. */
|
||||
} __attribute__ ((__packed__)) ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE,
|
||||
} __attribute__((__packed__)) ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE,
|
||||
SYSTEM_AUDIT_ACE, SYSTEM_ALARM_ACE;
|
||||
|
||||
/*
|
||||
|
@ -1596,7 +1596,7 @@ typedef struct {
|
|||
/* 12*/ GUID object_type;
|
||||
/* 28*/ GUID inherited_object_type;
|
||||
/* 44*/ SID sid; /* The SID associated with the ACE. */
|
||||
} __attribute__ ((__packed__)) ACCESS_ALLOWED_OBJECT_ACE,
|
||||
} __attribute__((__packed__)) ACCESS_ALLOWED_OBJECT_ACE,
|
||||
ACCESS_DENIED_OBJECT_ACE,
|
||||
SYSTEM_AUDIT_OBJECT_ACE,
|
||||
SYSTEM_ALARM_OBJECT_ACE;
|
||||
|
@ -1616,7 +1616,7 @@ typedef struct {
|
|||
u16 ace_count; /* Number of ACEs in the ACL. */
|
||||
u16 alignment2;
|
||||
/* sizeof() = 8 bytes */
|
||||
} __attribute__ ((__packed__)) ACL;
|
||||
} __attribute__((__packed__)) ACL;
|
||||
|
||||
/*
|
||||
* Current constants for ACLs.
|
||||
|
@ -1697,7 +1697,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;
|
||||
} __attribute__((__packed__)) SECURITY_DESCRIPTOR_CONTROL;
|
||||
|
||||
/*
|
||||
* Self-relative security descriptor. Contains the owner and group SIDs as well
|
||||
|
@ -1723,7 +1723,7 @@ typedef struct {
|
|||
SE_DACL_PRESENT is set but dacl is NULL, a NULL ACL
|
||||
(unconditionally granting access) is specified. */
|
||||
/* sizeof() = 0x14 bytes */
|
||||
} __attribute__ ((__packed__)) SECURITY_DESCRIPTOR_RELATIVE;
|
||||
} __attribute__((__packed__)) SECURITY_DESCRIPTOR_RELATIVE;
|
||||
|
||||
/*
|
||||
* Absolute security descriptor. Does not contain the owner and group SIDs, nor
|
||||
|
@ -1751,7 +1751,7 @@ typedef struct {
|
|||
SE_DACL_PRESENT is set in the control field. If
|
||||
SE_DACL_PRESENT is set but dacl is NULL, a NULL ACL
|
||||
(unconditionally granting access) is specified. */
|
||||
} __attribute__ ((__packed__)) SECURITY_DESCRIPTOR;
|
||||
} __attribute__((__packed__)) SECURITY_DESCRIPTOR;
|
||||
|
||||
/*
|
||||
* Current constants for security descriptors.
|
||||
|
@ -1825,16 +1825,16 @@ typedef struct {
|
|||
u32 security_id; /* The security_id assigned to the descriptor. */
|
||||
u64 offset; /* Byte offset of this entry in the $SDS stream. */
|
||||
u32 length; /* Size in bytes of this entry in $SDS stream. */
|
||||
} __attribute__ ((__packed__)) SECURITY_DESCRIPTOR_HEADER;
|
||||
} __attribute__((__packed__)) SECURITY_DESCRIPTOR_HEADER;
|
||||
|
||||
typedef struct {
|
||||
u32 hash; /* Hash of the security descriptor. */
|
||||
u32 security_id; /* The security_id assigned to the descriptor. */
|
||||
u32 security_id; /* The security_id assigned to the descriptor. */
|
||||
u64 offset_in_sds; /* Offset of the descriptor in SDS data stream */
|
||||
u32 size_in_sds; /* Size of the descriptor in SDS data stream */
|
||||
u64 reserved_II; /* Padding - always unicode "II" */
|
||||
} __attribute__ ((__packed__)) SDH_INDEX_DATA;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32 hash; /* Hash of the security descriptor. */
|
||||
u32 security_id; /* The security_id assigned to the descriptor. */
|
||||
|
@ -1843,7 +1843,7 @@ typedef struct {
|
|||
} __attribute__ ((__packed__)) SII_INDEX_DATA;
|
||||
|
||||
typedef struct {
|
||||
u64 owner_id;
|
||||
u64 owner_id;
|
||||
} __attribute__ ((__packed__)) QUOTA_O_INDEX_DATA;
|
||||
|
||||
/*
|
||||
|
@ -1866,7 +1866,7 @@ typedef struct {
|
|||
u32 length; /* Size in bytes of this entry in $SDS stream. */
|
||||
/* 20*/ SECURITY_DESCRIPTOR_RELATIVE sid; /* The self-relative security
|
||||
descriptor. */
|
||||
} __attribute__ ((__packed__)) SDS_ENTRY;
|
||||
} __attribute__((__packed__)) SDS_ENTRY;
|
||||
|
||||
/*
|
||||
* The index entry key used in the $SII index. The collation type is
|
||||
|
@ -1874,7 +1874,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
u32 security_id; /* The security_id assigned to the descriptor. */
|
||||
} __attribute__ ((__packed__)) SII_INDEX_KEY;
|
||||
} __attribute__((__packed__)) SII_INDEX_KEY;
|
||||
|
||||
/*
|
||||
* The index entry key used in the $SDH index. The keys are sorted first by
|
||||
|
@ -1884,7 +1884,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
u32 hash; /* Hash of the security descriptor. */
|
||||
u32 security_id; /* The security_id assigned to the descriptor. */
|
||||
} __attribute__ ((__packed__)) SDH_INDEX_KEY;
|
||||
} __attribute__((__packed__)) SDH_INDEX_KEY;
|
||||
|
||||
/*
|
||||
* Attribute: Volume name (0x60).
|
||||
|
@ -1894,7 +1894,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
ntfschar name[0]; /* The name of the volume in Unicode. */
|
||||
} __attribute__ ((__packed__)) VOLUME_NAME;
|
||||
} __attribute__((__packed__)) VOLUME_NAME;
|
||||
|
||||
/*
|
||||
* Possible flags for the volume (16-bit).
|
||||
|
@ -1908,7 +1908,7 @@ typedef enum {
|
|||
VOLUME_REPAIR_OBJECT_ID = const_cpu_to_le16(0x0020),
|
||||
VOLUME_MODIFIED_BY_CHKDSK = const_cpu_to_le16(0x8000),
|
||||
VOLUME_FLAGS_MASK = const_cpu_to_le16(0x803f),
|
||||
} __attribute__ ((__packed__)) VOLUME_FLAGS;
|
||||
} __attribute__((__packed__)) VOLUME_FLAGS;
|
||||
|
||||
/*
|
||||
* Attribute: Volume information (0x70).
|
||||
|
@ -1923,7 +1923,7 @@ typedef struct {
|
|||
u8 major_ver; /* Major version of the ntfs format. */
|
||||
u8 minor_ver; /* Minor version of the ntfs format. */
|
||||
VOLUME_FLAGS flags; /* Bit array of VOLUME_* flags. */
|
||||
} __attribute__ ((__packed__)) VOLUME_INFORMATION;
|
||||
} __attribute__((__packed__)) VOLUME_INFORMATION;
|
||||
|
||||
/*
|
||||
* Attribute: Data attribute (0x80).
|
||||
|
@ -1934,7 +1934,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
u8 data[0]; /* The file's data contents. */
|
||||
} __attribute__ ((__packed__)) DATA_ATTR;
|
||||
} __attribute__((__packed__)) DATA_ATTR;
|
||||
|
||||
/*
|
||||
* Index header flags (8-bit).
|
||||
|
@ -1956,7 +1956,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;
|
||||
} __attribute__((__packed__)) INDEX_HEADER_FLAGS;
|
||||
|
||||
/*
|
||||
* This is the header for indexes, describing the INDEX_ENTRY records, which
|
||||
|
@ -1984,7 +1984,7 @@ typedef struct {
|
|||
belongs to. */
|
||||
INDEX_HEADER_FLAGS flags; /* Bit field of INDEX_HEADER_FLAGS. */
|
||||
u8 reserved[3]; /* Reserved/align to 8-byte boundary. */
|
||||
} __attribute__ ((__packed__)) INDEX_HEADER;
|
||||
} __attribute__((__packed__)) INDEX_HEADER;
|
||||
|
||||
/*
|
||||
* Attribute: Index root (0x90).
|
||||
|
@ -2026,7 +2026,7 @@ typedef struct {
|
|||
u8 reserved[3]; /* Reserved/align to 8-byte boundary. */
|
||||
INDEX_HEADER index; /* Index header describing the
|
||||
following index entries. */
|
||||
} __attribute__ ((__packed__)) INDEX_ROOT;
|
||||
} __attribute__((__packed__)) INDEX_ROOT;
|
||||
|
||||
/*
|
||||
* Attribute: Index allocation (0xa0).
|
||||
|
@ -2057,7 +2057,7 @@ typedef struct {
|
|||
* by overwriting it since you then can't get it back...
|
||||
* When reading use the data from the ntfs record header.
|
||||
*/
|
||||
} __attribute__ ((__packed__)) INDEX_BLOCK;
|
||||
} __attribute__((__packed__)) INDEX_BLOCK;
|
||||
|
||||
typedef INDEX_BLOCK INDEX_ALLOCATION;
|
||||
|
||||
|
@ -2074,7 +2074,7 @@ typedef struct {
|
|||
u32 reparse_tag; /* Reparse point type (inc. flags). */
|
||||
MFT_REF file_id; /* Mft record of the file containing the
|
||||
reparse point attribute. */
|
||||
} __attribute__ ((__packed__)) REPARSE_INDEX_KEY;
|
||||
} __attribute__((__packed__)) REPARSE_INDEX_KEY;
|
||||
|
||||
/*
|
||||
* Quota flags (32-bit).
|
||||
|
@ -2132,7 +2132,7 @@ typedef struct {
|
|||
SID sid; /* The SID of the user/object associated with
|
||||
this quota entry. Equals zero for the quota
|
||||
defaults entry. */
|
||||
} __attribute__ ((__packed__)) QUOTA_CONTROL_ENTRY;
|
||||
} __attribute__((__packed__)) QUOTA_CONTROL_ENTRY;
|
||||
|
||||
/*
|
||||
* Predefined owner_id values (32-bit).
|
||||
|
@ -2156,7 +2156,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;
|
||||
} __attribute__((__packed__)) INDEX_ENTRY_FLAGS;
|
||||
|
||||
/*
|
||||
* This the index entry header (see below).
|
||||
|
@ -2173,8 +2173,8 @@ typedef struct {
|
|||
index key. */
|
||||
u16 data_length; /* Data length in bytes. */
|
||||
u32 reservedV; /* Reserved (zero). */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
/* 8*/ u16 length; /* Byte size of this index entry, multiple of
|
||||
8-bytes. */
|
||||
/* 10*/ u16 key_length; /* Byte size of the key value, which is in the
|
||||
|
@ -2183,7 +2183,7 @@ typedef struct {
|
|||
/* 12*/ INDEX_ENTRY_FLAGS flags; /* Bit field of INDEX_ENTRY_* flags. */
|
||||
/* 14*/ u16 reserved; /* Reserved/align to 8-byte boundary. */
|
||||
/* sizeof() = 16 bytes */
|
||||
} __attribute__ ((__packed__)) INDEX_ENTRY_HEADER;
|
||||
} __attribute__((__packed__)) INDEX_ENTRY_HEADER;
|
||||
|
||||
/*
|
||||
* This is an index entry. A sequence of such entries follows each INDEX_HEADER
|
||||
|
@ -2205,8 +2205,8 @@ typedef struct {
|
|||
index key. */
|
||||
u16 data_length; /* Data length in bytes. */
|
||||
u32 reservedV; /* Reserved (zero). */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
u16 length; /* Byte size of this index entry, multiple of
|
||||
8-bytes. */
|
||||
u16 key_length; /* Byte size of the key value, which is in the
|
||||
|
@ -2234,7 +2234,7 @@ typedef struct {
|
|||
user_id of the owner of the quota
|
||||
control entry in the data part of
|
||||
the index. */
|
||||
} __attribute__ ((__packed__)) key;
|
||||
} __attribute__((__packed__)) key;
|
||||
|
||||
/* The (optional) index data is inserted here when creating. */
|
||||
// VCN vcn; /* If INDEX_ENTRY_NODE bit in flags is set, the last
|
||||
|
@ -2249,7 +2249,7 @@ typedef struct {
|
|||
// aligned vcn of INDEX_ENTRY{_HEADER} *ie is given by
|
||||
// (char*)ie + le16_to_cpu(ie->length) - sizeof(VCN),
|
||||
// where sizeof(VCN) can be hardcoded as 8 if wanted. */
|
||||
} __attribute__ ((__packed__)) INDEX_ENTRY;
|
||||
} __attribute__((__packed__)) INDEX_ENTRY;
|
||||
|
||||
/*
|
||||
* Attribute: Bitmap (0xb0).
|
||||
|
@ -2263,7 +2263,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
u8 bitmap[0]; /* Array of bits. */
|
||||
} __attribute__ ((__packed__)) BITMAP_ATTR;
|
||||
} __attribute__((__packed__)) BITMAP_ATTR;
|
||||
|
||||
/*
|
||||
* The reparse point tag defines the type of the reparse point. It also
|
||||
|
@ -2316,7 +2316,7 @@ typedef struct {
|
|||
u16 reparse_data_length; /* Byte size of reparse data. */
|
||||
u16 reserved; /* Align to 8-byte boundary. */
|
||||
u8 reparse_data[0]; /* Meaning depends on reparse_tag. */
|
||||
} __attribute__ ((__packed__)) REPARSE_POINT;
|
||||
} __attribute__((__packed__)) REPARSE_POINT;
|
||||
|
||||
/*
|
||||
* Attribute: Extended attribute (EA) information (0xd0).
|
||||
|
@ -2333,14 +2333,14 @@ typedef struct {
|
|||
ZwQueryEaFile() in Windows NT/2k. I.e. the
|
||||
byte size of the unpacked extended
|
||||
attributes. */
|
||||
} __attribute__ ((__packed__)) EA_INFORMATION;
|
||||
} __attribute__((__packed__)) EA_INFORMATION;
|
||||
|
||||
/*
|
||||
* Extended attribute flags (8-bit).
|
||||
*/
|
||||
typedef enum {
|
||||
NEED_EA = 0x80,
|
||||
} __attribute__ ((__packed__)) EA_FLAGS;
|
||||
} __attribute__((__packed__)) EA_FLAGS;
|
||||
|
||||
/*
|
||||
* Attribute: Extended attribute (EA) (0xe0).
|
||||
|
@ -2360,7 +2360,7 @@ typedef struct {
|
|||
u8 name[0]; /* Name of the EA. */
|
||||
u8 value[0]; /* The value of the EA. Immediately
|
||||
follows the name. */
|
||||
} __attribute__ ((__packed__)) EA_ATTR;
|
||||
} __attribute__((__packed__)) EA_ATTR;
|
||||
|
||||
/*
|
||||
* Attribute: Property set (0xf0).
|
||||
|
@ -2370,7 +2370,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
/* Irrelevant as feature unused. */
|
||||
} __attribute__ ((__packed__)) PROPERTY_SET;
|
||||
} __attribute__((__packed__)) PROPERTY_SET;
|
||||
|
||||
/*
|
||||
* Attribute: Logged utility stream (0x100).
|
||||
|
@ -2385,7 +2385,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
/* Can be anything the creator chooses. */
|
||||
} __attribute__ ((__packed__)) LOGGED_UTILITY_STREAM;
|
||||
} __attribute__((__packed__)) LOGGED_UTILITY_STREAM;
|
||||
|
||||
/*
|
||||
* $EFS Data Structure:
|
||||
|
@ -2430,12 +2430,12 @@ typedef struct {
|
|||
recovery fields (DRF), see below. Zero if
|
||||
no DRFs are present. */
|
||||
u32 reserved; /* Reserved. */
|
||||
} __attribute__ ((__packed__)) EFS_ATTR_HEADER;
|
||||
} __attribute__((__packed__)) EFS_ATTR_HEADER;
|
||||
|
||||
typedef struct {
|
||||
u32 df_count; /* Number of data decryption/recovery fields in
|
||||
the array. */
|
||||
} __attribute__ ((__packed__)) EFS_DF_ARRAY_HEADER;
|
||||
} __attribute__((__packed__)) EFS_DF_ARRAY_HEADER;
|
||||
|
||||
typedef struct {
|
||||
/* 0*/ u32 df_length; /* Length of this data decryption/recovery
|
||||
|
@ -2446,7 +2446,7 @@ typedef struct {
|
|||
u32 fek_offset; /* Offset in bytes to the FEK from the start of
|
||||
the data decryption/recovery field. */
|
||||
/* 16*/ u32 unknown1; /* always 0? Might be just padding. */
|
||||
} __attribute__ ((__packed__)) EFS_DF_HEADER;
|
||||
} __attribute__((__packed__)) EFS_DF_HEADER;
|
||||
|
||||
typedef struct {
|
||||
/* 0*/ u32 cred_length; /* Length of this credential in bytes. */
|
||||
|
@ -2472,7 +2472,7 @@ typedef struct {
|
|||
structure. */
|
||||
/* 24*/ u32 public_key_blob_size; /* Size in bytes of
|
||||
public key blob. */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
/* Certificate thumbprint. */
|
||||
struct {
|
||||
/* 12*/ u32 cert_thumbprint_header_size; /* Size in
|
||||
|
@ -2483,9 +2483,9 @@ typedef struct {
|
|||
thumbprint from start of this structure. */
|
||||
u32 unknown1; /* Always 0? Might be padding... */
|
||||
u32 unknown2; /* Always 0? Might be padding... */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__ ((__packed__)) EFS_DF_CREDENTIAL_HEADER;
|
||||
} __attribute__((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
} __attribute__((__packed__)) EFS_DF_CREDENTIAL_HEADER;
|
||||
|
||||
typedef EFS_DF_CREDENTIAL_HEADER EFS_DF_CRED_HEADER;
|
||||
|
||||
|
@ -2503,7 +2503,7 @@ typedef struct {
|
|||
from start of this structure or 0 if
|
||||
no user name present. (This is also
|
||||
known as lpDisplayInformation.) */
|
||||
} __attribute__ ((__packed__)) EFS_DF_CERTIFICATE_THUMBPRINT_HEADER;
|
||||
} __attribute__((__packed__)) EFS_DF_CERTIFICATE_THUMBPRINT_HEADER;
|
||||
|
||||
typedef EFS_DF_CERTIFICATE_THUMBPRINT_HEADER EFS_DF_CERT_THUMBPRINT_HEADER;
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ typedef struct {
|
|||
/* 28*/ sle16 major_ver; /* Log file major version. We only support
|
||||
version 1.1. */
|
||||
/* sizeof() = 30 (0x1e) bytes */
|
||||
} __attribute__ ((__packed__)) RESTART_PAGE_HEADER;
|
||||
} __attribute__((__packed__)) RESTART_PAGE_HEADER;
|
||||
|
||||
/*
|
||||
* Constant for the log client indices meaning that there are no client records
|
||||
|
@ -109,7 +109,7 @@ typedef struct {
|
|||
enum {
|
||||
RESTART_VOLUME_IS_CLEAN = const_cpu_to_le16(0x0002),
|
||||
RESTART_SPACE_FILLER = 0xffff, /* gcc: Force enum bit width to 16. */
|
||||
} __attribute__ ((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
|
||||
typedef le16 RESTART_AREA_FLAGS;
|
||||
|
||||
|
@ -250,7 +250,7 @@ typedef struct {
|
|||
system time in NTFS format (see time.h). */
|
||||
/* 44*/ le32 reserved; /* Reserved/alignment to 8-byte boundary. */
|
||||
/* sizeof() = 48 (0x30) bytes */
|
||||
} __attribute__ ((__packed__)) RESTART_AREA;
|
||||
} __attribute__((__packed__)) RESTART_AREA;
|
||||
|
||||
/*
|
||||
* Log client record. The offset of this record is found by adding the offset
|
||||
|
@ -289,7 +289,7 @@ typedef struct {
|
|||
always be "NTFS" with the remaining bytes
|
||||
set to 0. */
|
||||
/* sizeof() = 160 (0xa0) bytes */
|
||||
} __attribute__ ((__packed__)) LOG_CLIENT_RECORD;
|
||||
} __attribute__((__packed__)) LOG_CLIENT_RECORD;
|
||||
|
||||
/*
|
||||
* Log page record page header. Each log page begins with this header and is
|
||||
|
@ -309,7 +309,7 @@ typedef struct {
|
|||
union {
|
||||
LSN last_lsn;
|
||||
s64 file_offset;
|
||||
} __attribute__ ((__packed__)) copy;
|
||||
} __attribute__((__packed__)) copy;
|
||||
u32 flags;
|
||||
u16 page_count;
|
||||
u16 page_position;
|
||||
|
@ -318,9 +318,9 @@ typedef struct {
|
|||
u16 next_record_offset;
|
||||
u8 reserved[6];
|
||||
LSN last_end_lsn;
|
||||
} __attribute__ ((__packed__)) packed;
|
||||
} __attribute__ ((__packed__)) header;
|
||||
} __attribute__ ((__packed__)) RECORD_PAGE_HEADER;
|
||||
} __attribute__((__packed__)) packed;
|
||||
} __attribute__((__packed__)) header;
|
||||
} __attribute__((__packed__)) RECORD_PAGE_HEADER;
|
||||
|
||||
/*
|
||||
* Possible 16-bit flags for log records. (Or is it log record pages?)
|
||||
|
@ -330,7 +330,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;
|
||||
} __attribute__((__packed__)) LOG_RECORD_FLAGS;
|
||||
|
||||
/*
|
||||
* The log client id structure identifying a log client.
|
||||
|
@ -338,7 +338,7 @@ typedef enum {
|
|||
typedef struct {
|
||||
u16 seq_number;
|
||||
u16 client_index;
|
||||
} __attribute__ ((__packed__)) LOG_CLIENT_ID;
|
||||
} __attribute__((__packed__)) LOG_CLIENT_ID;
|
||||
|
||||
/*
|
||||
* Log record header. Each log record seems to have a constant size of 0x70
|
||||
|
@ -374,7 +374,7 @@ typedef struct {
|
|||
is not 0. */
|
||||
LCN lcn;
|
||||
} __attribute__((__packed__)) lcn_list[0];
|
||||
} __attribute__ ((__packed__)) LOG_RECORD;
|
||||
} __attribute__((__packed__)) LOG_RECORD;
|
||||
|
||||
extern BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp);
|
||||
extern BOOL ntfs_is_logfile_clean(ntfs_attr *log_na, RESTART_PAGE_HEADER *rp);
|
||||
|
|
|
@ -22,7 +22,9 @@
|
|||
#ifndef _LOGGING_H_
|
||||
#define _LOGGING_H_
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
|
@ -33,8 +35,8 @@
|
|||
struct ntfs_logging;
|
||||
|
||||
/* Function prototype for the logging handlers */
|
||||
typedef int (logging_handler) (const char *handler, const char *file, int line,
|
||||
int level, FILE *stream, const char *format, va_list args);
|
||||
typedef int (ntfs_logging_handler)(const char *function, const char *file, int line,
|
||||
u32 level, void *data, const char *format, va_list args);
|
||||
|
||||
/**
|
||||
* struct ntfs_logging - Control info for the logging system
|
||||
|
@ -45,69 +47,72 @@ typedef int (logging_handler) (const char *handler, const char *file, int line,
|
|||
struct ntfs_logging {
|
||||
u32 levels;
|
||||
u32 flags;
|
||||
logging_handler *handler;
|
||||
ntfs_logging_handler *handler;
|
||||
};
|
||||
|
||||
extern struct ntfs_logging ntfs_log;
|
||||
|
||||
void ntfs_logging_set_handler (logging_handler *handler);
|
||||
void ntfs_logging_set_handler(ntfs_logging_handler *handler);
|
||||
|
||||
/* Enable/disable certain log levels */
|
||||
u32 ntfs_logging_set_levels (u32 levels);
|
||||
u32 ntfs_logging_clear_levels (u32 levels);
|
||||
u32 ntfs_logging_get_levels (void);
|
||||
u32 ntfs_logging_set_levels(u32 levels);
|
||||
u32 ntfs_logging_clear_levels(u32 levels);
|
||||
u32 ntfs_logging_get_levels(void);
|
||||
|
||||
/* Enable/disable certain log flags */
|
||||
u32 ntfs_logging_set_flags (u32 flags);
|
||||
u32 ntfs_logging_clear_flags (u32 flags);
|
||||
u32 ntfs_logging_get_flags (void);
|
||||
u32 ntfs_logging_set_flags(u32 flags);
|
||||
u32 ntfs_logging_clear_flags(u32 flags);
|
||||
u32 ntfs_logging_get_flags(void);
|
||||
|
||||
BOOL ntfs_logging_parse_option (const char *option);
|
||||
BOOL ntfs_logging_parse_option(const char *option);
|
||||
|
||||
int ntfs_logging_redirect (const char *handler, const char *file, int line,
|
||||
int level, FILE *stream, const char *format, ...)
|
||||
__attribute__ ((format (printf, 6, 7)));
|
||||
int ntfs_logging_redirect(const char *function, const char *file, int line,
|
||||
u32 level, void *data, const char *format, ...)
|
||||
__attribute__((format(printf, 6, 7)));
|
||||
|
||||
/* Logging handlers */
|
||||
logging_handler ntfs_logging_handler_printf __attribute__ ((format (printf, 6, 0)));
|
||||
logging_handler ntfs_logging_handler_colour __attribute__ ((format (printf, 6, 0)));
|
||||
ntfs_logging_handler ntfs_logging_handler_printf __attribute__((format(printf, 6, 0)));
|
||||
ntfs_logging_handler ntfs_logging_handler_colour __attribute__((format(printf, 6, 0)));
|
||||
|
||||
/* Logging levels - Determine what gets logged */
|
||||
#define LOG_LEVEL_DEBUG (1 << 0) /* x = 42 */
|
||||
#define LOG_LEVEL_TRACE (1 << 1) /* Entering function x() */
|
||||
#define LOG_LEVEL_QUIET (1 << 2) /* Quietable output */
|
||||
#define LOG_LEVEL_INFO (1 << 3) /* Volume needs defragmenting */
|
||||
#define LOG_LEVEL_VERBOSE (1 << 4) /* Forced to continue */
|
||||
#define LOG_LEVEL_PROGRESS (1 << 5) /* 54% complete */
|
||||
#define LOG_LEVEL_WARNING (1 << 6) /* You should backup before starting */
|
||||
#define LOG_LEVEL_ERROR (1 << 7) /* Operation failed, no damage done */
|
||||
#define LOG_LEVEL_PERROR (1 << 8) /* Message : standard error description */
|
||||
#define LOG_LEVEL_CRITICAL (1 << 9) /* Operation failed,damage may have occurred */
|
||||
#define NTFS_LOG_LEVEL_DEBUG (1 << 0) /* x = 42 */
|
||||
#define NTFS_LOG_LEVEL_TRACE (1 << 1) /* Entering function x() */
|
||||
#define NTFS_LOG_LEVEL_QUIET (1 << 2) /* Quietable output */
|
||||
#define NTFS_LOG_LEVEL_INFO (1 << 3) /* Volume needs defragmenting */
|
||||
#define NTFS_LOG_LEVEL_VERBOSE (1 << 4) /* Forced to continue */
|
||||
#define NTFS_LOG_LEVEL_PROGRESS (1 << 5) /* 54% complete */
|
||||
#define NTFS_LOG_LEVEL_WARNING (1 << 6) /* You should backup before starting */
|
||||
#define NTFS_LOG_LEVEL_ERROR (1 << 7) /* Operation failed, no damage done */
|
||||
#define NTFS_LOG_LEVEL_PERROR (1 << 8) /* Message : standard error description */
|
||||
#define NTFS_LOG_LEVEL_CRITICAL (1 << 9) /* Operation failed,damage may have occurred */
|
||||
#define NTFS_LOG_LEVEL_REASON (1 << 10) /* Human readable reason for failure */
|
||||
|
||||
/* Logging style flags - Manage the style of the output */
|
||||
#define LOG_FLAG_PREFIX (1 << 0) /* Prefix messages with "ERROR: ", etc */
|
||||
#define LOG_FLAG_FILENAME (1 << 1) /* Show the file origin of the message */
|
||||
#define LOG_FLAG_LINE (1 << 2) /* Show the line number of the message */
|
||||
#define LOG_FLAG_FUNCTION (1 << 3) /* Show the function name containing the message */
|
||||
#define NTFS_LOG_FLAG_PREFIX (1 << 0) /* Prefix messages with "ERROR: ", etc */
|
||||
#define NTFS_LOG_FLAG_FILENAME (1 << 1) /* Show the file origin of the message */
|
||||
#define NTFS_LOG_FLAG_LINE (1 << 2) /* Show the line number of the message */
|
||||
#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, if DEBUG isn't defined, then log_debug has no effect.
|
||||
* Note, if NTFS_DISABLE_DEBUG_LOGGING is defined, then ntfs_log_debug/trace have no effect.
|
||||
*/
|
||||
#define log_crit(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_CRITICAL,NULL,FORMAT,##ARGS)
|
||||
#define log_error(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_ERROR,NULL,FORMAT,##ARGS)
|
||||
#define log_info(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_INFO,NULL,FORMAT,##ARGS)
|
||||
#define log_perror(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_PERROR,NULL,FORMAT,##ARGS)
|
||||
#define log_progress(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_PROGRESS,NULL,FORMAT,##ARGS)
|
||||
#define log_quiet(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_QUIET,NULL,FORMAT,##ARGS)
|
||||
#define log_verbose(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_VERBOSE,NULL,FORMAT,##ARGS)
|
||||
#define log_warn(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_WARNING,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_critical(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_CRITICAL,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_error(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_ERROR,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_info(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_INFO,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_perror(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PERROR,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_progress(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PROGRESS,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_quiet(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_QUIET,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_verbose(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_VERBOSE,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_warning(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_WARNING,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_reason(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_REASON,NULL,FORMAT,##ARGS)
|
||||
|
||||
#ifdef NTFS_DISABLE_DEBUG_LOGGING
|
||||
#define log_debug(FORMAT, ARGS...)do {} while (0)
|
||||
#define log_trace(FORMAT, ARGS...)do {} while (0)
|
||||
#define ntfs_log_debug(FORMAT, ARGS...)do {} while (0)
|
||||
#define ntfs_log_trace(FORMAT, ARGS...)do {} while (0)
|
||||
#else
|
||||
#define log_debug(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_DEBUG,NULL,FORMAT,##ARGS)
|
||||
#define log_trace(FORMAT, ARGS...) ntfs_logging_redirect (__FUNCTION__,__FILE__,__LINE__,LOG_LEVEL_TRACE,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_debug(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_DEBUG,NULL,FORMAT,##ARGS)
|
||||
#define ntfs_log_trace(FORMAT, ARGS...) ntfs_logging_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_TRACE,NULL,FORMAT,##ARGS)
|
||||
#endif /* NTFS_DISABLE_DEBUG_LOGGING */
|
||||
|
||||
#endif /* _LOGGING_H_ */
|
||||
|
|
|
@ -116,11 +116,11 @@ extern int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni);
|
|||
#include "bitmap.h"
|
||||
#include "dir.h"
|
||||
|
||||
int ntfs_mft_remove_attr (struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_TYPES type);
|
||||
ATTR_RECORD * ntfs_mft_add_attr (ntfs_inode *inode, ATTR_TYPES type, u8 *data, int data_len);
|
||||
int ntfs_mft_resize_resident (ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len, u8 *data, int data_len);
|
||||
int ntfs_mft_free_space (struct ntfs_dir *dir);
|
||||
int ntfs_mft_add_index (struct ntfs_dir *dir);
|
||||
int ntfs_mft_remove_attr(struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_TYPES type);
|
||||
ATTR_RECORD * ntfs_mft_add_attr(ntfs_inode *inode, ATTR_TYPES type, u8 *data, int data_len);
|
||||
int ntfs_mft_resize_resident(ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len, u8 *data, int data_len);
|
||||
int ntfs_mft_free_space(struct ntfs_dir *dir);
|
||||
int ntfs_mft_add_index(struct ntfs_dir *dir);
|
||||
|
||||
#endif /* NTFS_RICH */
|
||||
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
#ifndef _NTFS_NTFSTIME_H
|
||||
#define _NTFS_NTFSTIME_H
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*
|
||||
* rich.h - Temporary junk file. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2004-2005 Richard Russon
|
||||
|
@ -40,11 +40,11 @@
|
|||
#define ROUND_DOWN(num,bound) ((num) & ~((bound)-1))
|
||||
#define ATTR_SIZE(s) ROUND_UP(s,8)
|
||||
|
||||
ATTR_RECORD * find_attribute (const ATTR_TYPES type, ntfs_attr_search_ctx *ctx);
|
||||
ATTR_RECORD * find_first_attribute (const ATTR_TYPES type, MFT_RECORD *mft);
|
||||
int utils_free_non_residents3 (struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_RECORD *attr);
|
||||
int utils_free_non_residents2 (ntfs_inode *inode, struct ntfs_bmp *bmp);
|
||||
void ntfs_name_print (ntfschar *name, int name_len);
|
||||
ATTR_RECORD * find_attribute(const ATTR_TYPES type, ntfs_attr_search_ctx *ctx);
|
||||
ATTR_RECORD * find_first_attribute(const ATTR_TYPES type, MFT_RECORD *mft);
|
||||
int utils_free_non_residents3(struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_RECORD *attr);
|
||||
int utils_free_non_residents2(ntfs_inode *inode, struct ntfs_bmp *bmp);
|
||||
void ntfs_name_print(ntfschar *name, int name_len);
|
||||
|
||||
#endif /* _NTFS_RICH_H_ */
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ extern int ntfs_rl_sparse(runlist *rl);
|
|||
extern s64 ntfs_rl_get_compressed_size(ntfs_volume *vol, runlist *rl);
|
||||
|
||||
#ifdef NTFS_TEST
|
||||
int test_rl_main (int argc, char *argv[]);
|
||||
int test_rl_main(int argc, char *argv[]);
|
||||
#endif
|
||||
|
||||
#endif /* defined _NTFS_RUNLIST_H */
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generic macro to convert pointers to values for comparison purposes.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*
|
||||
* tree.h - Directory tree handling code. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2004-2005 Richard Russon
|
||||
|
@ -45,38 +45,38 @@ struct ntfs_dt {
|
|||
};
|
||||
|
||||
|
||||
void ntfs_dt_free (struct ntfs_dt *dt);
|
||||
int ntfs_dt_rollback (struct ntfs_dt *dt);
|
||||
int ntfs_dt_commit (struct ntfs_dt *dt);
|
||||
BOOL ntfs_dt_create_children2 (struct ntfs_dt *dt, int count);
|
||||
BOOL ntfs_dt_resize_children3 (struct ntfs_dt *dt, int new);
|
||||
int ntfs_dt_root_count (struct ntfs_dt *dt);
|
||||
int ntfs_dt_alloc_count (struct ntfs_dt *dt);
|
||||
int ntfs_dt_initialise2 (ntfs_volume *vol, struct ntfs_dt *dt);
|
||||
struct ntfs_dt * ntfs_dt_create (struct ntfs_dir *dir, struct ntfs_dt *parent, VCN vcn);
|
||||
MFT_REF ntfs_dt_find (struct ntfs_dt *dt, ntfschar *name, int name_len);
|
||||
struct ntfs_dt * ntfs_dt_find2 (struct ntfs_dt *dt, ntfschar *name, int name_len, int *index_num);
|
||||
struct ntfs_dt * ntfs_dt_find3 (struct ntfs_dt *dt, ntfschar *name, int name_len, int *index_num);
|
||||
struct ntfs_dt * ntfs_dt_find4 (struct ntfs_dt *dt, ntfschar *name, int name_len, int *index_num);
|
||||
void ntfs_dt_find_all (struct ntfs_dt *dt);
|
||||
int ntfs_dt_find_parent (struct ntfs_dt *dt);
|
||||
BOOL ntfs_dt_isroot (struct ntfs_dt *dt);
|
||||
int ntfs_dt_root_freespace (struct ntfs_dt *dt);
|
||||
int ntfs_dt_alloc_freespace (struct ntfs_dt *dt);
|
||||
int ntfs_dt_transfer (struct ntfs_dt *old, struct ntfs_dt *new, int start, int count);
|
||||
int ntfs_dt_alloc_insert (struct ntfs_dt *dt, INDEX_ENTRY *first, int count);
|
||||
INDEX_ENTRY * ntfs_dt_alloc_insert2 (struct ntfs_dt *dt, int before, int count, int bytes);
|
||||
int ntfs_dt_root_insert (struct ntfs_dt *dt, INDEX_ENTRY *first, int count);
|
||||
int ntfs_dt_alloc_remove2 (struct ntfs_dt *dt, int start, int count);
|
||||
int ntfs_dt_root_remove2 (struct ntfs_dt *dt, int start, int count);
|
||||
int ntfs_dt_transfer2 (struct ntfs_dt *old, struct ntfs_dt *new, int start, int count);
|
||||
int ntfs_dt_root_replace (struct ntfs_dt *del, int del_num, INDEX_ENTRY *del_ie, INDEX_ENTRY *suc_ie);
|
||||
BOOL ntfs_dt_alloc_replace (struct ntfs_dt *del, int del_num, INDEX_ENTRY *del_ie, INDEX_ENTRY *suc_ie);
|
||||
BOOL ntfs_dt_root_remove (struct ntfs_dt *del, int del_num);
|
||||
BOOL ntfs_dt_alloc_remove (struct ntfs_dt *del, int del_num);
|
||||
int ntfs_dt_alloc_add (struct ntfs_dt *parent, int index_num, INDEX_ENTRY *ie, struct ntfs_dt *child);
|
||||
int ntfs_dt_root_add (struct ntfs_dt *parent, int index_num, INDEX_ENTRY *ie, struct ntfs_dt *child);
|
||||
int ntfs_dt_add2 (INDEX_ENTRY *ie, struct ntfs_dt *suc, int suc_num, struct ntfs_dt *ded);
|
||||
void ntfs_dt_free(struct ntfs_dt *dt);
|
||||
int ntfs_dt_rollback(struct ntfs_dt *dt);
|
||||
int ntfs_dt_commit(struct ntfs_dt *dt);
|
||||
BOOL ntfs_dt_create_children2(struct ntfs_dt *dt, int count);
|
||||
BOOL ntfs_dt_resize_children3(struct ntfs_dt *dt, int new);
|
||||
int ntfs_dt_root_count(struct ntfs_dt *dt);
|
||||
int ntfs_dt_alloc_count(struct ntfs_dt *dt);
|
||||
int ntfs_dt_initialise2(ntfs_volume *vol, struct ntfs_dt *dt);
|
||||
struct ntfs_dt * ntfs_dt_create(struct ntfs_dir *dir, struct ntfs_dt *parent, VCN vcn);
|
||||
MFT_REF ntfs_dt_find(struct ntfs_dt *dt, ntfschar *name, int name_len);
|
||||
struct ntfs_dt * ntfs_dt_find2(struct ntfs_dt *dt, ntfschar *name, int name_len, int *index_num);
|
||||
struct ntfs_dt * ntfs_dt_find3(struct ntfs_dt *dt, ntfschar *name, int name_len, int *index_num);
|
||||
struct ntfs_dt * ntfs_dt_find4(struct ntfs_dt *dt, ntfschar *name, int name_len, int *index_num);
|
||||
void ntfs_dt_find_all(struct ntfs_dt *dt);
|
||||
int ntfs_dt_find_parent(struct ntfs_dt *dt);
|
||||
BOOL ntfs_dt_isroot(struct ntfs_dt *dt);
|
||||
int ntfs_dt_root_freespace(struct ntfs_dt *dt);
|
||||
int ntfs_dt_alloc_freespace(struct ntfs_dt *dt);
|
||||
int ntfs_dt_transfer(struct ntfs_dt *old, struct ntfs_dt *new, int start, int count);
|
||||
int ntfs_dt_alloc_insert(struct ntfs_dt *dt, INDEX_ENTRY *first, int count);
|
||||
INDEX_ENTRY * ntfs_dt_alloc_insert2(struct ntfs_dt *dt, int before, int count, int bytes);
|
||||
int ntfs_dt_root_insert(struct ntfs_dt *dt, INDEX_ENTRY *first, int count);
|
||||
int ntfs_dt_alloc_remove2(struct ntfs_dt *dt, int start, int count);
|
||||
int ntfs_dt_root_remove2(struct ntfs_dt *dt, int start, int count);
|
||||
int ntfs_dt_transfer2(struct ntfs_dt *old, struct ntfs_dt *new, int start, int count);
|
||||
int ntfs_dt_root_replace(struct ntfs_dt *del, int del_num, INDEX_ENTRY *del_ie, INDEX_ENTRY *suc_ie);
|
||||
BOOL ntfs_dt_alloc_replace(struct ntfs_dt *del, int del_num, INDEX_ENTRY *del_ie, INDEX_ENTRY *suc_ie);
|
||||
BOOL ntfs_dt_root_remove(struct ntfs_dt *del, int del_num);
|
||||
BOOL ntfs_dt_alloc_remove(struct ntfs_dt *del, int del_num);
|
||||
int ntfs_dt_alloc_add(struct ntfs_dt *parent, int index_num, INDEX_ENTRY *ie, struct ntfs_dt *child);
|
||||
int ntfs_dt_root_add(struct ntfs_dt *parent, int index_num, INDEX_ENTRY *ie, struct ntfs_dt *child);
|
||||
int ntfs_dt_add2(INDEX_ENTRY *ie, struct ntfs_dt *suc, int suc_num, struct ntfs_dt *ded);
|
||||
|
||||
#endif /* _NTFS_TREE_H_ */
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@
|
|||
#if HAVE_STDINT_H || !HAVE_CONFIG_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
typedef uint8_t u8; /* Unsigned types of an exact size */
|
||||
typedef uint16_t u16;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*
|
||||
* version.h - Info about the NTFS library. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2005 Anton Altaparmakov
|
||||
|
|
|
@ -28,15 +28,17 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MOUNT_H
|
||||
# include <sys/mount.h>
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
#ifdef HAVE_MNTENT_H
|
||||
# include <mntent.h>
|
||||
#include <mntent.h>
|
||||
#endif
|
||||
|
||||
/* Both under Cygwin and DJGPP we do not have MS_RDONLY, so we define it. */
|
||||
|
@ -206,12 +208,12 @@ extern int ntfs_volume_write_flags(ntfs_volume *v, const u16 flags);
|
|||
|
||||
#ifdef NTFS_RICH
|
||||
|
||||
int ntfs_volume_commit (ntfs_volume *vol);
|
||||
int ntfs_volume_rollback (ntfs_volume *vol);
|
||||
int ntfs_volume_umount2 (ntfs_volume *vol, const BOOL force);
|
||||
ntfs_volume * ntfs_volume_mount2 (const char *device, unsigned long flags, BOOL force);
|
||||
int utils_valid_device (const char *name, int force);
|
||||
ntfs_volume * utils_mount_volume (const char *device, unsigned long flags, BOOL force);
|
||||
int ntfs_volume_commit(ntfs_volume *vol);
|
||||
int ntfs_volume_rollback(ntfs_volume *vol);
|
||||
int ntfs_volume_umount2(ntfs_volume *vol, const BOOL force);
|
||||
ntfs_volume * ntfs_volume_mount2(const char *device, unsigned long flags, BOOL force);
|
||||
int utils_valid_device(const char *name, int force);
|
||||
ntfs_volume * utils_mount_volume(const char *device, unsigned long flags, BOOL force);
|
||||
|
||||
#endif /* NTFS_RICH */
|
||||
|
||||
|
|
729
libntfs/attrib.c
729
libntfs/attrib.c
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* attrlist.c - Attribute list attribute handling code. Part of the Linux-NTFS
|
||||
* project.
|
||||
*
|
||||
|
@ -21,7 +21,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
|
@ -36,6 +38,7 @@
|
|||
#include "attrlist.h"
|
||||
#include "debug.h"
|
||||
#include "unistr.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* ntfs_attrlist_need - check whether inode need attribute list
|
||||
|
@ -55,23 +58,21 @@ int ntfs_attrlist_need(ntfs_inode *ni)
|
|||
ATTR_LIST_ENTRY *ale;
|
||||
|
||||
if (!ni) {
|
||||
Dprintf("%s(): Invalid arguments.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid arguments.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no);
|
||||
ntfs_log_trace("Entering for inode 0x%llx.\n", (long long) ni->mft_no);
|
||||
|
||||
if (!NInoAttrList(ni)) {
|
||||
Dprintf("%s(): Inode haven't got attribute list.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Inode haven't got attribute list.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ni->attr_list) {
|
||||
Dprintf("%s(): Corrupt in-memory struct.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Corrupt in-memory struct.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -107,12 +108,12 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
u8 *new_al;
|
||||
int entry_len, entry_offset, err;
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, attr 0x%x.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no,
|
||||
ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n",
|
||||
(long long) ni->mft_no,
|
||||
(unsigned) le32_to_cpu(attr->type));
|
||||
|
||||
if (!ni || !attr) {
|
||||
Dprintf("%s(): Invalid arguments.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid arguments.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -123,7 +124,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
ni = ni->base_ni;
|
||||
|
||||
if (!NInoAttrList(ni)) {
|
||||
Dprintf("%s(): Attribute list isn't present.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Attribute list isn't present.\n");
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
@ -133,7 +134,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
attr->name_length + 7) & ~7;
|
||||
new_al = malloc(ni->attr_list_size + entry_len);
|
||||
if (!new_al) {
|
||||
Dprintf("%s(): Not enough memory.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Not enough memory.\n");
|
||||
err = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
@ -142,8 +143,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
ctx = ntfs_attr_get_search_ctx(ni, NULL);
|
||||
if (!ctx) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to obtain attribute search context.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to obtain attribute search context.\n");
|
||||
goto err_out;
|
||||
}
|
||||
if (!ntfs_attr_lookup(attr->type, (attr->name_length) ? (ntfschar*)
|
||||
|
@ -156,8 +156,8 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
/* Found some extent, check it to be before new extent. */
|
||||
if (ctx->al_entry->lowest_vcn == attr->lowest_vcn) {
|
||||
err = EEXIST;
|
||||
Dprintf("%s(): Such attribute already present in the "
|
||||
"attribute list.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Such attribute already present in the "
|
||||
"attribute list.\n");
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -168,8 +168,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
/* Check for real errors. */
|
||||
if (errno != ENOENT) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Attribute lookup failed.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Attribute lookup failed.\n");
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -203,13 +202,12 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0);
|
||||
if (!na) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to open $ATTRIBUTE_LIST attribute.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to open $ATTRIBUTE_LIST attribute.\n");
|
||||
goto err_out;
|
||||
}
|
||||
if (ntfs_attr_truncate(na, ni->attr_list_size + entry_len)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): $ATTRIBUTE_LIST resize failed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("$ATTRIBUTE_LIST resize failed.\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
|
@ -219,8 +217,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
entry_offset, ni->attr_list_size - entry_offset);
|
||||
|
||||
/* Set new runlist. */
|
||||
if (ni->attr_list)
|
||||
free(ni->attr_list);
|
||||
free(ni->attr_list);
|
||||
ni->attr_list = new_al;
|
||||
ni->attr_list_size = ni->attr_list_size + entry_len;
|
||||
NInoAttrListSetDirty(ni);
|
||||
|
@ -253,7 +250,7 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
int err;
|
||||
|
||||
if (!ctx || !ctx->ntfs_ino || !ctx->al_entry) {
|
||||
Dprintf("%s(): Invalid arguments.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid arguments.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -264,13 +261,13 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
base_ni = ctx->ntfs_ino;
|
||||
ale = ctx->al_entry;
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, attr 0x%x, lowest_vcn "
|
||||
"%lld.\n", __FUNCTION__, (long long) ctx->ntfs_ino->mft_no,
|
||||
(unsigned) le32_to_cpu(ctx->al_entry->type),
|
||||
(long long) le64_to_cpu(ctx->al_entry->lowest_vcn));
|
||||
ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, lowest_vcn %lld.\n",
|
||||
(long long) ctx->ntfs_ino->mft_no,
|
||||
(unsigned) le32_to_cpu(ctx->al_entry->type),
|
||||
(long long) le64_to_cpu(ctx->al_entry->lowest_vcn));
|
||||
|
||||
if (!NInoAttrList(base_ni)) {
|
||||
Dprintf("%s(): Attribute list isn't present.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Attribute list isn't present.\n");
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
@ -279,7 +276,7 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
new_al_len = base_ni->attr_list_size - le16_to_cpu(ale->length);
|
||||
new_al = malloc(new_al_len);
|
||||
if (!new_al) {
|
||||
Dprintf("%s(): Not enough memory.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Not enough memory.\n");
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
@ -288,13 +285,12 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
na = ntfs_attr_open(base_ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0);
|
||||
if (!na) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to open $ATTRIBUTE_LIST attribute.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to open $ATTRIBUTE_LIST attribute.\n");
|
||||
goto err_out;
|
||||
}
|
||||
if (ntfs_attr_truncate(na, new_al_len)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): $ATTRIBUTE_LIST resize failed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("$ATTRIBUTE_LIST resize failed.\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
|
@ -304,8 +300,7 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
ale->length), new_al_len - ((u8*)ale - base_ni->attr_list));
|
||||
|
||||
/* Set new runlist. */
|
||||
if (base_ni->attr_list)
|
||||
free(base_ni->attr_list);
|
||||
free(base_ni->attr_list);
|
||||
base_ni->attr_list = new_al;
|
||||
base_ni->attr_list_size = new_al_len;
|
||||
NInoAttrListSetDirty(base_ni);
|
||||
|
|
167
libntfs/bitmap.c
167
libntfs/bitmap.c
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* bitmap.c - Bitmap handling code. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2002-2004 Anton Altaparmakov
|
||||
|
@ -20,7 +20,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
|
@ -39,6 +41,7 @@
|
|||
#include "attrib.h"
|
||||
#include "bitmap.h"
|
||||
#include "debug.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* ntfs_bitmap_set_bits_in_run - set a run of bits in a bitmap to a value
|
||||
|
@ -112,9 +115,8 @@ static __inline__ int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
|
|||
lastbyte_pos = ((count + 7) >> 3) + firstbyte;
|
||||
if (!lastbyte_pos) {
|
||||
// FIXME: Eeek! BUG!
|
||||
Dprintf("%s(): Eeek! lastbyte is zero. "
|
||||
"Leaving inconsistent "
|
||||
"metadata.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Eeek! lastbyte is zero. Leaving "
|
||||
"inconsistent metadata.\n");
|
||||
err = EIO;
|
||||
goto free_err_out;
|
||||
}
|
||||
|
@ -127,11 +129,9 @@ static __inline__ int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
|
|||
3, 1, lastbyte_buf);
|
||||
if (br != 1) {
|
||||
// FIXME: Eeek! We need rollback! (AIA)
|
||||
Dprintf("%s(): Eeek! Read of last "
|
||||
"byte failed. "
|
||||
"Leaving inconsistent "
|
||||
"metadata.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Eeek! Read of last byte "
|
||||
"failed. Leaving "
|
||||
"inconsistent metadata.\n");
|
||||
err = EIO;
|
||||
goto free_err_out;
|
||||
}
|
||||
|
@ -154,9 +154,8 @@ static __inline__ int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
|
|||
br = ntfs_attr_pwrite(na, tmp, bufsize, buf);
|
||||
if (br != bufsize) {
|
||||
// FIXME: Eeek! We need rollback! (AIA)
|
||||
Dprintf("%s(): Eeek! Failed to write buffer to "
|
||||
"bitmap. Leaving inconsistent "
|
||||
"metadata.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Eeek! Failed to write buffer to bitmap. "
|
||||
"Leaving inconsistent metadata.\n");
|
||||
err = EIO;
|
||||
goto free_err_out;
|
||||
}
|
||||
|
@ -171,10 +170,9 @@ static __inline__ int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
|
|||
|
||||
if (lastbyte && count != 0) {
|
||||
// FIXME: Eeek! BUG!
|
||||
Dprintf("%s(): Eeek! Last buffer but count is not "
|
||||
"zero (= %lli). Leaving "
|
||||
"inconsistent metadata.\n",
|
||||
__FUNCTION__, (long long)count);
|
||||
ntfs_log_trace("Eeek! Last buffer but count is not zero (= "
|
||||
"%lli). Leaving inconsistent metadata.\n",
|
||||
(long long)count);
|
||||
err = EIO;
|
||||
goto free_err_out;
|
||||
}
|
||||
|
@ -225,17 +223,14 @@ int ntfs_bitmap_clear_run(ntfs_attr *na, s64 start_bit, s64 count)
|
|||
|
||||
#ifdef NTFS_RICH
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "layout.h"
|
||||
#include "volume.h"
|
||||
#include "bitmap.h"
|
||||
#include "rich.h"
|
||||
|
||||
/**
|
||||
* ntfs_bmp_rollback
|
||||
*/
|
||||
int ntfs_bmp_rollback (struct ntfs_bmp *bmp)
|
||||
int ntfs_bmp_rollback(struct ntfs_bmp *bmp)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -243,10 +238,10 @@ int ntfs_bmp_rollback (struct ntfs_bmp *bmp)
|
|||
return 0;
|
||||
|
||||
for (i = 0; i < bmp->count; i++)
|
||||
free (bmp->data[i]);
|
||||
free(bmp->data[i]);
|
||||
|
||||
free (bmp->data);
|
||||
free (bmp->data_vcn);
|
||||
free(bmp->data);
|
||||
free(bmp->data_vcn);
|
||||
bmp->data = NULL;
|
||||
bmp->data_vcn = NULL;
|
||||
bmp->count = 0;
|
||||
|
@ -257,7 +252,7 @@ int ntfs_bmp_rollback (struct ntfs_bmp *bmp)
|
|||
/**
|
||||
* ntfs_bmp_commit
|
||||
*/
|
||||
int ntfs_bmp_commit (struct ntfs_bmp *bmp)
|
||||
int ntfs_bmp_commit(struct ntfs_bmp *bmp)
|
||||
{
|
||||
int i;
|
||||
u32 cs;
|
||||
|
@ -271,16 +266,16 @@ int ntfs_bmp_commit (struct ntfs_bmp *bmp)
|
|||
return 0;
|
||||
|
||||
#if 0
|
||||
printf ("attr = 0x%02X\n", bmp->attr->type);
|
||||
printf ("resident = %d\n", !NAttrNonResident (bmp->attr));
|
||||
printf ("\ta size = %lld\n", bmp->attr->allocated_size);
|
||||
printf ("\td size = %lld\n", bmp->attr->data_size);
|
||||
printf ("\ti size = %lld\n", bmp->attr->initialized_size);
|
||||
ntfs_log_debug("attr = 0x%02X\n", bmp->attr->type);
|
||||
ntfs_log_debug("resident = %d\n", !NAttrNonResident(bmp->attr));
|
||||
ntfs_log_debug("\ta size = %lld\n", bmp->attr->allocated_size);
|
||||
ntfs_log_debug("\td size = %lld\n", bmp->attr->data_size);
|
||||
ntfs_log_debug("\ti size = %lld\n", bmp->attr->initialized_size);
|
||||
#endif
|
||||
|
||||
printf ("commit bmp inode %lld, 0x%02X (%sresident)\n", bmp->attr->ni->mft_no, bmp->attr->type, NAttrNonResident (bmp->attr) ? "non-" : "");
|
||||
ntfs_log_debug("commit bmp inode %lld, 0x%02X (%sresident)\n", bmp->attr->ni->mft_no, bmp->attr->type, NAttrNonResident(bmp->attr) ? "non-" : "");
|
||||
|
||||
if (NAttrNonResident (bmp->attr)) {
|
||||
if (NAttrNonResident(bmp->attr)) {
|
||||
cs = bmp->vol->cluster_size;
|
||||
|
||||
// non-resident
|
||||
|
@ -290,20 +285,20 @@ int ntfs_bmp_commit (struct ntfs_bmp *bmp)
|
|||
ws = cs;
|
||||
else
|
||||
ws = bmp->attr->data_size & (cs - 1);
|
||||
//printf ("writing %d bytes\n", ws);
|
||||
ntfs_attr_pwrite (bmp->attr, bmp->data_vcn[i] * cs, ws, bmp->data[i]); // XXX retval
|
||||
//ntfs_log_debug("writing %d bytes\n", ws);
|
||||
ntfs_attr_pwrite(bmp->attr, bmp->data_vcn[i] * cs, ws, bmp->data[i]); // XXX retval
|
||||
#endif
|
||||
printf (RED "\tntfs_attr_pwrite (vcn %lld)\n" END, bmp->data_vcn[i]);
|
||||
ntfs_log_debug(RED "\tntfs_attr_pwrite(vcn %lld)\n" END, bmp->data_vcn[i]);
|
||||
}
|
||||
} else {
|
||||
// resident
|
||||
#ifdef RM_WRITE
|
||||
ntfs_attr_pwrite (bmp->attr, bmp->data_vcn[0], bmp->attr->data_size, bmp->data[0]); // XXX retval
|
||||
ntfs_attr_pwrite(bmp->attr, bmp->data_vcn[0], bmp->attr->data_size, bmp->data[0]); // XXX retval
|
||||
#endif
|
||||
printf (RED "\tntfs_attr_pwrite resident (%lld)\n" END, bmp->attr->data_size);
|
||||
ntfs_log_debug(RED "\tntfs_attr_pwrite resident (%lld)\n" END, bmp->attr->data_size);
|
||||
}
|
||||
|
||||
ntfs_bmp_rollback (bmp);
|
||||
ntfs_bmp_rollback(bmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -311,22 +306,22 @@ int ntfs_bmp_commit (struct ntfs_bmp *bmp)
|
|||
/**
|
||||
* ntfs_bmp_free
|
||||
*/
|
||||
void ntfs_bmp_free (struct ntfs_bmp *bmp)
|
||||
void ntfs_bmp_free(struct ntfs_bmp *bmp)
|
||||
{
|
||||
if (!bmp)
|
||||
return;
|
||||
|
||||
ntfs_bmp_rollback (bmp);
|
||||
ntfs_bmp_rollback(bmp);
|
||||
|
||||
ntfs_attr_close (bmp->attr);
|
||||
ntfs_attr_close(bmp->attr);
|
||||
|
||||
free (bmp);
|
||||
free(bmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_bmp_create
|
||||
*/
|
||||
struct ntfs_bmp * ntfs_bmp_create (ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len)
|
||||
struct ntfs_bmp * ntfs_bmp_create(ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len)
|
||||
{
|
||||
struct ntfs_bmp *bmp;
|
||||
ntfs_attr *attr;
|
||||
|
@ -334,13 +329,13 @@ struct ntfs_bmp * ntfs_bmp_create (ntfs_inode *inode, ATTR_TYPES type, ntfschar
|
|||
if (!inode)
|
||||
return NULL;
|
||||
|
||||
attr = ntfs_attr_open (inode, type, name, name_len);
|
||||
attr = ntfs_attr_open(inode, type, name, name_len);
|
||||
if (!attr)
|
||||
return NULL;
|
||||
|
||||
bmp = calloc (1, sizeof (*bmp));
|
||||
bmp = calloc(1, sizeof(*bmp));
|
||||
if (!bmp) {
|
||||
ntfs_attr_close (attr);
|
||||
ntfs_attr_close(attr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -356,7 +351,7 @@ struct ntfs_bmp * ntfs_bmp_create (ntfs_inode *inode, ATTR_TYPES type, ntfschar
|
|||
/**
|
||||
* ntfs_bmp_add_data
|
||||
*/
|
||||
int ntfs_bmp_add_data (struct ntfs_bmp *bmp, VCN vcn, u8 *data)
|
||||
int ntfs_bmp_add_data(struct ntfs_bmp *bmp, VCN vcn, u8 *data)
|
||||
{
|
||||
int i = 0;
|
||||
int old;
|
||||
|
@ -365,13 +360,13 @@ int ntfs_bmp_add_data (struct ntfs_bmp *bmp, VCN vcn, u8 *data)
|
|||
if (!bmp || !data)
|
||||
return -1;
|
||||
|
||||
old = ROUND_UP (bmp->count, 16);
|
||||
old = ROUND_UP(bmp->count, 16);
|
||||
bmp->count++;
|
||||
new = ROUND_UP (bmp->count, 16);
|
||||
new = ROUND_UP(bmp->count, 16);
|
||||
|
||||
if (old != new) {
|
||||
bmp->data = realloc (bmp->data, new * sizeof (*bmp->data));
|
||||
bmp->data_vcn = realloc (bmp->data_vcn , new * sizeof (*bmp->data_vcn));
|
||||
bmp->data = realloc(bmp->data, new * sizeof(*bmp->data));
|
||||
bmp->data_vcn = realloc(bmp->data_vcn , new * sizeof(*bmp->data_vcn));
|
||||
}
|
||||
|
||||
for (i = 0; i < bmp->count-1; i++)
|
||||
|
@ -379,8 +374,8 @@ int ntfs_bmp_add_data (struct ntfs_bmp *bmp, VCN vcn, u8 *data)
|
|||
break;
|
||||
|
||||
if ((bmp->count-i) > 0) {
|
||||
memmove (&bmp->data[i+1], &bmp->data[i], (bmp->count-i) * sizeof (*bmp->data));
|
||||
memmove (&bmp->data_vcn[i+1], &bmp->data_vcn[i], (bmp->count-i) * sizeof (*bmp->data_vcn));
|
||||
memmove(&bmp->data[i+1], &bmp->data[i], (bmp->count-i) * sizeof(*bmp->data));
|
||||
memmove(&bmp->data_vcn[i+1], &bmp->data_vcn[i], (bmp->count-i) * sizeof(*bmp->data_vcn));
|
||||
}
|
||||
|
||||
bmp->data[i] = data;
|
||||
|
@ -392,7 +387,7 @@ int ntfs_bmp_add_data (struct ntfs_bmp *bmp, VCN vcn, u8 *data)
|
|||
/**
|
||||
* ntfs_bmp_get_data
|
||||
*/
|
||||
u8 * ntfs_bmp_get_data (struct ntfs_bmp *bmp, VCN vcn)
|
||||
u8 * ntfs_bmp_get_data(struct ntfs_bmp *bmp, VCN vcn)
|
||||
{
|
||||
u8 *buffer;
|
||||
int i;
|
||||
|
@ -412,30 +407,30 @@ u8 * ntfs_bmp_get_data (struct ntfs_bmp *bmp, VCN vcn)
|
|||
|
||||
for (i = 0; i < bmp->count; i++) {
|
||||
if (vcn == bmp->data_vcn[i]) {
|
||||
//printf ("reusing bitmap cluster %lld\n", vcn);
|
||||
//ntfs_log_debug("reusing bitmap cluster %lld\n", vcn);
|
||||
return bmp->data[i];
|
||||
}
|
||||
}
|
||||
|
||||
buffer = calloc (1, cs); // XXX could be smaller if attr size < cluster size
|
||||
buffer = calloc(1, cs); // XXX could be smaller if attr size < cluster size
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
//printf ("loading from bitmap cluster %lld\n", vcn);
|
||||
//printf ("loading from bitmap byte %lld\n", vcn<<cb);
|
||||
if (ntfs_attr_pread (bmp->attr, vcn<<cb, cs, buffer) < 0) {
|
||||
free (buffer);
|
||||
//ntfs_log_debug("loading from bitmap cluster %lld\n", vcn);
|
||||
//ntfs_log_debug("loading from bitmap byte %lld\n", vcn<<cb);
|
||||
if (ntfs_attr_pread(bmp->attr, vcn<<cb, cs, buffer) < 0) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ntfs_bmp_add_data (bmp, vcn, buffer); // XXX retval
|
||||
ntfs_bmp_add_data(bmp, vcn, buffer); // XXX retval
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_bmp_set_range
|
||||
*/
|
||||
int ntfs_bmp_set_range (struct ntfs_bmp *bmp, VCN vcn, s64 length, int value)
|
||||
int ntfs_bmp_set_range(struct ntfs_bmp *bmp, VCN vcn, s64 length, int value)
|
||||
{
|
||||
// shouldn't all the vcns be lcns?
|
||||
s64 i;
|
||||
|
@ -460,15 +455,15 @@ int ntfs_bmp_set_range (struct ntfs_bmp *bmp, VCN vcn, s64 length, int value)
|
|||
vcn_start = vcn;
|
||||
vcn_finish = vcn + length - 1;
|
||||
|
||||
//printf ("vcn_start = %d, vcn_finish = %d\n", vcn_start, vcn_finish);
|
||||
a = ROUND_DOWN (vcn_start, csib);
|
||||
b = ROUND_DOWN (vcn_finish, csib) + 1;
|
||||
//ntfs_log_debug("vcn_start = %d, vcn_finish = %d\n", vcn_start, vcn_finish);
|
||||
a = ROUND_DOWN(vcn_start, csib);
|
||||
b = ROUND_DOWN(vcn_finish, csib) + 1;
|
||||
|
||||
//printf ("a = %lld, b = %lld\n", a, b);
|
||||
//ntfs_log_debug("a = %lld, b = %lld\n", a, b);
|
||||
|
||||
for (i = a; i < b; i += csib) {
|
||||
//printf ("ntfs_bmp_get_data %lld\n", i);
|
||||
buffer = ntfs_bmp_get_data (bmp, i);
|
||||
//ntfs_log_debug("ntfs_bmp_get_data %lld\n", i);
|
||||
buffer = ntfs_bmp_get_data(bmp, i);
|
||||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
|
@ -493,7 +488,7 @@ int ntfs_bmp_set_range (struct ntfs_bmp *bmp, VCN vcn, s64 length, int value)
|
|||
}
|
||||
|
||||
if ((byte_finish - byte_start) > 1) {
|
||||
memset (buffer+byte_start+1, value, byte_finish-byte_start-1);
|
||||
memset(buffer+byte_start+1, value, byte_finish-byte_start-1);
|
||||
} else if (byte_finish == byte_start) {
|
||||
mask_start &= mask_finish;
|
||||
mask_finish = 0x00;
|
||||
|
@ -509,13 +504,13 @@ int ntfs_bmp_set_range (struct ntfs_bmp *bmp, VCN vcn, s64 length, int value)
|
|||
}
|
||||
|
||||
#if 1
|
||||
printf (GREEN "Modified: inode %lld, ", bmp->attr->ni->mft_no);
|
||||
ntfs_log_debug(GREEN "Modified: inode %lld, ", bmp->attr->ni->mft_no);
|
||||
switch (bmp->attr->type) {
|
||||
case AT_BITMAP: printf ("$BITMAP"); break;
|
||||
case AT_DATA: printf ("$DATA"); break;
|
||||
default: break;
|
||||
case AT_BITMAP: ntfs_log_debug("$BITMAP"); break;
|
||||
case AT_DATA: ntfs_log_debug("$DATA"); break;
|
||||
default: break;
|
||||
}
|
||||
printf (" vcn %lld-%lld\n" END, vcn>>12, (vcn+length-1)>>12);
|
||||
ntfs_log_debug(" vcn %lld-%lld\n" END, vcn>>12, (vcn+length-1)>>12);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
@ -523,7 +518,7 @@ int ntfs_bmp_set_range (struct ntfs_bmp *bmp, VCN vcn, s64 length, int value)
|
|||
/**
|
||||
* ntfs_bmp_find_last_set
|
||||
*/
|
||||
s64 ntfs_bmp_find_last_set (struct ntfs_bmp *bmp)
|
||||
s64 ntfs_bmp_find_last_set(struct ntfs_bmp *bmp)
|
||||
{
|
||||
s64 clust_count;
|
||||
s64 byte_count;
|
||||
|
@ -540,17 +535,17 @@ s64 ntfs_bmp_find_last_set (struct ntfs_bmp *bmp)
|
|||
// find cluster size of bmp
|
||||
|
||||
byte_count = bmp->attr->data_size;
|
||||
clust_count = ROUND_UP (byte_count, bmp->vol->cluster_size) >> bmp->vol->cluster_size_bits;
|
||||
clust_count = ROUND_UP(byte_count, bmp->vol->cluster_size) >> bmp->vol->cluster_size_bits;
|
||||
|
||||
//printf ("bitmap = %lld bytes\n", byte_count);
|
||||
//printf ("bitmap = %lld buffers\n", clust_count);
|
||||
//ntfs_log_debug("bitmap = %lld bytes\n", byte_count);
|
||||
//ntfs_log_debug("bitmap = %lld buffers\n", clust_count);
|
||||
|
||||
// for each cluster backwards
|
||||
for (clust = clust_count-1; clust >= 0; clust--) {
|
||||
//printf ("cluster %lld\n", clust);
|
||||
//printf ("get vcn %lld\n", clust << (bmp->vol->cluster_size_bits + 3));
|
||||
buffer = ntfs_bmp_get_data (bmp, clust << (bmp->vol->cluster_size_bits + 3));
|
||||
//utils_dump_mem (buffer, 0, 8, DM_NO_ASCII);
|
||||
//ntfs_log_debug("cluster %lld\n", clust);
|
||||
//ntfs_log_debug("get vcn %lld\n", clust << (bmp->vol->cluster_size_bits + 3));
|
||||
buffer = ntfs_bmp_get_data(bmp, clust << (bmp->vol->cluster_size_bits + 3));
|
||||
//utils_dump_mem(buffer, 0, 8, DM_NO_ASCII);
|
||||
if (!buffer)
|
||||
return -2;
|
||||
if ((clust == (clust_count-1) && ((byte_count % bmp->vol->cluster_size) != 0))) {
|
||||
|
@ -558,14 +553,14 @@ s64 ntfs_bmp_find_last_set (struct ntfs_bmp *bmp)
|
|||
} else {
|
||||
byte = bmp->vol->cluster_size;
|
||||
}
|
||||
//printf ("start byte = %d\n", byte);
|
||||
//ntfs_log_debug("start byte = %d\n", byte);
|
||||
// for each byte backward
|
||||
for (byte--; byte >= 0; byte--) {
|
||||
//printf ("\tbyte %d (%d)\n", byte, buffer[byte]);
|
||||
//ntfs_log_debug("\tbyte %d (%d)\n", byte, buffer[byte]);
|
||||
// for each bit shift up
|
||||
note = -1;
|
||||
for (bit = 7; bit >= 0; bit--) {
|
||||
//printf ("\t\tbit %d (%d)\n", (1<<bit), buffer[byte] & (1<<bit));
|
||||
//ntfs_log_debug("\t\tbit %d (%d)\n", (1<<bit), buffer[byte] & (1<<bit));
|
||||
if (buffer[byte] & (1<<bit)) {
|
||||
// if set, keep note
|
||||
note = bit;
|
||||
|
@ -574,7 +569,7 @@ s64 ntfs_bmp_find_last_set (struct ntfs_bmp *bmp)
|
|||
}
|
||||
if (note >= 0) {
|
||||
// if note, return value
|
||||
//printf ("match %lld (c=%lld,b=%d,n=%d)\n", (((clust << bmp->vol->cluster_size_bits) + byte) << 3) + note, clust, byte, note);
|
||||
//ntfs_log_debug("match %lld (c=%lld,b=%d,n=%d)\n", (((clust << bmp->vol->cluster_size_bits) + byte) << 3) + note, clust, byte, note);
|
||||
return ((((clust << bmp->vol->cluster_size_bits) + byte) << 3) + note);
|
||||
}
|
||||
}
|
||||
|
@ -586,7 +581,7 @@ s64 ntfs_bmp_find_last_set (struct ntfs_bmp *bmp)
|
|||
/**
|
||||
* ntfs_bmp_find_space
|
||||
*/
|
||||
int ntfs_bmp_find_space (struct ntfs_bmp *bmp, LCN start, long size)
|
||||
int ntfs_bmp_find_space(struct ntfs_bmp *bmp, LCN start, long size)
|
||||
{
|
||||
if (!bmp)
|
||||
return 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* bootsect.c - Boot sector handling code. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2000-2005 Anton Altaparmakov
|
||||
|
@ -20,7 +20,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
|
@ -36,9 +38,9 @@
|
|||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include "bootsect.h"
|
||||
#include "debug.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* ntfs_boot_sector_is_ntfs - check if buffer contains a valid ntfs boot sector
|
||||
|
@ -54,11 +56,11 @@
|
|||
*
|
||||
* Return TRUE if @b contains a valid ntfs boot sector and FALSE if not.
|
||||
*/
|
||||
BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, const BOOL silent)
|
||||
BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, const BOOL silent __attribute__((unused)))
|
||||
{
|
||||
u32 i;
|
||||
|
||||
Sprintf(silent, "\nBeginning bootsector check...\n");
|
||||
ntfs_log_debug("\nBeginning bootsector check...\n");
|
||||
|
||||
/* Calculate the checksum. Note, this is just a simple addition of
|
||||
all u32 values in the bootsector starting at the beginning and
|
||||
|
@ -68,31 +70,31 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, const BOOL silent)
|
|||
u32 *u = (u32 *)b;
|
||||
u32 *bi = (u32 *)(&b->checksum);
|
||||
|
||||
Sprintf(silent, "Calculating bootsector checksum... ");
|
||||
ntfs_log_debug("Calculating bootsector checksum... ");
|
||||
|
||||
for (i = 0; u < bi; ++u)
|
||||
i += le32_to_cpup(u);
|
||||
|
||||
if (le32_to_cpu(b->checksum) && le32_to_cpu(b->checksum) != i)
|
||||
goto not_ntfs;
|
||||
Sprintf(silent, "OK\n");
|
||||
ntfs_log_debug("OK\n");
|
||||
}
|
||||
|
||||
/* Check OEMidentifier is "NTFS " */
|
||||
Sprintf(silent, "Checking OEMid... ");
|
||||
ntfs_log_debug("Checking OEMid... ");
|
||||
if (b->oem_id != cpu_to_le64(0x202020205346544eULL)) /* "NTFS " */
|
||||
goto not_ntfs;
|
||||
Sprintf(silent, "OK\n");
|
||||
ntfs_log_debug("OK\n");
|
||||
|
||||
/* Check bytes per sector value is between 256 and 4096. */
|
||||
Sprintf(silent, "Checking bytes per sector... ");
|
||||
ntfs_log_debug("Checking bytes per sector... ");
|
||||
if (le16_to_cpu(b->bpb.bytes_per_sector) < 0x100 ||
|
||||
le16_to_cpu(b->bpb.bytes_per_sector) > 0x1000)
|
||||
goto not_ntfs;
|
||||
Sprintf(silent, "OK\n");
|
||||
ntfs_log_debug("OK\n");
|
||||
|
||||
/* Check sectors per cluster value is valid. */
|
||||
Sprintf(silent, "Checking sectors per cluster... ");
|
||||
ntfs_log_debug("Checking sectors per cluster... ");
|
||||
switch (b->bpb.sectors_per_cluster) {
|
||||
case 1: case 2: case 4: case 8: case 16:
|
||||
case 32: case 64: case 128:
|
||||
|
@ -100,17 +102,17 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, const BOOL silent)
|
|||
default:
|
||||
goto not_ntfs;
|
||||
}
|
||||
Sprintf(silent, "OK\n");
|
||||
ntfs_log_debug("OK\n");
|
||||
|
||||
/* Check the cluster size is not above 65536 bytes. */
|
||||
Sprintf(silent, "Checking cluster size... ");
|
||||
ntfs_log_debug("Checking cluster size... ");
|
||||
if ((u32)le16_to_cpu(b->bpb.bytes_per_sector) *
|
||||
b->bpb.sectors_per_cluster > 0x10000)
|
||||
goto not_ntfs;
|
||||
Sprintf(silent, "OK\n");
|
||||
ntfs_log_debug("OK\n");
|
||||
|
||||
/* Check reserved/unused fields are really zero. */
|
||||
Sprintf(silent, "Checking reserved fields are zero... ");
|
||||
ntfs_log_debug("Checking reserved fields are zero... ");
|
||||
if (le16_to_cpu(b->bpb.reserved_sectors) ||
|
||||
le16_to_cpu(b->bpb.root_entries) ||
|
||||
le16_to_cpu(b->bpb.sectors) ||
|
||||
|
@ -118,10 +120,10 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, const BOOL silent)
|
|||
le32_to_cpu(b->bpb.large_sectors) ||
|
||||
b->bpb.fats)
|
||||
goto not_ntfs;
|
||||
Sprintf(silent, "OK\n");
|
||||
ntfs_log_debug("OK\n");
|
||||
|
||||
/* Check clusters per file mft record value is valid. */
|
||||
Sprintf(silent, "Checking clusters per mft record... ");
|
||||
ntfs_log_debug("Checking clusters per mft record... ");
|
||||
if ((u8)b->clusters_per_mft_record < 0xe1 ||
|
||||
(u8)b->clusters_per_mft_record > 0xf7) {
|
||||
switch (b->clusters_per_mft_record) {
|
||||
|
@ -131,10 +133,10 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, const BOOL silent)
|
|||
goto not_ntfs;
|
||||
}
|
||||
}
|
||||
Sprintf(silent, "OK\n");
|
||||
ntfs_log_debug("OK\n");
|
||||
|
||||
/* Check clusters per index block value is valid. */
|
||||
Sprintf(silent, "Checking clusters per index block... ");
|
||||
ntfs_log_debug("Checking clusters per index block... ");
|
||||
if ((u8)b->clusters_per_index_record < 0xe1 ||
|
||||
(u8)b->clusters_per_index_record > 0xf7) {
|
||||
switch (b->clusters_per_index_record) {
|
||||
|
@ -144,17 +146,17 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, const BOOL silent)
|
|||
goto not_ntfs;
|
||||
}
|
||||
}
|
||||
Sprintf(silent, "OK\n");
|
||||
ntfs_log_debug("OK\n");
|
||||
|
||||
if (b->end_of_sector_marker != cpu_to_le16(0xaa55))
|
||||
Dputs("Warning: Bootsector has invalid end of sector marker.");
|
||||
ntfs_log_debug("Warning: Bootsector has invalid end of sector marker.\n");
|
||||
|
||||
Sprintf(silent, "Bootsector check completed successfully.\n");
|
||||
ntfs_log_debug("Bootsector check completed successfully.\n");
|
||||
|
||||
return TRUE;
|
||||
not_ntfs:
|
||||
Sprintf(silent, "FAILED\n");
|
||||
Sprintf(silent, "Bootsector check failed. Aborting...\n");
|
||||
ntfs_log_debug("FAILED\n");
|
||||
ntfs_log_debug("Bootsector check failed. Aborting...\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -178,18 +180,18 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
|
|||
|
||||
vol->sector_size = le16_to_cpu(bs->bpb.bytes_per_sector);
|
||||
vol->sector_size_bits = ffs(vol->sector_size) - 1;
|
||||
Dprintf("SectorSize = 0x%x\n", vol->sector_size);
|
||||
Dprintf("SectorSizeBits = %u\n", vol->sector_size_bits);
|
||||
ntfs_log_debug("SectorSize = 0x%x\n", vol->sector_size);
|
||||
ntfs_log_debug("SectorSizeBits = %u\n", vol->sector_size_bits);
|
||||
/*
|
||||
* The bounds checks on mft_lcn and mft_mirr_lcn (i.e. them being
|
||||
* below or equal the number_of_clusters) really belong in the
|
||||
* ntfs_boot_sector_is_ntfs but in this way we can just do this once.
|
||||
*/
|
||||
sectors_per_cluster = bs->bpb.sectors_per_cluster;
|
||||
Dprintf("NumberOfSectors = %lli\n", sle64_to_cpu(bs->number_of_sectors));
|
||||
Dprintf("SectorsPerCluster = 0x%x\n", sectors_per_cluster);
|
||||
ntfs_log_debug("NumberOfSectors = %lli\n", sle64_to_cpu(bs->number_of_sectors));
|
||||
ntfs_log_debug("SectorsPerCluster = 0x%x\n", sectors_per_cluster);
|
||||
if (sectors_per_cluster & (sectors_per_cluster - 1)) {
|
||||
Dprintf("Error: %s is not a valid NTFS partition! "
|
||||
ntfs_log_debug("Error: %s is not a valid NTFS partition! "
|
||||
"sectors_per_cluster is not a power of 2.\n",
|
||||
vol->dev->d_name);
|
||||
return -1;
|
||||
|
@ -199,18 +201,19 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
|
|||
|
||||
vol->mft_lcn = sle64_to_cpu(bs->mft_lcn);
|
||||
vol->mftmirr_lcn = sle64_to_cpu(bs->mftmirr_lcn);
|
||||
Dprintf("MFT LCN = 0x%llx\n", vol->mft_lcn);
|
||||
Dprintf("MFTMirr LCN = 0x%llx\n", vol->mftmirr_lcn);
|
||||
ntfs_log_debug("MFT LCN = 0x%llx\n", vol->mft_lcn);
|
||||
ntfs_log_debug("MFTMirr LCN = 0x%llx\n", vol->mftmirr_lcn);
|
||||
if (vol->mft_lcn > vol->nr_clusters ||
|
||||
vol->mftmirr_lcn > vol->nr_clusters) {
|
||||
Dprintf("Error: %s is not a valid NTFS partition! ($Mft LCN "
|
||||
"or\n$MftMirr LCN is greater than the number "
|
||||
"of clusters!\n", vol->dev->d_name);
|
||||
ntfs_log_debug("Error: %s is not a valid NTFS partition!\n",
|
||||
vol->dev->d_name);
|
||||
ntfs_log_debug("($Mft LCN or $MftMirr LCN is greater than the "
|
||||
"number of clusters!)\n");
|
||||
return -1;
|
||||
}
|
||||
vol->cluster_size = sectors_per_cluster * vol->sector_size;
|
||||
if (vol->cluster_size & (vol->cluster_size - 1)) {
|
||||
Dprintf("Error: %s is not a valid NTFS partition! "
|
||||
ntfs_log_debug("Error: %s is not a valid NTFS partition! "
|
||||
"cluster_size is not a power of 2.\n",
|
||||
vol->dev->d_name);
|
||||
return -1;
|
||||
|
@ -222,9 +225,9 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
|
|||
* illegal, thus signed char is actually ok!
|
||||
*/
|
||||
c = bs->clusters_per_mft_record;
|
||||
Dprintf("ClusterSize = 0x%x\n", (unsigned)vol->cluster_size);
|
||||
Dprintf("ClusterSizeBits = %u\n", vol->cluster_size_bits);
|
||||
Dprintf("ClustersPerMftRecord = 0x%x\n", c);
|
||||
ntfs_log_debug("ClusterSize = 0x%x\n", (unsigned)vol->cluster_size);
|
||||
ntfs_log_debug("ClusterSizeBits = %u\n", vol->cluster_size_bits);
|
||||
ntfs_log_debug("ClustersPerMftRecord = 0x%x\n", c);
|
||||
/*
|
||||
* When clusters_per_mft_record is negative, it means that it is to
|
||||
* be taken to be the negative base 2 logarithm of the mft_record_size
|
||||
|
@ -236,24 +239,24 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
|
|||
else
|
||||
vol->mft_record_size = c << vol->cluster_size_bits;
|
||||
if (vol->mft_record_size & (vol->mft_record_size - 1)) {
|
||||
Dprintf("Error: %s is not a valid NTFS partition! "
|
||||
ntfs_log_debug("Error: %s is not a valid NTFS partition! "
|
||||
"mft_record_size is not a power of 2.\n",
|
||||
vol->dev->d_name);
|
||||
return -1;
|
||||
}
|
||||
vol->mft_record_size_bits = ffs(vol->mft_record_size) - 1;
|
||||
Dprintf("MftRecordSize = 0x%x\n", (unsigned)vol->mft_record_size);
|
||||
Dprintf("MftRecordSizeBits = %u\n", vol->mft_record_size_bits);
|
||||
ntfs_log_debug("MftRecordSize = 0x%x\n", (unsigned)vol->mft_record_size);
|
||||
ntfs_log_debug("MftRecordSizeBits = %u\n", vol->mft_record_size_bits);
|
||||
/* Same as above for INDX record. */
|
||||
c = bs->clusters_per_index_record;
|
||||
Dprintf("ClustersPerINDXRecord = 0x%x\n", c);
|
||||
ntfs_log_debug("ClustersPerINDXRecord = 0x%x\n", c);
|
||||
if (c < 0)
|
||||
vol->indx_record_size = 1 << -c;
|
||||
else
|
||||
vol->indx_record_size = c << vol->cluster_size_bits;
|
||||
vol->indx_record_size_bits = ffs(vol->indx_record_size) - 1;
|
||||
Dprintf("INDXRecordSize = 0x%x\n", (unsigned)vol->indx_record_size);
|
||||
Dprintf("INDXRecordSizeBits = %u\n", vol->indx_record_size_bits);
|
||||
ntfs_log_debug("INDXRecordSize = 0x%x\n", (unsigned)vol->indx_record_size);
|
||||
ntfs_log_debug("INDXRecordSizeBits = %u\n", vol->indx_record_size_bits);
|
||||
/*
|
||||
* Work out the size of the MFT mirror in number of mft records. If the
|
||||
* cluster size is less than or equal to the size taken by four mft
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* collate.c - NTFS collation handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2004 Anton Altaparmakov
|
||||
|
@ -20,17 +20,25 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "collate.h"
|
||||
#include "debug.h"
|
||||
#include "unistr.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* ntfs_collate_binary
|
||||
*/
|
||||
static int ntfs_collate_binary(ntfs_volume *vol __attribute__((unused)),
|
||||
const void *data1, const int data1_len,
|
||||
const void *data2, const int data2_len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
rc = memcmp(data1, data2, min(data1_len, data2_len));
|
||||
if (!rc && (data1_len != data2_len)) {
|
||||
if (data1_len < data2_len)
|
||||
|
@ -38,10 +46,13 @@ static int ntfs_collate_binary(ntfs_volume *vol __attribute__((unused)),
|
|||
else
|
||||
rc = 1;
|
||||
}
|
||||
ntfs_debug("Done, returning %i.", rc);
|
||||
ntfs_log_trace("Done, returning %i.", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_collate_ntofs_ulong
|
||||
*/
|
||||
static int ntfs_collate_ntofs_ulong(ntfs_volume *vol __attribute__((unused)),
|
||||
const void *data1, const int data1_len,
|
||||
const void *data2, const int data2_len)
|
||||
|
@ -49,9 +60,9 @@ static int ntfs_collate_ntofs_ulong(ntfs_volume *vol __attribute__((unused)),
|
|||
int rc;
|
||||
u32 d1, d2;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
if (data1_len != data2_len || data1_len != 4) {
|
||||
ntfs_error(, "data1_len or/and data2_len not equal to 4.");
|
||||
ntfs_log_error("data1_len or/and data2_len not equal to 4.");
|
||||
return NTFS_COLLATION_ERROR;
|
||||
}
|
||||
d1 = le32_to_cpup(data1);
|
||||
|
@ -64,24 +75,27 @@ static int ntfs_collate_ntofs_ulong(ntfs_volume *vol __attribute__((unused)),
|
|||
else
|
||||
rc = 1;
|
||||
}
|
||||
ntfs_debug("Done, returning %i.", rc);
|
||||
ntfs_log_trace("Done, returning %i.\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_collate_file_name
|
||||
*/
|
||||
static int ntfs_collate_file_name(ntfs_volume *vol,
|
||||
const void *data1, const int data1_len __attribute__((unused)),
|
||||
const void *data2, const int data2_len __attribute__((unused)))
|
||||
{
|
||||
int rc;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
rc = ntfs_file_values_compare(data1, data2, NTFS_COLLATION_ERROR,
|
||||
IGNORE_CASE, vol->upcase, vol->upcase_len);
|
||||
if (!rc)
|
||||
rc = ntfs_file_values_compare(data1, data2,
|
||||
NTFS_COLLATION_ERROR, CASE_SENSITIVE,
|
||||
vol->upcase, vol->upcase_len);
|
||||
ntfs_debug("Done, returning %i.", rc);
|
||||
ntfs_log_trace("Done, returning %i.\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -125,9 +139,9 @@ int ntfs_collate(ntfs_volume *vol, COLLATION_RULES cr,
|
|||
{
|
||||
int i;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
if (!vol || !data1 || !data2 || data1_len < 0 || data2_len < 0) {
|
||||
ntfs_error(, "Invalid arguments passed.");
|
||||
ntfs_log_error("Invalid arguments passed.");
|
||||
return NTFS_COLLATION_ERROR;
|
||||
}
|
||||
/*
|
||||
|
@ -151,6 +165,6 @@ int ntfs_collate(ntfs_volume *vol, COLLATION_RULES cr,
|
|||
return ntfs_do_collate0x1[i](vol, data1, data1_len,
|
||||
data2, data2_len);
|
||||
err:
|
||||
ntfs_error(, "Unknown collation rule.");
|
||||
ntfs_log_debug("Unknown collation rule.\n");
|
||||
return NTFS_COLLATION_ERROR;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* compat.c - Tweaks for Windows compatibility
|
||||
*
|
||||
* Copyright (c) 2002 Richard Russon
|
||||
|
@ -22,7 +22,9 @@
|
|||
|
||||
#ifdef WINDOWS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* compress.c - Compressed attribute handling code. Part of the Linux-NTFS
|
||||
* project.
|
||||
*
|
||||
|
@ -21,7 +21,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
|
@ -43,6 +45,7 @@
|
|||
#include "layout.h"
|
||||
#include "runlist.h"
|
||||
#include "compress.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* ntfs_compression_constants - enum of constants used in the compression code
|
||||
|
@ -93,9 +96,9 @@ static int ntfs_decompress(u8 *dest, const u32 dest_size,
|
|||
u8 tag; /* Current tag. */
|
||||
int token; /* Loop counter for the eight tokens in tag. */
|
||||
|
||||
Dprintf("Entering, cb_size = 0x%x.\n", (unsigned)cb_size);
|
||||
ntfs_log_trace("Entering, cb_size = 0x%x.\n", (unsigned)cb_size);
|
||||
do_next_sb:
|
||||
Dprintf("Beginning sub-block at offset = 0x%x in the cb.\n",
|
||||
ntfs_log_debug("Beginning sub-block at offset = 0x%x in the cb.\n",
|
||||
cb - cb_start);
|
||||
/*
|
||||
* Have we reached the end of the compression block or the end of the
|
||||
|
@ -104,7 +107,7 @@ do_next_sb:
|
|||
* first two checks do not detect it.
|
||||
*/
|
||||
if (cb == cb_end || !le16_to_cpup((u16*)cb) || dest == dest_end) {
|
||||
Dprintf("Completed. Returning success (0).\n");
|
||||
ntfs_log_debug("Completed. Returning success (0).\n");
|
||||
return 0;
|
||||
}
|
||||
/* Setup offset for the current sub-block destination. */
|
||||
|
@ -124,7 +127,7 @@ do_next_sb:
|
|||
goto return_overflow;
|
||||
/* Now, we are ready to process the current sub-block (sb). */
|
||||
if (!(le16_to_cpup((u16*)cb) & NTFS_SB_IS_COMPRESSED)) {
|
||||
Dprintf("Found uncompressed sub-block.\n");
|
||||
ntfs_log_debug("Found uncompressed sub-block.\n");
|
||||
/* This sb is not compressed, just copy it into destination. */
|
||||
/* Advance source position to first data byte. */
|
||||
cb += 2;
|
||||
|
@ -138,7 +141,7 @@ do_next_sb:
|
|||
dest += NTFS_SB_SIZE;
|
||||
goto do_next_sb;
|
||||
}
|
||||
Dprintf("Found compressed sub-block.\n");
|
||||
ntfs_log_debug("Found compressed sub-block.\n");
|
||||
/* This sb is compressed, decompress it into destination. */
|
||||
/* Forward to the first tag in the sub-block. */
|
||||
cb += 2;
|
||||
|
@ -148,7 +151,7 @@ do_next_tag:
|
|||
if (dest < dest_sb_end) {
|
||||
int nr_bytes = dest_sb_end - dest;
|
||||
|
||||
Dprintf("Filling incomplete sub-block with zeroes.\n");
|
||||
ntfs_log_debug("Filling incomplete sub-block with zeroes.\n");
|
||||
/* Zero remainder and update destination position. */
|
||||
memset(dest, 0, nr_bytes);
|
||||
dest += nr_bytes;
|
||||
|
@ -238,7 +241,7 @@ do_next_tag:
|
|||
/* No tokens left in the current tag. Continue with the next tag. */
|
||||
goto do_next_tag;
|
||||
return_overflow:
|
||||
Dprintf("Failed. Returning -EOVERFLOW.\n");
|
||||
ntfs_log_debug("Failed. Returning -EOVERFLOW.\n");
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
|
@ -329,8 +332,7 @@ s64 ntfs_compressed_attr_pread(ntfs_attr *na, s64 pos, s64 count, void *b)
|
|||
int err;
|
||||
unsigned int nr_cbs, cb_clusters;
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, attr 0x%x, pos 0x%llx, "
|
||||
"count 0x%llx.\n", __FUNCTION__,
|
||||
ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, pos 0x%llx, count 0x%llx.\n",
|
||||
(unsigned long long)na->ni->mft_no, na->type,
|
||||
(long long)pos, (long long)count);
|
||||
if (!na || !NAttrCompressed(na) || !na->ni || !na->ni->vol || !b ||
|
||||
|
@ -421,7 +423,7 @@ do_next_cb:
|
|||
}
|
||||
if (rl->lcn == LCN_HOLE) {
|
||||
/* Sparse cb, zero out destination range overlapping the cb. */
|
||||
Dprintf("Found sparse compression block.\n");
|
||||
ntfs_log_debug("Found sparse compression block.\n");
|
||||
to_read = min(count, cb_size - ofs);
|
||||
memset(b, 0, to_read);
|
||||
ofs = 0;
|
||||
|
@ -434,7 +436,7 @@ do_next_cb:
|
|||
* Uncompressed cb, read it straight into the destination range
|
||||
* overlapping the cb.
|
||||
*/
|
||||
Dprintf("Found uncompressed compression block.\n");
|
||||
ntfs_log_debug("Found uncompressed compression block.\n");
|
||||
/*
|
||||
* Read the uncompressed data into the destination buffer.
|
||||
* NOTE: We cheat a little bit here by marking the attribute as
|
||||
|
@ -480,7 +482,7 @@ do_next_cb:
|
|||
* Compressed cb, decompress it into the temporary buffer, then
|
||||
* copy the data to the destination range overlapping the cb.
|
||||
*/
|
||||
Dprintf("Found compressed compression block.\n");
|
||||
ntfs_log_debug("Found compressed compression block.\n");
|
||||
/*
|
||||
* Read the compressed data into the temporary buffer.
|
||||
* NOTE: We cheat a little bit here by marking the attribute as
|
||||
|
@ -520,7 +522,7 @@ do_next_cb:
|
|||
/* Just a precaution. */
|
||||
if (cb_pos + 2 <= cb_end)
|
||||
*(u16*)cb_pos = 0;
|
||||
Dprintf("Successfully read the compression block.\n");
|
||||
ntfs_log_debug("Successfully read the compression block.\n");
|
||||
if (ntfs_decompress(dest, cb_size, cb, cb_size) < 0) {
|
||||
err = errno;
|
||||
free(cb);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* debug.c - Debugging output functions. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2002-2004 Anton Altaparmakov
|
||||
|
@ -19,11 +19,14 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "attrib.h"
|
||||
#include "debug.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* Sprintf - silencable output to stderr
|
||||
|
@ -61,6 +64,9 @@ void __Sprintf(const int silent, const char *fmt, ...)
|
|||
|
||||
/* Debug output to stderr. To get it run ./configure --enable-debug. */
|
||||
|
||||
/**
|
||||
* __ntfs_error
|
||||
*/
|
||||
void __ntfs_error(const char *function, const char *fmt, ...)
|
||||
{
|
||||
int eo = errno;
|
||||
|
@ -78,7 +84,10 @@ void __ntfs_error(const char *function, const char *fmt, ...)
|
|||
errno = eo;
|
||||
}
|
||||
|
||||
void __ntfs_debug (const char *file, int line, const char *function,
|
||||
/**
|
||||
* __ntfs_debug
|
||||
*/
|
||||
void __ntfs_debug(const char *file, int line, const char *function,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
int eo = errno;
|
||||
|
@ -96,6 +105,9 @@ void __ntfs_debug (const char *file, int line, const char *function,
|
|||
errno = eo;
|
||||
}
|
||||
|
||||
/**
|
||||
* __Dprintf
|
||||
*/
|
||||
void __Dprintf(const char *fmt, ...)
|
||||
{
|
||||
int eo = errno;
|
||||
|
@ -107,6 +119,9 @@ void __Dprintf(const char *fmt, ...)
|
|||
errno = eo;
|
||||
}
|
||||
|
||||
/**
|
||||
* __Dputs
|
||||
*/
|
||||
void __Dputs(const char *s)
|
||||
{
|
||||
int eo = errno;
|
||||
|
@ -114,6 +129,9 @@ void __Dputs(const char *s)
|
|||
errno = eo;
|
||||
}
|
||||
|
||||
/**
|
||||
* __Dperror
|
||||
*/
|
||||
void __Dperror(const char *s)
|
||||
{
|
||||
int eo = errno;
|
||||
|
@ -121,6 +139,9 @@ void __Dperror(const char *s)
|
|||
errno = eo;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NTFS_DISABLE_DEBUG_LOGGING
|
||||
/**
|
||||
* ntfs_debug_runlist_dump - Dump a runlist.
|
||||
*/
|
||||
|
@ -131,12 +152,12 @@ void ntfs_debug_runlist_dump(const runlist_element *rl)
|
|||
"LCN_ENOENT ", "LCN_EINVAL ",
|
||||
"LCN_unknown " };
|
||||
|
||||
Dputs("NTFS-fs DEBUG: Dumping runlist (values in hex):");
|
||||
ntfs_log_debug("NTFS-fs DEBUG: Dumping runlist (values in hex):\n");
|
||||
if (!rl) {
|
||||
Dputs("Run list not present.");
|
||||
ntfs_log_debug("Run list not present.\n");
|
||||
return;
|
||||
}
|
||||
Dputs("VCN LCN Run length");
|
||||
ntfs_log_debug("VCN LCN Run length\n");
|
||||
do {
|
||||
LCN lcn = (rl + i)->lcn;
|
||||
|
||||
|
@ -145,14 +166,11 @@ void ntfs_debug_runlist_dump(const runlist_element *rl)
|
|||
|
||||
if (idx > -LCN_EINVAL - 1)
|
||||
idx = 4;
|
||||
Dprintf("%-16llx %s %-16llx%s\n", rl[i].vcn,
|
||||
lcn_str[idx], rl[i].length,
|
||||
rl[i].length ? "" : " (runlist end)");
|
||||
ntfs_log_debug("%-16llx %s %-16llx%s\n", rl[i].vcn, lcn_str[idx], rl[i].length, rl[i].length ? "" : " (runlist end)");
|
||||
} else
|
||||
Dprintf("%-16llx %-16llx %-16llx%s\n", rl[i].vcn,
|
||||
rl[i].lcn, rl[i].length,
|
||||
rl[i].length ? "" : " (runlist end)");
|
||||
ntfs_log_debug("%-16llx %-16llx %-16llx%s\n", rl[i].vcn, rl[i].lcn, rl[i].length, rl[i].length ? "" : " (runlist end)");
|
||||
} while (rl[i++].length);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* device.c - Low level device io functions. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2004 Anton Altaparmakov
|
||||
|
@ -19,7 +19,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
|
@ -46,19 +48,20 @@
|
|||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
# include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_FD_H
|
||||
# include <linux/fd.h>
|
||||
#include <linux/fd.h>
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_HDREG_H
|
||||
# include <linux/hdreg.h>
|
||||
#include <linux/hdreg.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "mst.h"
|
||||
#include "debug.h"
|
||||
#include "device.h"
|
||||
#include "logging.h"
|
||||
|
||||
#if defined(linux) && defined(_IO) && !defined(BLKGETSIZE)
|
||||
#define BLKGETSIZE _IO(0x12,96) /* Get device size in 512-byte blocks. */
|
||||
|
@ -132,8 +135,7 @@ int ntfs_device_free(struct ntfs_device *dev)
|
|||
errno = EBUSY;
|
||||
return -1;
|
||||
}
|
||||
if (dev->d_name)
|
||||
free(dev->d_name);
|
||||
free(dev->d_name);
|
||||
free(dev);
|
||||
return 0;
|
||||
}
|
||||
|
@ -162,8 +164,7 @@ s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
|
|||
s64 br, total;
|
||||
struct ntfs_device_operations *dops;
|
||||
|
||||
Dprintf("%s(): Entering for pos 0x%llx, count 0x%llx.\n", __FUNCTION__,
|
||||
pos, count);
|
||||
ntfs_log_trace("Entering for pos 0x%llx, count 0x%llx.\n", pos, count);
|
||||
if (!b || count < 0 || pos < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
@ -173,8 +174,8 @@ s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
|
|||
dops = dev->d_ops;
|
||||
/* Locate to position. */
|
||||
if (dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
|
||||
Dprintf("ntfs_pread: device seek to 0x%llx returned error: "
|
||||
"%s\n", pos, strerror(errno));
|
||||
ntfs_log_perror("ntfs_pread: device seek to 0x%llx returned error",
|
||||
pos);
|
||||
return -1;
|
||||
}
|
||||
/* Read the data. */
|
||||
|
@ -218,8 +219,7 @@ s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
|
|||
s64 written, total;
|
||||
struct ntfs_device_operations *dops;
|
||||
|
||||
Dprintf("%s(): Entering for pos 0x%llx, count 0x%llx.\n", __FUNCTION__,
|
||||
pos, count);
|
||||
ntfs_log_trace("Entering for pos 0x%llx, count 0x%llx.\n", pos, count);
|
||||
if (!b || count < 0 || pos < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
@ -233,8 +233,8 @@ s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
|
|||
dops = dev->d_ops;
|
||||
/* Locate to position. */
|
||||
if (dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
|
||||
Dprintf("ntfs_pwrite: seek to 0x%llx returned error: %s\n",
|
||||
pos, strerror(errno));
|
||||
ntfs_log_perror("ntfs_pwrite: seek to 0x%llx returned error",
|
||||
pos);
|
||||
return -1;
|
||||
}
|
||||
NDevSetDirty(dev);
|
||||
|
@ -405,7 +405,7 @@ s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count,
|
|||
br = ntfs_pread(vol->dev, lcn << vol->cluster_size_bits,
|
||||
count << vol->cluster_size_bits, b);
|
||||
if (br < 0) {
|
||||
Dperror("Error reading cluster(s)");
|
||||
ntfs_log_perror("Error reading cluster(s)");
|
||||
return br;
|
||||
}
|
||||
return br >> vol->cluster_size_bits;
|
||||
|
@ -441,7 +441,7 @@ s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn,
|
|||
else
|
||||
bw = count << vol->cluster_size_bits;
|
||||
if (bw < 0) {
|
||||
Dperror("Error writing cluster(s)");
|
||||
ntfs_log_perror("Error writing cluster(s)");
|
||||
return bw;
|
||||
}
|
||||
return bw >> vol->cluster_size_bits;
|
||||
|
@ -491,7 +491,7 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
|
|||
{ u64 size;
|
||||
|
||||
if (dev->d_ops->ioctl(dev, BLKGETSIZE64, &size) >= 0) {
|
||||
Dprintf("BLKGETSIZE64 nr bytes = %llu (0x%llx)\n",
|
||||
ntfs_log_debug("BLKGETSIZE64 nr bytes = %llu (0x%llx)\n",
|
||||
(unsigned long long)size,
|
||||
(unsigned long long)size);
|
||||
return (s64)size / block_size;
|
||||
|
@ -502,8 +502,8 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
|
|||
{ unsigned long size;
|
||||
|
||||
if (dev->d_ops->ioctl(dev, BLKGETSIZE, &size) >= 0) {
|
||||
Dprintf("BLKGETSIZE nr 512 byte blocks = %lu "
|
||||
"(0x%lx)\n", size, size);
|
||||
ntfs_log_debug("BLKGETSIZE nr 512 byte blocks = %lu (0x%lx)\n",
|
||||
size, size);
|
||||
return (s64)size * 512 / block_size;
|
||||
}
|
||||
}
|
||||
|
@ -512,7 +512,7 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
|
|||
{ struct floppy_struct this_floppy;
|
||||
|
||||
if (dev->d_ops->ioctl(dev, FDGETPRM, &this_floppy) >= 0) {
|
||||
Dprintf("FDGETPRM nr 512 byte blocks = %lu (0x%lx)\n",
|
||||
ntfs_log_debug("FDGETPRM nr 512 byte blocks = %lu (0x%lx)\n",
|
||||
(unsigned long)this_floppy.size,
|
||||
(unsigned long)this_floppy.size);
|
||||
return (s64)this_floppy.size * 512 / block_size;
|
||||
|
@ -560,7 +560,7 @@ s64 ntfs_device_partition_start_sector_get(struct ntfs_device *dev)
|
|||
{ struct hd_geometry geo;
|
||||
|
||||
if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) {
|
||||
Dprintf("HDIO_GETGEO start_sect = %lu (0x%lx)\n",
|
||||
ntfs_log_debug("HDIO_GETGEO start_sect = %lu (0x%lx)\n",
|
||||
geo.start, geo.start);
|
||||
return geo.start;
|
||||
}
|
||||
|
@ -593,7 +593,7 @@ int ntfs_device_heads_get(struct ntfs_device *dev)
|
|||
{ struct hd_geometry geo;
|
||||
|
||||
if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) {
|
||||
Dprintf("HDIO_GETGEO heads = %u (0x%x)\n",
|
||||
ntfs_log_debug("HDIO_GETGEO heads = %u (0x%x)\n",
|
||||
(unsigned)geo.heads,
|
||||
(unsigned)geo.heads);
|
||||
return geo.heads;
|
||||
|
@ -627,7 +627,7 @@ int ntfs_device_sectors_per_track_get(struct ntfs_device *dev)
|
|||
{ struct hd_geometry geo;
|
||||
|
||||
if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) {
|
||||
Dprintf("HDIO_GETGEO sectors_per_track = %u (0x%x)\n",
|
||||
ntfs_log_debug("HDIO_GETGEO sectors_per_track = %u (0x%x)\n",
|
||||
(unsigned)geo.sectors,
|
||||
(unsigned)geo.sectors);
|
||||
return geo.sectors;
|
||||
|
|
423
libntfs/dir.c
423
libntfs/dir.c
File diff suppressed because it is too large
Load Diff
157
libntfs/index.c
157
libntfs/index.c
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* index.c - NTFS index handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2004-2005 Anton Altaparmakov
|
||||
|
@ -21,7 +21,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
|
@ -33,6 +35,7 @@
|
|||
#include "index.h"
|
||||
#include "mst.h"
|
||||
#include "dir.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* ntfs_index_ctx_get - allocate and initialize a new index context
|
||||
|
@ -85,7 +88,7 @@ void ntfs_index_ctx_put(ntfs_index_context *ictx)
|
|||
cluster_size_bits,
|
||||
1, ictx->block_size,
|
||||
ictx->ia) != 1)
|
||||
ntfs_error(, "Failed to write out "
|
||||
ntfs_log_error("Failed to write out "
|
||||
"index block.");
|
||||
}
|
||||
/* Free resources. */
|
||||
|
@ -117,7 +120,7 @@ void ntfs_index_ctx_reinit(ntfs_index_context *ictx)
|
|||
cluster_size_bits,
|
||||
1, ictx->block_size,
|
||||
ictx->ia) != 1)
|
||||
ntfs_error(, "Failed to write out "
|
||||
ntfs_log_error("Failed to write out "
|
||||
"index block.");
|
||||
}
|
||||
/* Free resources. */
|
||||
|
@ -179,7 +182,7 @@ int ntfs_index_lookup(const void *key, const int key_len,
|
|||
ntfs_attr *na = NULL;
|
||||
int rc, err = 0;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
if (!key || key_len <= 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
@ -196,7 +199,7 @@ int ntfs_index_lookup(const void *key, const int key_len,
|
|||
CASE_SENSITIVE, 0, NULL, 0, actx);
|
||||
if (err) {
|
||||
if (errno == ENOENT) {
|
||||
ntfs_error(sb, "Index root attribute missing in inode "
|
||||
ntfs_log_error("Index root attribute missing in inode "
|
||||
"0x%llx.", ni->mft_no);
|
||||
err = EIO;
|
||||
} else
|
||||
|
@ -212,7 +215,7 @@ int ntfs_index_lookup(const void *key, const int key_len,
|
|||
/* Get collation rule type and validate it. */
|
||||
cr = ir->collation_rule;
|
||||
if (!ntfs_is_collation_rule_supported(cr)) {
|
||||
ntfs_error(sb, "Index uses unsupported collation rule 0x%x. "
|
||||
ntfs_log_error("Index uses unsupported collation rule 0x%x. "
|
||||
"Aborting lookup.", (unsigned)le32_to_cpu(cr));
|
||||
err = EOPNOTSUPP;
|
||||
goto err_out;
|
||||
|
@ -248,7 +251,7 @@ done:
|
|||
ictx->entry = ie;
|
||||
ictx->data = (u8*)ie + offsetof(INDEX_ENTRY, key);
|
||||
ictx->data_len = le16_to_cpu(ie->key_length);
|
||||
ntfs_debug("Done.");
|
||||
ntfs_log_trace("Done.\n");
|
||||
if (err) {
|
||||
errno = err;
|
||||
return -1;
|
||||
|
@ -262,7 +265,7 @@ done:
|
|||
rc = ntfs_collate(vol, cr, key, key_len, &ie->key,
|
||||
le16_to_cpu(ie->key_length));
|
||||
if (rc == NTFS_COLLATION_ERROR) {
|
||||
ntfs_error(, "Collation error. Probably filename "
|
||||
ntfs_log_error("Collation error. Probably filename "
|
||||
"contain invalid characters.");
|
||||
err = ERANGE;
|
||||
goto err_out;
|
||||
|
@ -288,7 +291,7 @@ done:
|
|||
* -1 with errno ENOENT.
|
||||
*/
|
||||
if (!(ie->flags & INDEX_ENTRY_NODE)) {
|
||||
ntfs_debug("Entry not found.");
|
||||
ntfs_log_debug("Entry not found.\n");
|
||||
err = ENOENT;
|
||||
goto ir_done;
|
||||
} /* Child node present, descend into it. */
|
||||
|
@ -301,7 +304,7 @@ done:
|
|||
na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION,
|
||||
ictx->name, ictx->name_len);
|
||||
if (!na) {
|
||||
ntfs_error(sb, "No index allocation attribute but index entry "
|
||||
ntfs_log_error("No index allocation attribute but index entry "
|
||||
"requires one. Inode 0x%llx is corrupt or "
|
||||
"library bug.", ni->mft_no);
|
||||
goto err_out;
|
||||
|
@ -309,28 +312,28 @@ done:
|
|||
/* Allocate memory to store index block. */
|
||||
ia = malloc(ictx->block_size);
|
||||
if (!ia) {
|
||||
ntfs_error(, "Not enough memory to allocate buffer for index"
|
||||
ntfs_log_error("Not enough memory to allocate buffer for index"
|
||||
" allocation.");
|
||||
err = ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
descend_into_child_node:
|
||||
ntfs_debug("Descend into node with VCN %lld.", vcn);
|
||||
ntfs_log_debug("Descend into node with VCN %lld.\n", vcn);
|
||||
/* Read index allocation block. */
|
||||
if (ntfs_attr_mst_pread(na, vcn << vol->cluster_size_bits, 1,
|
||||
ictx->block_size, ia) != 1) {
|
||||
ntfs_error(, "Failed to read index allocation.");
|
||||
ntfs_log_error("Failed to read index allocation.");
|
||||
goto err_out;
|
||||
}
|
||||
/* Catch multi sector transfer fixup errors. */
|
||||
if (!ntfs_is_indx_record(ia->magic)) {
|
||||
ntfs_error(sb, "Index record with vcn 0x%llx is corrupt. "
|
||||
ntfs_log_error("Index record with vcn 0x%llx is corrupt. "
|
||||
"Corrupt inode 0x%llx. Run chkdsk.",
|
||||
(long long)vcn, ni->mft_no);
|
||||
goto err_out;
|
||||
}
|
||||
if (sle64_to_cpu(ia->index_block_vcn) != vcn) {
|
||||
ntfs_error(sb, "Actual VCN (0x%llx) of index buffer is "
|
||||
ntfs_log_error("Actual VCN (0x%llx) of index buffer is "
|
||||
"different from expected VCN (0x%llx). Inode "
|
||||
"0x%llx is corrupt or driver bug.",
|
||||
(unsigned long long)
|
||||
|
@ -339,7 +342,7 @@ descend_into_child_node:
|
|||
goto err_out;
|
||||
}
|
||||
if (le32_to_cpu(ia->index.allocated_size) + 0x18 != ictx->block_size) {
|
||||
ntfs_error(sb, "Index buffer (VCN 0x%llx) of inode 0x%llx has "
|
||||
ntfs_log_error("Index buffer (VCN 0x%llx) of inode 0x%llx has "
|
||||
"a size (%u) differing from the index "
|
||||
"specified size (%u). Inode is corrupt or "
|
||||
"driver bug.", (unsigned long long)vcn,
|
||||
|
@ -350,7 +353,7 @@ descend_into_child_node:
|
|||
}
|
||||
index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
|
||||
if (index_end > (u8*)ia + ictx->block_size) {
|
||||
ntfs_error(sb, "Size of index buffer (VCN 0x%llx) of inode "
|
||||
ntfs_log_error("Size of index buffer (VCN 0x%llx) of inode "
|
||||
"0x%llx exceeds maximum size.",
|
||||
(unsigned long long)vcn, ni->mft_no);
|
||||
goto err_out;
|
||||
|
@ -368,7 +371,7 @@ descend_into_child_node:
|
|||
if ((u8*)ie < (u8*)ia || (u8*)ie +
|
||||
sizeof(INDEX_ENTRY_HEADER) > index_end ||
|
||||
(u8*)ie + le16_to_cpu(ie->length) > index_end) {
|
||||
ntfs_error(sb, "Index entry out of bounds in inode "
|
||||
ntfs_log_error("Index entry out of bounds in inode "
|
||||
"0x%llx.", ni->mft_no);
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -396,7 +399,7 @@ ia_done:
|
|||
rc = ntfs_collate(vol, cr, key, key_len, &ie->key,
|
||||
le16_to_cpu(ie->key_length));
|
||||
if (rc == NTFS_COLLATION_ERROR) {
|
||||
ntfs_error(, "Collation error. Probably filename "
|
||||
ntfs_log_error("Collation error. Probably filename "
|
||||
"contain invalid characters.");
|
||||
err = ERANGE;
|
||||
goto err_out;
|
||||
|
@ -421,12 +424,12 @@ ia_done:
|
|||
* the presence of a child node and if not present return ENOENT.
|
||||
*/
|
||||
if (!(ie->flags & INDEX_ENTRY_NODE)) {
|
||||
ntfs_debug("Entry not found.");
|
||||
ntfs_log_debug("Entry not found.\n");
|
||||
err = ENOENT;
|
||||
goto ia_done;
|
||||
}
|
||||
if ((ia->index.flags & NODE_MASK) == LEAF_NODE) {
|
||||
ntfs_error(sb, "Index entry with child node found in a leaf "
|
||||
ntfs_log_error("Index entry with child node found in a leaf "
|
||||
"node in inode 0x%llx.", ni->mft_no);
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -434,12 +437,11 @@ ia_done:
|
|||
vcn = sle64_to_cpup((sle64*)((u8*)ie + le16_to_cpu(ie->length) - 8));
|
||||
if (vcn >= 0)
|
||||
goto descend_into_child_node;
|
||||
ntfs_error(sb, "Negative child node vcn in inode 0x%llx.", ni->mft_no);
|
||||
ntfs_log_error("Negative child node vcn in inode 0x%llx.", ni->mft_no);
|
||||
err_out:
|
||||
if (na)
|
||||
ntfs_attr_close(na);
|
||||
if (ia)
|
||||
free(ia);
|
||||
free(ia);
|
||||
if (!err)
|
||||
err = EIO;
|
||||
if (actx)
|
||||
|
@ -447,7 +449,7 @@ err_out:
|
|||
errno = err;
|
||||
return -1;
|
||||
idx_err_out:
|
||||
ntfs_error(sb, "Corrupt index. Aborting lookup.");
|
||||
ntfs_log_error("Corrupt index. Aborting lookup.");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
|
@ -469,9 +471,9 @@ int ntfs_index_add_filename(ntfs_inode *ni, FILE_NAME_ATTR *fn, MFT_REF mref)
|
|||
INDEX_HEADER *ih;
|
||||
int err, fn_size, ie_size, allocated_size = 0;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
if (!ni || !fn) {
|
||||
ntfs_error(, "Invalid arguments.");
|
||||
ntfs_log_error("Invalid arguments.");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -485,12 +487,12 @@ retry:
|
|||
/* Find place where insert new entry. */
|
||||
if (!ntfs_index_lookup(fn, fn_size, ictx)) {
|
||||
err = EEXIST;
|
||||
ntfs_error(, "Index already have such entry.");
|
||||
ntfs_log_error("Index already have such entry.");
|
||||
goto err_out;
|
||||
}
|
||||
if (errno != ENOENT) {
|
||||
err = errno;
|
||||
ntfs_error(, "Failed to find place where to insert new entry.");
|
||||
ntfs_log_error("Failed to find place where to insert new entry.");
|
||||
goto err_out;
|
||||
}
|
||||
/* Some setup. */
|
||||
|
@ -512,21 +514,21 @@ retry:
|
|||
ictx->name_len);
|
||||
if (!na) {
|
||||
err = errno;
|
||||
ntfs_error(, "Failed to open INDEX_ROOT.");
|
||||
ntfs_log_error("Failed to open INDEX_ROOT.");
|
||||
goto err_out;
|
||||
}
|
||||
if (ntfs_attr_truncate(na, allocated_size + offsetof(
|
||||
INDEX_ROOT, index))) {
|
||||
err = EOPNOTSUPP;
|
||||
ntfs_attr_close(na);
|
||||
ntfs_error(, "Failed to truncate INDEX_ROOT.");
|
||||
ntfs_log_error("Failed to truncate INDEX_ROOT.");
|
||||
goto err_out;
|
||||
}
|
||||
ntfs_attr_close(na);
|
||||
ntfs_index_ctx_reinit(ictx);
|
||||
goto retry;
|
||||
}
|
||||
ntfs_debug("Not implemented case.");
|
||||
ntfs_log_debug("Not implemented case.\n");
|
||||
err = EOPNOTSUPP;
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -553,10 +555,10 @@ retry:
|
|||
ntfs_index_entry_mark_dirty(ictx);
|
||||
ntfs_index_ctx_put(ictx);
|
||||
free(ie);
|
||||
ntfs_debug("Done.");
|
||||
ntfs_log_trace("Done.\n");
|
||||
return 0;
|
||||
err_out:
|
||||
ntfs_debug("Failed.");
|
||||
ntfs_log_trace("Failed.\n");
|
||||
ntfs_index_ctx_put(ictx);
|
||||
errno = err;
|
||||
return -1;
|
||||
|
@ -579,10 +581,10 @@ int ntfs_index_rm(ntfs_index_context *ictx)
|
|||
u32 new_index_length;
|
||||
int err;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
if (!ictx || (!ictx->ia && !ictx->ir) ||
|
||||
ictx->entry->flags & INDEX_ENTRY_END) {
|
||||
ntfs_error(, "Invalid arguments.");
|
||||
ntfs_log_error("Invalid arguments.");
|
||||
err = EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -621,25 +623,25 @@ int ntfs_index_rm(ntfs_index_context *ictx)
|
|||
ictx->name_len);
|
||||
if (!na) {
|
||||
err = errno;
|
||||
ntfs_error(, "Failed to open INDEX_ROOT attribute. "
|
||||
ntfs_log_error("Failed to open INDEX_ROOT attribute. "
|
||||
"Leaving inconsist metadata.");
|
||||
goto err_out;
|
||||
}
|
||||
if (ntfs_attr_truncate(na, new_index_length + offsetof(
|
||||
INDEX_ROOT, index))) {
|
||||
err = errno;
|
||||
ntfs_error(, "Failed to truncate INDEX_ROOT attribute. "
|
||||
ntfs_log_error("Failed to truncate INDEX_ROOT attribute. "
|
||||
" Leaving inconsist metadata.");
|
||||
goto err_out;
|
||||
}
|
||||
ntfs_attr_close(na);
|
||||
}
|
||||
ntfs_index_ctx_reinit(ictx);
|
||||
ntfs_debug("Done.");
|
||||
ntfs_log_trace("Done.\n");
|
||||
return 0;
|
||||
err_out:
|
||||
ntfs_index_ctx_reinit(ictx);
|
||||
ntfs_debug("Failed.");
|
||||
ntfs_log_trace("Failed.\n");
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
@ -647,30 +649,29 @@ err_out:
|
|||
|
||||
#ifdef NTFS_RICH
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
|
||||
#include "index.h"
|
||||
#endif
|
||||
#include "rich.h"
|
||||
|
||||
/**
|
||||
* ntfs_ie_free
|
||||
*/
|
||||
void ntfs_ie_free (INDEX_ENTRY *ie)
|
||||
void ntfs_ie_free(INDEX_ENTRY *ie)
|
||||
{
|
||||
free (ie);
|
||||
free(ie);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_ie_create
|
||||
*/
|
||||
INDEX_ENTRY * ntfs_ie_create (void)
|
||||
INDEX_ENTRY * ntfs_ie_create(void)
|
||||
{
|
||||
int length;
|
||||
INDEX_ENTRY *ie;
|
||||
|
||||
length = 16;
|
||||
ie = calloc (1, length);
|
||||
ie = calloc(1, length);
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
|
@ -685,7 +686,7 @@ INDEX_ENTRY * ntfs_ie_create (void)
|
|||
/**
|
||||
* ntfs_ie_get_vcn
|
||||
*/
|
||||
VCN ntfs_ie_get_vcn (INDEX_ENTRY *ie)
|
||||
VCN ntfs_ie_get_vcn(INDEX_ENTRY *ie)
|
||||
{
|
||||
if (!ie)
|
||||
return -1;
|
||||
|
@ -698,17 +699,17 @@ VCN ntfs_ie_get_vcn (INDEX_ENTRY *ie)
|
|||
/**
|
||||
* ntfs_ie_copy
|
||||
*/
|
||||
INDEX_ENTRY * ntfs_ie_copy (INDEX_ENTRY *ie)
|
||||
INDEX_ENTRY * ntfs_ie_copy(INDEX_ENTRY *ie)
|
||||
{
|
||||
INDEX_ENTRY *copy = NULL;
|
||||
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
copy = malloc (ie->length);
|
||||
copy = malloc(ie->length);
|
||||
if (!copy)
|
||||
return NULL;
|
||||
memcpy (copy, ie, ie->length);
|
||||
memcpy(copy, ie, ie->length);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
@ -716,14 +717,14 @@ INDEX_ENTRY * ntfs_ie_copy (INDEX_ENTRY *ie)
|
|||
/**
|
||||
* ntfs_ie_set_vcn
|
||||
*/
|
||||
INDEX_ENTRY * ntfs_ie_set_vcn (INDEX_ENTRY *ie, VCN vcn)
|
||||
INDEX_ENTRY * ntfs_ie_set_vcn(INDEX_ENTRY *ie, VCN vcn)
|
||||
{
|
||||
if (!ie)
|
||||
return 0;
|
||||
|
||||
if (!(ie->flags & INDEX_ENTRY_NODE)) {
|
||||
ie->length += 8;
|
||||
ie = realloc (ie, ie->length);
|
||||
ie = realloc(ie, ie->length);
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
|
@ -737,7 +738,7 @@ INDEX_ENTRY * ntfs_ie_set_vcn (INDEX_ENTRY *ie, VCN vcn)
|
|||
/**
|
||||
* ntfs_ie_remove_vcn
|
||||
*/
|
||||
INDEX_ENTRY * ntfs_ie_remove_vcn (INDEX_ENTRY *ie)
|
||||
INDEX_ENTRY * ntfs_ie_remove_vcn(INDEX_ENTRY *ie)
|
||||
{
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
@ -746,14 +747,14 @@ INDEX_ENTRY * ntfs_ie_remove_vcn (INDEX_ENTRY *ie)
|
|||
|
||||
ie->length -= 8;
|
||||
ie->flags &= ~INDEX_ENTRY_NODE;
|
||||
ie = realloc (ie, ie->length);
|
||||
ie = realloc(ie, ie->length);
|
||||
return ie;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_ie_set_name
|
||||
*/
|
||||
INDEX_ENTRY * ntfs_ie_set_name (INDEX_ENTRY *ie, ntfschar *name, int namelen, FILE_NAME_TYPE_FLAGS nametype)
|
||||
INDEX_ENTRY * ntfs_ie_set_name(INDEX_ENTRY *ie, ntfschar *name, int namelen, FILE_NAME_TYPE_FLAGS nametype)
|
||||
{
|
||||
FILE_NAME_ATTR *file;
|
||||
int need;
|
||||
|
@ -789,50 +790,50 @@ INDEX_ENTRY * ntfs_ie_set_name (INDEX_ENTRY *ie, ntfschar *name, int namelen, FI
|
|||
* VCN vcn;
|
||||
*/
|
||||
|
||||
//printf ("key length = 0x%02X\n", ie->key_length);
|
||||
//printf ("new name length = %d\n", namelen);
|
||||
//ntfs_log_debug("key length = 0x%02X\n", ie->key_length);
|
||||
//ntfs_log_debug("new name length = %d\n", namelen);
|
||||
if (ie->key_length > 0) {
|
||||
file = &ie->key.file_name;
|
||||
//printf ("filename, length %d\n", file->file_name_length);
|
||||
need = ATTR_SIZE (namelen * sizeof (ntfschar) + 2) -
|
||||
ATTR_SIZE (file->file_name_length * sizeof (ntfschar) + 2);
|
||||
//ntfs_log_debug("filename, length %d\n", file->file_name_length);
|
||||
need = ATTR_SIZE(namelen * sizeof(ntfschar) + 2) -
|
||||
ATTR_SIZE(file->file_name_length * sizeof(ntfschar) + 2);
|
||||
} else {
|
||||
//printf ("no filename\n");
|
||||
need = ATTR_SIZE (sizeof (FILE_NAME_ATTR) + (namelen * sizeof (ntfschar)));
|
||||
//ntfs_log_debug("no filename\n");
|
||||
need = ATTR_SIZE(sizeof(FILE_NAME_ATTR) + (namelen * sizeof(ntfschar)));
|
||||
wipe = TRUE;
|
||||
}
|
||||
|
||||
//printf ("need 0x%02X bytes\n", need);
|
||||
//ntfs_log_debug("need 0x%02X bytes\n", need);
|
||||
|
||||
if (need != 0) {
|
||||
if (ie->flags & INDEX_ENTRY_NODE)
|
||||
vcn = ntfs_ie_get_vcn (ie);
|
||||
vcn = ntfs_ie_get_vcn(ie);
|
||||
|
||||
ie->length += need;
|
||||
ie->key_length += need;
|
||||
|
||||
//printf ("realloc 0x%02X\n", ie->length);
|
||||
ie = realloc (ie, ie->length);
|
||||
//ntfs_log_debug("realloc 0x%02X\n", ie->length);
|
||||
ie = realloc(ie, ie->length);
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
if (ie->flags & INDEX_ENTRY_NODE)
|
||||
ie = ntfs_ie_set_vcn (ie, vcn);
|
||||
ie = ntfs_ie_set_vcn(ie, vcn);
|
||||
|
||||
if (wipe)
|
||||
memset (&ie->key.file_name, 0, sizeof (FILE_NAME_ATTR));
|
||||
memset(&ie->key.file_name, 0, sizeof(FILE_NAME_ATTR));
|
||||
if (need > 0)
|
||||
memset ((u8*)ie + ie->length - need, 0, need);
|
||||
memset((u8*)ie + ie->length - need, 0, need);
|
||||
}
|
||||
|
||||
memcpy (ie->key.file_name.file_name, name, namelen * sizeof (ntfschar));
|
||||
memcpy(ie->key.file_name.file_name, name, namelen * sizeof(ntfschar));
|
||||
|
||||
ie->key.file_name.file_name_length = namelen;
|
||||
ie->key.file_name.file_name_type = nametype;
|
||||
ie->flags &= ~INDEX_ENTRY_END;
|
||||
|
||||
//printf ("ie->length = 0x%02X\n", ie->length);
|
||||
//printf ("ie->key_length = 0x%02X\n", ie->key_length);
|
||||
//ntfs_log_debug("ie->length = 0x%02X\n", ie->length);
|
||||
//ntfs_log_debug("ie->key_length = 0x%02X\n", ie->key_length);
|
||||
|
||||
return ie;
|
||||
}
|
||||
|
@ -840,7 +841,7 @@ INDEX_ENTRY * ntfs_ie_set_name (INDEX_ENTRY *ie, ntfschar *name, int namelen, FI
|
|||
/**
|
||||
* ntfs_ie_remove_name
|
||||
*/
|
||||
INDEX_ENTRY * ntfs_ie_remove_name (INDEX_ENTRY *ie)
|
||||
INDEX_ENTRY * ntfs_ie_remove_name(INDEX_ENTRY *ie)
|
||||
{
|
||||
VCN vcn = 0;
|
||||
|
||||
|
@ -850,18 +851,18 @@ INDEX_ENTRY * ntfs_ie_remove_name (INDEX_ENTRY *ie)
|
|||
return ie;
|
||||
|
||||
if (ie->flags & INDEX_ENTRY_NODE)
|
||||
vcn = ntfs_ie_get_vcn (ie);
|
||||
vcn = ntfs_ie_get_vcn(ie);
|
||||
|
||||
ie->length -= ATTR_SIZE (ie->key_length);
|
||||
ie->length -= ATTR_SIZE(ie->key_length);
|
||||
ie->key_length = 0;
|
||||
ie->flags |= INDEX_ENTRY_END;
|
||||
|
||||
ie = realloc (ie, ie->length);
|
||||
ie = realloc(ie, ie->length);
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
if (ie->flags & INDEX_ENTRY_NODE)
|
||||
ie = ntfs_ie_set_vcn (ie, vcn);
|
||||
ie = ntfs_ie_set_vcn(ie, vcn);
|
||||
return ie;
|
||||
}
|
||||
|
||||
|
|
199
libntfs/inode.c
199
libntfs/inode.c
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* inode.c - Inode handling code. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2002-2005 Anton Altaparmakov
|
||||
|
@ -21,7 +21,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
|
@ -34,7 +36,6 @@
|
|||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "attrib.h"
|
||||
#include "inode.h"
|
||||
|
@ -46,6 +47,7 @@
|
|||
#include "index.h"
|
||||
#include "dir.h"
|
||||
#include "ntfstime.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* Internal:
|
||||
|
@ -80,11 +82,10 @@ ntfs_inode *ntfs_inode_allocate(ntfs_volume *vol)
|
|||
static __inline__ int __ntfs_inode_release(ntfs_inode *ni)
|
||||
{
|
||||
if (NInoDirty(ni))
|
||||
Dputs("Eeek. Discarding dirty inode!");
|
||||
ntfs_log_debug("Eeek. Discarding dirty inode!\n");
|
||||
if (NInoAttrList(ni) && ni->attr_list)
|
||||
free(ni->attr_list);
|
||||
if (ni->mrec)
|
||||
free(ni->mrec);
|
||||
free(ni->mrec);
|
||||
free(ni);
|
||||
return 0;
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ ntfs_inode *ntfs_inode_open(ntfs_volume *vol, const MFT_REF mref)
|
|||
int err = 0;
|
||||
STANDARD_INFORMATION *std_info;
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx.\n", __FUNCTION__, MREF(mref));
|
||||
ntfs_log_trace("Entering for inode 0x%llx.\n", MREF(mref));
|
||||
if (!vol) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
|
@ -144,8 +145,8 @@ ntfs_inode *ntfs_inode_open(ntfs_volume *vol, const MFT_REF mref)
|
|||
if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED,
|
||||
0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to receive STANDARD_INFORMATION "
|
||||
"attribute.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Failed to receive STANDARD_INFORMATION "
|
||||
"attribute.\n");
|
||||
goto put_err_out;
|
||||
}
|
||||
std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr +
|
||||
|
@ -280,15 +281,15 @@ int ntfs_inode_close(ntfs_inode *ni)
|
|||
/* Ignore errors, they don't really matter. */
|
||||
if (tmp_nis)
|
||||
base_ni->extent_nis = tmp_nis;
|
||||
} else if(tmp_nis)
|
||||
} else if (tmp_nis)
|
||||
free(tmp_nis);
|
||||
/* Allow for error checking. */
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
if (i != -1)
|
||||
Dputs("Extent inode was not attached to base inode! "
|
||||
"Weird! Continuing regardless.");
|
||||
ntfs_log_debug("Extent inode was not attached to base inode! "
|
||||
"Weird! Continuing regardless.\n");
|
||||
}
|
||||
return __ntfs_inode_release(ni);
|
||||
}
|
||||
|
@ -329,8 +330,8 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
|
|||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
Dprintf("%s(): Opening extent inode 0x%llx (base mft record 0x%llx).\n",
|
||||
__FUNCTION__, (unsigned long long)mft_no,
|
||||
ntfs_log_trace("Opening extent inode 0x%llx (base mft record 0x%llx).\n",
|
||||
(unsigned long long)mft_no,
|
||||
(unsigned long long)base_ni->mft_no);
|
||||
/* Is the extent inode already open and attached to the base inode? */
|
||||
if (base_ni->nr_extents > 0) {
|
||||
|
@ -345,9 +346,8 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
|
|||
seq_no = MSEQNO_LE(mref);
|
||||
if (seq_no && seq_no != le16_to_cpu(
|
||||
ni->mrec->sequence_number)) {
|
||||
Dputs("Found stale extent mft reference! "
|
||||
"Corrupt file system. Run "
|
||||
"chkdsk.");
|
||||
ntfs_log_debug("Found stale extent mft reference! "
|
||||
"Corrupt file system. Run chkdsk.\n");
|
||||
errno = EIO;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ err_out:
|
|||
i = errno;
|
||||
__ntfs_inode_release(ni);
|
||||
errno = i;
|
||||
Dperror("Failed to open extent inode");
|
||||
ntfs_log_perror("Failed to open extent inode");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ int ntfs_inode_attach_all_extents(ntfs_inode *ni)
|
|||
u64 prev_attached = 0;
|
||||
|
||||
if (!ni) {
|
||||
Dprintf("%s(): Invalid arguments.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid arguments.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -409,15 +409,14 @@ int ntfs_inode_attach_all_extents(ntfs_inode *ni)
|
|||
if (ni->nr_extents == -1)
|
||||
ni = ni->base_ni;
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no);
|
||||
ntfs_log_trace("Entering for inode 0x%llx.\n", (long long) ni->mft_no);
|
||||
|
||||
/* Inode haven't got attribute list, thus nothing to attach. */
|
||||
if (!NInoAttrList(ni))
|
||||
return 0;
|
||||
|
||||
if (!ni->attr_list) {
|
||||
Dprintf("%s(): Corrupt in-memory struct.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Corrupt in-memory struct.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -430,8 +429,7 @@ int ntfs_inode_attach_all_extents(ntfs_inode *ni)
|
|||
prev_attached != MREF_LE(ale->mft_reference)) {
|
||||
if (!ntfs_extent_inode_open(ni,
|
||||
MREF_LE(ale->mft_reference))) {
|
||||
Dprintf("%s(): Couldn't attach extent inode.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Couldn't attach extent inode.\n");
|
||||
return -1;
|
||||
}
|
||||
prev_attached = MREF_LE(ale->mft_reference);
|
||||
|
@ -459,8 +457,8 @@ static int ntfs_inode_sync_standard_information(ntfs_inode *ni)
|
|||
if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED,
|
||||
0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to receive STANDARD_INFORMATION "
|
||||
"attribute.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Failed to receive STANDARD_INFORMATION "
|
||||
"attribute.\n");
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
errno = err;
|
||||
return -1;
|
||||
|
@ -507,8 +505,7 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni)
|
|||
ctx = ntfs_attr_get_search_ctx(ni, NULL);
|
||||
if (!ctx) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to get attribute search context.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to get attribute search context.\n");
|
||||
goto err_out;
|
||||
}
|
||||
/* Walk through all FILE_NAME attributes and update them. */
|
||||
|
@ -530,16 +527,14 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni)
|
|||
if (!index_ni) {
|
||||
if (!err)
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to open inode with index.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to open inode with index.\n");
|
||||
continue;
|
||||
}
|
||||
ictx = ntfs_index_ctx_get(index_ni, I30, 4);
|
||||
if (!ictx) {
|
||||
if (!err)
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to get index context.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to get index context.\n");
|
||||
ntfs_inode_close(index_ni);
|
||||
continue;
|
||||
}
|
||||
|
@ -550,7 +545,7 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni)
|
|||
else
|
||||
err = errno;
|
||||
}
|
||||
Dprintf("%s(): Index lookup failed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Index lookup failed.\n");
|
||||
ntfs_index_ctx_put(ictx);
|
||||
ntfs_inode_close(index_ni);
|
||||
continue;
|
||||
|
@ -584,7 +579,7 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni)
|
|||
/* Check for real error occurred. */
|
||||
if (errno != ENOENT) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Attribute lookup failed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Attribute lookup failed.\n");
|
||||
goto err_out;
|
||||
}
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
|
@ -628,8 +623,7 @@ int ntfs_inode_sync(ntfs_inode *ni)
|
|||
return -1;
|
||||
}
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no);
|
||||
ntfs_log_trace("Entering for inode 0x%llx.\n", (long long) ni->mft_no);
|
||||
|
||||
/* Update STANDARD_INFORMATION. */
|
||||
if ((ni->mrec->flags & MFT_RECORD_IN_USE) && ni->nr_extents != -1 &&
|
||||
|
@ -639,8 +633,7 @@ int ntfs_inode_sync(ntfs_inode *ni)
|
|||
if (err != EIO)
|
||||
err = EBUSY;
|
||||
}
|
||||
Dprintf("%s(): Failed to sync standard information.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to sync standard information.\n");
|
||||
}
|
||||
|
||||
/* Update FILE_NAME's in the index. */
|
||||
|
@ -652,8 +645,7 @@ int ntfs_inode_sync(ntfs_inode *ni)
|
|||
if (err != EIO)
|
||||
err = EBUSY;
|
||||
}
|
||||
Dprintf("%s(): Failed to sync FILE_NAME attributes.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to sync FILE_NAME attributes.\n");
|
||||
NInoFileNameSetDirty(ni);
|
||||
}
|
||||
|
||||
|
@ -668,8 +660,8 @@ int ntfs_inode_sync(ntfs_inode *ni)
|
|||
err = errno;
|
||||
if (err != EIO)
|
||||
err = EBUSY;
|
||||
Dprintf("%s(): Attribute list sync failed "
|
||||
"(open failed).\n", __FUNCTION__);
|
||||
ntfs_log_trace("Attribute list sync failed (open "
|
||||
"failed).\n");
|
||||
}
|
||||
NInoAttrListSetDirty(ni);
|
||||
} else {
|
||||
|
@ -681,16 +673,14 @@ int ntfs_inode_sync(ntfs_inode *ni)
|
|||
err = errno;
|
||||
if (err != EIO)
|
||||
err = EBUSY;
|
||||
Dprintf("%s(): Attribute list "
|
||||
"sync failed (write failed).\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Attribute list sync "
|
||||
"failed (write failed).\n");
|
||||
}
|
||||
NInoAttrListSetDirty(ni);
|
||||
}
|
||||
} else {
|
||||
err = EIO;
|
||||
Dprintf("%s(): Attribute list sync failed "
|
||||
"(invalid size).\n", __FUNCTION__);
|
||||
ntfs_log_trace("Attribute list sync failed (invalid size).\n");
|
||||
NInoAttrListSetDirty(ni);
|
||||
}
|
||||
ntfs_attr_close(na);
|
||||
|
@ -706,8 +696,7 @@ int ntfs_inode_sync(ntfs_inode *ni)
|
|||
err = EBUSY;
|
||||
}
|
||||
NInoSetDirty(ni);
|
||||
Dprintf("%s(): Base MFT record sync failed.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Base MFT record sync failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -728,8 +717,8 @@ int ntfs_inode_sync(ntfs_inode *ni)
|
|||
err = EBUSY;
|
||||
}
|
||||
NInoSetDirty(eni);
|
||||
Dprintf("%s(): Extent MFT record sync "
|
||||
"failed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Extent MFT record sync "
|
||||
"failed.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -762,17 +751,15 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
ntfs_attr *na;
|
||||
|
||||
if (!ni) {
|
||||
Dprintf("%s(): Invalid arguments.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid arguments.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no);
|
||||
ntfs_log_trace("Entering for inode 0x%llx.\n", (long long) ni->mft_no);
|
||||
|
||||
if (NInoAttrList(ni) || ni->nr_extents) {
|
||||
Dprintf("%s(): Inode already has got attribute list.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Inode already has got attribute list.\n");
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
@ -782,7 +769,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
al = malloc(al_allocated);
|
||||
ale = (ATTR_LIST_ENTRY *) al;
|
||||
if (!al) {
|
||||
Dprintf("%s(): Not enough memory.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Not enough memory.\n");
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
@ -791,15 +778,14 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
ctx = ntfs_attr_get_search_ctx(ni, NULL);
|
||||
if (!ctx) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Couldn't get search context.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Couldn't get search context.\n");
|
||||
goto err_out;
|
||||
}
|
||||
/* Walk through all attributes. */
|
||||
while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) {
|
||||
if (ctx->attr->type == AT_ATTRIBUTE_LIST) {
|
||||
err = EIO;
|
||||
Dprintf("%s(): Eeek! Attribute list already present.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Eeek! Attribute list already present.\n");
|
||||
goto put_err_out;
|
||||
}
|
||||
/* Calculate new length of attribute list. */
|
||||
|
@ -810,8 +796,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
al_allocated += 0x40;
|
||||
aln = realloc(al, al_allocated);
|
||||
if (!aln) {
|
||||
Dprintf("%s(): Not enough memory.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Not enough memory.\n");
|
||||
err = ENOMEM;
|
||||
goto put_err_out;
|
||||
}
|
||||
|
@ -839,14 +824,14 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
/* Check for real error occurred. */
|
||||
if (errno != ENOENT) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Attribute lookup failed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Attribute lookup failed.\n");
|
||||
goto put_err_out;
|
||||
}
|
||||
/* Deallocate trailing memory. */
|
||||
aln = realloc(al, al_len);
|
||||
if (!aln) {
|
||||
err = errno;
|
||||
Dprintf("%s(): realloc() failed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("realloc() failed.\n");
|
||||
goto put_err_out;
|
||||
}
|
||||
al = aln;
|
||||
|
@ -865,8 +850,8 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
offsetof(ATTR_RECORD, resident_end))) {
|
||||
/* Failed to free space. */
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to free space for "
|
||||
"$ATTRIBUTE_LIST.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Failed to free space for "
|
||||
"$ATTRIBUTE_LIST.\n");
|
||||
goto rollback;
|
||||
}
|
||||
}
|
||||
|
@ -875,8 +860,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
if (ntfs_resident_attr_record_add(ni,
|
||||
AT_ATTRIBUTE_LIST, NULL, 0, NULL, 0, 0) < 0) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Couldn't add $ATTRIBUTE_LIST to MFT record.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Couldn't add $ATTRIBUTE_LIST to MFT record.\n");
|
||||
goto rollback;
|
||||
}
|
||||
|
||||
|
@ -884,14 +868,12 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0);
|
||||
if (!na) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to open just added $ATTRIBUTE_LIST.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to open just added $ATTRIBUTE_LIST.\n");
|
||||
goto remove_attrlist_record;
|
||||
}
|
||||
if (ntfs_attr_truncate(na, al_len)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to resize just added $ATTRIBUTE_LIST.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to resize just added $ATTRIBUTE_LIST.\n");
|
||||
ntfs_attr_close(na);
|
||||
goto remove_attrlist_record;;
|
||||
}
|
||||
|
@ -907,11 +889,11 @@ remove_attrlist_record:
|
|||
if (!ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0,
|
||||
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
|
||||
if (ntfs_attr_record_rm(ctx))
|
||||
Dprintf("%s(): Rollback failed. Failed to remove "
|
||||
"attribute list record.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Rollback failed. Failed to remove attribute "
|
||||
"list record.\n");
|
||||
} else
|
||||
Dprintf("%s(): Rollback failed. Couldn't find attribute list "
|
||||
"record.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Rollback failed. Couldn't find attribute list "
|
||||
"record.\n");
|
||||
/* Setup back in-memory runlist. */
|
||||
ni->attr_list = al;
|
||||
ni->attr_list_size = al_len;
|
||||
|
@ -931,14 +913,11 @@ rollback:
|
|||
sle64_to_cpu(ale->lowest_vcn),
|
||||
NULL, 0, ctx)) {
|
||||
if (ntfs_attr_record_move_to(ctx, ni))
|
||||
Dprintf("%s(): Rollback failed. "
|
||||
"Couldn't back attribute to "
|
||||
"base MFT record.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Rollback failed. Couldn't "
|
||||
"back attribute to base MFT record.\n");
|
||||
} else
|
||||
Dprintf("%s(): Rollback failed. "
|
||||
"ntfs_attr_lookup failed.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Rollback failed. ntfs_attr_lookup "
|
||||
"failed.\n");
|
||||
ntfs_attr_reinit_search_ctx(ctx);
|
||||
}
|
||||
ale = (ATTR_LIST_ENTRY*)((u8*)ale + le16_to_cpu(ale->length));
|
||||
|
@ -969,13 +948,13 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||
int freed, err;
|
||||
|
||||
if (!ni || size < 0) {
|
||||
Dprintf("%s(): Invalid arguments.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid arguments.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, size %d.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no, size);
|
||||
ntfs_log_trace("Entering for inode 0x%llx, size %d.\n",
|
||||
(long long) ni->mft_no, size);
|
||||
|
||||
freed = (le32_to_cpu(ni->mrec->bytes_allocated) -
|
||||
le32_to_cpu(ni->mrec->bytes_in_use));
|
||||
|
@ -986,8 +965,7 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||
ctx = ntfs_attr_get_search_ctx(ni, NULL);
|
||||
if (!ctx) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to get attribute search context.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to get attribute search context.\n");
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1010,8 +988,7 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||
0, ctx)) {
|
||||
if (errno != ENOENT) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Attribute lookup failed.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Attribute lookup failed.\n");
|
||||
goto put_err_out;
|
||||
}
|
||||
if (ctx->attr->type == AT_END) {
|
||||
|
@ -1032,8 +1009,7 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||
0, NULL, 0, ctx)) {
|
||||
err = errno;
|
||||
if (errno != ENOENT) {
|
||||
Dprintf("%s(): Attribute lookup failed."
|
||||
"\n", __FUNCTION__);
|
||||
ntfs_log_trace("Attribute lookup failed.\n");
|
||||
} else
|
||||
err = ENOSPC;
|
||||
goto put_err_out;
|
||||
|
@ -1045,8 +1021,7 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||
/* Move away attribute. */
|
||||
if (ntfs_attr_record_move_away(ctx, 0)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to move out attribute.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to move out attribute.\n");
|
||||
break;
|
||||
}
|
||||
freed += record_size;
|
||||
|
@ -1066,8 +1041,7 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||
NULL, 0, ctx)) {
|
||||
if (errno != ENOENT) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Attribute lookup failed.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Attribute lookup failed.\n");
|
||||
break;
|
||||
}
|
||||
if (ctx->attr->type == AT_END) {
|
||||
|
@ -1079,8 +1053,7 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||
put_err_out:
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
if (err == ENOSPC)
|
||||
Dprintf("%s(): No attributes left that can be moved out.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("No attributes left that can be moved out.\n");
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1091,12 +1064,12 @@ put_err_out:
|
|||
/**
|
||||
* ntfs_inode_close2
|
||||
*/
|
||||
int ntfs_inode_close2 (ntfs_inode *ni)
|
||||
int ntfs_inode_close2(ntfs_inode *ni)
|
||||
{
|
||||
if (!ni)
|
||||
return 0;
|
||||
|
||||
//printf (BOLD YELLOW "inode close %lld (%d)\n" END, ni->mft_no, ni->ref_count);
|
||||
//ntfs_log_debug(BOLD YELLOW "inode close %lld (%d)\n" END, ni->mft_no, ni->ref_count);
|
||||
|
||||
ni->ref_count--;
|
||||
if (ni->ref_count > 0)
|
||||
|
@ -1108,13 +1081,13 @@ int ntfs_inode_close2 (ntfs_inode *ni)
|
|||
// XXX temporary until we have commit/rollback
|
||||
NInoClearDirty(ni);
|
||||
|
||||
return ntfs_inode_close (ni);
|
||||
return ntfs_inode_close(ni);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_inode_open2
|
||||
*/
|
||||
ntfs_inode * ntfs_inode_open2 (ntfs_volume *vol, const MFT_REF mref)
|
||||
ntfs_inode * ntfs_inode_open2(ntfs_volume *vol, const MFT_REF mref)
|
||||
{
|
||||
ntfs_inode *ino = NULL;
|
||||
struct ntfs_dir *dir;
|
||||
|
@ -1134,12 +1107,12 @@ ntfs_inode * ntfs_inode_open2 (ntfs_volume *vol, const MFT_REF mref)
|
|||
}
|
||||
|
||||
if (ino) {
|
||||
//printf (BOLD YELLOW "inode reuse %lld\n" END, mref);
|
||||
//ntfs_log_debug(BOLD YELLOW "inode reuse %lld\n" END, mref);
|
||||
ino->ref_count++;
|
||||
return ino;
|
||||
}
|
||||
|
||||
ino = ntfs_inode_open (vol, mref);
|
||||
ino = ntfs_inode_open(vol, mref);
|
||||
if (!ino)
|
||||
return NULL;
|
||||
|
||||
|
@ -1154,7 +1127,7 @@ ntfs_inode * ntfs_inode_open2 (ntfs_volume *vol, const MFT_REF mref)
|
|||
ino->private_data = NULL;
|
||||
ino->ref_count = 1;
|
||||
|
||||
//printf (BOLD YELLOW "inode open %lld\n" END, mref);
|
||||
//ntfs_log_debug(BOLD YELLOW "inode open %lld\n" END, mref);
|
||||
return ino;
|
||||
}
|
||||
|
||||
|
@ -1162,20 +1135,20 @@ ntfs_inode * ntfs_inode_open2 (ntfs_volume *vol, const MFT_REF mref)
|
|||
* ntfs_inode_open3
|
||||
* open a deleted inode
|
||||
*/
|
||||
ntfs_inode * ntfs_inode_open3 (ntfs_volume *vol, const MFT_REF mref)
|
||||
ntfs_inode * ntfs_inode_open3(ntfs_volume *vol, const MFT_REF mref)
|
||||
{
|
||||
ntfs_inode *ino = NULL;
|
||||
|
||||
if (!vol)
|
||||
return NULL;
|
||||
|
||||
ino = calloc (1, sizeof (*ino));
|
||||
ino = calloc(1, sizeof(*ino));
|
||||
if (!ino)
|
||||
return NULL;
|
||||
|
||||
ino->mrec = malloc (vol->mft_record_size);
|
||||
ino->mrec = malloc(vol->mft_record_size);
|
||||
if (!ino->mrec) {
|
||||
free (ino);
|
||||
free(ino);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1188,14 +1161,14 @@ ntfs_inode * ntfs_inode_open3 (ntfs_volume *vol, const MFT_REF mref)
|
|||
ino->private_data = NULL;
|
||||
ino->ref_count = 1;
|
||||
|
||||
if (1 != ntfs_attr_mst_pread (vol->mft_na, MREF(mref) * vol->mft_record_size, 1, vol->mft_record_size, ino->mrec)) {
|
||||
//ntfs_inode_close2 (ino); ???
|
||||
free (ino->mrec);
|
||||
free (ino);
|
||||
if (1 != ntfs_attr_mst_pread(vol->mft_na, MREF(mref) * vol->mft_record_size, 1, vol->mft_record_size, ino->mrec)) {
|
||||
//ntfs_inode_close2(ino); ???
|
||||
free(ino->mrec);
|
||||
free(ino);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NInoSetDirty (ino);
|
||||
NInoSetDirty(ino);
|
||||
return ino;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* lcnalloc.c - Cluster (de)allocation code. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2002-2004 Anton Altaparmakov
|
||||
|
@ -20,7 +20,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
|
@ -39,6 +41,7 @@
|
|||
#include "runlist.h"
|
||||
#include "volume.h"
|
||||
#include "lcnalloc.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* ntfs_cluster_alloc - allocate clusters on an ntfs volume
|
||||
|
@ -107,13 +110,12 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||
int err = 0, rlpos, rlsize, buf_size;
|
||||
u8 pass, done_zones, search_zone, need_writeback, bit;
|
||||
|
||||
Dprintf("%s(): Entering with count = 0x%llx, start_lcn = 0x%llx, "
|
||||
"zone = %s_ZONE.\n", __FUNCTION__, (long long)count,
|
||||
(long long)start_lcn,
|
||||
ntfs_log_trace("Entering with count = 0x%llx, start_lcn = 0x%llx, zone = "
|
||||
"%s_ZONE.\n", (long long)count, (long long)start_lcn,
|
||||
zone == MFT_ZONE ? "MFT" : "DATA");
|
||||
if (!vol || count < 0 || start_lcn < -1 || !vol->lcnbmp_na ||
|
||||
(s8)zone < FIRST_ZONE || zone > LAST_ZONE) {
|
||||
Dprintf("%s(): Invalid arguments!\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid arguments!\n");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -207,30 +209,27 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||
clusters = count;
|
||||
rlpos = rlsize = 0;
|
||||
while (1) {
|
||||
Dprintf("%s(): Start of outer while loop: done_zones = 0x%x, "
|
||||
ntfs_log_trace("Start of outer while loop: done_zones = 0x%x, "
|
||||
"search_zone = %i, pass = %i, zone_start = "
|
||||
"0x%llx, zone_end = 0x%llx, bmp_initial_pos = "
|
||||
"0x%llx, bmp_pos = 0x%llx, rlpos = %i, rlsize = "
|
||||
"%i.\n", __FUNCTION__, done_zones, search_zone,
|
||||
pass, (long long)zone_start,
|
||||
(long long)zone_end, (long long)bmp_initial_pos,
|
||||
(long long)bmp_pos, rlpos, rlsize);
|
||||
"%i.\n", done_zones, search_zone, pass,
|
||||
(long long)zone_start, (long long)zone_end,
|
||||
(long long)bmp_initial_pos, (long long)bmp_pos,
|
||||
rlpos, rlsize);
|
||||
/* Loop until we run out of free clusters. */
|
||||
last_read_pos = bmp_pos >> 3;
|
||||
Dprintf("%s(): last_read_pos = 0x%llx.\n", __FUNCTION__,
|
||||
(long long)last_read_pos);
|
||||
ntfs_log_trace("last_read_pos = 0x%llx.\n", (long long)last_read_pos);
|
||||
br = ntfs_attr_pread(vol->lcnbmp_na, last_read_pos, 8192, buf);
|
||||
if (br <= 0) {
|
||||
if (!br) {
|
||||
/* Reached end of attribute. */
|
||||
Dprintf("%s(): End of attribute reached. "
|
||||
"Skipping to zone_pass_done.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("End of attribute reached. Skipping "
|
||||
"to zone_pass_done.\n");
|
||||
goto zone_pass_done;
|
||||
}
|
||||
err = errno;
|
||||
Dprintf("%s(): ntfs_attr_pread() failed. Aborting.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("ntfs_attr_pread() failed. Aborting.\n");
|
||||
goto err_ret;
|
||||
}
|
||||
/*
|
||||
|
@ -241,109 +240,90 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||
lcn = bmp_pos & 7;
|
||||
bmp_pos &= ~7;
|
||||
need_writeback = 0;
|
||||
Dprintf("%s(): Before inner while loop: buf_size = %i, "
|
||||
"lcn = 0x%llx, bmp_pos = 0x%llx, need_writeback "
|
||||
"= %i.\n", __FUNCTION__, buf_size,
|
||||
(long long)lcn, (long long)bmp_pos,
|
||||
ntfs_log_trace("Before inner while loop: buf_size = %i, lcn = "
|
||||
"0x%llx, bmp_pos = 0x%llx, need_writeback = %i.\n",
|
||||
buf_size, (long long)lcn, (long long)bmp_pos,
|
||||
need_writeback);
|
||||
while (lcn < buf_size && lcn + bmp_pos < zone_end) {
|
||||
byte = buf + (lcn >> 3);
|
||||
Dprintf("%s(): In inner while loop: buf_size = %i, "
|
||||
"lcn = 0x%llx, bmp_pos = 0x%llx, "
|
||||
ntfs_log_trace("In inner while loop: buf_size = %i, lcn = "
|
||||
"0x%llx, bmp_pos = 0x%llx, "
|
||||
"need_writeback = %i, byte ofs = 0x%x, "
|
||||
"*byte = 0x%x.\n", __FUNCTION__,
|
||||
buf_size, (long long)lcn,
|
||||
(long long)bmp_pos, need_writeback,
|
||||
(unsigned int)(lcn >> 3),
|
||||
"*byte = 0x%x.\n", buf_size,
|
||||
(long long)lcn, (long long)bmp_pos,
|
||||
need_writeback, (unsigned int)(lcn >> 3),
|
||||
(unsigned int)*byte);
|
||||
/* Skip full bytes. */
|
||||
if (*byte == 0xff) {
|
||||
lcn = (lcn + 8) & ~7;
|
||||
Dprintf("%s(): continuing while loop 1.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("continuing while loop 1.\n");
|
||||
continue;
|
||||
}
|
||||
bit = 1 << (lcn & 7);
|
||||
Dprintf("%s(): bit = %i.\n", __FUNCTION__, bit);
|
||||
ntfs_log_trace("bit = %i.\n", bit);
|
||||
/* If the bit is already set, go onto the next one. */
|
||||
if (*byte & bit) {
|
||||
lcn++;
|
||||
Dprintf("%s(): continuing while loop 2.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("continuing while loop 2.\n");
|
||||
continue;
|
||||
}
|
||||
/* Reallocate memory if necessary. */
|
||||
if ((rlpos + 2) * (int)sizeof(runlist) >= rlsize) {
|
||||
Dprintf("%s(): Reallocating space.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Reallocating space.\n");
|
||||
if (!rl)
|
||||
Dprintf("%s(): First free bit is at "
|
||||
"LCN = 0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)(lcn +
|
||||
bmp_pos));
|
||||
ntfs_log_trace("First free bit is at LCN = "
|
||||
"0x%llx.\n", (long long)(lcn + bmp_pos));
|
||||
rlsize += 4096;
|
||||
trl = (runlist*)realloc(rl, rlsize);
|
||||
if (!trl) {
|
||||
err = ENOMEM;
|
||||
Dprintf("%s(): Failed to allocate "
|
||||
"memory, going to "
|
||||
"wb_err_ret.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Failed to allocate memory, "
|
||||
"going to wb_err_ret.\n");
|
||||
goto wb_err_ret;
|
||||
}
|
||||
rl = trl;
|
||||
Dprintf("%s(): Reallocated memory, rlsize = "
|
||||
"0x%x.\n", __FUNCTION__,
|
||||
rlsize);
|
||||
ntfs_log_trace("Reallocated memory, rlsize = "
|
||||
"0x%x.\n", rlsize);
|
||||
}
|
||||
/* Allocate the bitmap bit. */
|
||||
*byte |= bit;
|
||||
/* We need to write this bitmap buffer back to disk! */
|
||||
need_writeback = 1;
|
||||
Dprintf("%s(): *byte = 0x%x, need_writeback is set.\n",
|
||||
__FUNCTION__, (unsigned int)*byte);
|
||||
ntfs_log_trace("*byte = 0x%x, need_writeback is set.\n",
|
||||
(unsigned int)*byte);
|
||||
/*
|
||||
* Coalesce with previous run if adjacent LCNs.
|
||||
* Otherwise, append a new run.
|
||||
*/
|
||||
Dprintf("%s(): Adding run (lcn 0x%llx, len 0x%llx), "
|
||||
ntfs_log_trace("Adding run (lcn 0x%llx, len 0x%llx), "
|
||||
"prev_lcn = 0x%llx, lcn = 0x%llx, "
|
||||
"bmp_pos = 0x%llx, prev_run_len = "
|
||||
"0x%llx, rlpos = %i.\n", __FUNCTION__,
|
||||
"0x%llx, rlpos = %i.\n",
|
||||
(long long)(lcn + bmp_pos), 1LL,
|
||||
(long long)prev_lcn, (long long)lcn,
|
||||
(long long)bmp_pos,
|
||||
(long long)prev_run_len, rlpos);
|
||||
if (prev_lcn == lcn + bmp_pos - prev_run_len && rlpos) {
|
||||
Dprintf("%s(): Coalescing to run (lcn 0x%llx, "
|
||||
"len 0x%llx).\n", __FUNCTION__,
|
||||
ntfs_log_trace("Coalescing to run (lcn 0x%llx, len "
|
||||
"0x%llx).\n",
|
||||
(long long)rl[rlpos - 1].lcn,
|
||||
(long long)
|
||||
rl[rlpos - 1].length);
|
||||
(long long) rl[rlpos - 1].length);
|
||||
rl[rlpos - 1].length = ++prev_run_len;
|
||||
Dprintf("%s(): Run now (lcn 0x%llx, len 0x%llx), "
|
||||
ntfs_log_trace("Run now (lcn 0x%llx, len 0x%llx), "
|
||||
"prev_run_len = 0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)rl[rlpos - 1].lcn,
|
||||
(long long)rl[rlpos - 1].length,
|
||||
(long long)prev_run_len);
|
||||
} else {
|
||||
if (rlpos) {
|
||||
Dprintf("%s(): Adding new run, "
|
||||
"(previous run lcn "
|
||||
"0x%llx, len 0x%llx).\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
rl[rlpos - 1].lcn,
|
||||
(long long)
|
||||
rl[rlpos - 1].length);
|
||||
ntfs_log_trace("Adding new run, (previous "
|
||||
"run lcn 0x%llx, len 0x%llx).\n",
|
||||
(long long) rl[rlpos - 1].lcn,
|
||||
(long long) rl[rlpos - 1].length);
|
||||
rl[rlpos].vcn = rl[rlpos - 1].vcn +
|
||||
prev_run_len;
|
||||
} else {
|
||||
Dprintf("%s(): Adding new run, is "
|
||||
"first run.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Adding new run, is first run.\n");
|
||||
rl[rlpos].vcn = start_vcn;
|
||||
}
|
||||
rl[rlpos].lcn = prev_lcn = lcn + bmp_pos;
|
||||
|
@ -359,19 +339,13 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||
* during the respective zone switches.
|
||||
*/
|
||||
tc = lcn + bmp_pos + 1;
|
||||
Dprintf("%s(): Done. Updating current zone "
|
||||
"position, tc = 0x%llx, "
|
||||
"search_zone = %i.\n",
|
||||
__FUNCTION__, (long long)tc,
|
||||
search_zone);
|
||||
ntfs_log_trace("Done. Updating current zone "
|
||||
"position, tc = 0x%llx, search_zone = %i.\n",
|
||||
(long long)tc, search_zone);
|
||||
switch (search_zone) {
|
||||
case 1:
|
||||
Dprintf("%s(): Before checks, "
|
||||
"vol->mft_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->mft_zone_pos);
|
||||
ntfs_log_trace("Before checks, vol->mft_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->mft_zone_pos);
|
||||
if (tc >= vol->mft_zone_end) {
|
||||
vol->mft_zone_pos =
|
||||
vol->mft_lcn;
|
||||
|
@ -382,20 +356,12 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||
tc > vol->mft_zone_pos)
|
||||
&& tc >= vol->mft_lcn)
|
||||
vol->mft_zone_pos = tc;
|
||||
Dprintf("%s(): After checks, "
|
||||
"vol->mft_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->mft_zone_pos);
|
||||
ntfs_log_trace("After checks, vol->mft_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->mft_zone_pos);
|
||||
break;
|
||||
case 2:
|
||||
Dprintf("%s(): Before checks, "
|
||||
"vol->data1_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->data1_zone_pos);
|
||||
ntfs_log_trace("Before checks, vol->data1_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->data1_zone_pos);
|
||||
if (tc >= vol->nr_clusters)
|
||||
vol->data1_zone_pos =
|
||||
vol->mft_zone_end;
|
||||
|
@ -404,55 +370,40 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||
tc > vol->data1_zone_pos)
|
||||
&& tc >= vol->mft_zone_end)
|
||||
vol->data1_zone_pos = tc;
|
||||
Dprintf("%s(): After checks, "
|
||||
"vol->data1_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->data1_zone_pos);
|
||||
ntfs_log_trace("After checks, vol->data1_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->data1_zone_pos);
|
||||
break;
|
||||
case 4:
|
||||
Dprintf("%s(): Before checks, "
|
||||
"vol->data2_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->data2_zone_pos);
|
||||
ntfs_log_trace("Before checks, vol->data2_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->data2_zone_pos);
|
||||
if (tc >= vol->mft_zone_start)
|
||||
vol->data2_zone_pos = 0;
|
||||
else if (bmp_initial_pos >=
|
||||
vol->data2_zone_pos ||
|
||||
tc > vol->data2_zone_pos)
|
||||
vol->data2_zone_pos = tc;
|
||||
Dprintf("%s(): After checks, "
|
||||
"vol->data2_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->data2_zone_pos);
|
||||
ntfs_log_trace("After checks, vol->data2_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->data2_zone_pos);
|
||||
break;
|
||||
default:
|
||||
if (rl)
|
||||
free(rl);
|
||||
free(rl);
|
||||
free(buf);
|
||||
NTFS_BUG("switch(search_zone) 1");
|
||||
NTFS_BUG("switch (search_zone) 1");
|
||||
return NULL;
|
||||
}
|
||||
Dprintf("%s(): Going to done_ret.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Going to done_ret.\n");
|
||||
goto done_ret;
|
||||
}
|
||||
lcn++;
|
||||
}
|
||||
bmp_pos += buf_size;
|
||||
Dprintf("%s(): After inner while loop: buf_size = 0x%x, "
|
||||
"lcn = 0x%llx, bmp_pos = 0x%llx, need_writeback "
|
||||
"= %i.\n", __FUNCTION__, buf_size,
|
||||
(long long)lcn, (long long)bmp_pos,
|
||||
need_writeback);
|
||||
ntfs_log_trace("After inner while loop: buf_size = 0x%x, lcn = "
|
||||
"0x%llx, bmp_pos = 0x%llx, need_writeback = %i.\n",
|
||||
buf_size, (long long)lcn,
|
||||
(long long)bmp_pos, need_writeback);
|
||||
if (need_writeback) {
|
||||
s64 bw;
|
||||
Dprintf("%s(): Writing back.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Writing back.\n");
|
||||
need_writeback = 0;
|
||||
bw = ntfs_attr_pwrite(vol->lcnbmp_na, last_read_pos,
|
||||
br, buf);
|
||||
|
@ -461,23 +412,20 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||
err = errno;
|
||||
else
|
||||
err = EIO;
|
||||
Dprintf("%s(): Bitmap writeback failed in "
|
||||
"read next buffer code path "
|
||||
"with error code %i.\n",
|
||||
__FUNCTION__, err);
|
||||
ntfs_log_trace("Bitmap writeback failed in read next "
|
||||
"buffer code path with error code %i.\n", err);
|
||||
goto err_ret;
|
||||
}
|
||||
}
|
||||
if (bmp_pos < zone_end) {
|
||||
Dprintf("%s(): Continuing outer while loop, bmp_pos = "
|
||||
ntfs_log_trace("Continuing outer while loop, bmp_pos = "
|
||||
"0x%llx, zone_end = 0x%llx.\n",
|
||||
__FUNCTION__, (long long)bmp_pos,
|
||||
(long long)bmp_pos,
|
||||
(long long)zone_end);
|
||||
continue;
|
||||
}
|
||||
zone_pass_done: /* Finished with the current zone pass. */
|
||||
Dprintf("%s(): At zone_pass_done, pass = %i.\n", __FUNCTION__,
|
||||
pass);
|
||||
ntfs_log_trace("At zone_pass_done, pass = %i.\n", pass);
|
||||
if (pass == 1) {
|
||||
/*
|
||||
* Now do pass 2, scanning the first part of the zone
|
||||
|
@ -496,41 +444,36 @@ zone_pass_done: /* Finished with the current zone pass. */
|
|||
zone_start = 0;
|
||||
break;
|
||||
default:
|
||||
NTFS_BUG("switch(search_zone) 2");
|
||||
NTFS_BUG("switch (search_zone) 2");
|
||||
}
|
||||
/* Sanity check. */
|
||||
if (zone_end < zone_start)
|
||||
zone_end = zone_start;
|
||||
bmp_pos = zone_start;
|
||||
Dprintf("%s(): Continuing outer while loop, pass = 2, "
|
||||
"zone_start = 0x%llx, zone_end = 0x%llx, "
|
||||
"bmp_pos = 0x%llx.\n", __FUNCTION__,
|
||||
ntfs_log_trace("Continuing outer while loop, pass = 2, "
|
||||
"zone_start = 0x%llx, zone_end = "
|
||||
"0x%llx, bmp_pos = 0x%llx.\n",
|
||||
zone_start, zone_end, bmp_pos);
|
||||
continue;
|
||||
} /* pass == 2 */
|
||||
done_zones_check:
|
||||
Dprintf("%s(): At done_zones_check, search_zone = %i, "
|
||||
"done_zones before = 0x%x, done_zones after = "
|
||||
"0x%x.\n", __FUNCTION__, search_zone,
|
||||
done_zones, done_zones | search_zone);
|
||||
ntfs_log_trace("At done_zones_check, search_zone = %i, done_zones "
|
||||
"before = 0x%x, done_zones after = 0x%x.\n",
|
||||
search_zone, done_zones, done_zones | search_zone);
|
||||
done_zones |= search_zone;
|
||||
if (done_zones < 7) {
|
||||
Dprintf("%s(): Switching zone.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Switching zone.\n");
|
||||
/* Now switch to the next zone we haven't done yet. */
|
||||
pass = 1;
|
||||
switch (search_zone) {
|
||||
case 1:
|
||||
Dprintf("%s(): Switching from mft zone to "
|
||||
"data1 zone.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Switching from mft zone to data1 "
|
||||
"zone.\n");
|
||||
/* Update mft zone position. */
|
||||
if (rlpos) {
|
||||
LCN tc;
|
||||
Dprintf("%s(): Before checks, "
|
||||
"vol->mft_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->mft_zone_pos);
|
||||
ntfs_log_trace("Before checks, vol->mft_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->mft_zone_pos);
|
||||
tc = rl[rlpos - 1].lcn +
|
||||
rl[rlpos - 1].length;
|
||||
if (tc >= vol->mft_zone_end) {
|
||||
|
@ -543,12 +486,8 @@ done_zones_check:
|
|||
tc > vol->mft_zone_pos)
|
||||
&& tc >= vol->mft_lcn)
|
||||
vol->mft_zone_pos = tc;
|
||||
Dprintf("%s(): After checks, "
|
||||
"vol->mft_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->mft_zone_pos);
|
||||
ntfs_log_trace("After checks, vol->mft_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->mft_zone_pos);
|
||||
}
|
||||
/* Switch from mft zone to data1 zone. */
|
||||
switch_to_data1_zone: search_zone = 2;
|
||||
|
@ -564,17 +503,13 @@ switch_to_data1_zone: search_zone = 2;
|
|||
}
|
||||
break;
|
||||
case 2:
|
||||
Dprintf("%s(): Switching from data1 zone to "
|
||||
"data2 zone.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Switching from data1 zone to data2 "
|
||||
"zone.\n");
|
||||
/* Update data1 zone position. */
|
||||
if (rlpos) {
|
||||
LCN tc;
|
||||
Dprintf("%s(): Before checks, "
|
||||
"vol->data1_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->data1_zone_pos);
|
||||
ntfs_log_trace("Before checks, vol->data1_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->data1_zone_pos);
|
||||
tc = rl[rlpos - 1].lcn +
|
||||
rl[rlpos - 1].length;
|
||||
if (tc >= vol->nr_clusters)
|
||||
|
@ -585,12 +520,8 @@ switch_to_data1_zone: search_zone = 2;
|
|||
tc > vol->data1_zone_pos)
|
||||
&& tc >= vol->mft_zone_end)
|
||||
vol->data1_zone_pos = tc;
|
||||
Dprintf("%s(): After checks, "
|
||||
"vol->data1_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->data1_zone_pos);
|
||||
ntfs_log_trace("After checks, vol->data1_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->data1_zone_pos);
|
||||
}
|
||||
/* Switch from data1 zone to data2 zone. */
|
||||
search_zone = 4;
|
||||
|
@ -606,17 +537,13 @@ switch_to_data1_zone: search_zone = 2;
|
|||
}
|
||||
break;
|
||||
case 4:
|
||||
Dputs("Switching from data2 zone to data1 "
|
||||
"zone.");
|
||||
ntfs_log_debug("Switching from data2 zone to data1 "
|
||||
"zone.\n");
|
||||
/* Update data2 zone position. */
|
||||
if (rlpos) {
|
||||
LCN tc;
|
||||
Dprintf("%s(): Before checks, "
|
||||
"vol->data2_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->data2_zone_pos);
|
||||
ntfs_log_trace("Before checks, vol->data2_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->data2_zone_pos);
|
||||
tc = rl[rlpos - 1].lcn +
|
||||
rl[rlpos - 1].length;
|
||||
if (tc >= vol->mft_zone_start)
|
||||
|
@ -625,56 +552,49 @@ switch_to_data1_zone: search_zone = 2;
|
|||
vol->data2_zone_pos ||
|
||||
tc > vol->data2_zone_pos)
|
||||
vol->data2_zone_pos = tc;
|
||||
Dprintf("%s(): After checks, "
|
||||
"vol->data2_zone_pos = "
|
||||
"0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
(long long)
|
||||
vol->data2_zone_pos);
|
||||
ntfs_log_trace("After checks, vol->data2_zone_pos = 0x%llx.\n",
|
||||
(long long) vol->data2_zone_pos);
|
||||
}
|
||||
/* Switch from data2 zone to data1 zone. */
|
||||
goto switch_to_data1_zone; /* See above. */
|
||||
default:
|
||||
NTFS_BUG("switch(search_zone) 3");
|
||||
NTFS_BUG("switch (search_zone) 3");
|
||||
}
|
||||
Dprintf("%s(): After zone switch, search_zone = %i, "
|
||||
"pass = %i, bmp_initial_pos = 0x%llx, "
|
||||
ntfs_log_trace("After zone switch, search_zone = %i, pass = "
|
||||
"%i, bmp_initial_pos = 0x%llx, "
|
||||
"zone_start = 0x%llx, zone_end = "
|
||||
"0x%llx.\n", __FUNCTION__, search_zone,
|
||||
pass, (long long)bmp_initial_pos,
|
||||
"0x%llx.\n", search_zone, pass,
|
||||
(long long)bmp_initial_pos,
|
||||
(long long)zone_start,
|
||||
(long long)zone_end);
|
||||
bmp_pos = zone_start;
|
||||
if (zone_start == zone_end) {
|
||||
Dprintf("%s(): Empty zone, going to "
|
||||
"done_zones_check.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Empty zone, going to "
|
||||
"done_zones_check.\n");
|
||||
/* Empty zone. Don't bother searching it. */
|
||||
goto done_zones_check;
|
||||
}
|
||||
Dprintf("%s(): Continuing outer while loop.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Continuing outer while loop.\n");
|
||||
continue;
|
||||
} /* done_zones == 7 */
|
||||
Dprintf("%s(): All zones are finished.\n", __FUNCTION__);
|
||||
ntfs_log_trace("All zones are finished.\n");
|
||||
/*
|
||||
* All zones are finished! If DATA_ZONE, shrink mft zone. If
|
||||
* MFT_ZONE, we have really run out of space.
|
||||
*/
|
||||
mft_zone_size = vol->mft_zone_end - vol->mft_zone_start;
|
||||
Dprintf("%s(): vol->mft_zone_start = 0x%llx, vol->mft_zone_end "
|
||||
"= 0x%llx, mft_zone_size = 0x%llx.\n",
|
||||
__FUNCTION__, (long long)vol->mft_zone_start,
|
||||
ntfs_log_trace("vol->mft_zone_start = 0x%llx, vol->mft_zone_end = "
|
||||
"0x%llx, mft_zone_size = 0x%llx.\n",
|
||||
(long long)vol->mft_zone_start,
|
||||
(long long)vol->mft_zone_end,
|
||||
(long long)mft_zone_size);
|
||||
if (zone == MFT_ZONE || mft_zone_size <= 0) {
|
||||
Dprintf("%s(): No free clusters left, going to "
|
||||
"err_ret.\n", __FUNCTION__);
|
||||
ntfs_log_trace("No free clusters left, going to err_ret.\n");
|
||||
/* Really no more space left on device. */
|
||||
err = ENOSPC;
|
||||
goto err_ret;
|
||||
} /* zone == DATA_ZONE && mft_zone_size > 0 */
|
||||
Dprintf("%s(): Shrinking mft zone.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Shrinking mft zone.\n");
|
||||
zone_end = vol->mft_zone_end;
|
||||
mft_zone_size >>= 1;
|
||||
if (mft_zone_size > 0)
|
||||
|
@ -692,31 +612,32 @@ switch_to_data1_zone: search_zone = 2;
|
|||
search_zone = 2;
|
||||
pass = 2;
|
||||
done_zones &= ~2;
|
||||
Dprintf("%s(): After shrinking mft zone, mft_zone_size = "
|
||||
"0x%llx, vol->mft_zone_start = 0x%llx, "
|
||||
ntfs_log_trace("After shrinking mft zone, mft_zone_size = 0x%llx, "
|
||||
"vol->mft_zone_start = 0x%llx, "
|
||||
"vol->mft_zone_end = 0x%llx, vol->mft_zone_pos "
|
||||
"= 0x%llx, search_zone = 2, pass = 2, "
|
||||
"dones_zones = 0x%x, zone_start = 0x%llx, "
|
||||
"zone_end = 0x%llx, vol->data1_zone_pos = "
|
||||
"0x%llx, continuing outer while loop.\n",
|
||||
__FUNCTION__, (long long)mft_zone_size,
|
||||
(long long)mft_zone_size,
|
||||
(long long)vol->mft_zone_start,
|
||||
(long long)vol->mft_zone_end,
|
||||
(long long)vol->mft_zone_pos,
|
||||
done_zones, (long long)zone_start,
|
||||
done_zones,
|
||||
(long long)zone_start,
|
||||
(long long)zone_end,
|
||||
(long long)vol->data1_zone_pos);
|
||||
}
|
||||
Dputs("After outer while loop.");
|
||||
ntfs_log_debug("After outer while loop.\n");
|
||||
done_ret:
|
||||
Dputs("At done_ret.");
|
||||
ntfs_log_debug("At done_ret.\n");
|
||||
/* Add runlist terminator element. */
|
||||
rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length;
|
||||
rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
|
||||
rl[rlpos].length = 0;
|
||||
if (need_writeback) {
|
||||
s64 bw;
|
||||
Dprintf("%s(): Writing back.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Writing back.\n");
|
||||
need_writeback = 0;
|
||||
bw = ntfs_attr_pwrite(vol->lcnbmp_na, last_read_pos, br, buf);
|
||||
if (bw != br) {
|
||||
|
@ -724,27 +645,26 @@ done_ret:
|
|||
err = errno;
|
||||
else
|
||||
err = EIO;
|
||||
Dprintf("%s(): Bitmap writeback failed in done code "
|
||||
"path with error code %i.\n",
|
||||
__FUNCTION__, err);
|
||||
ntfs_log_trace("Bitmap writeback failed in done code path "
|
||||
"with error code %i.\n", err);
|
||||
goto err_ret;
|
||||
}
|
||||
}
|
||||
done_err_ret:
|
||||
Dputs("At done_err_ret (follows done_ret).");
|
||||
ntfs_log_debug("At done_err_ret (follows done_ret).\n");
|
||||
free(buf);
|
||||
/* Done! */
|
||||
if (!err)
|
||||
return rl;
|
||||
Dprintf("%s(): Failed to allocate clusters. Returning with error code "
|
||||
"%i.\n", __FUNCTION__, err);
|
||||
ntfs_log_trace("Failed to allocate clusters. Returning with error code "
|
||||
"%i.\n", err);
|
||||
errno = err;
|
||||
return NULL;
|
||||
wb_err_ret:
|
||||
Dprintf("%s(): At wb_err_ret.\n", __FUNCTION__);
|
||||
ntfs_log_trace("At wb_err_ret.\n");
|
||||
if (need_writeback) {
|
||||
s64 bw;
|
||||
Dprintf("%s(): Writing back.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Writing back.\n");
|
||||
need_writeback = 0;
|
||||
bw = ntfs_attr_pwrite(vol->lcnbmp_na, last_read_pos, br, buf);
|
||||
if (bw != br) {
|
||||
|
@ -752,18 +672,16 @@ wb_err_ret:
|
|||
err = errno;
|
||||
else
|
||||
err = EIO;
|
||||
Dprintf("%s(): Bitmap writeback failed in error code "
|
||||
"path with error code %i.\n",
|
||||
__FUNCTION__, err);
|
||||
ntfs_log_trace("Bitmap writeback failed in error code path "
|
||||
"with error code %i.\n", err);
|
||||
}
|
||||
}
|
||||
err_ret:
|
||||
Dprintf("%s(): At err_ret.\n", __FUNCTION__);
|
||||
ntfs_log_trace("At err_ret.\n");
|
||||
if (rl) {
|
||||
if (err == ENOSPC) {
|
||||
Dprintf("%s(): err = ENOSPC, first free lcn = 0x%llx, "
|
||||
"could allocate up to = 0x%llx "
|
||||
"clusters.\n", __FUNCTION__,
|
||||
ntfs_log_trace("err = ENOSPC, first free lcn = 0x%llx, could "
|
||||
"allocate up to = 0x%llx clusters.\n",
|
||||
(long long)rl[0].lcn,
|
||||
(long long)count - clusters);
|
||||
}
|
||||
|
@ -772,21 +690,19 @@ err_ret:
|
|||
rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
|
||||
rl[rlpos].length = 0;
|
||||
/* Deallocate all allocated clusters. */
|
||||
Dprintf("%s(): Deallocating allocated clusters.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_cluster_free_from_rl (vol, rl);
|
||||
ntfs_log_trace("Deallocating allocated clusters.\n");
|
||||
ntfs_cluster_free_from_rl(vol, rl);
|
||||
/* Free the runlist. */
|
||||
free(rl);
|
||||
rl = NULL;
|
||||
} else {
|
||||
if (err == ENOSPC) {
|
||||
Dprintf("%s(): No space left at all, err = ENOSPC, "
|
||||
"first free lcn = 0x%llx.\n",
|
||||
__FUNCTION__,
|
||||
ntfs_log_trace("No space left at all, err = ENOSPC, first "
|
||||
"free lcn = 0x%llx.\n",
|
||||
(long long)vol->data1_zone_pos);
|
||||
}
|
||||
}
|
||||
Dprintf("%s(): rl = NULL, going to done_err_ret.\n", __FUNCTION__);
|
||||
ntfs_log_trace("rl = NULL, going to done_err_ret.\n");
|
||||
goto done_err_ret;
|
||||
}
|
||||
|
||||
|
@ -803,8 +719,7 @@ int ntfs_cluster_free_from_rl(ntfs_volume *vol, runlist *rl)
|
|||
if (rl->lcn >= 0 && ntfs_bitmap_clear_run(vol->lcnbmp_na,
|
||||
rl->lcn, rl->length)) {
|
||||
int eo = errno;
|
||||
Dprintf("%s(): Eeek! Deallocation of clusters "
|
||||
"failed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Eeek! Deallocation of clusters failed.\n");
|
||||
errno = eo;
|
||||
return -1;
|
||||
}
|
||||
|
@ -835,7 +750,7 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
|
|||
|
||||
if (!vol || !vol->lcnbmp_na || !na || start_vcn < 0 ||
|
||||
(count < 0 && count != -1)) {
|
||||
Dprintf("%s(): Invalid arguments!\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid arguments!\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -887,10 +802,9 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
|
|||
// list support! (AIA)
|
||||
if (rl->lcn < 0 && rl->lcn != LCN_HOLE) {
|
||||
// FIXME: Eeek! We need rollback! (AIA)
|
||||
Dprintf("%s(): Eeek! invalid lcn (= %lli). Should "
|
||||
"attempt to map runlist! "
|
||||
"Leaving inconsistent metadata!\n",
|
||||
__FUNCTION__, (long long)rl->lcn);
|
||||
ntfs_log_trace("Eeek! invalid lcn (= %lli). Should attempt "
|
||||
"to map runlist! Leaving inconsistent "
|
||||
"metadata!\n", (long long)rl->lcn);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
@ -907,9 +821,8 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
|
|||
int eo = errno;
|
||||
|
||||
// FIXME: Eeek! We need rollback! (AIA)
|
||||
Dprintf("%s(): Eeek! bitmap clear run "
|
||||
"failed. Leaving inconsistent "
|
||||
"metadata!\n", __FUNCTION__);
|
||||
ntfs_log_trace("Eeek! bitmap clear run failed. "
|
||||
"Leaving inconsistent metadata!\n");
|
||||
errno = eo;
|
||||
return -1;
|
||||
}
|
||||
|
@ -923,9 +836,8 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
|
|||
|
||||
if (count != -1 && count != 0) {
|
||||
// FIXME: Eeek! BUG()
|
||||
Dprintf("%s(): Eeek! count still not zero (= %lli). Leaving "
|
||||
"inconsistent metadata!\n", __FUNCTION__,
|
||||
(long long)count);
|
||||
ntfs_log_trace("Eeek! count still not zero (= %lli). Leaving "
|
||||
"inconsistent metadata!\n", (long long)count);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* logfile.c - NTFS journal handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2002-2005 Anton Altaparmakov
|
||||
|
@ -20,7 +20,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
|
@ -31,6 +33,7 @@
|
|||
#include "logfile.h"
|
||||
#include "volume.h"
|
||||
#include "mst.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* ntfs_check_restart_page_header - check the page header for consistency
|
||||
|
@ -49,7 +52,7 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
|
|||
u16 ra_ofs, usa_count, usa_ofs, usa_end = 0;
|
||||
BOOL have_usa = TRUE;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
/*
|
||||
* If the system or log page sizes are smaller than the ntfs block size
|
||||
* or either is not a power of 2 we cannot handle this log file.
|
||||
|
@ -61,7 +64,7 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
|
|||
logfile_system_page_size &
|
||||
(logfile_system_page_size - 1) ||
|
||||
logfile_log_page_size & (logfile_log_page_size - 1)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile uses unsupported page size.");
|
||||
ntfs_log_error("$LogFile uses unsupported page size.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
|
@ -69,14 +72,14 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
|
|||
* size (2nd restart page).
|
||||
*/
|
||||
if (pos && pos != logfile_system_page_size) {
|
||||
ntfs_error(vi->i_sb, "Found restart area in incorrect "
|
||||
ntfs_log_error("Found restart area in incorrect "
|
||||
"position in $LogFile.");
|
||||
return FALSE;
|
||||
}
|
||||
/* We only know how to handle version 1.1. */
|
||||
if (sle16_to_cpu(rp->major_ver) != 1 ||
|
||||
sle16_to_cpu(rp->minor_ver) != 1) {
|
||||
ntfs_error(vi->i_sb, "$LogFile version %i.%i is not "
|
||||
ntfs_log_error("$LogFile version %i.%i is not "
|
||||
"supported. (This driver supports version "
|
||||
"1.1 only.)", (int)sle16_to_cpu(rp->major_ver),
|
||||
(int)sle16_to_cpu(rp->minor_ver));
|
||||
|
@ -93,7 +96,7 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
|
|||
/* Verify the size of the update sequence array. */
|
||||
usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS);
|
||||
if (usa_count != le16_to_cpu(rp->usa_count)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
|
||||
ntfs_log_error("$LogFile restart page specifies "
|
||||
"inconsistent update sequence array count.");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -102,7 +105,7 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
|
|||
usa_end = usa_ofs + usa_count * sizeof(u16);
|
||||
if (usa_ofs < sizeof(RESTART_PAGE_HEADER) ||
|
||||
usa_end > NTFS_BLOCK_SIZE - sizeof(u16)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
|
||||
ntfs_log_error("$LogFile restart page specifies "
|
||||
"inconsistent update sequence array offset.");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -117,7 +120,7 @@ skip_usa_checks:
|
|||
if (ra_ofs & 7 || (have_usa ? ra_ofs < usa_end :
|
||||
ra_ofs < sizeof(RESTART_PAGE_HEADER)) ||
|
||||
ra_ofs > logfile_system_page_size) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
|
||||
ntfs_log_error("$LogFile restart page specifies "
|
||||
"inconsistent restart area offset.");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -126,11 +129,11 @@ skip_usa_checks:
|
|||
* set.
|
||||
*/
|
||||
if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart page is not modified "
|
||||
ntfs_log_error("$LogFile restart page is not modified "
|
||||
"by chkdsk but a chkdsk LSN is specified.");
|
||||
return FALSE;
|
||||
}
|
||||
ntfs_debug("Done.");
|
||||
ntfs_log_trace("Done.\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -154,7 +157,7 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
|
|||
u16 ra_ofs, ra_len, ca_ofs;
|
||||
u8 fs_bits;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
ra_ofs = le16_to_cpu(rp->restart_area_offset);
|
||||
ra = (RESTART_AREA*)((u8*)rp + ra_ofs);
|
||||
/*
|
||||
|
@ -164,7 +167,7 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
|
|||
*/
|
||||
if (ra_ofs + offsetof(RESTART_AREA, file_size) >
|
||||
NTFS_BLOCK_SIZE - sizeof(u16)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
ntfs_log_error("$LogFile restart area specifies "
|
||||
"inconsistent file offset.");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -179,7 +182,7 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
|
|||
if (((ca_ofs + 7) & ~7) != ca_ofs ||
|
||||
ra_ofs + ca_ofs > (u16)(NTFS_BLOCK_SIZE -
|
||||
sizeof(u16))) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
ntfs_log_error("$LogFile restart area specifies "
|
||||
"inconsistent client array offset.");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -194,7 +197,7 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
|
|||
(u32)(ra_ofs + le16_to_cpu(ra->restart_area_length)) >
|
||||
le32_to_cpu(rp->system_page_size) ||
|
||||
ra_len > le16_to_cpu(ra->restart_area_length)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area is out of bounds "
|
||||
ntfs_log_error("$LogFile restart area is out of bounds "
|
||||
"of the system page size specified by the "
|
||||
"restart page header and/or the specified "
|
||||
"restart area length is inconsistent.");
|
||||
|
@ -211,7 +214,7 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
|
|||
(ra->client_in_use_list != LOGFILE_NO_CLIENT &&
|
||||
le16_to_cpu(ra->client_in_use_list) >=
|
||||
le16_to_cpu(ra->log_clients))) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
ntfs_log_error("$LogFile restart area specifies "
|
||||
"overflowing client free and/or in use lists.");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -226,25 +229,25 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
|
|||
fs_bits++;
|
||||
}
|
||||
if (le32_to_cpu(ra->seq_number_bits) != (u32)(67 - fs_bits)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
ntfs_log_error("$LogFile restart area specifies "
|
||||
"inconsistent sequence number bits.");
|
||||
return FALSE;
|
||||
}
|
||||
/* The log record header length must be a multiple of 8. */
|
||||
if (((le16_to_cpu(ra->log_record_header_length) + 7) & ~7) !=
|
||||
le16_to_cpu(ra->log_record_header_length)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
ntfs_log_error("$LogFile restart area specifies "
|
||||
"inconsistent log record header length.");
|
||||
return FALSE;
|
||||
}
|
||||
/* Ditto for the log page data offset. */
|
||||
if (((le16_to_cpu(ra->log_page_data_offset) + 7) & ~7) !=
|
||||
le16_to_cpu(ra->log_page_data_offset)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
ntfs_log_error("$LogFile restart area specifies "
|
||||
"inconsistent log page data offset.");
|
||||
return FALSE;
|
||||
}
|
||||
ntfs_debug("Done.");
|
||||
ntfs_log_trace("Done.\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -269,7 +272,7 @@ static BOOL ntfs_check_log_client_array(RESTART_PAGE_HEADER *rp)
|
|||
u16 nr_clients, idx;
|
||||
BOOL in_free_list, idx_is_first;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
|
||||
ca = (LOG_CLIENT_RECORD*)((u8*)ra +
|
||||
le16_to_cpu(ra->client_array_offset));
|
||||
|
@ -304,10 +307,10 @@ check_list:
|
|||
idx = le16_to_cpu(ra->client_in_use_list);
|
||||
goto check_list;
|
||||
}
|
||||
ntfs_debug("Done.");
|
||||
ntfs_log_trace("Done.\n");
|
||||
return TRUE;
|
||||
err_out:
|
||||
ntfs_error(vi->i_sb, "$LogFile log client array is corrupt.");
|
||||
ntfs_log_error("$LogFile log client array is corrupt.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -346,7 +349,7 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
|
|||
RESTART_PAGE_HEADER *trp;
|
||||
int err;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
/* Check the restart page header for consistency. */
|
||||
if (!ntfs_check_restart_page_header(rp, pos)) {
|
||||
/* Error output already done inside the function. */
|
||||
|
@ -364,7 +367,7 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
|
|||
*/
|
||||
trp = malloc(le32_to_cpu(rp->system_page_size));
|
||||
if (!trp) {
|
||||
ntfs_error(vi->i_sb, "Failed to allocate memory for $LogFile "
|
||||
ntfs_log_error("Failed to allocate memory for $LogFile "
|
||||
"restart page buffer.");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
@ -379,7 +382,7 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
|
|||
le32_to_cpu(rp->system_page_size), trp) !=
|
||||
le32_to_cpu(rp->system_page_size)) {
|
||||
err = errno;
|
||||
ntfs_error(, "Failed to read whole restart page into the "
|
||||
ntfs_log_error("Failed to read whole restart page into the "
|
||||
"buffer.");
|
||||
if (err != ENOMEM)
|
||||
err = EIO;
|
||||
|
@ -400,7 +403,7 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
|
|||
if (le16_to_cpu(rp->restart_area_offset) +
|
||||
le16_to_cpu(ra->restart_area_length) >
|
||||
NTFS_BLOCK_SIZE - (int)sizeof(u16)) {
|
||||
ntfs_error(vi->i_sb, "Multi sector transfer error "
|
||||
ntfs_log_error("Multi sector transfer error "
|
||||
"detected in $LogFile restart page.");
|
||||
err = EINVAL;
|
||||
goto err_out;
|
||||
|
@ -425,7 +428,7 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
|
|||
else /* if (ntfs_is_chkd_record(rp->magic)) */
|
||||
*lsn = sle64_to_cpu(rp->chkdsk_lsn);
|
||||
}
|
||||
ntfs_debug("Done.");
|
||||
ntfs_log_trace("Done.\n");
|
||||
if (wrp)
|
||||
*wrp = trp;
|
||||
else {
|
||||
|
@ -464,7 +467,7 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
|
|||
BOOL logfile_is_empty = TRUE;
|
||||
u8 log_page_bits;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
/* An empty $LogFile must have been clean before it got emptied. */
|
||||
if (NVolLogFileEmpty(vol))
|
||||
goto is_empty;
|
||||
|
@ -487,13 +490,13 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
|
|||
*/
|
||||
if (size < log_page_size * 2 || (size - log_page_size * 2) >>
|
||||
log_page_bits < MinLogRecordPages) {
|
||||
ntfs_error(vol->sb, "$LogFile is too small.");
|
||||
ntfs_log_error("$LogFile is too small.");
|
||||
return FALSE;
|
||||
}
|
||||
/* Allocate memory for restart page. */
|
||||
kaddr = malloc(NTFS_BLOCK_SIZE);
|
||||
if (!kaddr) {
|
||||
ntfs_error(, "Not enough memory.");
|
||||
ntfs_log_error("Not enough memory.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
|
@ -510,7 +513,7 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
|
|||
*/
|
||||
if (ntfs_attr_pread(log_na, pos, NTFS_BLOCK_SIZE, kaddr) !=
|
||||
NTFS_BLOCK_SIZE) {
|
||||
ntfs_error(, "Failed to read first NTFS_BLOCK_SIZE "
|
||||
ntfs_log_error("Failed to read first NTFS_BLOCK_SIZE "
|
||||
"bytes of potential restart page.");
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -579,13 +582,13 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
|
|||
if (logfile_is_empty) {
|
||||
NVolSetLogFileEmpty(vol);
|
||||
is_empty:
|
||||
ntfs_debug("Done. ($LogFile is empty.)");
|
||||
ntfs_log_trace("Done. ($LogFile is empty.)\n");
|
||||
return TRUE;
|
||||
}
|
||||
if (!rstr1_ph) {
|
||||
if (rstr2_ph)
|
||||
ntfs_error(vol->sb, "BUG: rstr2_ph isn't NULL!");
|
||||
ntfs_error(vol->sb, "Did not find any restart pages in "
|
||||
ntfs_log_error("BUG: rstr2_ph isn't NULL!");
|
||||
ntfs_log_error("Did not find any restart pages in "
|
||||
"$LogFile and it was not empty.");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -596,13 +599,13 @@ is_empty:
|
|||
* Otherwise just throw it away.
|
||||
*/
|
||||
if (rstr2_lsn > rstr1_lsn) {
|
||||
ntfs_debug("Using second restart page as it is more "
|
||||
ntfs_log_debug("Using second restart page as it is more "
|
||||
"recent.");
|
||||
free(rstr1_ph);
|
||||
rstr1_ph = rstr2_ph;
|
||||
/* rstr1_lsn = rstr2_lsn; */
|
||||
} else {
|
||||
ntfs_debug("Using first restart page as it is more "
|
||||
ntfs_log_debug("Using first restart page as it is more "
|
||||
"recent.");
|
||||
free(rstr2_ph);
|
||||
}
|
||||
|
@ -613,15 +616,12 @@ is_empty:
|
|||
*rp = rstr1_ph;
|
||||
else
|
||||
free(rstr1_ph);
|
||||
ntfs_debug("Done.");
|
||||
ntfs_log_trace("Done.\n");
|
||||
return TRUE;
|
||||
err_out:
|
||||
if (kaddr)
|
||||
free(kaddr);
|
||||
if (rstr1_ph)
|
||||
free(rstr1_ph);
|
||||
if (rstr2_ph)
|
||||
free(rstr2_ph);
|
||||
free(kaddr);
|
||||
free(rstr1_ph);
|
||||
free(rstr2_ph);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -649,19 +649,19 @@ BOOL ntfs_is_logfile_clean(ntfs_attr *log_na, RESTART_PAGE_HEADER *rp)
|
|||
{
|
||||
RESTART_AREA *ra;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
/* An empty $LogFile must have been clean before it got emptied. */
|
||||
if (NVolLogFileEmpty(log_na->ni->vol)) {
|
||||
ntfs_debug("Done. ($LogFile is empty.)");
|
||||
ntfs_log_trace("Done. ($LogFile is empty.)\n");
|
||||
return TRUE;
|
||||
}
|
||||
if (!rp) {
|
||||
ntfs_error(, "Restart page header is NULL.");
|
||||
ntfs_log_error("Restart page header is NULL.");
|
||||
return FALSE;
|
||||
}
|
||||
if (!ntfs_is_rstr_record(rp->magic) &&
|
||||
!ntfs_is_chkd_record(rp->magic)) {
|
||||
ntfs_error(vol->sb, "Restart page buffer is invalid. This is "
|
||||
ntfs_log_error("Restart page buffer is invalid. This is "
|
||||
"probably a bug in that the $LogFile should "
|
||||
"have been consistency checked before calling "
|
||||
"this function.");
|
||||
|
@ -676,11 +676,11 @@ BOOL ntfs_is_logfile_clean(ntfs_attr *log_na, RESTART_PAGE_HEADER *rp)
|
|||
*/
|
||||
if (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
|
||||
!(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
|
||||
ntfs_debug("Done. $LogFile indicates a dirty shutdown.");
|
||||
ntfs_log_debug("Done. $LogFile indicates a dirty shutdown.\n");
|
||||
return FALSE;
|
||||
}
|
||||
/* $LogFile indicates a clean shutdown. */
|
||||
ntfs_debug("Done. $LogFile indicates a clean shutdown.");
|
||||
ntfs_log_trace("Done. $LogFile indicates a clean shutdown.\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -701,21 +701,21 @@ int ntfs_empty_logfile(ntfs_attr *na)
|
|||
char buf[NTFS_BUF_SIZE];
|
||||
int err;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ntfs_log_trace("Entering.\n");
|
||||
if (NVolLogFileEmpty(na->ni->vol))
|
||||
goto done;
|
||||
|
||||
/* The $DATA attribute of the $LogFile has to be non-resident. */
|
||||
if (!NAttrNonResident(na)) {
|
||||
err = EIO;
|
||||
Dprintf("$LogFile $DATA attribute is resident!?!\n");
|
||||
ntfs_log_debug("$LogFile $DATA attribute is resident!?!\n");
|
||||
goto io_error_exit;
|
||||
}
|
||||
|
||||
/* Get length of $LogFile contents. */
|
||||
len = na->data_size;
|
||||
if (!len) {
|
||||
Dprintf("$LogFile has zero length, no disk write needed.\n");
|
||||
ntfs_log_debug("$LogFile has zero length, no disk write needed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -728,8 +728,8 @@ int ntfs_empty_logfile(ntfs_attr *na)
|
|||
|
||||
if (count == -1 || pos != len) {
|
||||
err = errno;
|
||||
Dprintf("Amount of $LogFile data read does not "
|
||||
"correspond to expected length!");
|
||||
ntfs_log_debug("Amount of $LogFile data read does not correspond to "
|
||||
"expected length!");
|
||||
if (count != -1)
|
||||
err = EIO;
|
||||
goto io_error_exit;
|
||||
|
@ -746,7 +746,7 @@ int ntfs_empty_logfile(ntfs_attr *na)
|
|||
|
||||
if ((count = ntfs_attr_pwrite(na, pos, count, buf)) <= 0) {
|
||||
err = errno;
|
||||
Dprintf("Failed to set the $LogFile attribute value.");
|
||||
ntfs_log_debug("Failed to set the $LogFile attribute value.\n");
|
||||
if (count != -1)
|
||||
err = EIO;
|
||||
goto io_error_exit;
|
||||
|
@ -757,7 +757,7 @@ int ntfs_empty_logfile(ntfs_attr *na)
|
|||
/* Set the flag so we do not have to do it again on remount. */
|
||||
NVolSetLogFileEmpty(na->ni->vol);
|
||||
done:
|
||||
ntfs_debug("Done.");
|
||||
ntfs_log_trace("Done.\n");
|
||||
return 0;
|
||||
io_error_exit:
|
||||
ntfs_attr_close(na);
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
|
@ -33,6 +35,9 @@
|
|||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
|
@ -47,10 +52,12 @@
|
|||
struct ntfs_logging ntfs_log =
|
||||
{
|
||||
#ifdef DEBUG
|
||||
LOG_LEVEL_DEBUG | LOG_LEVEL_TRACE |
|
||||
NTFS_LOG_LEVEL_DEBUG | NTFS_LOG_LEVEL_TRACE |
|
||||
#endif
|
||||
LOG_LEVEL_INFO | LOG_LEVEL_WARNING | LOG_LEVEL_ERROR | LOG_LEVEL_PERROR | LOG_LEVEL_CRITICAL,
|
||||
LOG_FLAG_PREFIX,
|
||||
NTFS_LOG_LEVEL_INFO | NTFS_LOG_LEVEL_QUIET | NTFS_LOG_LEVEL_WARNING |
|
||||
NTFS_LOG_LEVEL_ERROR | NTFS_LOG_LEVEL_PERROR | NTFS_LOG_LEVEL_CRITICAL |
|
||||
NTFS_LOG_LEVEL_REASON,
|
||||
NTFS_LOG_FLAG_ONLYNAME,
|
||||
ntfs_logging_handler_printf
|
||||
};
|
||||
|
||||
|
@ -61,7 +68,7 @@ struct ntfs_logging ntfs_log =
|
|||
*
|
||||
* Returns: Log levels in a 32-bit field
|
||||
*/
|
||||
u32 ntfs_logging_get_levels (void)
|
||||
u32 ntfs_logging_get_levels(void)
|
||||
{
|
||||
return ntfs_log.levels;
|
||||
}
|
||||
|
@ -71,11 +78,11 @@ u32 ntfs_logging_get_levels (void)
|
|||
* @levels: 32-bit field of log levels to set
|
||||
*
|
||||
* Enable one or more logging levels.
|
||||
* The logging levels are named: LOG_LEVEL_*.
|
||||
* The logging levels are named: NTFS_LOG_LEVEL_*.
|
||||
*
|
||||
* Returns: Log levels that were enabled before the call
|
||||
*/
|
||||
u32 ntfs_logging_set_levels (u32 levels)
|
||||
u32 ntfs_logging_set_levels(u32 levels)
|
||||
{
|
||||
u32 old;
|
||||
old = ntfs_log.levels;
|
||||
|
@ -88,11 +95,11 @@ u32 ntfs_logging_set_levels (u32 levels)
|
|||
* @levels: 32-bit field of log levels to clear
|
||||
*
|
||||
* Disable one or more logging levels.
|
||||
* The logging levels are named: LOG_LEVEL_*.
|
||||
* The logging levels are named: NTFS_LOG_LEVEL_*.
|
||||
*
|
||||
* Returns: Log levels that were enabled before the call
|
||||
*/
|
||||
u32 ntfs_logging_clear_levels (u32 levels)
|
||||
u32 ntfs_logging_clear_levels(u32 levels)
|
||||
{
|
||||
u32 old;
|
||||
old = ntfs_log.levels;
|
||||
|
@ -108,7 +115,7 @@ u32 ntfs_logging_clear_levels (u32 levels)
|
|||
*
|
||||
* Returns: Logging flags in a 32-bit field
|
||||
*/
|
||||
u32 ntfs_logging_get_flags (void)
|
||||
u32 ntfs_logging_get_flags(void)
|
||||
{
|
||||
return ntfs_log.flags;
|
||||
}
|
||||
|
@ -118,11 +125,11 @@ u32 ntfs_logging_get_flags (void)
|
|||
* @flags: 32-bit field of logging flags to set
|
||||
*
|
||||
* Enable one or more logging flags.
|
||||
* The log flags are named: LOG_LEVEL_*.
|
||||
* The log flags are named: NTFS_LOG_LEVEL_*.
|
||||
*
|
||||
* Returns: Logging flags that were enabled before the call
|
||||
*/
|
||||
u32 ntfs_logging_set_flags (u32 flags)
|
||||
u32 ntfs_logging_set_flags(u32 flags)
|
||||
{
|
||||
u32 old;
|
||||
old = ntfs_log.flags;
|
||||
|
@ -135,11 +142,11 @@ u32 ntfs_logging_set_flags (u32 flags)
|
|||
* @flags: 32-bit field of logging flags to clear
|
||||
*
|
||||
* Disable one or more logging flags.
|
||||
* The log flags are named: LOG_LEVEL_*.
|
||||
* The log flags are named: NTFS_LOG_LEVEL_*.
|
||||
*
|
||||
* Returns: Logging flags that were enabled before the call
|
||||
*/
|
||||
u32 ntfs_logging_clear_flags (u32 flags)
|
||||
u32 ntfs_logging_clear_flags(u32 flags)
|
||||
{
|
||||
u32 old;
|
||||
old = ntfs_log.flags;
|
||||
|
@ -157,23 +164,24 @@ u32 ntfs_logging_clear_flags (u32 flags)
|
|||
*
|
||||
* Returns: "string" Prefix to be used
|
||||
*/
|
||||
static FILE * ntfs_logging_get_stream (int level)
|
||||
static FILE * ntfs_logging_get_stream(u32 level)
|
||||
{
|
||||
FILE *stream;
|
||||
|
||||
switch (level) {
|
||||
case LOG_LEVEL_INFO:
|
||||
case LOG_LEVEL_QUIET:
|
||||
case LOG_LEVEL_PROGRESS:
|
||||
case NTFS_LOG_LEVEL_INFO:
|
||||
case NTFS_LOG_LEVEL_QUIET:
|
||||
case NTFS_LOG_LEVEL_PROGRESS:
|
||||
case NTFS_LOG_LEVEL_VERBOSE:
|
||||
stream = stdout;
|
||||
break;
|
||||
|
||||
case LOG_LEVEL_DEBUG:
|
||||
case LOG_LEVEL_TRACE:
|
||||
case LOG_LEVEL_WARNING:
|
||||
case LOG_LEVEL_ERROR:
|
||||
case LOG_LEVEL_CRITICAL:
|
||||
case LOG_LEVEL_PERROR:
|
||||
case NTFS_LOG_LEVEL_DEBUG:
|
||||
case NTFS_LOG_LEVEL_TRACE:
|
||||
case NTFS_LOG_LEVEL_WARNING:
|
||||
case NTFS_LOG_LEVEL_ERROR:
|
||||
case NTFS_LOG_LEVEL_CRITICAL:
|
||||
case NTFS_LOG_LEVEL_PERROR:
|
||||
default:
|
||||
stream = stderr;
|
||||
break;
|
||||
|
@ -190,39 +198,39 @@ static FILE * ntfs_logging_get_stream (int level)
|
|||
*
|
||||
* Returns: "string" Prefix to be used
|
||||
*/
|
||||
static const char * ntfs_logging_get_prefix (int level)
|
||||
static const char * ntfs_logging_get_prefix(u32 level)
|
||||
{
|
||||
const char *prefix;
|
||||
|
||||
switch (level) {
|
||||
case LOG_LEVEL_DEBUG:
|
||||
case NTFS_LOG_LEVEL_DEBUG:
|
||||
prefix = "DEBUG: ";
|
||||
break;
|
||||
case LOG_LEVEL_TRACE:
|
||||
case NTFS_LOG_LEVEL_TRACE:
|
||||
prefix = "TRACE: ";
|
||||
break;
|
||||
case LOG_LEVEL_QUIET:
|
||||
case NTFS_LOG_LEVEL_QUIET:
|
||||
prefix = "QUIET: ";
|
||||
break;
|
||||
case LOG_LEVEL_INFO:
|
||||
case NTFS_LOG_LEVEL_INFO:
|
||||
prefix = "INFO: ";
|
||||
break;
|
||||
case LOG_LEVEL_VERBOSE:
|
||||
case NTFS_LOG_LEVEL_VERBOSE:
|
||||
prefix = "VERBOSE: ";
|
||||
break;
|
||||
case LOG_LEVEL_PROGRESS:
|
||||
case NTFS_LOG_LEVEL_PROGRESS:
|
||||
prefix = "PROGRESS: ";
|
||||
break;
|
||||
case LOG_LEVEL_WARNING:
|
||||
case NTFS_LOG_LEVEL_WARNING:
|
||||
prefix = "WARNING: ";
|
||||
break;
|
||||
case LOG_LEVEL_ERROR:
|
||||
case NTFS_LOG_LEVEL_ERROR:
|
||||
prefix = "ERROR: ";
|
||||
break;
|
||||
case LOG_LEVEL_PERROR:
|
||||
case NTFS_LOG_LEVEL_PERROR:
|
||||
prefix = "ERROR: ";
|
||||
break;
|
||||
case LOG_LEVEL_CRITICAL:
|
||||
case NTFS_LOG_LEVEL_CRITICAL:
|
||||
prefix = "CRITICAL: ";
|
||||
break;
|
||||
default:
|
||||
|
@ -243,7 +251,7 @@ static const char * ntfs_logging_get_prefix (int level)
|
|||
*
|
||||
* Returns: void
|
||||
*/
|
||||
void ntfs_logging_set_handler (logging_handler *handler)
|
||||
void ntfs_logging_set_handler(ntfs_logging_handler *handler)
|
||||
{
|
||||
if (handler)
|
||||
ntfs_log.handler = handler;
|
||||
|
@ -257,22 +265,19 @@ void ntfs_logging_set_handler (logging_handler *handler)
|
|||
* @file: File in which the log line occurred
|
||||
* @line: Line number on which the log line occurred
|
||||
* @level: Level at which the line is logged
|
||||
* @stream: FILE stream to output to (may be NULL)
|
||||
* @data: User specified data, possibly specific to a handler
|
||||
* @format: printf-style formatting string
|
||||
* @...: Arguments to be formatted
|
||||
*
|
||||
* This is just a redirector function. The arguments are simply passed to the
|
||||
* main logging handler (as defined in the global logging struct @ntfs_log).
|
||||
*
|
||||
* Note: If @stream is NULL, the output stream will be determined by the
|
||||
* function: ntfs_logging_get_stream
|
||||
*
|
||||
* Returns: -1 Error occurred
|
||||
* 0 Message wasn't logged
|
||||
* num Number of output characters
|
||||
*/
|
||||
int ntfs_logging_redirect (const char *function, const char *file,
|
||||
int line, int level, FILE *stream, const char *format, ...)
|
||||
int ntfs_logging_redirect(const char *function, const char *file,
|
||||
int line, u32 level, void *data, const char *format, ...)
|
||||
{
|
||||
int olderr = errno;
|
||||
int ret;
|
||||
|
@ -281,10 +286,10 @@ int ntfs_logging_redirect (const char *function, const char *file,
|
|||
if (!(ntfs_log.levels & level)) /* Don't log this message */
|
||||
return 0;
|
||||
|
||||
va_start (args, format);
|
||||
va_start(args, format);
|
||||
errno = olderr;
|
||||
ret = ntfs_log.handler (function, file, line, level, stream, format, args);
|
||||
va_end (args);
|
||||
ret = ntfs_log.handler(function, file, line, level, data, format, args);
|
||||
va_end(args);
|
||||
|
||||
errno = olderr;
|
||||
return ret;
|
||||
|
@ -296,49 +301,73 @@ int ntfs_logging_redirect (const char *function, const char *file,
|
|||
* @file: File in which the log line occurred
|
||||
* @line: Line number on which the log line occurred
|
||||
* @level: Level at which the line is logged
|
||||
* @stream: FILE stream to output to (may be NULL)
|
||||
* @data: User specified data, possibly specific to a handler
|
||||
* @format: printf-style formatting string
|
||||
* @args: Arguments to be formatted
|
||||
*
|
||||
* A simple logging handler. This is where the log line is finally displayed.
|
||||
*
|
||||
* Note: If @stream is NULL, the output stream will be determined by the
|
||||
* function: ntfs_logging_get_stream
|
||||
* Note: For this handler, @data is a pointer to a FILE output stream.
|
||||
* If @data is NULL, the function ntfs_logging_get_stream will be called
|
||||
*
|
||||
* Returns: -1 Error occurred
|
||||
* 0 Message wasn't logged
|
||||
* num Number of output characters
|
||||
*/
|
||||
int ntfs_logging_handler_printf (const char *function, const char *file,
|
||||
int line, int level, FILE *stream, const char *format, va_list args)
|
||||
int ntfs_logging_handler_printf(const char *function, const char *file,
|
||||
int line, u32 level, void *data, const char *format, va_list args)
|
||||
{
|
||||
const int reason_size = 128;
|
||||
static char *reason = NULL;
|
||||
int ret = 0;
|
||||
int olderr = errno;
|
||||
FILE *stream;
|
||||
|
||||
if (!stream)
|
||||
stream = ntfs_logging_get_stream (level);
|
||||
|
||||
if (strchr (file, PATH_SEP)) /* Abbreviate the filename */
|
||||
file = strrchr (file, PATH_SEP) + 1;
|
||||
|
||||
if (ntfs_log.flags & LOG_FLAG_PREFIX) /* Prefix the output */
|
||||
ret += fprintf (stream, "%s", ntfs_logging_get_prefix (level));
|
||||
|
||||
if (ntfs_log.flags & LOG_FLAG_FILENAME) /* Source filename */
|
||||
ret += fprintf (stream, "%s ", file);
|
||||
|
||||
if (ntfs_log.flags & LOG_FLAG_LINE) /* Source line number */
|
||||
ret += fprintf (stream, "(%d) ", line);
|
||||
|
||||
if (ntfs_log.flags & LOG_FLAG_FUNCTION) /* Source function */
|
||||
ret += fprintf (stream, ": %s : ", function);
|
||||
|
||||
if (level & LOG_LEVEL_PERROR) {
|
||||
errno = olderr;
|
||||
ret += fprintf (stream, "<%s> : ", strerror (olderr));
|
||||
if (level == NTFS_LOG_LEVEL_REASON) {
|
||||
if (!reason)
|
||||
reason = malloc (reason_size);
|
||||
if (reason) {
|
||||
memset (reason, 0, reason_size);
|
||||
return vsnprintf (reason, reason_size, format, args);
|
||||
} else {
|
||||
/* Rather than call ourselves, just drop through */
|
||||
level = NTFS_LOG_LEVEL_PERROR;
|
||||
format = "Couldn't create reason";
|
||||
args = NULL;
|
||||
olderr = errno;
|
||||
}
|
||||
}
|
||||
|
||||
ret += vfprintf (stream, format, args);
|
||||
if (data)
|
||||
stream = (FILE*) data;
|
||||
else
|
||||
stream = ntfs_logging_get_stream(level);
|
||||
|
||||
if ((ntfs_log.flags & NTFS_LOG_FLAG_ONLYNAME) &&
|
||||
(strchr(file, PATH_SEP))) /* Abbreviate the filename */
|
||||
file = strrchr(file, PATH_SEP) + 1;
|
||||
|
||||
if (ntfs_log.flags & NTFS_LOG_FLAG_PREFIX) /* Prefix the output */
|
||||
ret += fprintf(stream, "%s", ntfs_logging_get_prefix(level));
|
||||
|
||||
if (ntfs_log.flags & NTFS_LOG_FLAG_FILENAME) /* Source filename */
|
||||
ret += fprintf(stream, "%s ", file);
|
||||
|
||||
if (ntfs_log.flags & NTFS_LOG_FLAG_LINE) /* Source line number */
|
||||
ret += fprintf(stream, "(%d) ", line);
|
||||
|
||||
if ((ntfs_log.flags & NTFS_LOG_FLAG_FUNCTION) && /* Source function */
|
||||
(level & NTFS_LOG_LEVEL_TRACE))
|
||||
ret += fprintf(stream, "%s(): ", function);
|
||||
|
||||
ret += vfprintf(stream, format, args);
|
||||
|
||||
if (level & NTFS_LOG_LEVEL_PERROR) {
|
||||
if (reason)
|
||||
ret += fprintf(stream, " : %s\n", reason);
|
||||
else
|
||||
ret += fprintf(stream, " : %s\n", strerror(olderr));
|
||||
}
|
||||
|
||||
errno = olderr;
|
||||
return ret;
|
||||
|
@ -350,7 +379,7 @@ int ntfs_logging_handler_printf (const char *function, const char *file,
|
|||
* @file: File in which the log line occurred
|
||||
* @line: Line number on which the log line occurred
|
||||
* @level: Level at which the line is logged
|
||||
* @stream: FILE stream to output to (may be NULL)
|
||||
* @data: User specified data, possibly specific to a handler
|
||||
* @format: printf-style formatting string
|
||||
* @args: Arguments to be formatted
|
||||
*
|
||||
|
@ -361,49 +390,62 @@ int ntfs_logging_handler_printf (const char *function, const char *file,
|
|||
*
|
||||
* Note: This function calls ntfs_logging_handler_printf to do the main work.
|
||||
*
|
||||
* Note: If @stream is NULL, the output stream will be determined by the
|
||||
* function: ntfs_logging_get_stream
|
||||
* Note: For this handler, @data is a pointer to a FILE output stream.
|
||||
* If @data is NULL, the function ntfs_logging_get_stream will be called
|
||||
*
|
||||
* Returns: -1 Error occurred
|
||||
* 0 Message wasn't logged
|
||||
* num Number of output characters
|
||||
*/
|
||||
int ntfs_logging_handler_colour (const char *function, const char *file,
|
||||
int line, int level, FILE *stream, const char *format, va_list args)
|
||||
int ntfs_logging_handler_colour(const char *function, const char *file,
|
||||
int line, u32 level, void *data, const char *format, va_list args)
|
||||
{
|
||||
int ret = 0;
|
||||
int olderr = errno;
|
||||
const char *prefix = NULL;
|
||||
const char *suffix = NULL;
|
||||
const char *end = "\e[0m";
|
||||
FILE *stream = NULL;
|
||||
|
||||
if (!stream)
|
||||
stream = ntfs_logging_get_stream (level);
|
||||
if (level != NTFS_LOG_LEVEL_REASON) { /* Reasons get passed through */
|
||||
if (data)
|
||||
stream = (FILE*) data;
|
||||
else
|
||||
stream = ntfs_logging_get_stream(level);
|
||||
|
||||
switch (level) {
|
||||
case LOG_LEVEL_WARNING:
|
||||
prefix = "\e[01;33m"; /* Yellow */
|
||||
suffix = end;
|
||||
break;
|
||||
case LOG_LEVEL_ERROR:
|
||||
case LOG_LEVEL_PERROR:
|
||||
prefix = "\e[01;31m"; /* Red */
|
||||
suffix = end;
|
||||
break;
|
||||
case LOG_LEVEL_CRITICAL:
|
||||
prefix = "\e[01;07;31m"; /* Red, inverse */
|
||||
suffix = end;
|
||||
break;
|
||||
switch (level) {
|
||||
case NTFS_LOG_LEVEL_DEBUG:
|
||||
prefix = "\e[32m"; /* Green */
|
||||
suffix = end;
|
||||
break;
|
||||
case NTFS_LOG_LEVEL_TRACE:
|
||||
prefix = "\e[36m"; /* Cyan */
|
||||
suffix = end;
|
||||
break;
|
||||
case NTFS_LOG_LEVEL_WARNING:
|
||||
prefix = "\e[01;33m"; /* Yellow */
|
||||
suffix = end;
|
||||
break;
|
||||
case NTFS_LOG_LEVEL_ERROR:
|
||||
case NTFS_LOG_LEVEL_PERROR:
|
||||
prefix = "\e[01;31m"; /* Red */
|
||||
suffix = end;
|
||||
break;
|
||||
case NTFS_LOG_LEVEL_CRITICAL:
|
||||
prefix = "\e[01;07;31m"; /* Red, inverse */
|
||||
suffix = end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (prefix)
|
||||
ret += fprintf (stream, prefix);
|
||||
ret += fprintf(stream, prefix);
|
||||
|
||||
errno = olderr;
|
||||
ret += ntfs_logging_handler_printf (function, file, line, level, stream, format, args);
|
||||
ret += ntfs_logging_handler_printf(function, file, line, level, stream, format, args);
|
||||
|
||||
if (suffix)
|
||||
ret += fprintf (stream, suffix);
|
||||
ret += fprintf(stream, suffix);
|
||||
|
||||
errno = olderr;
|
||||
return ret;
|
||||
|
@ -423,27 +465,27 @@ int ntfs_logging_handler_colour (const char *function, const char *file,
|
|||
* Returns: TRUE Option understood
|
||||
* FALSE Invalid log option
|
||||
*/
|
||||
BOOL ntfs_logging_parse_option (const char *option)
|
||||
BOOL ntfs_logging_parse_option(const char *option)
|
||||
{
|
||||
if (strcmp (option, "--log-debug") == 0) {
|
||||
ntfs_logging_set_levels (LOG_LEVEL_DEBUG);
|
||||
if (strcmp(option, "--log-debug") == 0) {
|
||||
ntfs_logging_set_levels(NTFS_LOG_LEVEL_DEBUG);
|
||||
return TRUE;
|
||||
} else if (strcmp (option, "--log-verbose") == 0) {
|
||||
ntfs_logging_set_levels (LOG_LEVEL_VERBOSE);
|
||||
} else if (strcmp(option, "--log-verbose") == 0) {
|
||||
ntfs_logging_set_levels(NTFS_LOG_LEVEL_VERBOSE);
|
||||
return TRUE;
|
||||
} else if (strcmp (option, "--log-quiet") == 0) {
|
||||
ntfs_logging_set_levels (LOG_LEVEL_QUIET);
|
||||
} else if (strcmp(option, "--log-quiet") == 0) {
|
||||
ntfs_logging_set_levels(NTFS_LOG_LEVEL_QUIET);
|
||||
return TRUE;
|
||||
} else if (strcmp (option, "--log-trace") == 0) {
|
||||
ntfs_logging_set_levels (LOG_LEVEL_TRACE);
|
||||
} else if (strcmp(option, "--log-trace") == 0) {
|
||||
ntfs_logging_set_levels(NTFS_LOG_LEVEL_TRACE);
|
||||
return TRUE;
|
||||
} else if ((strcmp (option, "--log-colour") == 0) ||
|
||||
(strcmp (option, "--log-color") == 0)) {
|
||||
ntfs_logging_set_handler (ntfs_logging_handler_colour);
|
||||
} else if ((strcmp(option, "--log-colour") == 0) ||
|
||||
(strcmp(option, "--log-color") == 0)) {
|
||||
ntfs_logging_set_handler(ntfs_logging_handler_colour);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
log_error ("Unknown logging option '%s'\n", option);
|
||||
ntfs_log_warning("Unknown logging option '%s'\n", option);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
383
libntfs/mft.c
383
libntfs/mft.c
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* mst.c - Multi sector fixup handling code. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2000-2004 Anton Altaparmakov
|
||||
|
@ -19,13 +19,16 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "mst.h"
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "mst.h"
|
||||
|
||||
/**
|
||||
* ntfs_mst_post_read_fixup - deprotect multi sector transfer protected data
|
||||
* @b: pointer to the data to deprotect
|
||||
|
|
|
@ -21,9 +21,17 @@
|
|||
|
||||
#ifdef NTFS_RICH
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "rich.h"
|
||||
#include "layout.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* find_attribute - Find an attribute of the given type
|
||||
|
@ -39,7 +47,7 @@
|
|||
* Return: Pointer Success, an attribute was found
|
||||
* NULL Error, no matching attributes were found
|
||||
*/
|
||||
ATTR_RECORD * find_attribute (const ATTR_TYPES type, ntfs_attr_search_ctx *ctx)
|
||||
ATTR_RECORD * find_attribute(const ATTR_TYPES type, ntfs_attr_search_ctx *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
errno = EINVAL;
|
||||
|
@ -47,11 +55,11 @@ ATTR_RECORD * find_attribute (const ATTR_TYPES type, ntfs_attr_search_ctx *ctx)
|
|||
}
|
||||
|
||||
if (ntfs_attr_lookup(type, NULL, 0, 0, 0, NULL, 0, ctx) != 0) {
|
||||
Dprintf ("find_attribute didn't find an attribute of type: 0x%02x.\n", type);
|
||||
ntfs_log_debug("find_attribute didn't find an attribute of type: 0x%02x.\n", type);
|
||||
return NULL; /* None / no more of that type */
|
||||
}
|
||||
|
||||
Dprintf ("find_attribute found an attribute of type: 0x%02x.\n", type);
|
||||
ntfs_log_debug("find_attribute found an attribute of type: 0x%02x.\n", type);
|
||||
return ctx->attr;
|
||||
}
|
||||
|
||||
|
@ -69,7 +77,7 @@ ATTR_RECORD * find_attribute (const ATTR_TYPES type, ntfs_attr_search_ctx *ctx)
|
|||
* Return: Pointer Success, an attribute was found
|
||||
* NULL Error, no matching attributes were found
|
||||
*/
|
||||
ATTR_RECORD * find_first_attribute (const ATTR_TYPES type, MFT_RECORD *mft)
|
||||
ATTR_RECORD * find_first_attribute(const ATTR_TYPES type, MFT_RECORD *mft)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
ATTR_RECORD *rec;
|
||||
|
@ -79,41 +87,41 @@ ATTR_RECORD * find_first_attribute (const ATTR_TYPES type, MFT_RECORD *mft)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ctx = ntfs_attr_get_search_ctx (NULL, mft);
|
||||
ctx = ntfs_attr_get_search_ctx(NULL, mft);
|
||||
if (!ctx) {
|
||||
//XXX Eprintf ("Couldn't create a search context.\n");
|
||||
//XXX ntfs_log_error("Couldn't create a search context.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rec = find_attribute (type, ctx);
|
||||
ntfs_attr_put_search_ctx (ctx);
|
||||
rec = find_attribute(type, ctx);
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
if (rec)
|
||||
Dprintf ("find_first_attribute: found attr of type 0x%02x.\n", type);
|
||||
ntfs_log_debug("find_first_attribute: found attr of type 0x%02x.\n", type);
|
||||
else
|
||||
Dprintf ("find_first_attribute: didn't find attr of type 0x%02x.\n", type);
|
||||
ntfs_log_debug("find_first_attribute: didn't find attr of type 0x%02x.\n", type);
|
||||
return rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_name_print
|
||||
*/
|
||||
void ntfs_name_print (ntfschar *name, int name_len)
|
||||
void ntfs_name_print(ntfschar *name, int name_len)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
|
||||
if (name_len) {
|
||||
ntfs_ucstombs (name, name_len, &buffer, 0);
|
||||
printf ("%s", buffer);
|
||||
free (buffer);
|
||||
ntfs_ucstombs(name, name_len, &buffer, 0);
|
||||
ntfs_log_info("%s", buffer);
|
||||
free(buffer);
|
||||
} else {
|
||||
printf ("!");
|
||||
ntfs_log_info("!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* utils_free_non_residents3
|
||||
*/
|
||||
int utils_free_non_residents3 (struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_RECORD *attr)
|
||||
int utils_free_non_residents3(struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_RECORD *attr)
|
||||
{
|
||||
ntfs_attr *na;
|
||||
runlist_element *rl;
|
||||
|
@ -129,19 +137,19 @@ int utils_free_non_residents3 (struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_REC
|
|||
if (!attr->non_resident)
|
||||
return 0;
|
||||
|
||||
na = ntfs_attr_open (inode, attr->type, NULL, 0);
|
||||
na = ntfs_attr_open(inode, attr->type, NULL, 0);
|
||||
if (!na)
|
||||
return 1;
|
||||
|
||||
ntfs_attr_map_whole_runlist (na);
|
||||
ntfs_attr_map_whole_runlist(na);
|
||||
rl = na->rl;
|
||||
size = na->allocated_size >> inode->vol->cluster_size_bits;
|
||||
for (count = 0; count < size; count += rl->length, rl++) {
|
||||
if (ntfs_bmp_set_range (bmp, rl->lcn, rl->length, 0) < 0) {
|
||||
printf (RED "set range : %lld - %lld FAILED\n" END, rl->lcn, rl->lcn+rl->length-1);
|
||||
if (ntfs_bmp_set_range(bmp, rl->lcn, rl->length, 0) < 0) {
|
||||
ntfs_log_info(RED "set range : %lld - %lld FAILED\n" END, rl->lcn, rl->lcn+rl->length-1);
|
||||
}
|
||||
}
|
||||
ntfs_attr_close (na);
|
||||
ntfs_attr_close(na);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -149,7 +157,7 @@ int utils_free_non_residents3 (struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_REC
|
|||
/**
|
||||
* utils_free_non_residents2
|
||||
*/
|
||||
int utils_free_non_residents2 (ntfs_inode *inode, struct ntfs_bmp *bmp)
|
||||
int utils_free_non_residents2(ntfs_inode *inode, struct ntfs_bmp *bmp)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
|
||||
|
@ -158,17 +166,17 @@ int utils_free_non_residents2 (ntfs_inode *inode, struct ntfs_bmp *bmp)
|
|||
if (!bmp)
|
||||
return -1;
|
||||
|
||||
ctx = ntfs_attr_get_search_ctx (NULL, inode->mrec);
|
||||
ctx = ntfs_attr_get_search_ctx(NULL, inode->mrec);
|
||||
if (!ctx) {
|
||||
printf ("can't create a search context\n");
|
||||
ntfs_log_info("can't create a search context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx) == 0) {
|
||||
utils_free_non_residents3 (bmp, inode, ctx->attr);
|
||||
utils_free_non_residents3(bmp, inode, ctx->attr);
|
||||
}
|
||||
|
||||
ntfs_attr_put_search_ctx (ctx);
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
|
@ -37,13 +39,13 @@
|
|||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "attrib.h"
|
||||
#include "volume.h"
|
||||
#include "layout.h"
|
||||
#include "debug.h"
|
||||
#include "device.h"
|
||||
#include "logging.h"
|
||||
|
||||
/**
|
||||
* Internal:
|
||||
|
@ -114,8 +116,8 @@ static __inline__ BOOL ntfs_rl_are_mergeable(runlist_element *dst,
|
|||
runlist_element *src)
|
||||
{
|
||||
if (!dst || !src) {
|
||||
Dputs("Eeek. ntfs_rl_are_mergeable() invoked with NULL "
|
||||
"pointer!");
|
||||
ntfs_log_debug("Eeek. ntfs_rl_are_mergeable() invoked with NULL "
|
||||
"pointer!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -182,7 +184,8 @@ static __inline__ runlist_element *ntfs_rl_append(runlist_element *dst,
|
|||
int marker; /* End of the inserted runs */
|
||||
|
||||
if (!dst || !src) {
|
||||
Dputs("Eeek. ntfs_rl_append() invoked with NULL pointer!");
|
||||
ntfs_log_debug("Eeek. ntfs_rl_append() invoked with NULL "
|
||||
"pointer!\n");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -251,7 +254,8 @@ static __inline__ runlist_element *ntfs_rl_insert(runlist_element *dst,
|
|||
int marker; /* End of the inserted runs */
|
||||
|
||||
if (!dst || !src) {
|
||||
Dputs("Eeek. ntfs_rl_insert() invoked with NULL pointer!");
|
||||
ntfs_log_debug("Eeek. ntfs_rl_insert() invoked with NULL "
|
||||
"pointer!\n");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -349,7 +353,8 @@ static __inline__ runlist_element *ntfs_rl_replace(runlist_element *dst,
|
|||
int marker; /* End of the inserted runs */
|
||||
|
||||
if (!dst || !src) {
|
||||
Dputs("Eeek. ntfs_rl_replace() invoked with NULL pointer!");
|
||||
ntfs_log_debug("Eeek. ntfs_rl_replace() invoked with NULL "
|
||||
"pointer!\n");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -428,7 +433,7 @@ static __inline__ runlist_element *ntfs_rl_split(runlist_element *dst,
|
|||
int dsize, runlist_element *src, int ssize, int loc)
|
||||
{
|
||||
if (!dst || !src) {
|
||||
Dputs("Eeek. ntfs_rl_split() invoked with NULL pointer!");
|
||||
ntfs_log_debug("Eeek. ntfs_rl_split() invoked with NULL pointer!\n");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -499,9 +504,9 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
|
|||
int marker = 0;
|
||||
VCN marker_vcn = 0;
|
||||
|
||||
Dputs("dst:");
|
||||
ntfs_log_debug("dst:\n");
|
||||
ntfs_debug_runlist_dump(drl);
|
||||
Dputs("src:");
|
||||
ntfs_log_debug("src:\n");
|
||||
ntfs_debug_runlist_dump(srl);
|
||||
|
||||
/* Check for silly calling... */
|
||||
|
@ -537,8 +542,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
|
|||
|
||||
/* Can't have an entirely unmapped source runlist. */
|
||||
if (!srl[si].length) {
|
||||
Dputs("Eeek! ntfs_runlists_merge() received entirely "
|
||||
"unmapped source runlist.");
|
||||
ntfs_log_debug("Eeek! ntfs_runlists_merge() received entirely "
|
||||
"unmapped source runlist.\n");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -560,7 +565,7 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
|
|||
/* Sanity check for illegal overlaps. */
|
||||
if ((drl[di].vcn == srl[si].vcn) && (drl[di].lcn >= 0) &&
|
||||
(srl[si].lcn >= 0)) {
|
||||
Dputs("Run lists overlap. Cannot merge!");
|
||||
ntfs_log_debug("Run lists overlap. Cannot merge!\n");
|
||||
errno = ERANGE;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -598,10 +603,10 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
|
|||
if (marker && (drl[dins].vcn + drl[dins].length > srl[send - 1].vcn))
|
||||
finish = FALSE;
|
||||
#ifdef DEBUG
|
||||
Dprintf("dfinal = %i, dend = %i\n", dfinal, dend);
|
||||
Dprintf("sstart = %i, sfinal = %i, send = %i\n", sstart, sfinal, send);
|
||||
Dprintf("start = %i, finish = %i\n", start, finish);
|
||||
Dprintf("ds = %i, ss = %i, dins = %i\n", ds, ss, dins);
|
||||
ntfs_log_debug("dfinal = %i, dend = %i\n", dfinal, dend);
|
||||
ntfs_log_debug("sstart = %i, sfinal = %i, send = %i\n", sstart, sfinal, send);
|
||||
ntfs_log_debug("start = %i, finish = %i\n", start, finish);
|
||||
ntfs_log_debug("ds = %i, ss = %i, dins = %i\n", ds, ss, dins);
|
||||
#endif
|
||||
if (start) {
|
||||
if (finish)
|
||||
|
@ -615,13 +620,12 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
|
|||
drl = ntfs_rl_split(drl, ds, srl + sstart, ss, dins);
|
||||
}
|
||||
if (!drl) {
|
||||
Dprintf("%s(): Merge failed: %s\n", __FUNCTION__,
|
||||
strerror(errno));
|
||||
ntfs_log_perror("Merge failed");
|
||||
return drl;
|
||||
}
|
||||
free(srl);
|
||||
if (marker) {
|
||||
Dputs("Triggering marker code.");
|
||||
ntfs_log_debug("Triggering marker code.\n");
|
||||
for (ds = dend; drl[ds].length; ds++)
|
||||
;
|
||||
/* We only need to care if @srl ended after @drl. */
|
||||
|
@ -629,7 +633,7 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
|
|||
int slots = 0;
|
||||
|
||||
if (drl[ds].vcn == marker_vcn) {
|
||||
Dprintf("Old marker = %lli, replacing with "
|
||||
ntfs_log_debug("Old marker = %lli, replacing with "
|
||||
"LCN_ENOENT.\n",
|
||||
(long long)drl[ds].lcn);
|
||||
drl[ds].lcn = (LCN)LCN_ENOENT;
|
||||
|
@ -684,14 +688,14 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
|
|||
|
||||
finished:
|
||||
/* The merge was completed successfully. */
|
||||
Dputs("Merged runlist:");
|
||||
ntfs_log_debug("Merged runlist:\n");
|
||||
ntfs_debug_runlist_dump(drl);
|
||||
return drl;
|
||||
|
||||
critical_error:
|
||||
/* Critical error! We cannot afford to fail here. */
|
||||
Dperror("libntfs: Critical error");
|
||||
Dputs("Forcing segmentation fault!");
|
||||
ntfs_log_perror("libntfs: Critical error");
|
||||
ntfs_log_debug("Forcing segmentation fault!\n");
|
||||
marker_vcn = ((runlist*)NULL)->lcn;
|
||||
return drl;
|
||||
}
|
||||
|
@ -737,7 +741,7 @@ runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
|
|||
runlist_elements. */
|
||||
u8 b; /* Current byte offset in buf. */
|
||||
|
||||
Dprintf("%s(): Entering for attr 0x%x.\n", __FUNCTION__,
|
||||
ntfs_log_trace("Entering for attr 0x%x.\n",
|
||||
(unsigned)le32_to_cpu(attr->type));
|
||||
/* Make sure attr exists and is non-resident. */
|
||||
if (!attr || !attr->non_resident ||
|
||||
|
@ -752,7 +756,7 @@ runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
|
|||
buf = (const u8*)attr + le16_to_cpu(attr->mapping_pairs_offset);
|
||||
attr_end = (const u8*)attr + le32_to_cpu(attr->length);
|
||||
if (buf < (const u8*)attr || buf > attr_end) {
|
||||
Dputs("Corrupt attribute.");
|
||||
ntfs_log_debug("Corrupt attribute.\n");
|
||||
errno = EIO;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -803,7 +807,8 @@ runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
|
|||
for (deltaxcn = (s8)buf[b--]; b; b--)
|
||||
deltaxcn = (deltaxcn << 8) + buf[b];
|
||||
} else { /* The length entry is compulsory. */
|
||||
Dputs("Missing length entry in mapping pairs array.");
|
||||
ntfs_log_debug("Missing length entry in mapping pairs "
|
||||
"array.\n");
|
||||
deltaxcn = (s64)-1;
|
||||
}
|
||||
/*
|
||||
|
@ -811,7 +816,7 @@ runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
|
|||
* hence clean-up and return NULL.
|
||||
*/
|
||||
if (deltaxcn < 0) {
|
||||
Dputs("Invalid length in mapping pairs array.");
|
||||
ntfs_log_debug("Invalid length in mapping pairs array.\n");
|
||||
goto err_out;
|
||||
}
|
||||
/*
|
||||
|
@ -848,15 +853,15 @@ runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
|
|||
*/
|
||||
if (vol->major_ver < 3) {
|
||||
if (deltaxcn == (LCN)-1)
|
||||
Dputs("lcn delta == -1");
|
||||
ntfs_log_debug("lcn delta == -1\n");
|
||||
if (lcn == (LCN)-1)
|
||||
Dputs("lcn == -1");
|
||||
ntfs_log_debug("lcn == -1\n");
|
||||
}
|
||||
#endif
|
||||
/* Check lcn is not below -1. */
|
||||
if (lcn < (LCN)-1) {
|
||||
Dputs("Invalid LCN < -1 in mapping pairs "
|
||||
"array.");
|
||||
ntfs_log_debug("Invalid LCN < -1 in mapping pairs "
|
||||
"array.\n");
|
||||
goto err_out;
|
||||
}
|
||||
/* Enter the current lcn into the runlist element. */
|
||||
|
@ -876,7 +881,8 @@ runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
|
|||
deltaxcn = sle64_to_cpu(attr->highest_vcn);
|
||||
if (deltaxcn && vcn - 1 != deltaxcn) {
|
||||
mpa_err:
|
||||
Dputs("Corrupt mapping pairs array in non-resident attribute.");
|
||||
ntfs_log_debug("Corrupt mapping pairs array in non-resident "
|
||||
"attribute.\n");
|
||||
goto err_out;
|
||||
}
|
||||
/* Setup not mapped runlist element if this is the base extent. */
|
||||
|
@ -898,8 +904,8 @@ mpa_err:
|
|||
* this one.
|
||||
*/
|
||||
if (deltaxcn < max_cluster) {
|
||||
Dprintf("More extents to follow; deltaxcn = 0x%llx, "
|
||||
"max_cluster = 0x%llx\n",
|
||||
ntfs_log_debug("More extents to follow; deltaxcn = "
|
||||
"0x%llx, max_cluster = 0x%llx\n",
|
||||
(long long)deltaxcn,
|
||||
(long long)max_cluster);
|
||||
rl[rlpos].vcn = vcn;
|
||||
|
@ -907,8 +913,8 @@ mpa_err:
|
|||
rl[rlpos].lcn = (LCN)LCN_RL_NOT_MAPPED;
|
||||
rlpos++;
|
||||
} else if (deltaxcn > max_cluster) {
|
||||
Dprintf("Corrupt attribute. deltaxcn = 0x%llx, "
|
||||
"max_cluster = 0x%llx",
|
||||
ntfs_log_debug("Corrupt attribute. deltaxcn = "
|
||||
"0x%llx, max_cluster = 0x%llx",
|
||||
(long long)deltaxcn,
|
||||
(long long)max_cluster);
|
||||
goto mpa_err;
|
||||
|
@ -923,7 +929,7 @@ mpa_err:
|
|||
rl[rlpos].length = (s64)0;
|
||||
/* If no existing runlist was specified, we are done. */
|
||||
if (!old_rl) {
|
||||
Dputs("Mapping pairs array successfully decompressed:");
|
||||
ntfs_log_debug("Mapping pairs array successfully decompressed:\n");
|
||||
ntfs_debug_runlist_dump(rl);
|
||||
return rl;
|
||||
}
|
||||
|
@ -933,11 +939,11 @@ mpa_err:
|
|||
return old_rl;
|
||||
err = errno;
|
||||
free(rl);
|
||||
Dputs("Failed to merge runlists.");
|
||||
ntfs_log_debug("Failed to merge runlists.\n");
|
||||
errno = err;
|
||||
return NULL;
|
||||
io_error:
|
||||
Dputs("Corrupt attribute.");
|
||||
ntfs_log_debug("Corrupt attribute.\n");
|
||||
err_out:
|
||||
free(rl);
|
||||
errno = EIO;
|
||||
|
@ -1256,15 +1262,15 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
|
|||
int rls;
|
||||
|
||||
if (start_vcn < 0) {
|
||||
Dprintf("%s(): start_vcn %lld (should be >= 0)",
|
||||
__FUNCTION__, (long long) start_vcn);
|
||||
ntfs_log_trace("start_vcn %lld (should be >= 0)\n",
|
||||
(long long) start_vcn);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (!rl) {
|
||||
if (start_vcn) {
|
||||
Dprintf("%s(): rl NULL, start_vcn %lld (should be > 0)",
|
||||
__FUNCTION__, (long long) start_vcn);
|
||||
ntfs_log_trace("rl NULL, start_vcn %lld (should be > 0)\n",
|
||||
(long long) start_vcn);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1581,8 +1587,8 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn)
|
|||
rl = *arl;
|
||||
if (start_vcn < rl->vcn) {
|
||||
// FIXME: Eeek! BUG()
|
||||
Dprintf("%s(): Eeek! start_vcn lies outside front of "
|
||||
"runlist! Aborting.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Eeek! start_vcn lies outside front of runlist! "
|
||||
"Aborting.\n");
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1594,15 +1600,14 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn)
|
|||
}
|
||||
if (!rl->length) {
|
||||
// FIXME: Weird, probably a BUG()!
|
||||
Dprintf("%s(): Weird! Asking to truncate already truncated "
|
||||
"runlist?!? Abort.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Weird! Asking to truncate already truncated "
|
||||
"runlist?!? Abort.\n");
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
if (start_vcn < rl->vcn) {
|
||||
// FIXME: Eeek! BUG()
|
||||
Dprintf("%s(): Eeek! start_vcn < rl->vcn! Aborting.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Eeek! start_vcn < rl->vcn! Aborting.\n");
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1635,9 +1640,8 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn)
|
|||
*arl = NULL;
|
||||
else {
|
||||
// FIXME: Eeek!
|
||||
Dprintf("%s(): Eeek! Failed to reallocate runlist "
|
||||
"buffer! Continuing regardless and "
|
||||
"returning success.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Eeek! Failed to reallocate runlist buffer! "
|
||||
"Continuing regardless and returning success.\n");
|
||||
}
|
||||
}
|
||||
/* Done! */
|
||||
|
@ -1655,7 +1659,7 @@ int ntfs_rl_sparse(runlist *rl)
|
|||
runlist *rlc;
|
||||
|
||||
if (!rl) {
|
||||
Dprintf("%s(): Invalid argument passed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid argument passed.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1663,8 +1667,7 @@ int ntfs_rl_sparse(runlist *rl)
|
|||
for (rlc = rl; rlc->length; rlc++)
|
||||
if (rlc->lcn < 0) {
|
||||
if (rlc->lcn != LCN_HOLE) {
|
||||
Dprintf("%s(): Received unmapped runlist.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Received unmapped runlist.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1686,7 +1689,7 @@ s64 ntfs_rl_get_compressed_size(ntfs_volume *vol, runlist *rl)
|
|||
s64 ret = 0;
|
||||
|
||||
if (!rl) {
|
||||
Dprintf("%s(): Invalid argument passed.\n", __FUNCTION__);
|
||||
ntfs_log_trace("Invalid argument passed.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1694,8 +1697,7 @@ s64 ntfs_rl_get_compressed_size(ntfs_volume *vol, runlist *rl)
|
|||
for (rlc = rl; rlc->length; rlc++) {
|
||||
if (rlc->lcn < 0) {
|
||||
if (rlc->lcn != LCN_HOLE) {
|
||||
Dprintf("%s(): Received unmapped runlist.\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Received unmapped runlist.\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1720,7 +1722,7 @@ s64 ntfs_rl_get_compressed_size(ntfs_volume *vol, runlist *rl)
|
|||
/**
|
||||
* test_rl_dump_runlist
|
||||
*/
|
||||
static void test_rl_dump_runlist (const runlist_element *rl)
|
||||
static void test_rl_dump_runlist(const runlist_element *rl)
|
||||
{
|
||||
int abbr = 0; /* abbreviate long lists */
|
||||
int len = 0;
|
||||
|
@ -1728,20 +1730,20 @@ static void test_rl_dump_runlist (const runlist_element *rl)
|
|||
const char *lcn_str[5] = { "HOLE", "NOTMAP", "ENOENT", "XXXX" };
|
||||
|
||||
if (!rl) {
|
||||
printf(" Run list not present.\n");
|
||||
ntfs_log_debug(" Run list not present.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (abbr)
|
||||
for (len = 0; rl[len].length; len++) ;
|
||||
|
||||
printf(" VCN LCN len\n");
|
||||
ntfs_log_debug(" VCN LCN len\n");
|
||||
for (i = 0; ; i++, rl++) {
|
||||
LCN lcn = rl->lcn;
|
||||
|
||||
if ((abbr) && (len > 20)) {
|
||||
if (i == 4)
|
||||
printf (" ...\n");
|
||||
ntfs_log_debug(" ...\n");
|
||||
if ((i > 3) && (i < (len - 3)))
|
||||
continue;
|
||||
}
|
||||
|
@ -1751,35 +1753,35 @@ static void test_rl_dump_runlist (const runlist_element *rl)
|
|||
|
||||
if (ind > -LCN_ENOENT - 1)
|
||||
ind = 3;
|
||||
printf("%8lld %8s %8lld\n",
|
||||
ntfs_log_debug("%8lld %8s %8lld\n",
|
||||
rl->vcn, lcn_str[ind], rl->length);
|
||||
} else
|
||||
printf("%8lld %8lld %8lld\n",
|
||||
ntfs_log_debug("%8lld %8lld %8lld\n",
|
||||
rl->vcn, rl->lcn, rl->length);
|
||||
if (!rl->length)
|
||||
break;
|
||||
}
|
||||
if ((abbr) && (len > 20))
|
||||
printf (" (%d entries)\n", len+1);
|
||||
printf ("\n");
|
||||
ntfs_log_debug(" (%d entries)\n", len+1);
|
||||
ntfs_log_debug("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* test_rl_runlists_merge
|
||||
*/
|
||||
static runlist_element * test_rl_runlists_merge (runlist_element *drl, runlist_element *srl)
|
||||
static runlist_element * test_rl_runlists_merge(runlist_element *drl, runlist_element *srl)
|
||||
{
|
||||
runlist_element *res = NULL;
|
||||
|
||||
printf ("dst:\n");
|
||||
test_rl_dump_runlist (drl);
|
||||
printf ("src:\n");
|
||||
test_rl_dump_runlist (srl);
|
||||
ntfs_log_debug("dst:\n");
|
||||
test_rl_dump_runlist(drl);
|
||||
ntfs_log_debug("src:\n");
|
||||
test_rl_dump_runlist(srl);
|
||||
|
||||
res = ntfs_runlists_merge (drl, srl);
|
||||
res = ntfs_runlists_merge(drl, srl);
|
||||
|
||||
printf ("res:\n");
|
||||
test_rl_dump_runlist (res);
|
||||
ntfs_log_debug("res:\n");
|
||||
test_rl_dump_runlist(res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -1787,29 +1789,29 @@ static runlist_element * test_rl_runlists_merge (runlist_element *drl, runlist_e
|
|||
/**
|
||||
* test_rl_read_buffer
|
||||
*/
|
||||
static int test_rl_read_buffer (const char *file, u8 *buf, int bufsize)
|
||||
static int test_rl_read_buffer(const char *file, u8 *buf, int bufsize)
|
||||
{
|
||||
FILE *fptr;
|
||||
|
||||
fptr = fopen (file, "r");
|
||||
fptr = fopen(file, "r");
|
||||
if (!fptr) {
|
||||
printf ("open %s\n", file);
|
||||
ntfs_log_debug("open %s\n", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fread (buf, bufsize, 1, fptr) == 99) {
|
||||
printf ("read %s\n", file);
|
||||
if (fread(buf, bufsize, 1, fptr) == 99) {
|
||||
ntfs_log_debug("read %s\n", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose (fptr);
|
||||
fclose(fptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* test_rl_pure_src
|
||||
*/
|
||||
static runlist_element * test_rl_pure_src (BOOL contig, BOOL multi, int vcn, int len)
|
||||
static runlist_element * test_rl_pure_src(BOOL contig, BOOL multi, int vcn, int len)
|
||||
{
|
||||
runlist_element *result;
|
||||
int fudge;
|
||||
|
@ -1819,16 +1821,16 @@ static runlist_element * test_rl_pure_src (BOOL contig, BOOL multi, int vcn, int
|
|||
else
|
||||
fudge = 999;
|
||||
|
||||
result = malloc (4096);
|
||||
result = malloc(4096);
|
||||
if (multi) {
|
||||
MKRL (result+0, vcn + (0*len/4), fudge + vcn + 1000 + (0*len/4), len / 4)
|
||||
MKRL (result+1, vcn + (1*len/4), fudge + vcn + 1000 + (1*len/4), len / 4)
|
||||
MKRL (result+2, vcn + (2*len/4), fudge + vcn + 1000 + (2*len/4), len / 4)
|
||||
MKRL (result+3, vcn + (3*len/4), fudge + vcn + 1000 + (3*len/4), len / 4)
|
||||
MKRL (result+4, vcn + (4*len/4), LCN_RL_NOT_MAPPED, 0)
|
||||
MKRL(result+0, vcn + (0*len/4), fudge + vcn + 1000 + (0*len/4), len / 4)
|
||||
MKRL(result+1, vcn + (1*len/4), fudge + vcn + 1000 + (1*len/4), len / 4)
|
||||
MKRL(result+2, vcn + (2*len/4), fudge + vcn + 1000 + (2*len/4), len / 4)
|
||||
MKRL(result+3, vcn + (3*len/4), fudge + vcn + 1000 + (3*len/4), len / 4)
|
||||
MKRL(result+4, vcn + (4*len/4), LCN_RL_NOT_MAPPED, 0)
|
||||
} else {
|
||||
MKRL (result+0, vcn, fudge + vcn + 1000, len)
|
||||
MKRL (result+1, vcn + len, LCN_RL_NOT_MAPPED, 0)
|
||||
MKRL(result+0, vcn, fudge + vcn + 1000, len)
|
||||
MKRL(result+1, vcn + len, LCN_RL_NOT_MAPPED, 0)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1836,27 +1838,27 @@ static runlist_element * test_rl_pure_src (BOOL contig, BOOL multi, int vcn, int
|
|||
/**
|
||||
* test_rl_pure_test
|
||||
*/
|
||||
static void test_rl_pure_test (int test, BOOL contig, BOOL multi, int vcn, int len, runlist_element *file, int size)
|
||||
static void test_rl_pure_test(int test, BOOL contig, BOOL multi, int vcn, int len, runlist_element *file, int size)
|
||||
{
|
||||
runlist_element *src;
|
||||
runlist_element *dst;
|
||||
runlist_element *res;
|
||||
|
||||
src = test_rl_pure_src (contig, multi, vcn, len);
|
||||
dst = malloc (4096);
|
||||
src = test_rl_pure_src(contig, multi, vcn, len);
|
||||
dst = malloc(4096);
|
||||
|
||||
memcpy (dst, file, size);
|
||||
memcpy(dst, file, size);
|
||||
|
||||
printf ("Test %2d ----------\n", test);
|
||||
res = test_rl_runlists_merge (dst, src);
|
||||
ntfs_log_debug("Test %2d ----------\n", test);
|
||||
res = test_rl_runlists_merge(dst, src);
|
||||
|
||||
free (res);
|
||||
free(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* test_rl_pure
|
||||
*/
|
||||
static void test_rl_pure (char *contig, char *multi)
|
||||
static void test_rl_pure(char *contig, char *multi)
|
||||
{
|
||||
/* VCN, LCN, len */
|
||||
static runlist_element file1[] = {
|
||||
|
@ -1894,118 +1896,118 @@ static void test_rl_pure (char *contig, char *multi)
|
|||
};
|
||||
BOOL c, m;
|
||||
|
||||
if (strcmp (contig, "contig") == 0)
|
||||
if (strcmp(contig, "contig") == 0)
|
||||
c = TRUE;
|
||||
else if (strcmp (contig, "noncontig") == 0)
|
||||
else if (strcmp(contig, "noncontig") == 0)
|
||||
c = FALSE;
|
||||
else {
|
||||
printf ("rl pure [contig|noncontig] [single|multi]\n");
|
||||
ntfs_log_debug("rl pure [contig|noncontig] [single|multi]\n");
|
||||
return;
|
||||
}
|
||||
if (strcmp (multi, "multi") == 0)
|
||||
if (strcmp(multi, "multi") == 0)
|
||||
m = TRUE;
|
||||
else if (strcmp (multi, "single") == 0)
|
||||
else if (strcmp(multi, "single") == 0)
|
||||
m = FALSE;
|
||||
else {
|
||||
printf ("rl pure [contig|noncontig] [single|multi]\n");
|
||||
ntfs_log_debug("rl pure [contig|noncontig] [single|multi]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
test_rl_pure_test (1, c, m, 0, 40, file1, sizeof (file1));
|
||||
test_rl_pure_test (2, c, m, 40, 40, file1, sizeof (file1));
|
||||
test_rl_pure_test (3, c, m, 60, 40, file1, sizeof (file1));
|
||||
test_rl_pure_test (4, c, m, 0, 100, file1, sizeof (file1));
|
||||
test_rl_pure_test (5, c, m, 200, 40, file1, sizeof (file1));
|
||||
test_rl_pure_test (6, c, m, 240, 40, file1, sizeof (file1));
|
||||
test_rl_pure_test (7, c, m, 260, 40, file1, sizeof (file1));
|
||||
test_rl_pure_test (8, c, m, 200, 100, file1, sizeof (file1));
|
||||
test_rl_pure_test (9, c, m, 400, 40, file1, sizeof (file1));
|
||||
test_rl_pure_test (10, c, m, 440, 40, file1, sizeof (file1));
|
||||
test_rl_pure_test (11, c, m, 460, 40, file1, sizeof (file1));
|
||||
test_rl_pure_test (12, c, m, 400, 100, file1, sizeof (file1));
|
||||
test_rl_pure_test (13, c, m, 160, 100, file2, sizeof (file2));
|
||||
test_rl_pure_test (14, c, m, 100, 140, file2, sizeof (file2));
|
||||
test_rl_pure_test (15, c, m, 200, 40, file2, sizeof (file2));
|
||||
test_rl_pure_test (16, c, m, 240, 40, file2, sizeof (file2));
|
||||
test_rl_pure_test (17, c, m, 100, 40, file3, sizeof (file3));
|
||||
test_rl_pure_test (18, c, m, 140, 40, file3, sizeof (file3));
|
||||
test_rl_pure_test (19, c, m, 0, 40, file4, sizeof (file4));
|
||||
test_rl_pure_test (20, c, m, 40, 40, file4, sizeof (file4));
|
||||
test_rl_pure_test (21, c, m, 0, 40, file5, sizeof (file5));
|
||||
test_rl_pure_test (22, c, m, 40, 40, file5, sizeof (file5));
|
||||
test_rl_pure_test (23, c, m, 60, 40, file5, sizeof (file5));
|
||||
test_rl_pure_test (24, c, m, 0, 100, file5, sizeof (file5));
|
||||
test_rl_pure_test (25, c, m, 200, 40, file5, sizeof (file5));
|
||||
test_rl_pure_test (26, c, m, 240, 40, file5, sizeof (file5));
|
||||
test_rl_pure_test (27, c, m, 260, 40, file5, sizeof (file5));
|
||||
test_rl_pure_test (28, c, m, 200, 100, file5, sizeof (file5));
|
||||
test_rl_pure_test (29, c, m, 400, 40, file5, sizeof (file5));
|
||||
test_rl_pure_test (30, c, m, 440, 40, file5, sizeof (file5));
|
||||
test_rl_pure_test (31, c, m, 460, 40, file5, sizeof (file5));
|
||||
test_rl_pure_test (32, c, m, 400, 100, file5, sizeof (file5));
|
||||
test_rl_pure_test (33, c, m, 160, 100, file6, sizeof (file6));
|
||||
test_rl_pure_test (34, c, m, 100, 140, file6, sizeof (file6));
|
||||
test_rl_pure_test(1, c, m, 0, 40, file1, sizeof(file1));
|
||||
test_rl_pure_test(2, c, m, 40, 40, file1, sizeof(file1));
|
||||
test_rl_pure_test(3, c, m, 60, 40, file1, sizeof(file1));
|
||||
test_rl_pure_test(4, c, m, 0, 100, file1, sizeof(file1));
|
||||
test_rl_pure_test(5, c, m, 200, 40, file1, sizeof(file1));
|
||||
test_rl_pure_test(6, c, m, 240, 40, file1, sizeof(file1));
|
||||
test_rl_pure_test(7, c, m, 260, 40, file1, sizeof(file1));
|
||||
test_rl_pure_test(8, c, m, 200, 100, file1, sizeof(file1));
|
||||
test_rl_pure_test(9, c, m, 400, 40, file1, sizeof(file1));
|
||||
test_rl_pure_test(10, c, m, 440, 40, file1, sizeof(file1));
|
||||
test_rl_pure_test(11, c, m, 460, 40, file1, sizeof(file1));
|
||||
test_rl_pure_test(12, c, m, 400, 100, file1, sizeof(file1));
|
||||
test_rl_pure_test(13, c, m, 160, 100, file2, sizeof(file2));
|
||||
test_rl_pure_test(14, c, m, 100, 140, file2, sizeof(file2));
|
||||
test_rl_pure_test(15, c, m, 200, 40, file2, sizeof(file2));
|
||||
test_rl_pure_test(16, c, m, 240, 40, file2, sizeof(file2));
|
||||
test_rl_pure_test(17, c, m, 100, 40, file3, sizeof(file3));
|
||||
test_rl_pure_test(18, c, m, 140, 40, file3, sizeof(file3));
|
||||
test_rl_pure_test(19, c, m, 0, 40, file4, sizeof(file4));
|
||||
test_rl_pure_test(20, c, m, 40, 40, file4, sizeof(file4));
|
||||
test_rl_pure_test(21, c, m, 0, 40, file5, sizeof(file5));
|
||||
test_rl_pure_test(22, c, m, 40, 40, file5, sizeof(file5));
|
||||
test_rl_pure_test(23, c, m, 60, 40, file5, sizeof(file5));
|
||||
test_rl_pure_test(24, c, m, 0, 100, file5, sizeof(file5));
|
||||
test_rl_pure_test(25, c, m, 200, 40, file5, sizeof(file5));
|
||||
test_rl_pure_test(26, c, m, 240, 40, file5, sizeof(file5));
|
||||
test_rl_pure_test(27, c, m, 260, 40, file5, sizeof(file5));
|
||||
test_rl_pure_test(28, c, m, 200, 100, file5, sizeof(file5));
|
||||
test_rl_pure_test(29, c, m, 400, 40, file5, sizeof(file5));
|
||||
test_rl_pure_test(30, c, m, 440, 40, file5, sizeof(file5));
|
||||
test_rl_pure_test(31, c, m, 460, 40, file5, sizeof(file5));
|
||||
test_rl_pure_test(32, c, m, 400, 100, file5, sizeof(file5));
|
||||
test_rl_pure_test(33, c, m, 160, 100, file6, sizeof(file6));
|
||||
test_rl_pure_test(34, c, m, 100, 140, file6, sizeof(file6));
|
||||
}
|
||||
|
||||
/**
|
||||
* test_rl_zero
|
||||
*/
|
||||
static void test_rl_zero (void)
|
||||
static void test_rl_zero(void)
|
||||
{
|
||||
runlist_element *jim = NULL;
|
||||
runlist_element *bob = NULL;
|
||||
|
||||
bob = calloc (3, sizeof (runlist_element));
|
||||
bob = calloc(3, sizeof(runlist_element));
|
||||
if (!bob)
|
||||
return;
|
||||
|
||||
MKRL(bob+0, 10, 99, 5)
|
||||
MKRL(bob+1, 15, LCN_RL_NOT_MAPPED, 0)
|
||||
|
||||
jim = test_rl_runlists_merge (jim, bob);
|
||||
jim = test_rl_runlists_merge(jim, bob);
|
||||
if (!jim)
|
||||
return;
|
||||
|
||||
free (jim);
|
||||
free(jim);
|
||||
}
|
||||
|
||||
/**
|
||||
* test_rl_frag_combine
|
||||
*/
|
||||
static void test_rl_frag_combine (ntfs_volume *vol, ATTR_RECORD *attr1, ATTR_RECORD *attr2, ATTR_RECORD *attr3)
|
||||
static void test_rl_frag_combine(ntfs_volume *vol, ATTR_RECORD *attr1, ATTR_RECORD *attr2, ATTR_RECORD *attr3)
|
||||
{
|
||||
runlist_element *run1;
|
||||
runlist_element *run2;
|
||||
runlist_element *run3;
|
||||
|
||||
run1 = ntfs_mapping_pairs_decompress (vol, attr1, NULL);
|
||||
run1 = ntfs_mapping_pairs_decompress(vol, attr1, NULL);
|
||||
if (!run1)
|
||||
return;
|
||||
|
||||
run2 = ntfs_mapping_pairs_decompress (vol, attr2, NULL);
|
||||
run2 = ntfs_mapping_pairs_decompress(vol, attr2, NULL);
|
||||
if (!run2)
|
||||
return;
|
||||
|
||||
run1 = test_rl_runlists_merge (run1, run2);
|
||||
run1 = test_rl_runlists_merge(run1, run2);
|
||||
|
||||
run3 = ntfs_mapping_pairs_decompress (vol, attr3, NULL);
|
||||
run3 = ntfs_mapping_pairs_decompress(vol, attr3, NULL);
|
||||
if (!run3)
|
||||
return;
|
||||
|
||||
run1 = test_rl_runlists_merge (run1, run3);
|
||||
run1 = test_rl_runlists_merge(run1, run3);
|
||||
|
||||
free (run1);
|
||||
free(run1);
|
||||
}
|
||||
|
||||
/**
|
||||
* test_rl_frag
|
||||
*/
|
||||
static void test_rl_frag (char *test)
|
||||
static void test_rl_frag(char *test)
|
||||
{
|
||||
ntfs_volume vol;
|
||||
ATTR_RECORD *attr1 = malloc (1024);
|
||||
ATTR_RECORD *attr2 = malloc (1024);
|
||||
ATTR_RECORD *attr3 = malloc (1024);
|
||||
ATTR_RECORD *attr1 = malloc(1024);
|
||||
ATTR_RECORD *attr2 = malloc(1024);
|
||||
ATTR_RECORD *attr3 = malloc(1024);
|
||||
|
||||
if (!attr1 || !attr2 || !attr3)
|
||||
goto out;
|
||||
|
@ -2016,36 +2018,36 @@ static void test_rl_frag (char *test)
|
|||
vol.cluster_size_bits = 11;
|
||||
vol.major_ver = 3;
|
||||
|
||||
if (!test_rl_read_buffer ("runlist-data/attr1.bin", (u8*) attr1, 1024))
|
||||
if (!test_rl_read_buffer("runlist-data/attr1.bin", (u8*) attr1, 1024))
|
||||
goto out;
|
||||
if (!test_rl_read_buffer ("runlist-data/attr2.bin", (u8*) attr2, 1024))
|
||||
if (!test_rl_read_buffer("runlist-data/attr2.bin", (u8*) attr2, 1024))
|
||||
goto out;
|
||||
if (!test_rl_read_buffer ("runlist-data/attr3.bin", (u8*) attr3, 1024))
|
||||
if (!test_rl_read_buffer("runlist-data/attr3.bin", (u8*) attr3, 1024))
|
||||
goto out;
|
||||
|
||||
if (strcmp (test, "123") == 0) test_rl_frag_combine (&vol, attr1, attr2, attr3);
|
||||
else if (strcmp (test, "132") == 0) test_rl_frag_combine (&vol, attr1, attr3, attr2);
|
||||
else if (strcmp (test, "213") == 0) test_rl_frag_combine (&vol, attr2, attr1, attr3);
|
||||
else if (strcmp (test, "231") == 0) test_rl_frag_combine (&vol, attr2, attr3, attr1);
|
||||
else if (strcmp (test, "312") == 0) test_rl_frag_combine (&vol, attr3, attr1, attr2);
|
||||
else if (strcmp (test, "321") == 0) test_rl_frag_combine (&vol, attr3, attr2, attr1);
|
||||
else printf ("Frag: No such test '%s'\n", test);
|
||||
if (strcmp(test, "123") == 0) test_rl_frag_combine(&vol, attr1, attr2, attr3);
|
||||
else if (strcmp(test, "132") == 0) test_rl_frag_combine(&vol, attr1, attr3, attr2);
|
||||
else if (strcmp(test, "213") == 0) test_rl_frag_combine(&vol, attr2, attr1, attr3);
|
||||
else if (strcmp(test, "231") == 0) test_rl_frag_combine(&vol, attr2, attr3, attr1);
|
||||
else if (strcmp(test, "312") == 0) test_rl_frag_combine(&vol, attr3, attr1, attr2);
|
||||
else if (strcmp(test, "321") == 0) test_rl_frag_combine(&vol, attr3, attr2, attr1);
|
||||
else ntfs_log_debug("Frag: No such test '%s'\n", test);
|
||||
|
||||
out:
|
||||
free (attr1);
|
||||
free (attr2);
|
||||
free (attr3);
|
||||
free(attr1);
|
||||
free(attr2);
|
||||
free(attr3);
|
||||
}
|
||||
|
||||
/**
|
||||
* test_rl_main
|
||||
*/
|
||||
int test_rl_main (int argc, char *argv[])
|
||||
int test_rl_main(int argc, char *argv[])
|
||||
{
|
||||
if ((argc == 2) && (strcmp (argv[1], "zero") == 0)) test_rl_zero();
|
||||
else if ((argc == 3) && (strcmp (argv[1], "frag") == 0)) test_rl_frag (argv[2]);
|
||||
else if ((argc == 4) && (strcmp (argv[1], "pure") == 0)) test_rl_pure (argv[2], argv[3]);
|
||||
else printf ("rl [zero|frag|pure] {args}\n");
|
||||
if ((argc == 2) && (strcmp(argv[1], "zero") == 0)) test_rl_zero();
|
||||
else if ((argc == 3) && (strcmp(argv[1], "frag") == 0)) test_rl_frag(argv[2]);
|
||||
else if ((argc == 4) && (strcmp(argv[1], "pure") == 0)) test_rl_pure(argv[2], argv[3]);
|
||||
else ntfs_log_debug("rl [zero|frag|pure] {args}\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
* security.c - Code for handling security/ACLs in NTFS. Part of the
|
||||
* Linux-NTFS project.
|
||||
/**
|
||||
* security.c - Handling security/ACLs in NTFS. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2004 Anton Altaparmakov
|
||||
*
|
||||
|
@ -20,7 +19,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
|
@ -249,12 +250,11 @@ err_out:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* GUID generate_guid(GUID *guid)
|
||||
/**
|
||||
* GUID generate_guid(GUID *guid)
|
||||
* generatates a random current guid
|
||||
* perhaps not a very good random number generator though...
|
||||
*/
|
||||
|
||||
GUID *generate_guid(GUID *guid) {
|
||||
|
||||
int i;
|
||||
|
@ -262,9 +262,9 @@ GUID *generate_guid(GUID *guid) {
|
|||
|
||||
for (i = 0; i < 16; i++) {
|
||||
array[i] = (u8)(random() & 0xFF);
|
||||
if (i == 7)
|
||||
if (i == 7)
|
||||
array[7] = (array[7] & 0x0F) | 0x40;
|
||||
if (i == 8)
|
||||
if (i == 8)
|
||||
array[8] = (array[8] & 0x3F) | 0x80;
|
||||
}
|
||||
memcpy(guid, array, sizeof(guid));
|
||||
|
|
894
libntfs/tree.c
894
libntfs/tree.c
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* unistr.c - Unicode string handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2000-2004 Anton Altaparmakov
|
||||
|
@ -19,7 +19,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
|
@ -40,6 +42,7 @@
|
|||
#include "types.h"
|
||||
#include "unistr.h"
|
||||
#include "debug.h"
|
||||
#include "logging.h"
|
||||
|
||||
/*
|
||||
* IMPORTANT
|
||||
|
@ -129,7 +132,7 @@ int ntfs_names_collate(const ntfschar *name1, const u32 name1_len,
|
|||
|
||||
#ifdef DEBUG
|
||||
if (!name1 || !name2 || (ic && (!upcase || !upcase_len))) {
|
||||
Dputs("ntfs_names_collate received NULL pointer!");
|
||||
ntfs_log_debug("ntfs_names_collate received NULL pointer!\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
@ -187,7 +190,7 @@ int ntfs_ucsncmp(const ntfschar *s1, const ntfschar *s2, size_t n)
|
|||
|
||||
#ifdef DEBUG
|
||||
if (!s1 || !s2) {
|
||||
Dputs("ntfs_wcsncmp() received NULL pointer!");
|
||||
ntfs_log_debug("ntfs_wcsncmp() received NULL pointer!\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
@ -230,7 +233,7 @@ int ntfs_ucsncasecmp(const ntfschar *s1, const ntfschar *s2, size_t n,
|
|||
|
||||
#ifdef DEBUG
|
||||
if (!s1 || !s2 || !upcase) {
|
||||
Dputs("ntfs_wcsncasecmp() received NULL pointer!");
|
||||
ntfs_log_debug("ntfs_wcsncasecmp() received NULL pointer!\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
@ -428,7 +431,7 @@ int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
|
|||
if (cnt == -1)
|
||||
goto err_out;
|
||||
if (cnt <= 0) {
|
||||
Dprintf("Eeek. cnt <= 0, cnt = %i\n", cnt);
|
||||
ntfs_log_debug("Eeek. cnt <= 0, cnt = %i\n", cnt);
|
||||
errno = EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -437,7 +440,7 @@ int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
|
|||
#ifdef HAVE_MBSINIT
|
||||
/* Make sure we are back in the initial state. */
|
||||
if (!mbsinit(&mbstate)) {
|
||||
Dputs("Eeek. mbstate not in initial state!");
|
||||
ntfs_log_debug("Eeek. mbstate not in initial state!\n");
|
||||
errno = EILSEQ;
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -572,7 +575,7 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len)
|
|||
if (cnt == -1)
|
||||
goto err_out;
|
||||
if (cnt < -1) {
|
||||
Dprintf("%s(): Eeek. cnt = %i\n", __FUNCTION__, cnt);
|
||||
ntfs_log_trace("Eeek. cnt = %i\n", cnt);
|
||||
errno = EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -588,8 +591,7 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len)
|
|||
#ifdef HAVE_MBSINIT
|
||||
/* Make sure we are back in the initial state. */
|
||||
if (!mbsinit(&mbstate)) {
|
||||
Dprintf("%s(): Eeek. mbstate not in initial state!\n",
|
||||
__FUNCTION__);
|
||||
ntfs_log_trace("Eeek. mbstate not in initial state!\n");
|
||||
errno = EILSEQ;
|
||||
goto err_out;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* unix_io.c - Unix style disk io functions. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2000-2003 Anton Altaparmakov
|
||||
|
@ -19,7 +19,9 @@
|
|||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
|
@ -49,13 +51,14 @@
|
|||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_FD_H
|
||||
# include <linux/fd.h>
|
||||
#include <linux/fd.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "mst.h"
|
||||
#include "debug.h"
|
||||
#include "device.h"
|
||||
#include "logging.h"
|
||||
|
||||
#if defined(linux) && defined(_IO) && !defined(BLKGETSIZE)
|
||||
# define BLKGETSIZE _IO(0x12,96) /* Get device size in 512byte blocks. */
|
||||
|
@ -63,6 +66,9 @@
|
|||
|
||||
#define DEV_FD(dev) (*(int *)dev->d_private)
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_open
|
||||
*/
|
||||
static int ntfs_device_unix_io_open(struct ntfs_device *dev, int flags)
|
||||
{
|
||||
struct flock flk;
|
||||
|
@ -92,13 +98,11 @@ static int ntfs_device_unix_io_open(struct ntfs_device *dev, int flags)
|
|||
flk.l_start = flk.l_len = 0LL;
|
||||
if (fcntl(DEV_FD(dev), F_SETLK, &flk)) {
|
||||
err = errno;
|
||||
Dprintf("ntfs_device_unix_io_open: Could not lock %s for %s: "
|
||||
"%s\n", dev->d_name, NDevReadOnly(dev) ?
|
||||
"reading" : "writing", strerror(errno));
|
||||
ntfs_log_debug("ntfs_device_unix_io_open: Could not lock %s for %s",
|
||||
dev->d_name, NDevReadOnly(dev) ? "reading" : "writing");
|
||||
if (close(DEV_FD(dev)))
|
||||
Dprintf("ntfs_device_unix_io_open: Warning: Could not "
|
||||
"close %s: %s\n", dev->d_name,
|
||||
strerror(errno));
|
||||
ntfs_log_perror("ntfs_device_unix_io_open: Warning: Could not "
|
||||
"close %s", dev->d_name);
|
||||
goto err_out;
|
||||
}
|
||||
/* Set our open flag. */
|
||||
|
@ -111,6 +115,9 @@ err_out:
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_close
|
||||
*/
|
||||
static int ntfs_device_unix_io_close(struct ntfs_device *dev)
|
||||
{
|
||||
struct flock flk;
|
||||
|
@ -127,8 +134,8 @@ static int ntfs_device_unix_io_close(struct ntfs_device *dev)
|
|||
flk.l_whence = SEEK_SET;
|
||||
flk.l_start = flk.l_len = 0LL;
|
||||
if (fcntl(DEV_FD(dev), F_SETLK, &flk))
|
||||
Dprintf("ntfs_device_unix_io_close: Warning: Could not unlock "
|
||||
"%s: %s\n", dev->d_name, strerror(errno));
|
||||
ntfs_log_perror("ntfs_device_unix_io_close: Warning: Could not "
|
||||
"unlock %s", dev->d_name);
|
||||
/* Close the file descriptor and clear our open flag. */
|
||||
if (close(DEV_FD(dev)))
|
||||
return -1;
|
||||
|
@ -138,18 +145,27 @@ static int ntfs_device_unix_io_close(struct ntfs_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_seek
|
||||
*/
|
||||
static s64 ntfs_device_unix_io_seek(struct ntfs_device *dev, s64 offset,
|
||||
int whence)
|
||||
{
|
||||
return lseek(DEV_FD(dev), offset, whence);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_read
|
||||
*/
|
||||
static s64 ntfs_device_unix_io_read(struct ntfs_device *dev, void *buf,
|
||||
s64 count)
|
||||
{
|
||||
return read(DEV_FD(dev), buf, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_write
|
||||
*/
|
||||
static s64 ntfs_device_unix_io_write(struct ntfs_device *dev, const void *buf,
|
||||
s64 count)
|
||||
{
|
||||
|
@ -161,12 +177,18 @@ static s64 ntfs_device_unix_io_write(struct ntfs_device *dev, const void *buf,
|
|||
return write(DEV_FD(dev), buf, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_pread
|
||||
*/
|
||||
static s64 ntfs_device_unix_io_pread(struct ntfs_device *dev, void *buf,
|
||||
s64 count, s64 offset)
|
||||
{
|
||||
return ntfs_pread(dev, offset, count, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_pwrite
|
||||
*/
|
||||
static s64 ntfs_device_unix_io_pwrite(struct ntfs_device *dev, const void *buf,
|
||||
s64 count, s64 offset)
|
||||
{
|
||||
|
@ -178,6 +200,9 @@ static s64 ntfs_device_unix_io_pwrite(struct ntfs_device *dev, const void *buf,
|
|||
return ntfs_pwrite(dev, offset, count, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_sync
|
||||
*/
|
||||
static int ntfs_device_unix_io_sync(struct ntfs_device *dev)
|
||||
{
|
||||
if (!NDevReadOnly(dev) && NDevDirty(dev)) {
|
||||
|
@ -189,11 +214,17 @@ static int ntfs_device_unix_io_sync(struct ntfs_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_stat
|
||||
*/
|
||||
static int ntfs_device_unix_io_stat(struct ntfs_device *dev, struct stat *buf)
|
||||
{
|
||||
return fstat(DEV_FD(dev), buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_device_unix_io_ioctl
|
||||
*/
|
||||
static int ntfs_device_unix_io_ioctl(struct ntfs_device *dev, int request,
|
||||
void *argp)
|
||||
{
|
||||
|
|
533
libntfs/volume.c
533
libntfs/volume.c
File diff suppressed because it is too large
Load Diff
|
@ -48,7 +48,7 @@ ntfsfix_SOURCES = ntfsfix.c utils.c utils.h
|
|||
ntfsfix_LDADD = $(AM_LIBS)
|
||||
ntfsfix_LDFLAGS = $(AM_LFLAGS)
|
||||
|
||||
mkntfs_SOURCES = attrdef.c upcase.c boot.c sd.c mkntfs.c utils.c utils.h
|
||||
mkntfs_SOURCES = attrdef.c attrdef.h upcase.c upcase.h boot.c boot.h sd.c sd.h mkntfs.c utils.c utils.h
|
||||
mkntfs_LDADD = $(AM_LIBS)
|
||||
mkntfs_LDFLAGS = $(AM_LFLAGS)
|
||||
|
||||
|
|
|
@ -203,7 +203,8 @@ const unsigned char attrdef_ntfs3x_array[2560] = {
|
|||
, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00
|
||||
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
, 0x24, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x44, 0x00, 0x45, 0x00, 0x58, 0x00, 0x5F, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x43, 0x00, 0x41, 0x00, 0x54, 0x00
|
||||
, 0x49, 0x00, 0x4F, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
|
@ -245,3 +246,4 @@ const unsigned char attrdef_ntfs3x_array[2560] = {
|
|||
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
};
|
||||
|
||||
|
|
1139
ntfsprogs/mkntfs.c
1139
ntfsprogs/mkntfs.c
File diff suppressed because it is too large
Load Diff
|
@ -243,7 +243,7 @@ static int parse_options (int argc, char **argv)
|
|||
opts.quiet = 0;
|
||||
} else {
|
||||
if (opts.device == NULL) {
|
||||
Eprintf ("You must specify a device.\n");
|
||||
Eprintf ("You must specify a device.\n");
|
||||
err++;
|
||||
|
||||
} else if (opts.file == NULL && opts.inode == -1) {
|
||||
|
|
|
@ -162,10 +162,10 @@ struct {
|
|||
#define PERR_PREFIX ERR_PREFIX "(%d): "
|
||||
#define NERR_PREFIX ERR_PREFIX ": "
|
||||
|
||||
#define LAST_METADATA_INODE 11
|
||||
#define LAST_METADATA_INODE 11
|
||||
|
||||
#define NTFS_MAX_CLUSTER_SIZE 65536
|
||||
#define NTFS_SECTOR_SIZE 512
|
||||
#define NTFS_MAX_CLUSTER_SIZE 65536
|
||||
#define NTFS_SECTOR_SIZE 512
|
||||
|
||||
#define rounded_up_division(a, b) (((a) + (b - 1)) / (b))
|
||||
|
||||
|
@ -383,7 +383,7 @@ static void parse_options(int argc, char **argv)
|
|||
|
||||
msg_out = stdout;
|
||||
|
||||
/* FIXME: this is a workaround for loosing debug info if stdout != stderr
|
||||
/* FIXME: this is a workaround for losing debug info if stdout != stderr
|
||||
and for the uncontrollable verbose messages in libntfs. Ughhh. */
|
||||
if (opt.std_out)
|
||||
msg_out = stderr;
|
||||
|
@ -699,7 +699,7 @@ static void restore_image(void)
|
|||
#define WIPE_TIMESTAMPS(atype, attr) \
|
||||
do { \
|
||||
atype *ats; \
|
||||
ats = (atype *)((char*)(attr) + (attr)->value_offset); \
|
||||
ats = (atype *)((char*)(attr) + (attr)->value_offset); \
|
||||
\
|
||||
ats->creation_time = 0; \
|
||||
ats->last_data_change_time = 0; \
|
||||
|
@ -708,7 +708,7 @@ do { \
|
|||
\
|
||||
wiped_timestamp_data += 32; \
|
||||
\
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
static void wipe_timestamps(ntfs_walk_clusters_ctx *image)
|
||||
{
|
||||
|
@ -1004,8 +1004,7 @@ static int walk_clusters(ntfs_volume *volume, struct ntfs_walk_cluster *walk)
|
|||
}
|
||||
}
|
||||
|
||||
if (ni->mrec)
|
||||
free(ni->mrec);
|
||||
free(ni->mrec);
|
||||
free(ni);
|
||||
|
||||
if (deleted_inode)
|
||||
|
@ -1248,9 +1247,9 @@ static void set_filesize(s64 filesize)
|
|||
if (fstatfs(fd_out, &opt.stfs) == -1)
|
||||
Printf("WARNING: Couldn't get filesystem type: "
|
||||
"%s\n", strerror(errno));
|
||||
else
|
||||
else
|
||||
fs_type = opt.stfs.f_type;
|
||||
|
||||
|
||||
if (fs_type == 0x52654973)
|
||||
Printf("WARNING: You're using ReiserFS, it has very poor "
|
||||
"performance creating\nlarge sparse files. The next "
|
||||
|
|
|
@ -176,7 +176,7 @@ static void parse_options(int argc, char **argv)
|
|||
{ "debug", no_argument, NULL, 'd' },
|
||||
#endif
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "no-progress-bar", no_argument, NULL, 'P' },
|
||||
{ "no-progress-bar", no_argument, NULL, 'P' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
@ -193,7 +193,7 @@ static void parse_options(int argc, char **argv)
|
|||
opt.vol1 = argv[optind - 1];
|
||||
} else if (!opt.vol2) {
|
||||
opt.vol2 = argv[optind - 1];
|
||||
} else {
|
||||
} else {
|
||||
err_printf("Too many arguments!\n");
|
||||
usage();
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ static u64 inumber(ntfs_inode *ni)
|
|||
{
|
||||
if (ni->nr_extents >= 0)
|
||||
return ni->mft_no;
|
||||
|
||||
|
||||
return ni->base_ni->mft_no;
|
||||
}
|
||||
|
||||
|
@ -312,7 +312,7 @@ static inline s64 get_nr_mft_records(ntfs_volume *vol)
|
|||
#define NTFSCMP_EXTENSION_RECORD 4
|
||||
#define NTFSCMP_INODE_CLOSE_ERROR 5
|
||||
|
||||
const char *ntfscmp_errs[] = {
|
||||
const char *ntfscmp_errs[] = {
|
||||
"OK",
|
||||
"INODE_OPEN_ERROR",
|
||||
"INODE_OPEN_IO_ERROR",
|
||||
|
@ -325,7 +325,7 @@ const char *ntfscmp_errs[] = {
|
|||
|
||||
static const char *err2string(int err)
|
||||
{
|
||||
return ntfscmp_errs[err];
|
||||
return ntfscmp_errs[err];
|
||||
}
|
||||
|
||||
static const char *pret2str(void *p)
|
||||
|
@ -352,7 +352,7 @@ static int inode_open(ntfs_volume *vol, MFT_REF mref, ntfs_inode **ni)
|
|||
|
||||
if (inode_close(*ni) != 0)
|
||||
return NTFSCMP_INODE_CLOSE_ERROR;
|
||||
|
||||
|
||||
return NTFSCMP_EXTENSION_RECORD;
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ static ntfs_inode *base_inode(ntfs_attr_search_ctx *ctx)
|
|||
{
|
||||
if (ctx->base_ntfs_ino)
|
||||
return ctx->base_ntfs_ino;
|
||||
|
||||
|
||||
return ctx->ntfs_ino;
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ static void free_name(char **name)
|
|||
|
||||
static char *get_attr_name(u64 mft_no,
|
||||
ATTR_TYPES atype,
|
||||
const ntfschar *uname,
|
||||
const ntfschar *uname,
|
||||
const int uname_len)
|
||||
{
|
||||
char *name = NULL;
|
||||
|
@ -417,7 +417,7 @@ static char *get_attr_name(u64 mft_no,
|
|||
print_attribute_type(atype);
|
||||
puts("");
|
||||
exit(1);
|
||||
|
||||
|
||||
} else if (name_len > 0)
|
||||
return name;
|
||||
|
||||
|
@ -495,9 +495,9 @@ static void cmp_attribute_data(ntfs_attr *na1, ntfs_attr *na2)
|
|||
printf("len = %lld, pos = %lld\n", na1->data_size, pos);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (count1 == 0) {
|
||||
|
||||
|
||||
if (pos + count1 == na1->data_size)
|
||||
return; /* we are ready */
|
||||
|
||||
|
@ -506,7 +506,7 @@ static void cmp_attribute_data(ntfs_attr *na1, ntfs_attr *na2)
|
|||
printf("%lld != %lld\n", pos + count1, na1->data_size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (memcmp(buf1, buf2, count1)) {
|
||||
print_na(na1);
|
||||
printf("content");
|
||||
|
@ -515,15 +515,15 @@ static void cmp_attribute_data(ntfs_attr *na1, ntfs_attr *na2)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
err_printf("%s read overrun: ", __FUNCTION__);
|
||||
print_na(na1);
|
||||
err_printf("(len = %lld, pos = %lld, count = %lld)\n",
|
||||
err_printf("(len = %lld, pos = %lld, count = %lld)\n",
|
||||
na1->data_size, pos, count1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void cmp_attribute(ntfs_attr_search_ctx *ctx1,
|
||||
static void cmp_attribute(ntfs_attr_search_ctx *ctx1,
|
||||
ntfs_attr_search_ctx *ctx2)
|
||||
{
|
||||
ATTR_RECORD *a1 = ctx1->attr;
|
||||
|
@ -532,7 +532,7 @@ static void cmp_attribute(ntfs_attr_search_ctx *ctx1,
|
|||
|
||||
na1 = ntfs_attr_open(base_inode(ctx1), a1->type, GET_ATTR_NAME(a1));
|
||||
na2 = ntfs_attr_open(base_inode(ctx2), a2->type, GET_ATTR_NAME(a2));
|
||||
|
||||
|
||||
if ((!na1 && na2) || (na1 && !na2)) {
|
||||
print_ctx(ctx1);
|
||||
printf("open: %s != %s\n", pret2str(na1), pret2str(na2));
|
||||
|
@ -579,7 +579,7 @@ static int new_name(ntfs_attr_search_ctx *ctx, char *prev_name)
|
|||
{
|
||||
int ret = 0;
|
||||
char *name = get_attr_name_ctx(ctx);
|
||||
|
||||
|
||||
if (prev_name && name) {
|
||||
if (strcmp(prev_name, name) != 0)
|
||||
ret = 1;
|
||||
|
@ -597,13 +597,13 @@ static int new_attribute(ntfs_attr_search_ctx *ctx,
|
|||
{
|
||||
if (!prev_atype && !prev_name)
|
||||
return 1;
|
||||
|
||||
|
||||
if (!ctx->attr->non_resident)
|
||||
return 1;
|
||||
|
||||
if (prev_atype != ctx->attr->type)
|
||||
return 1;
|
||||
|
||||
|
||||
if (new_name(ctx, prev_name))
|
||||
return 1;
|
||||
|
||||
|
@ -613,11 +613,11 @@ static int new_attribute(ntfs_attr_search_ctx *ctx,
|
|||
printf("record %llu lowest_vcn %lld: SKIPPED\n",
|
||||
ctx->ntfs_ino->mft_no, ctx->attr->lowest_vcn);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_prev(char **prev_name, ATTR_TYPES *prev_atype,
|
||||
|
||||
static void set_prev(char **prev_name, ATTR_TYPES *prev_atype,
|
||||
char *name, ATTR_TYPES atype)
|
||||
{
|
||||
free_name(prev_name);
|
||||
|
@ -632,8 +632,8 @@ static void set_prev(char **prev_name, ATTR_TYPES *prev_atype,
|
|||
|
||||
static void set_cmp_attr(ntfs_attr_search_ctx *ctx, ATTR_TYPES *atype, char **name)
|
||||
{
|
||||
*atype = ctx->attr->type;
|
||||
|
||||
*atype = ctx->attr->type;
|
||||
|
||||
free_name(name);
|
||||
*name = get_attr_name_ctx(ctx);
|
||||
}
|
||||
|
@ -642,15 +642,15 @@ static int next_attr(ntfs_attr_search_ctx *ctx, ATTR_TYPES *atype, char **name,
|
|||
int *err)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
ret = ntfs_attrs_walk(ctx);
|
||||
*err = errno;
|
||||
if (ret) {
|
||||
if (ret) {
|
||||
*atype = AT_END;
|
||||
free_name(name);
|
||||
} else
|
||||
set_cmp_attr(ctx, atype, name);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -662,12 +662,12 @@ static int cmp_attributes(ntfs_inode *ni1, ntfs_inode *ni2)
|
|||
char *prev_name = NULL, *name1 = NULL, *name2 = NULL;
|
||||
ATTR_TYPES old_atype1, prev_atype = 0, atype1, atype2;
|
||||
ntfs_attr_search_ctx *ctx1, *ctx2;
|
||||
|
||||
|
||||
if (!(ctx1 = attr_get_search_ctx(ni1)))
|
||||
return -1;
|
||||
if (!(ctx2 = attr_get_search_ctx(ni2)))
|
||||
goto out;
|
||||
|
||||
|
||||
set_cmp_attr(ctx1, &atype1, &name1);
|
||||
set_cmp_attr(ctx2, &atype2, &name2);
|
||||
|
||||
|
@ -681,7 +681,7 @@ static int cmp_attributes(ntfs_inode *ni1, ntfs_inode *ni2)
|
|||
ret2 = next_attr(ctx2, &atype2, &name2, &errno2);
|
||||
|
||||
print_attributes(ni1, atype1, atype2, name1, name2);
|
||||
|
||||
|
||||
if (ret1 && ret2) {
|
||||
if (errno1 != errno2) {
|
||||
print_inode_ni(ni1);
|
||||
|
@ -697,14 +697,14 @@ static int cmp_attributes(ntfs_inode *ni1, ntfs_inode *ni2)
|
|||
printf("presence: EXISTS != MISSING\n");
|
||||
set_prev(&prev_name, &prev_atype, name1, atype1);
|
||||
}
|
||||
|
||||
|
||||
} else if (ret1 || atype1 > atype2) {
|
||||
if (new_attribute(ctx2, prev_atype, prev_name)) {
|
||||
print_ctx(ctx2);
|
||||
printf("presence: MISSING != EXISTS \n");
|
||||
set_prev(&prev_name, &prev_atype, name2, atype2);
|
||||
}
|
||||
|
||||
|
||||
} else /* atype1 == atype2 */ {
|
||||
if (new_attribute(ctx1, prev_atype, prev_name)) {
|
||||
cmp_attribute(ctx1, ctx2);
|
||||
|
@ -759,7 +759,7 @@ static int cmp_inodes(ntfs_volume *vol1, ntfs_volume *vol2)
|
|||
|
||||
if (ret1 != ret2) {
|
||||
print_inode(inode);
|
||||
printf("open: %s != %s\n",
|
||||
printf("open: %s != %s\n",
|
||||
err2string(ret1), err2string(ret2));
|
||||
goto close_inodes;
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ static int parse_options (int argc, char **argv)
|
|||
opts.quiet = 0;
|
||||
} else {
|
||||
if (!opts.device) {
|
||||
Eprintf("You must specify a device.\n");
|
||||
Eprintf("You must specify a device.\n");
|
||||
err++;
|
||||
} else if (!opts.src_file) {
|
||||
Eprintf("You must specify a source file.\n");
|
||||
|
|
|
@ -153,8 +153,7 @@ static void log_err_exit(u8 *buf, const char *fmt, ...)
|
|||
{
|
||||
va_list ap;
|
||||
|
||||
if (buf)
|
||||
free(buf);
|
||||
free(buf);
|
||||
|
||||
fprintf(stderr, "ERROR: ");
|
||||
va_start(ap, fmt);
|
||||
|
|
|
@ -228,8 +228,7 @@ static int OLD_ntfs_volume_set_flags(ntfs_volume *vol, const u16 flags)
|
|||
err_out:
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
err_exit:
|
||||
if (m)
|
||||
free(m);
|
||||
free(m);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -509,10 +508,8 @@ mount_ok:
|
|||
/* Set return code to 0. */
|
||||
i = 0;
|
||||
final_exit:
|
||||
if (m)
|
||||
free(m);
|
||||
if (m2)
|
||||
free(m2);
|
||||
free(m);
|
||||
free(m2);
|
||||
if (vol && ntfs_umount(vol, 0))
|
||||
ntfs_umount(vol, 1);
|
||||
return i;
|
||||
|
|
|
@ -625,7 +625,7 @@ static void ntfs_dump_attr_list(ATTR_RECORD *attr, ntfs_volume *vol)
|
|||
}
|
||||
printf("\tDumping attribute list:");
|
||||
entry = (ATTR_LIST_ENTRY *) value;
|
||||
for(;(u8 *)entry < (u8 *) value + l; entry = (ATTR_LIST_ENTRY *)
|
||||
for (;(u8 *)entry < (u8 *) value + l; entry = (ATTR_LIST_ENTRY *)
|
||||
((u8 *) entry + le16_to_cpu(entry->length))) {
|
||||
printf("\n");
|
||||
printf("\t\tAttribute type:\t0x%x\n",
|
||||
|
@ -832,8 +832,7 @@ static void ntfs_dump_acl(const char *prefix,ACL *acl)
|
|||
/* get a SID string */
|
||||
sid = ntfs_sid_to_mbs(&ace->sid, NULL, 0);
|
||||
printf("%s\t\t SID: %s\n",prefix,sid);
|
||||
if (sid)
|
||||
free(sid);
|
||||
free(sid);
|
||||
|
||||
/* proceed to next ACE */
|
||||
ace = (ACCESS_ALLOWED_ACE *)(((char *)ace) + le32_to_cpu(ace->size));
|
||||
|
@ -1098,7 +1097,7 @@ static int ntfs_dump_index_entries(INDEX_ENTRY *entry, ATTR_TYPES type)
|
|||
int numb_entries = 1;
|
||||
char *name = NULL;
|
||||
|
||||
while(1) {
|
||||
while (1) {
|
||||
if (!opts.verbose) {
|
||||
if (entry->flags & INDEX_ENTRY_END)
|
||||
break;
|
||||
|
@ -1121,7 +1120,7 @@ static int ntfs_dump_index_entries(INDEX_ENTRY *entry, ATTR_TYPES type)
|
|||
if (entry->flags & INDEX_ENTRY_END)
|
||||
break;
|
||||
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
case(AT_FILE_NAME):
|
||||
Vprintf("\t\tFILE record number:\t %llu\n",
|
||||
MREF_LE(entry->indexed_file));
|
||||
|
@ -1351,7 +1350,7 @@ static void ntfs_dump_index_allocation(ATTR_RECORD *attr, ntfs_inode *ni)
|
|||
tmp_alloc = allocation;
|
||||
|
||||
bit = 0;
|
||||
while((u8 *)tmp_alloc < (u8 *)allocation + na->data_size) {
|
||||
while ((u8 *)tmp_alloc < (u8 *)allocation + na->data_size) {
|
||||
if (*byte & (1 << bit)) {
|
||||
if (ntfs_mst_post_read_fixup((NTFS_RECORD *) tmp_alloc,
|
||||
indx_record_size)) {
|
||||
|
@ -1493,7 +1492,7 @@ static void ntfs_dump_attr_reparse_point(ATTR_RECORD *attr __attribute__((unused
|
|||
static void ntfs_dump_attr_ea_information(ATTR_RECORD *attr)
|
||||
{
|
||||
EA_INFORMATION *ea_info;
|
||||
|
||||
|
||||
ea_info = (EA_INFORMATION*)((u8*)attr +
|
||||
le16_to_cpu(attr->value_offset));
|
||||
printf("Dumping attribute $EA_INFORMATION (0xD0)\n");
|
||||
|
@ -1519,7 +1518,7 @@ static void ntfs_dump_attr_ea(ATTR_RECORD *attr, ntfs_volume *vol)
|
|||
if (attr->non_resident) {
|
||||
runlist *rl;
|
||||
|
||||
data_size = sle64_to_cpu(attr->data_size);
|
||||
data_size = sle64_to_cpu(attr->data_size);
|
||||
printf("\tIs resident? \t\t No\n");
|
||||
printf("\tData size:\t\t %lld\n", data_size);
|
||||
if (!opts.verbose)
|
||||
|
@ -1578,8 +1577,7 @@ static void ntfs_dump_attr_ea(ATTR_RECORD *attr, ntfs_volume *vol)
|
|||
if ((u8*)ea - buf >= data_size)
|
||||
break;
|
||||
}
|
||||
if (buf)
|
||||
free(buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -354,8 +354,7 @@ static int change_label(ntfs_volume *vol, unsigned long mnt_flags, char *label,
|
|||
}
|
||||
result = 0;
|
||||
err_out:
|
||||
if (new_label)
|
||||
free(new_label);
|
||||
free(new_label);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ static long ntfs_fuse_get_nr_free_mft_records(ntfs_volume *vol)
|
|||
u8 *buf;
|
||||
long nr_free = 0;
|
||||
s64 br, total = 0;
|
||||
|
||||
|
||||
if (!(ctx->state & NF_FreeMFTOutdate))
|
||||
return ctx->free_mft;
|
||||
buf = malloc(vol->cluster_size);
|
||||
|
@ -494,7 +494,7 @@ static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size,
|
|||
total += res;
|
||||
}
|
||||
res = total;
|
||||
exit:
|
||||
exit:
|
||||
ctx->state |= (NF_FreeClustersOutdate | NF_FreeMFTOutdate);
|
||||
if (na)
|
||||
ntfs_attr_close(na);
|
||||
|
@ -587,8 +587,7 @@ static int ntfs_fuse_create(const char *org_path, const unsigned type)
|
|||
else
|
||||
res = -errno;
|
||||
exit:
|
||||
if (uname)
|
||||
free(uname);
|
||||
free(uname);
|
||||
if (dir_ni)
|
||||
ntfs_inode_close(dir_ni);
|
||||
free(path);
|
||||
|
@ -693,8 +692,7 @@ static int ntfs_fuse_link(const char *old_path, const char *new_path)
|
|||
exit:
|
||||
if (ni)
|
||||
ntfs_inode_close(ni);
|
||||
if (uname)
|
||||
free(uname);
|
||||
free(uname);
|
||||
if (dir_ni)
|
||||
ntfs_inode_close(dir_ni);
|
||||
free(path);
|
||||
|
@ -742,8 +740,7 @@ static int ntfs_fuse_rm(const char *org_path)
|
|||
exit:
|
||||
if (ni)
|
||||
ntfs_inode_close(ni);
|
||||
if (uname)
|
||||
free(uname);
|
||||
free(uname);
|
||||
if (dir_ni)
|
||||
ntfs_inode_close(dir_ni);
|
||||
free(path);
|
||||
|
@ -1015,8 +1012,7 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
|
|||
exit:
|
||||
if (na)
|
||||
ntfs_attr_close(na);
|
||||
if (lename)
|
||||
free(lename);
|
||||
free(lename);
|
||||
if (ntfs_inode_close(ni))
|
||||
perror("Failed to close inode");
|
||||
return res;
|
||||
|
@ -1070,8 +1066,7 @@ static int ntfs_fuse_setxattr(const char *path, const char *name,
|
|||
exit:
|
||||
if (na)
|
||||
ntfs_attr_close(na);
|
||||
if (lename)
|
||||
free(lename);
|
||||
free(lename);
|
||||
if (ntfs_inode_close(ni))
|
||||
perror("Failed to close inode");
|
||||
return res;
|
||||
|
@ -1111,8 +1106,7 @@ static int ntfs_fuse_removexattr(const char *path, const char *name)
|
|||
exit:
|
||||
if (na)
|
||||
ntfs_attr_close(na);
|
||||
if (lename)
|
||||
free(lename);
|
||||
free(lename);
|
||||
if (ntfs_inode_close(ni))
|
||||
perror("Failed to close inode");
|
||||
return res;
|
||||
|
@ -1140,7 +1134,7 @@ static struct fuse_operations ntfs_fuse_oper = {
|
|||
.utime = ntfs_fuse_utime,
|
||||
#ifdef HAVE_SETXATTR
|
||||
.getxattr = ntfs_fuse_getxattr,
|
||||
#if 0
|
||||
#if 0
|
||||
.setxattr = ntfs_fuse_setxattr,
|
||||
.removexattr = ntfs_fuse_removexattr,
|
||||
.listxattr = ntfs_fuse_listxattr,
|
||||
|
@ -1487,8 +1481,7 @@ int main(int argc, char *argv[])
|
|||
parsed_options = parse_mount_options((opts.options) ?
|
||||
opts.options : "");
|
||||
if (!parsed_options) {
|
||||
if (opts.device)
|
||||
free(opts.device);
|
||||
free(opts.device);
|
||||
ntfs_fuse_destroy();
|
||||
return 3;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ struct options {
|
|||
int verbose; /* Extra output */
|
||||
int noaction; /* Do not write to disk */
|
||||
int nodirty; /* Do not mark volume dirty */
|
||||
u8 padding[4]; /* Unused: alignment to 64 bit. */
|
||||
u8 padding[4]; /* Unused: alignment to 64 bit. */
|
||||
};
|
||||
|
||||
#endif /* _NTFSMOVE_H_ */
|
||||
|
|
|
@ -204,7 +204,7 @@ s64 max_free_cluster_range = 0;
|
|||
#define DIRTY_INODE (1)
|
||||
#define DIRTY_ATTRIB (2)
|
||||
|
||||
#define NTFS_MAX_CLUSTER_SIZE (65536)
|
||||
#define NTFS_MAX_CLUSTER_SIZE (65536)
|
||||
|
||||
GEN_PRINTF(Eprintf, stderr, NULL, FALSE)
|
||||
GEN_PRINTF(Vprintf, stdout, &opt.verbose, TRUE)
|
||||
|
@ -694,7 +694,7 @@ static void collect_resize_constraints(ntfs_resize_t *resize, runlist *rl)
|
|||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (inode == FILE_Bitmap) {
|
||||
llcn = &resize->last_lcn;
|
||||
if (atype == AT_DATA && NInoAttrList(resize->ni))
|
||||
|
@ -765,7 +765,7 @@ static void collect_relocation_info(ntfs_resize_t *resize, runlist *rl)
|
|||
|
||||
if (inode == FILE_Bitmap && resize->ctx->attr->type == AT_DATA)
|
||||
return;
|
||||
|
||||
|
||||
start = lcn;
|
||||
len = lcn_length;
|
||||
|
||||
|
@ -1636,11 +1636,11 @@ static int is_mftdata(ntfs_resize_t *resize)
|
|||
|
||||
if (resize->mref == 0)
|
||||
return 1;
|
||||
|
||||
|
||||
if ( MREF(resize->mrec->base_mft_record) == 0 &&
|
||||
MSEQNO(resize->mrec->base_mft_record) != 0)
|
||||
return 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1648,30 +1648,30 @@ static int handle_mftdata(ntfs_resize_t *resize, int do_mftdata)
|
|||
{
|
||||
ATTR_RECORD *attr = resize->ctx->attr;
|
||||
VCN highest_vcn, lowest_vcn;
|
||||
|
||||
|
||||
if (do_mftdata) {
|
||||
|
||||
|
||||
if (!is_mftdata(resize))
|
||||
return 0;
|
||||
|
||||
|
||||
highest_vcn = sle64_to_cpu(attr->highest_vcn);
|
||||
lowest_vcn = sle64_to_cpu(attr->lowest_vcn);
|
||||
|
||||
|
||||
if (resize->mft_highest_vcn != highest_vcn)
|
||||
return 0;
|
||||
|
||||
|
||||
if (lowest_vcn == 0)
|
||||
resize->mft_highest_vcn = lowest_vcn;
|
||||
else
|
||||
resize->mft_highest_vcn = lowest_vcn - 1;
|
||||
|
||||
} else if (is_mftdata(resize)) {
|
||||
|
||||
|
||||
highest_vcn = sle64_to_cpu(attr->highest_vcn);
|
||||
|
||||
|
||||
if (resize->mft_highest_vcn < highest_vcn)
|
||||
resize->mft_highest_vcn = highest_vcn;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1688,10 +1688,10 @@ static void relocate_attributes(ntfs_resize_t *resize, int do_mftdata)
|
|||
while (!ntfs_attrs_walk(resize->ctx)) {
|
||||
if (resize->ctx->attr->type == AT_END)
|
||||
break;
|
||||
|
||||
|
||||
if (handle_mftdata(resize, do_mftdata) == 0)
|
||||
continue;
|
||||
|
||||
|
||||
ret = has_bad_sectors(resize, 0);
|
||||
if (ret == -1)
|
||||
exit(1);
|
||||
|
@ -1752,10 +1752,10 @@ static void relocate_inodes(ntfs_resize_t *resize)
|
|||
nr_mft_records = resize->vol->mft_na->initialized_size >>
|
||||
resize->vol->mft_record_size_bits;
|
||||
|
||||
for (mref = 0; mref < (MFT_REF)nr_mft_records; mref++)
|
||||
for (mref = 0; mref < (MFT_REF)nr_mft_records; mref++)
|
||||
relocate_inode(resize, mref, 0);
|
||||
|
||||
while(1) {
|
||||
while (1) {
|
||||
highest_vcn = resize->mft_highest_vcn;
|
||||
mref = nr_mft_records;
|
||||
do {
|
||||
|
@ -1769,8 +1769,7 @@ static void relocate_inodes(ntfs_resize_t *resize)
|
|||
"Please report!\n", highest_vcn);
|
||||
}
|
||||
done:
|
||||
if (resize->mrec)
|
||||
free(resize->mrec);
|
||||
free(resize->mrec);
|
||||
}
|
||||
|
||||
static void print_hint(ntfs_volume *vol, const char *s, struct llcn_t llcn)
|
||||
|
@ -1800,12 +1799,12 @@ static void advise_on_resize(ntfs_resize_t *resize)
|
|||
if (opt.verbose) {
|
||||
printf("Estimating smallest shrunken size supported ...\n");
|
||||
printf("File feature Last used at By inode\n");
|
||||
print_hint(vol, "$MFT", resize->last_mft);
|
||||
print_hint(vol, "$MFT", resize->last_mft);
|
||||
print_hint(vol, "Multi-Record", resize->last_multi_mft);
|
||||
print_hint(vol, "$MFTMirr", resize->last_mftmir);
|
||||
print_hint(vol, "Compressed", resize->last_compressed);
|
||||
print_hint(vol, "Sparse", resize->last_sparse);
|
||||
print_hint(vol, "Ordinary", resize->last_lcn);
|
||||
print_hint(vol, "$MFTMirr", resize->last_mftmir);
|
||||
print_hint(vol, "Compressed", resize->last_compressed);
|
||||
print_hint(vol, "Sparse", resize->last_sparse);
|
||||
print_hint(vol, "Ordinary", resize->last_lcn);
|
||||
}
|
||||
|
||||
print_advise(vol, resize->last_unsupp);
|
||||
|
@ -1849,16 +1848,16 @@ static void rl_truncate(runlist **rl, const VCN last_vcn)
|
|||
{
|
||||
int len;
|
||||
VCN vcn;
|
||||
|
||||
|
||||
len = rl_items(*rl) - 1;
|
||||
if (len <= 0)
|
||||
err_exit("rl_truncate: bad runlist length: %d\n", len);
|
||||
|
||||
vcn = (*rl)[len].vcn;
|
||||
|
||||
|
||||
if (vcn < last_vcn)
|
||||
rl_expand(rl, last_vcn);
|
||||
|
||||
|
||||
else if (vcn > last_vcn)
|
||||
if (ntfs_rl_truncate(rl, last_vcn) == -1)
|
||||
perr_exit("ntfs_rl_truncate");
|
||||
|
@ -1898,7 +1897,7 @@ static void truncate_badclust_bad_attr(ntfs_resize_t *resize)
|
|||
|
||||
if (!(rl_bad = ntfs_mapping_pairs_decompress(vol, a, NULL)))
|
||||
perr_exit("ntfs_mapping_pairs_decompress");
|
||||
|
||||
|
||||
rl_truncate(&rl_bad, nr_clusters);
|
||||
|
||||
a->highest_vcn = cpu_to_le64(nr_clusters - 1LL);
|
||||
|
@ -1945,7 +1944,7 @@ static void realloc_lcn_bitmap(ntfs_resize_t *resize, s64 bm_bsize)
|
|||
|
||||
if (!(tmp = realloc(resize->lcn_bitmap.bm, bm_bsize)))
|
||||
perr_exit("realloc");
|
||||
|
||||
|
||||
resize->lcn_bitmap.bm = tmp;
|
||||
resize->lcn_bitmap.size = bm_bsize;
|
||||
bitmap_file_data_fixup(resize->new_volume_size, &resize->lcn_bitmap);
|
||||
|
@ -2037,41 +2036,41 @@ static int check_bad_sectors(ntfs_volume *vol)
|
|||
ntfs_attr_search_ctx *ctx;
|
||||
runlist *rl;
|
||||
s64 i, badclusters = 0;
|
||||
|
||||
|
||||
Vprintf("Checking for bad sectors ...\n");
|
||||
|
||||
lookup_data_attr(vol, FILE_BadClus, "$Bad", &ctx);
|
||||
|
||||
|
||||
if (NInoAttrList(ctx->ntfs_ino))
|
||||
err_exit("Hopelessly many bad sectors! Please report to "
|
||||
"linux-ntfs@lists.sf.net\n");
|
||||
|
||||
|
||||
if (!ctx->attr->non_resident)
|
||||
err_exit("Resident attribute in $BadClust! Please report to "
|
||||
"linux-ntfs@lists.sf.net\n");
|
||||
|
||||
if (!(rl = ntfs_mapping_pairs_decompress(vol, ctx->attr, NULL)))
|
||||
perr_exit("Decompressing $BadClust:$Bad mapping pairs failed");
|
||||
|
||||
|
||||
for (i = 0; rl[i].length; i++) {
|
||||
/* CHECKME: LCN_RL_NOT_MAPPED check isn't needed */
|
||||
if (rl[i].lcn == LCN_HOLE || rl[i].lcn == LCN_RL_NOT_MAPPED)
|
||||
continue;
|
||||
|
||||
|
||||
badclusters += rl[i].length;
|
||||
Vprintf("Bad cluster: %8lld - %lld\n", rl[i].lcn,
|
||||
Vprintf("Bad cluster: %8lld - %lld\n", rl[i].lcn,
|
||||
rl[i].lcn + rl[i].length - 1);
|
||||
}
|
||||
|
||||
if (badclusters) {
|
||||
printf("%sThis software has detected that the disk has at least"
|
||||
" %lld bad sector%s.\n",
|
||||
" %lld bad sector%s.\n",
|
||||
!opt.badsectors ? NERR_PREFIX : "WARNING: ",
|
||||
badclusters, badclusters - 1 ? "s" : "");
|
||||
if (!opt.badsectors) {
|
||||
printf("%s", bad_sectors_warning_msg);
|
||||
exit(1);
|
||||
} else
|
||||
} else
|
||||
printf("WARNING: Bad sectors can cause reliability "
|
||||
"problems and massive data loss!!!\n");
|
||||
}
|
||||
|
@ -2263,7 +2262,7 @@ static ntfs_volume *mount_volume(void)
|
|||
printf("%s", corrupt_volume_msg);
|
||||
else if (err == EPERM)
|
||||
printf("%s", hibernated_volume_msg);
|
||||
else if (err == EOPNOTSUPP)
|
||||
else if (err == EOPNOTSUPP)
|
||||
printf("%s", unclean_journal_msg);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -2384,7 +2383,7 @@ static void check_cluster_allocation(ntfs_volume *vol, ntfsck_t *fsck)
|
|||
printf("%s", corrupt_volume_msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
compare_bitmaps(vol, &fsck->lcn_bitmap);
|
||||
}
|
||||
|
||||
|
@ -2444,7 +2443,7 @@ int main(int argc, char **argv)
|
|||
printf("Nothing to do: NTFS volume size is already OK.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
memset(&resize, 0, sizeof(resize));
|
||||
resize.vol = vol;
|
||||
resize.new_volume_size = new_size;
|
||||
|
@ -2453,13 +2452,13 @@ int main(int argc, char **argv)
|
|||
resize.shrink = 1;
|
||||
if (opt.show_progress)
|
||||
resize.progress.flags |= NTFS_PROGBAR;
|
||||
/*
|
||||
/*
|
||||
* Checking and __reporting__ of bad sectors must be done before cluster
|
||||
* allocation check because chkdsk doesn't fix $Bitmap's w/ bad sectors
|
||||
* thus users would (were) quite confused why chkdsk doesn't work.
|
||||
*/
|
||||
*/
|
||||
resize.badclusters = check_bad_sectors(vol);
|
||||
|
||||
|
||||
check_cluster_allocation(vol, &fsck);
|
||||
|
||||
print_disk_usage(vol, fsck.inuse);
|
||||
|
@ -2472,7 +2471,7 @@ int main(int argc, char **argv)
|
|||
check_resize_constraints(&resize);
|
||||
|
||||
if (opt.info) {
|
||||
advise_on_resize(&resize);
|
||||
advise_on_resize(&resize);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -264,7 +264,7 @@ static int utils_array_insert (void *ptr, int asize, int before, int count)
|
|||
return -1;
|
||||
|
||||
src = (u8*) ptr + (before * esize);
|
||||
dst = src + (count * esize);
|
||||
dst = src + (count * esize);
|
||||
len = (asize - before) * esize;
|
||||
|
||||
// XXX what about realloc?
|
||||
|
@ -291,7 +291,7 @@ static int utils_array_remove (void *ptr, int asize, int first, int count)
|
|||
return -1;
|
||||
|
||||
dst = (u8*) ptr + (first * esize);
|
||||
src = dst + (count * esize);
|
||||
src = dst + (count * esize);
|
||||
len = (asize - first) * esize;
|
||||
|
||||
memmove (dst, src, len);
|
||||
|
|
|
@ -64,10 +64,9 @@
|
|||
#include "layout.h"
|
||||
#include "volume.h"
|
||||
#include "utils.h"
|
||||
#include "attrdef.h"
|
||||
#include "version.h"
|
||||
|
||||
extern const unsigned char attrdef_ntfs12_array[2400];
|
||||
|
||||
const char *EXEC_NAME = "ntfstruncate";
|
||||
|
||||
/* Need these global so ntfstruncate_exit can access them. */
|
||||
|
|
|
@ -105,10 +105,6 @@ GEN_PRINTF (Eprintf, stderr, NULL, FALSE)
|
|||
GEN_PRINTF (Vprintf, stdout, &opts.verbose, TRUE)
|
||||
GEN_PRINTF (Qprintf, stdout, &opts.quiet, FALSE)
|
||||
|
||||
static int undelete_file (ntfs_volume *vol, long long inode);
|
||||
|
||||
#define _(S) gettext(S)
|
||||
|
||||
/**
|
||||
* parse_inode_arg - parses the inode expression
|
||||
*
|
||||
|
@ -1571,130 +1567,6 @@ static int set_date (const char *pathname, time_t date)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* scan_disk - Search an NTFS volume for files that could be undeleted
|
||||
* @vol: An ntfs volume obtained from ntfs_mount
|
||||
*
|
||||
* Read through all the MFT entries looking for deleted files. For each one
|
||||
* determine how much of the data lies in unused disk space.
|
||||
*
|
||||
* The list can be filtered by name, size and date, using command line options.
|
||||
*
|
||||
* Return: -1 Error, something went wrong
|
||||
* n Success, the number of recoverable files
|
||||
*/
|
||||
static int scan_disk (ntfs_volume *vol)
|
||||
{
|
||||
s64 nr_mft_records;
|
||||
const int BUFSIZE = 8192;
|
||||
char *buffer = NULL;
|
||||
int results = 0;
|
||||
ntfs_attr *attr;
|
||||
long long size;
|
||||
long long bmpsize;
|
||||
int i, j, k, b;
|
||||
int percent;
|
||||
struct ufile *file;
|
||||
regex_t re;
|
||||
|
||||
if (!vol)
|
||||
return -1;
|
||||
|
||||
attr = ntfs_attr_open (vol->mft_ni, AT_BITMAP, AT_UNNAMED, 0);
|
||||
if (!attr) {
|
||||
Eprintf ("ERROR: Couldn't open $MFT/$BITMAP: %s\n", strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
bmpsize = attr->initialized_size;
|
||||
|
||||
buffer = malloc (BUFSIZE);
|
||||
if (!buffer) {
|
||||
Eprintf ("ERROR: Couldn't allocate memory in scan_disk()\n");
|
||||
results = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opts.match) {
|
||||
int flags = REG_NOSUB;
|
||||
|
||||
if (!opts.match_case)
|
||||
flags |= REG_ICASE;
|
||||
if (regcomp (&re, opts.match, flags)) {
|
||||
Eprintf ("ERROR: Couldn't create a regex.\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
nr_mft_records = vol->mft_na->initialized_size >>
|
||||
vol->mft_record_size_bits;
|
||||
|
||||
Qprintf ("Inode Flags %%age Date Size Filename\n");
|
||||
Qprintf ("---------------------------------------------------------------\n");
|
||||
for (i = 0; i < bmpsize; i += BUFSIZE) {
|
||||
long long read_count = min ((bmpsize - i), BUFSIZE);
|
||||
size = ntfs_attr_pread (attr, i, read_count, buffer);
|
||||
if (size < 0)
|
||||
break;
|
||||
|
||||
for (j = 0; j < size; j++) {
|
||||
b = buffer[j];
|
||||
for (k = 0; k < 8; k++, b>>=1) {
|
||||
if (((i+j)*8+k) >= nr_mft_records)
|
||||
goto done;
|
||||
if (b & 1)
|
||||
continue;
|
||||
file = read_record (vol, (i+j)*8+k);
|
||||
if (!file) {
|
||||
Eprintf ("Couldn't read MFT Record %d.\n", (i+j)*8+k);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((opts.since > 0) && (file->date <= opts.since))
|
||||
goto skip;
|
||||
if (opts.match && !name_match (&re, file))
|
||||
goto skip;
|
||||
if (opts.size_begin && (opts.size_begin > file->max_size))
|
||||
goto skip;
|
||||
if (opts.size_end && (opts.size_end < file->max_size))
|
||||
goto skip;
|
||||
|
||||
percent = calc_percentage (file, vol);
|
||||
if ((opts.percent == -1) || (percent >= opts.percent)) {
|
||||
if (opts.verbose)
|
||||
dump_record (file);
|
||||
else
|
||||
list_record (file);
|
||||
|
||||
/* Was -u specified with no inode
|
||||
so undelete file by regex */
|
||||
if (opts.mode == MODE_UNDELETE) {
|
||||
if (!undelete_file (vol, file->inode))
|
||||
Vprintf ("ERROR: Failed to undelete "
|
||||
"inode %lli\n!",
|
||||
file->inode);
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
if (((opts.percent == -1) && (percent > 0)) ||
|
||||
((opts.percent > 0) && (percent >= opts.percent))) {
|
||||
results++;
|
||||
}
|
||||
skip:
|
||||
free_file (file);
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
Qprintf ("\nFiles with potentially recoverable content: %d\n", results);
|
||||
out:
|
||||
if (opts.match)
|
||||
regfree (&re);
|
||||
free (buffer);
|
||||
if (attr)
|
||||
ntfs_attr_close (attr);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* undelete_file - Recover a deleted file from an NTFS volume
|
||||
* @vol: An ntfs volume obtained from ntfs_mount
|
||||
|
@ -1940,6 +1812,130 @@ free:
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* scan_disk - Search an NTFS volume for files that could be undeleted
|
||||
* @vol: An ntfs volume obtained from ntfs_mount
|
||||
*
|
||||
* Read through all the MFT entries looking for deleted files. For each one
|
||||
* determine how much of the data lies in unused disk space.
|
||||
*
|
||||
* The list can be filtered by name, size and date, using command line options.
|
||||
*
|
||||
* Return: -1 Error, something went wrong
|
||||
* n Success, the number of recoverable files
|
||||
*/
|
||||
static int scan_disk (ntfs_volume *vol)
|
||||
{
|
||||
s64 nr_mft_records;
|
||||
const int BUFSIZE = 8192;
|
||||
char *buffer = NULL;
|
||||
int results = 0;
|
||||
ntfs_attr *attr;
|
||||
long long size;
|
||||
long long bmpsize;
|
||||
int i, j, k, b;
|
||||
int percent;
|
||||
struct ufile *file;
|
||||
regex_t re;
|
||||
|
||||
if (!vol)
|
||||
return -1;
|
||||
|
||||
attr = ntfs_attr_open (vol->mft_ni, AT_BITMAP, AT_UNNAMED, 0);
|
||||
if (!attr) {
|
||||
Eprintf ("ERROR: Couldn't open $MFT/$BITMAP: %s\n", strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
bmpsize = attr->initialized_size;
|
||||
|
||||
buffer = malloc (BUFSIZE);
|
||||
if (!buffer) {
|
||||
Eprintf ("ERROR: Couldn't allocate memory in scan_disk()\n");
|
||||
results = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opts.match) {
|
||||
int flags = REG_NOSUB;
|
||||
|
||||
if (!opts.match_case)
|
||||
flags |= REG_ICASE;
|
||||
if (regcomp (&re, opts.match, flags)) {
|
||||
Eprintf ("ERROR: Couldn't create a regex.\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
nr_mft_records = vol->mft_na->initialized_size >>
|
||||
vol->mft_record_size_bits;
|
||||
|
||||
Qprintf ("Inode Flags %%age Date Size Filename\n");
|
||||
Qprintf ("---------------------------------------------------------------\n");
|
||||
for (i = 0; i < bmpsize; i += BUFSIZE) {
|
||||
long long read_count = min ((bmpsize - i), BUFSIZE);
|
||||
size = ntfs_attr_pread (attr, i, read_count, buffer);
|
||||
if (size < 0)
|
||||
break;
|
||||
|
||||
for (j = 0; j < size; j++) {
|
||||
b = buffer[j];
|
||||
for (k = 0; k < 8; k++, b>>=1) {
|
||||
if (((i+j)*8+k) >= nr_mft_records)
|
||||
goto done;
|
||||
if (b & 1)
|
||||
continue;
|
||||
file = read_record (vol, (i+j)*8+k);
|
||||
if (!file) {
|
||||
Eprintf ("Couldn't read MFT Record %d.\n", (i+j)*8+k);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((opts.since > 0) && (file->date <= opts.since))
|
||||
goto skip;
|
||||
if (opts.match && !name_match (&re, file))
|
||||
goto skip;
|
||||
if (opts.size_begin && (opts.size_begin > file->max_size))
|
||||
goto skip;
|
||||
if (opts.size_end && (opts.size_end < file->max_size))
|
||||
goto skip;
|
||||
|
||||
percent = calc_percentage (file, vol);
|
||||
if ((opts.percent == -1) || (percent >= opts.percent)) {
|
||||
if (opts.verbose)
|
||||
dump_record (file);
|
||||
else
|
||||
list_record (file);
|
||||
|
||||
/* Was -u specified with no inode
|
||||
so undelete file by regex */
|
||||
if (opts.mode == MODE_UNDELETE) {
|
||||
if (!undelete_file (vol, file->inode))
|
||||
Vprintf ("ERROR: Failed to undelete "
|
||||
"inode %lli\n!",
|
||||
file->inode);
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
if (((opts.percent == -1) && (percent > 0)) ||
|
||||
((opts.percent > 0) && (percent >= opts.percent))) {
|
||||
results++;
|
||||
}
|
||||
skip:
|
||||
free_file (file);
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
Qprintf ("\nFiles with potentially recoverable content: %d\n", results);
|
||||
out:
|
||||
if (opts.match)
|
||||
regfree (&re);
|
||||
free (buffer);
|
||||
if (attr)
|
||||
ntfs_attr_close (attr);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* copy_mft - Write a range of MFT Records to a file
|
||||
* @vol: An ntfs volume obtained from ntfs_mount
|
||||
|
|
|
@ -102,7 +102,7 @@ struct ufile {
|
|||
struct list_head name; /* A list of filenames */
|
||||
struct list_head data; /* A list of data streams */
|
||||
char *pref_name; /* Preferred filename */
|
||||
char *pref_pname; /* parent filename */
|
||||
char *pref_pname; /* parent filename */
|
||||
long long max_size; /* Largest size we find */
|
||||
int attr_list; /* MFT record may be one of many */
|
||||
int directory; /* MFT record represents a directory */
|
||||
|
|
1974
ntfsprogs/sd.c
1974
ntfsprogs/sd.c
File diff suppressed because it is too large
Load Diff
|
@ -29,11 +29,11 @@
|
|||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "upcase.h"
|
||||
|
||||
/**
|
||||
* init_upcase_table
|
||||
*/
|
||||
void init_upcase_table(ntfschar *uc, u32 uc_len);
|
||||
void init_upcase_table(ntfschar *uc, u32 uc_len)
|
||||
{
|
||||
static int uc_run_table[][3] = { /* Start, End, Add */
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#include <locale.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
|
@ -69,6 +69,7 @@
|
|||
#include "debug.h"
|
||||
#include "dir.h"
|
||||
#include "version.h"
|
||||
#include "logging.h"
|
||||
|
||||
const char *ntfs_bugs = "Developers' email address: linux-ntfs-dev@lists.sourceforge.net\n";
|
||||
const char *ntfs_home = "Linux NTFS homepage: http://linux-ntfs.sourceforge.net\n";
|
||||
|
@ -89,10 +90,10 @@ int utils_set_locale (void)
|
|||
locale = setlocale (LC_ALL, "");
|
||||
if (!locale) {
|
||||
locale = setlocale (LC_ALL, NULL);
|
||||
Eprintf ("Failed to set locale, using default '%s'.\n", locale);
|
||||
ntfs_log_error ("Failed to set locale, using default '%s'.\n", locale);
|
||||
return 1;
|
||||
} else {
|
||||
Vprintf ("Using locale '%s'.\n", locale);
|
||||
ntfs_log_verbose ("Using locale '%s'.\n", locale);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -125,37 +126,37 @@ int utils_valid_device (const char *name, int force)
|
|||
|
||||
if (stat (name, &st) == -1) {
|
||||
if (errno == ENOENT) {
|
||||
Eprintf ("The device %s doesn't exist\n", name);
|
||||
ntfs_log_error ("The device %s doesn't exist\n", name);
|
||||
} else {
|
||||
Eprintf ("Error getting information about %s: %s\n", name, strerror (errno));
|
||||
ntfs_log_error ("Error getting information about %s: %s\n", name, strerror (errno));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!S_ISBLK (st.st_mode)) {
|
||||
Vprintf ("%s is not a block device.\n", name);
|
||||
ntfs_log_verbose ("%s is not a block device.\n", name);
|
||||
if (!force) {
|
||||
Eprintf ("Use the force option to work with files.\n");
|
||||
ntfs_log_error ("Use the force option to work with files.\n");
|
||||
return 0;
|
||||
}
|
||||
Vprintf ("Forced to continue.\n");
|
||||
ntfs_log_verbose ("Forced to continue.\n");
|
||||
}
|
||||
|
||||
/* Make sure the file system is not mounted. */
|
||||
if (ntfs_check_if_mounted (name, &mnt_flags)) {
|
||||
Vprintf ("Failed to determine whether %s is mounted: %s\n", name, strerror (errno));
|
||||
ntfs_log_verbose ("Failed to determine whether %s is mounted: %s\n", name, strerror (errno));
|
||||
if (!force) {
|
||||
Eprintf ("Use the force option to ignore this error.\n");
|
||||
ntfs_log_error ("Use the force option to ignore this error.\n");
|
||||
return 0;
|
||||
}
|
||||
Vprintf ("Forced to continue.\n");
|
||||
ntfs_log_verbose ("Forced to continue.\n");
|
||||
} else if (mnt_flags & NTFS_MF_MOUNTED) {
|
||||
Vprintf ("The device %s, is mounted.\n", name);
|
||||
ntfs_log_verbose ("The device %s, is mounted.\n", name);
|
||||
if (!force) {
|
||||
Eprintf ("Use the force option to work a mounted filesystem.\n");
|
||||
ntfs_log_error ("Use the force option to work a mounted filesystem.\n");
|
||||
return 0;
|
||||
}
|
||||
Vprintf ("Forced to continue.\n");
|
||||
ntfs_log_verbose ("Forced to continue.\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -181,27 +182,27 @@ ntfs_volume * utils_mount_volume (const char *device, unsigned long flags, BOOL
|
|||
int err;
|
||||
|
||||
err = errno;
|
||||
Eprintf("Couldn't mount device '%s': %s\n", device,
|
||||
ntfs_log_error("Couldn't mount device '%s': %s\n", device,
|
||||
strerror(err));
|
||||
if (err == EPERM)
|
||||
Eprintf("Windows was hibernated. Try to mount volume "
|
||||
ntfs_log_error("Windows was hibernated. Try to mount volume "
|
||||
"in windows, shut down and try "
|
||||
"again.\n");
|
||||
if (err == EOPNOTSUPP)
|
||||
Eprintf("Windows did not shut down properly. Try to "
|
||||
ntfs_log_error("Windows did not shut down properly. Try to "
|
||||
"mount volume in windows, shut down "
|
||||
"and try again.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (vol->flags & VOLUME_IS_DIRTY) {
|
||||
Qprintf ("Volume is dirty.\n");
|
||||
ntfs_log_quiet ("Volume is dirty.\n");
|
||||
if (!force) {
|
||||
Eprintf ("Run chkdsk and try again, or use the --force option.\n");
|
||||
ntfs_log_error ("Run chkdsk and try again, or use the --force option.\n");
|
||||
ntfs_umount (vol, FALSE);
|
||||
return NULL;
|
||||
}
|
||||
Qprintf ("Forced to continue.\n");
|
||||
ntfs_log_quiet ("Forced to continue.\n");
|
||||
}
|
||||
|
||||
return vol;
|
||||
|
@ -241,16 +242,16 @@ int utils_parse_size (const char *value, s64 *size, BOOL scale)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Dprintf ("Parsing size '%s'.\n", value);
|
||||
ntfs_log_debug ("Parsing size '%s'.\n", value);
|
||||
|
||||
result = strtoll (value, &suffix, 10);
|
||||
if (result < 0 || errno == ERANGE) {
|
||||
Eprintf ("Invalid size '%s'.\n", value);
|
||||
ntfs_log_error ("Invalid size '%s'.\n", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!suffix) {
|
||||
Eprintf ("Internal error, strtoll didn't return a suffix.\n");
|
||||
ntfs_log_error ("Internal error, strtoll didn't return a suffix.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -263,17 +264,17 @@ int utils_parse_size (const char *value, s64 *size, BOOL scale)
|
|||
case '-': case 0:
|
||||
break;
|
||||
default:
|
||||
Eprintf ("Invalid size suffix '%s'. Use T, G, M, or K.\n", suffix);
|
||||
ntfs_log_error ("Invalid size suffix '%s'. Use T, G, M, or K.\n", suffix);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if ((suffix[0] != '-') && (suffix[0] != 0)) {
|
||||
Eprintf ("Invalid number '%.*s'.\n", (int)(suffix - value + 1), value);
|
||||
ntfs_log_error ("Invalid number '%.*s'.\n", (int)(suffix - value + 1), value);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Dprintf ("Parsed size = %lld.\n", result);
|
||||
ntfs_log_debug ("Parsed size = %lld.\n", result);
|
||||
*size = result;
|
||||
return 1;
|
||||
}
|
||||
|
@ -303,7 +304,7 @@ int utils_parse_range (const char *string, s64 *start, s64 *finish, BOOL scale)
|
|||
|
||||
middle = strchr (string, '-');
|
||||
if (string == middle) {
|
||||
Dprintf ("Range has no beginning, defaulting to 0.\n");
|
||||
ntfs_log_debug ("Range has no beginning, defaulting to 0.\n");
|
||||
a = 0;
|
||||
} else {
|
||||
if (!utils_parse_size (string, &a, scale))
|
||||
|
@ -313,7 +314,7 @@ int utils_parse_range (const char *string, s64 *start, s64 *finish, BOOL scale)
|
|||
if (middle) {
|
||||
if (middle[1] == 0) {
|
||||
b = LONG_MAX; // XXX ULLONG_MAX
|
||||
Dprintf ("Range has no end, defaulting to %lld.\n", b);
|
||||
ntfs_log_debug ("Range has no end, defaulting to %lld.\n", b);
|
||||
} else {
|
||||
if (!utils_parse_size (middle+1, &b, scale))
|
||||
return 0;
|
||||
|
@ -322,7 +323,7 @@ int utils_parse_range (const char *string, s64 *start, s64 *finish, BOOL scale)
|
|||
b = a;
|
||||
}
|
||||
|
||||
Dprintf ("Range '%s' = %lld - %lld\n", string, a, b);
|
||||
ntfs_log_debug ("Range '%s' = %lld - %lld\n", string, a, b);
|
||||
|
||||
*start = a;
|
||||
*finish = b;
|
||||
|
@ -352,11 +353,11 @@ ATTR_RECORD * find_attribute (const ATTR_TYPES type, ntfs_attr_search_ctx *ctx)
|
|||
}
|
||||
|
||||
if (ntfs_attr_lookup(type, NULL, 0, 0, 0, NULL, 0, ctx) != 0) {
|
||||
Dprintf ("find_attribute didn't find an attribute of type: 0x%02x.\n", type);
|
||||
ntfs_log_debug ("find_attribute didn't find an attribute of type: 0x%02x.\n", type);
|
||||
return NULL; /* None / no more of that type */
|
||||
}
|
||||
|
||||
Dprintf ("find_attribute found an attribute of type: 0x%02x.\n", type);
|
||||
ntfs_log_debug ("find_attribute found an attribute of type: 0x%02x.\n", type);
|
||||
return ctx->attr;
|
||||
}
|
||||
|
||||
|
@ -386,16 +387,16 @@ ATTR_RECORD * find_first_attribute (const ATTR_TYPES type, MFT_RECORD *mft)
|
|||
|
||||
ctx = ntfs_attr_get_search_ctx (NULL, mft);
|
||||
if (!ctx) {
|
||||
Eprintf ("Couldn't create a search context.\n");
|
||||
ntfs_log_error ("Couldn't create a search context.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rec = find_attribute (type, ctx);
|
||||
ntfs_attr_put_search_ctx (ctx);
|
||||
if (rec)
|
||||
Dprintf ("find_first_attribute: found attr of type 0x%02x.\n", type);
|
||||
ntfs_log_debug ("find_first_attribute: found attr of type 0x%02x.\n", type);
|
||||
else
|
||||
Dprintf ("find_first_attribute: didn't find attr of type 0x%02x.\n", type);
|
||||
ntfs_log_debug ("find_first_attribute: didn't find attr of type 0x%02x.\n", type);
|
||||
return rec;
|
||||
}
|
||||
|
||||
|
@ -432,18 +433,18 @@ int utils_inode_get_name (ntfs_inode *inode, char *buffer, int bufsize)
|
|||
|
||||
vol = inode->vol;
|
||||
|
||||
//printf ("sizeof (char*) = %d, sizeof (names) = %d\n", sizeof (char*), sizeof (names));
|
||||
//ntfs_log_debug ("sizeof (char*) = %d, sizeof (names) = %d\n", sizeof (char*), sizeof (names));
|
||||
memset (names, 0, sizeof (names));
|
||||
|
||||
for (i = 0; i < max_path; i++) {
|
||||
|
||||
ctx = ntfs_attr_get_search_ctx (inode, NULL);
|
||||
if (!ctx) {
|
||||
Eprintf ("Couldn't create a search context.\n");
|
||||
ntfs_log_error ("Couldn't create a search context.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//printf ("i = %d, inode = %p (%lld)\n", i, inode, inode->mft_no);
|
||||
//ntfs_log_debug ("i = %d, inode = %p (%lld)\n", i, inode, inode->mft_no);
|
||||
|
||||
name_space = 4;
|
||||
while ((rec = find_attribute (AT_FILE_NAME, ctx))) {
|
||||
|
@ -465,7 +466,7 @@ int utils_inode_get_name (ntfs_inode *inode, char *buffer, int bufsize)
|
|||
if (ntfs_ucstombs (attr->file_name, attr->file_name_length,
|
||||
&names[i], 0) < 0) {
|
||||
char *temp;
|
||||
Eprintf ("Couldn't translate filename to current locale.\n");
|
||||
ntfs_log_error ("Couldn't translate filename to current locale.\n");
|
||||
temp = malloc (30);
|
||||
if (!temp)
|
||||
return 0;
|
||||
|
@ -474,8 +475,8 @@ int utils_inode_get_name (ntfs_inode *inode, char *buffer, int bufsize)
|
|||
names[i] = temp;
|
||||
}
|
||||
|
||||
//printf ("names[%d] %s\n", i, names[i]);
|
||||
//printf ("parent = %lld\n", MREF (parent));
|
||||
//ntfs_log_debug ("names[%d] %s\n", i, names[i]);
|
||||
//ntfs_log_debug ("parent = %lld\n", MREF (parent));
|
||||
}
|
||||
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
|
@ -484,13 +485,13 @@ int utils_inode_get_name (ntfs_inode *inode, char *buffer, int bufsize)
|
|||
ntfs_inode_close (inode);
|
||||
|
||||
if (MREF (parent) == FILE_root) { /* The root directory, stop. */
|
||||
//printf ("inode 5\n");
|
||||
//ntfs_log_debug ("inode 5\n");
|
||||
break;
|
||||
}
|
||||
|
||||
inode = ntfs_inode_open (vol, parent);
|
||||
if (!inode) {
|
||||
Eprintf ("Couldn't open inode %llu.\n",
|
||||
ntfs_log_error ("Couldn't open inode %llu.\n",
|
||||
(unsigned long long)MREF(parent));
|
||||
break;
|
||||
}
|
||||
|
@ -498,7 +499,7 @@ int utils_inode_get_name (ntfs_inode *inode, char *buffer, int bufsize)
|
|||
|
||||
if (i >= max_path) {
|
||||
/* If we get into an infinite loop, we'll end up here. */
|
||||
Eprintf ("The directory structure is too deep (over %d) nested directories.\n", max_path);
|
||||
ntfs_log_error ("The directory structure is too deep (over %d) nested directories.\n", max_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -509,7 +510,7 @@ int utils_inode_get_name (ntfs_inode *inode, char *buffer, int bufsize)
|
|||
|
||||
len = snprintf (buffer + offset, bufsize - offset, "%c%s", PATH_SEP, names[i]);
|
||||
if (len >= (bufsize - offset)) {
|
||||
Eprintf ("Pathname was truncated.\n");
|
||||
ntfs_log_error ("Pathname was truncated.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -520,7 +521,7 @@ int utils_inode_get_name (ntfs_inode *inode, char *buffer, int bufsize)
|
|||
for (i = 0; i < max_path; i++)
|
||||
free (names[i]);
|
||||
|
||||
Dprintf ("Pathname: %s\n", buffer);
|
||||
ntfs_log_debug ("Pathname: %s\n", buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -545,18 +546,18 @@ int utils_attr_get_name (ntfs_volume *vol, ATTR_RECORD *attr, char *buffer, int
|
|||
name = NULL;
|
||||
namelen = ntfs_ucsnlen (attrdef->name, sizeof (attrdef->name));
|
||||
if (ntfs_ucstombs (attrdef->name, namelen, &name, 0) < 0) {
|
||||
Eprintf ("Couldn't translate attribute type to current locale.\n");
|
||||
ntfs_log_error ("Couldn't translate attribute type to current locale.\n");
|
||||
// <UNKNOWN>?
|
||||
return 0;
|
||||
}
|
||||
len = snprintf (buffer, bufsize, "%s", name);
|
||||
} else {
|
||||
Eprintf ("Unknown attribute type 0x%02x\n", attr->type);
|
||||
ntfs_log_error ("Unknown attribute type 0x%02x\n", attr->type);
|
||||
len = snprintf (buffer, bufsize, "<UNKNOWN>");
|
||||
}
|
||||
|
||||
if (len >= bufsize) {
|
||||
Eprintf ("Attribute type was truncated.\n");
|
||||
ntfs_log_error ("Attribute type was truncated.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -571,7 +572,7 @@ int utils_attr_get_name (ntfs_volume *vol, ATTR_RECORD *attr, char *buffer, int
|
|||
namelen = attr->name_length;
|
||||
if (ntfs_ucstombs ((ntfschar *)((char *)attr + attr->name_offset),
|
||||
namelen, &name, 0) < 0) {
|
||||
Eprintf ("Couldn't translate attribute name to current locale.\n");
|
||||
ntfs_log_error ("Couldn't translate attribute name to current locale.\n");
|
||||
// <UNKNOWN>?
|
||||
len = snprintf (buffer, bufsize, "<UNKNOWN>");
|
||||
return 0;
|
||||
|
@ -581,7 +582,7 @@ int utils_attr_get_name (ntfs_volume *vol, ATTR_RECORD *attr, char *buffer, int
|
|||
free (name);
|
||||
|
||||
if (len >= bufsize) {
|
||||
Eprintf ("Attribute name was truncated.\n");
|
||||
ntfs_log_error ("Attribute name was truncated.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -620,10 +621,10 @@ int utils_cluster_in_use (ntfs_volume *vol, long long lcn)
|
|||
|
||||
/* Does lcn lie in the section of $Bitmap we already have cached? */
|
||||
if ((lcn < bmplcn) || (lcn >= (bmplcn + (sizeof (buffer) << 3)))) {
|
||||
Dprintf ("Bit lies outside cache.\n");
|
||||
ntfs_log_debug ("Bit lies outside cache.\n");
|
||||
attr = ntfs_attr_open (vol->lcnbmp_ni, AT_DATA, AT_UNNAMED, 0);
|
||||
if (!attr) {
|
||||
Eprintf ("Couldn't open $Bitmap: %s\n", strerror (errno));
|
||||
ntfs_log_error ("Couldn't open $Bitmap: %s\n", strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -632,19 +633,18 @@ int utils_cluster_in_use (ntfs_volume *vol, long long lcn)
|
|||
bmplcn = lcn & (~((sizeof (buffer) << 3) - 1));
|
||||
|
||||
if (ntfs_attr_pread (attr, (bmplcn>>3), sizeof (buffer), buffer) < 0) {
|
||||
Eprintf ("Couldn't read $Bitmap: %s\n", strerror (errno));
|
||||
ntfs_log_error ("Couldn't read $Bitmap: %s\n", strerror (errno));
|
||||
ntfs_attr_close (attr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Dprintf ("Reloaded bitmap buffer.\n");
|
||||
ntfs_log_debug ("Reloaded bitmap buffer.\n");
|
||||
ntfs_attr_close (attr);
|
||||
}
|
||||
|
||||
bit = 1 << (lcn & 7);
|
||||
byte = (lcn >> 3) & (sizeof (buffer) - 1);
|
||||
Dprintf ("cluster = %lld, bmplcn = %lld, byte = %d, bit = %d, in use %d\n",
|
||||
lcn, bmplcn, byte, bit, buffer[byte] & bit);
|
||||
ntfs_log_debug ("cluster = %lld, bmplcn = %lld, byte = %d, bit = %d, in use %d\n", lcn, bmplcn, byte, bit, buffer[byte] & bit);
|
||||
|
||||
return (buffer[byte] & bit);
|
||||
}
|
||||
|
@ -681,24 +681,23 @@ int utils_mftrec_in_use (ntfs_volume *vol, MFT_REF mref)
|
|||
/* Does mref lie in the section of $Bitmap we already have cached? */
|
||||
if (((s64)MREF(mref) < bmpmref) || ((s64)MREF(mref) >= (bmpmref +
|
||||
(sizeof (buffer) << 3)))) {
|
||||
Dprintf ("Bit lies outside cache.\n");
|
||||
ntfs_log_debug ("Bit lies outside cache.\n");
|
||||
|
||||
/* Mark the buffer as not in use, in case the read is shorter. */
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
bmpmref = mref & (~((sizeof (buffer) << 3) - 1));
|
||||
|
||||
if (ntfs_attr_pread (vol->mftbmp_na, (bmpmref>>3), sizeof (buffer), buffer) < 0) {
|
||||
Eprintf ("Couldn't read $MFT/$BITMAP: %s\n", strerror (errno));
|
||||
ntfs_log_error ("Couldn't read $MFT/$BITMAP: %s\n", strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
Dprintf ("Reloaded bitmap buffer.\n");
|
||||
ntfs_log_debug ("Reloaded bitmap buffer.\n");
|
||||
}
|
||||
|
||||
bit = 1 << (mref & 7);
|
||||
byte = (mref >> 3) & (sizeof (buffer) - 1);
|
||||
Dprintf ("cluster = %lld, bmpmref = %lld, byte = %d, bit = %d, in use %d\n",
|
||||
mref, bmpmref, byte, bit, buffer[byte] & bit);
|
||||
ntfs_log_debug ("cluster = %lld, bmpmref = %lld, byte = %d, bit = %d, in use %d\n", mref, bmpmref, byte, bit, buffer[byte] & bit);
|
||||
|
||||
return (buffer[byte] & bit);
|
||||
}
|
||||
|
@ -804,38 +803,38 @@ void utils_dump_mem (void *buf, int start, int length, int flags)
|
|||
if (flags & DM_BLUE)
|
||||
col += 4;
|
||||
if (flags & DM_INDENT)
|
||||
printf ("\t");
|
||||
ntfs_log_debug ("\t");
|
||||
if (flags & DM_BOLD)
|
||||
printf ("\e[01m");
|
||||
ntfs_log_debug ("\e[01m");
|
||||
if (flags & (DM_RED | DM_BLUE | DM_GREEN | DM_BOLD))
|
||||
printf ("\e[%dm", col);
|
||||
ntfs_log_debug ("\e[%dm", col);
|
||||
if (off == s)
|
||||
printf("%6.6x ", start);
|
||||
ntfs_log_debug("%6.6x ", start);
|
||||
else
|
||||
printf("%6.6x ", off);
|
||||
ntfs_log_debug("%6.6x ", off);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if ((i == 8) && (!(flags & DM_NO_DIVIDER)))
|
||||
printf (" -");
|
||||
ntfs_log_debug (" -");
|
||||
if (((off+i) >= start) && ((off+i) < (start+length)))
|
||||
printf (" %02X", mem[off+i]);
|
||||
ntfs_log_debug (" %02X", mem[off+i]);
|
||||
else
|
||||
printf (" ");
|
||||
ntfs_log_debug (" ");
|
||||
}
|
||||
if (!(flags & DM_NO_ASCII)) {
|
||||
printf (" ");
|
||||
ntfs_log_debug (" ");
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (((off+i) < start) || ((off+i) >= (start+length)))
|
||||
printf (" ");
|
||||
ntfs_log_debug (" ");
|
||||
else if (isprint (mem[off + i]))
|
||||
printf ("%c", mem[off + i]);
|
||||
ntfs_log_debug ("%c", mem[off + i]);
|
||||
else
|
||||
printf (".");
|
||||
ntfs_log_debug (".");
|
||||
}
|
||||
}
|
||||
if (flags & (DM_RED | DM_BLUE | DM_GREEN | DM_BOLD))
|
||||
printf ("\e[0m");
|
||||
printf ("\n");
|
||||
ntfs_log_debug ("\e[0m");
|
||||
ntfs_log_debug ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -902,7 +901,7 @@ int mft_next_record (struct mft_search_ctx *ctx)
|
|||
ctx->flags_match = 0;
|
||||
in_use = utils_mftrec_in_use (ctx->vol, (MFT_REF) ctx->mft_num);
|
||||
if (in_use == -1) {
|
||||
Eprintf ("Error reading inode %llu. Aborting.\n",
|
||||
ntfs_log_error ("Error reading inode %llu. Aborting.\n",
|
||||
(unsigned long long)ctx->mft_num);
|
||||
return -1;
|
||||
}
|
||||
|
@ -912,7 +911,7 @@ int mft_next_record (struct mft_search_ctx *ctx)
|
|||
|
||||
ctx->inode = ntfs_inode_open (ctx->vol, (MFT_REF) ctx->mft_num);
|
||||
if (ctx->inode == NULL) {
|
||||
Eprintf ("Error reading inode %llu.\n", (unsigned
|
||||
ntfs_log_error ("Error reading inode %llu.\n", (unsigned
|
||||
long long) ctx->mft_num);
|
||||
continue;
|
||||
}
|
||||
|
@ -940,7 +939,7 @@ int mft_next_record (struct mft_search_ctx *ctx)
|
|||
|
||||
ntfs_attr_put_search_ctx (attr_ctx);
|
||||
} else {
|
||||
Eprintf ("Couldn't create a search context.\n");
|
||||
ntfs_log_error ("Couldn't create a search context.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -950,7 +949,7 @@ int mft_next_record (struct mft_search_ctx *ctx)
|
|||
case 0: ctx->flags_match |= FEMR_NOT_METADATA; break;
|
||||
default:
|
||||
ctx->flags_match |= FEMR_NOT_METADATA; break;
|
||||
//Eprintf ("Error reading inode %lld.\n", ctx->mft_num);
|
||||
//ntfs_log_error ("Error reading inode %lld.\n", ctx->mft_num);
|
||||
//return -1;
|
||||
}
|
||||
|
||||
|
@ -961,7 +960,7 @@ int mft_next_record (struct mft_search_ctx *ctx)
|
|||
|
||||
ctx->inode = calloc (1, sizeof (*ctx->inode));
|
||||
if (!ctx->inode) {
|
||||
Eprintf ("Out of memory. Aborting.\n");
|
||||
ntfs_log_error ("Out of memory. Aborting.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -970,20 +969,20 @@ int mft_next_record (struct mft_search_ctx *ctx)
|
|||
ctx->inode->mrec = malloc (ctx->vol->mft_record_size);
|
||||
if (!ctx->inode->mrec) {
|
||||
free (ctx->inode); // == ntfs_inode_close
|
||||
Eprintf ("Out of memory. Aborting.\n");
|
||||
ntfs_log_error ("Out of memory. Aborting.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mft = ntfs_attr_open (ctx->vol->mft_ni, AT_DATA,
|
||||
AT_UNNAMED, 0);
|
||||
if (!mft) {
|
||||
Eprintf ("Couldn't open $MFT/$DATA: %s\n", strerror (errno));
|
||||
ntfs_log_error ("Couldn't open $MFT/$DATA: %s\n", strerror (errno));
|
||||
// free / close
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ntfs_attr_pread (mft, ctx->vol->mft_record_size * ctx->mft_num, ctx->vol->mft_record_size, ctx->inode->mrec) < ctx->vol->mft_record_size) {
|
||||
Eprintf ("Couldn't read MFT Record %llu: %s.\n",
|
||||
ntfs_log_error ("Couldn't read MFT Record %llu: %s.\n",
|
||||
(unsigned long long)
|
||||
ctx->mft_num, strerror (errno));
|
||||
// free / close
|
||||
|
@ -999,7 +998,7 @@ int mft_next_record (struct mft_search_ctx *ctx)
|
|||
}
|
||||
|
||||
if (ntfs_inode_close (ctx->inode)) {
|
||||
Eprintf ("Error closing inode %llu.\n",
|
||||
ntfs_log_error ("Error closing inode %llu.\n",
|
||||
(unsigned long long)ctx->mft_num);
|
||||
return -errno;
|
||||
}
|
||||
|
|
|
@ -31,9 +31,13 @@
|
|||
#include "layout.h"
|
||||
#include "volume.h"
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#include <regex.h>
|
||||
#endif
|
||||
//#include <regex.h>
|
||||
|
||||
extern const char *ntfs_bugs;
|
||||
extern const char *ntfs_home;
|
||||
|
@ -42,7 +46,6 @@ extern const char *ntfs_gpl;
|
|||
#if !defined(REG_NOERROR) || (REG_NOERROR != 0)
|
||||
# define REG_NOERROR 0
|
||||
#endif
|
||||
|
||||
#define DEC_PRINTF(NAME) \
|
||||
int NAME (const char *format, ...) \
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
@ -67,6 +70,7 @@ extern const char *ntfs_gpl;
|
|||
return ret; \
|
||||
}
|
||||
|
||||
|
||||
/* utils.c's utilities require the following functions implemented.
|
||||
* Example of implementation is:
|
||||
* GEN_PRINTF (Eprintf, stderr, NULL, FALSE)
|
||||
|
|
Loading…
Reference in New Issue