Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/include
In directory usw-pr-cvs1:/tmp/cvs-serv19513/include
Added Files:
attrib.h endians.h mft.h ntfs_rec.h volume.h
Log Message:
Add a bunch of headers (attrib.h is work in progress).
--- NEW FILE ---
/*
* attrib.h - Exports for attribute handling. Part of the Linux-NTFS project.
*
* Copyright (c) 2000,2001 Anton Altaparmakov.
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef ATTRIB_H
#define ATTRIB_H
#include "endians.h"
#include "mft.h"
/*
* System defined attributes (32-bit).
*/
typedef enum {
$UNUSED = cpu_to_le32( 0),
$STANDARD_INFORMATION = cpu_to_le32( 0x10),
$ATTRIBUTE_LIST = cpu_to_le32( 0x20),
$FILENAME = cpu_to_le32( 0x30),
$OBJECT_ID = cpu_to_le32( 0x40),
$SECURITY_DESCRIPTOR = cpu_to_le32( 0x50),
$VOLUME_NAME = cpu_to_le32( 0x60),
$VOLUME_INFORMATION = cpu_to_le32( 0x70),
$DATA = cpu_to_le32( 0x80),
$INDEX_ROOT = cpu_to_le32( 0x90),
$INDEX_ALLOCATION = cpu_to_le32( 0xa0),
$BITMAP = cpu_to_le32( 0xb0),
$REPARSE_POINT = cpu_to_le32( 0xc0),
$EA_INFORMATION = cpu_to_le32( 0xd0),
$EA = cpu_to_le32( 0xe0),
$PROPERTY_SET = cpu_to_le32( 0xf0),
$LOGGED_UTILITY_STREAM = cpu_to_le32( 0x100),
$FIRST_USER_DEFINED_ATTRIBUTE = cpu_to_le32( 0x1000),
$END = cpu_to_le32(0xffffffff),
} ATTRIBUTE_TYPE;
/*
* System file numbers. All these files are always marked as used in the $Mft
* bitmap attribute, presumably in order to avoid accidental allocation for
* random other mft records.
*/
typedef enum {
FILE_$Mft = 0, /* Master file table (mft). */
FILE_$MftMirr = 1, /* Mft mirror (copy of first 4 mft records). */
FILE_$LogFile = 2, /* Journalling log. */
FILE_$Volume = 3, /* Volume name, flags and ntfs version. */
FILE_$AttrDef = 4, /* Attribute definitions. */
FILE_$root = 5, /* Root directory. */
FILE_$BitMap = 6, /* Allocation map of all clusters. */
FILE_$Boot = 7, /* Boot sector (always at cluster 0). */
FILE_$BadClus = 8, /* Contains all bad clusters. */
FILE_$Secure = 9, /* Shared security descriptors. */
FILE_$UpCase = 10, /* Upcase table for all 65536 Unicode chars. */
FILE_$Extend = 11, /* Directory containing other system files (eg.
$ObjId, $Quota, $Reparse and $UsnJrnl). This
is new to NTFS3.0. */
FILE_reserved12 = 12, /* Reserved for future use (records 12-15). */
FILE_reserved13 = 13,
FILE_reserved14 = 14,
FILE_reserved15 = 15,
FILE_first_user = 16, /* First user file, used as test limit for
whether to allow opening a file or not. */
} NTFS_SYSTEM_FILES;
/*
* Attribute flags (16-bit).
*/
typedef enum {
ATTRIBUTE_IS_COMPRESSED = cpu_to_le16(0x0001),
ATTRIBUTE_COMPRESSION_MASK = cpu_to_le16(0x00ff), /* Compression method
* mask. First
* illegal value. */
ATTRIBUTE_IS_ENCRYPTED = cpu_to_le16(0x4000),
ATTRIBUTE_IS_SPARSE = cpu_to_le16(0x8000),
} __attribute__ ((__packed__)) ATTRIBUTE_FLAGS;
/*
* The collation rules for sorting views/indexes/etc (32-bit).
*/
typedef enum {
COLLATION_BINARY = cpu_to_le32(0), /* Collate by binary compare
where the first byte is
most significant. */
COLLATION_FILENAME = cpu_to_le32(1), /* Collate file names as
Unicode strings. */
COLLATION_UNICODE_STRING = cpu_to_le32(2), /* Collate Unicode strings
by comparing their binary
Unicode values, except
that when a character can
be uppercased, the upper
case value collates before
the lower case one. */
COLLATION_NTOFS_ULONG = cpu_to_le32(16), /* ??? */
COLLATION_NTOFS_SID = cpu_to_le32(17), /* ??? */
COLLATION_NTOFS_SECURITY_HASH = cpu_to_le32(18), /* ??? */
COLLATION_NTOFS_ULONGS = cpu_to_le32(19), /* ??? */
} COLLATION_RULES;
/*
* Attribute record header.
*/
typedef struct {
/*Ofs*/
/* 0*/ ATTRIBUTE_TYPE type; /* The (4-byte) type of the attribute. */
/* 4*/ __u32 length; /* Byte size of the resident part of the
attribute (aligned to 8-byte boundary). */
/* 8*/ __u8 non_resident; /* If 0, attribute is resident.
If 1, attribute is non-resident. */
/* 9*/ __u8 name_length; /* Unicode character size of name of attribute.
0 if unnamed. */
/* 10*/ __u16 name_offset; /* If name_length != 0, the byte offset to the
beginning of the name from the attribute
record. Note that the name is stored as a
Unicode string. */
/* 12*/ ATTRIBUTE_FLAGS flags; /* Bit array of ATTRIBUTE_* flags (16-bit). */
/* 14*/ __u16 instance; /* The instance of this attribute record. This
number is unique within this mft record (see
MFT_RECORD_HEADER/next_attribute_instance
notes in mft.h for more details). */
/* sizeof() = 16 bytes */
} __attribute__ ((__packed__)) ATTRIBUTE_RECORD_HEADER;
/*
* Flags of resident attributes (8-bit).
*/
typedef enum {
RESIDENT_ATTRIBUTE_IS_INDEXED = 0x01, /* Attribute is referenced in
an index somewhere (has
implications for deleting
modifying the attribute). */
} __attribute__ ((__packed__)) RESIDENT_ATTRIBUTE_FLAGS;
/*
* Resident attribute record header.
*/
typedef struct {
/*Ofs*/
/* 0*/ ATTRIBUTE_RECORD_HEADER attribute;
/* 16*/ __u32 value_length; /* Byte size of attribute value. */
/* 20*/ __u16 value_offset; /* Byte offset of the attribute value from the
start of the attribute record. */
/* 22*/ __u8 resident_flags; /* Bit array of RESIDENT_ATTRIBUTE_* flags. */
/* 23*/ __s8 reserved; /* Reserved/alignment to 8-byte boundary. */
/* sizeof() = 24 bytes */
} __attribute__ ((__packed__)) RESIDENT_ATTRIBUTE_RECORD_HEADER;
/*
* Non-resident attribute record header.
*/
typedef struct {
/*Ofs*/
/* 0*/ ATTRIBUTE_RECORD_HEADER attribute;
/* 16*/ __u64 lowest_vcn; /* Lowest valid virtual cluster number (vcn)
for this portion of the attribute value or
0 if this is the only portion (usually the
case. - Only when an attribute list is used
does lowest_vcn != 0 ever occur. */
/* 24*/ __u64 highest_vcn; /* Highest valid vcn of this portion of the
attribute value. - Usually there is only one
portion, so this usually equals the attribute
value size in clusters. */
/* 30*/ __u16 mapping_pairs_offset; /* Byte offset from the beginning of the
structure to the mapping pairs array which
contains the mappings between the vcns and
the logical cluster numbers (lcns). */
/* 32*/ __u8 compression_unit; /* The compression unit expressed as the log
to the base 2 of the number of clusters in a
compression unit. 0 means not compressed.
(This effectively limits the compression
unit size to be a power of two clusters.) */
/* 33*/ __u8 reserved[5]; /* Align to 8-byte boundary. */
/* 38*/ __u64 allocated_size; /* Byte size of disk space allocated to hold
the attribute value. Always is a multiple of
the cluster size. */
/* 46*/ __u64 data_size; /* Byte size of the attribute value. Can be
larger than allocated_size if attribute
value is compressed or sparse. */
/* 54*/ __u64 initialized_size; /* Byte size of initialized portion of the
attribute value. */
/* 62*/ __u64 compressed_size; /* Byte size of the attribute value after
compression. Only present when compressed. */
/* sizeof() = 70 bytes (when compressed, otherwise = 62 bytes) */
} __attribute__ ((__packed__)) NONRESIDENT_ATTRIBUTE_RECORD_HEADER;
/*
* FIXME: Should we combine the resident and non-resident attribute record
* headers into the attribute record header with a union for the two structs
* inside it? - Probably but will break existing programs so keep it ATM.
*/
/*
* File attribute flags (32-bit).
*/
typedef enum {
FILE_ATTRIBUTE_READONLY = cpu_to_le32(0x00000001),
FILE_ATTRIBUTE_HIDDEN = cpu_to_le32(0x00000002),
FILE_ATTRIBUTE_SYSTEM = cpu_to_le32(0x00000004),
/* Old DOS volid. Unused in NT. = cpu_to_le32(0x00000008), */
FILE_ATTRIBUTE_DIRECTORY = cpu_to_le32(0x00000010),
/* FILE_ATTRIBUTE_DIRECTORY is not considered valid in NT. It is
reserved for the DOS SUBDIRECTORY flag. */
FILE_ATTRIBUTE_ARCHIVE = cpu_to_le32(0x00000020),
FILE_ATTRIBUTE_DEVICE = cpu_to_le32(0x00000040),
FILE_ATTRIBUTE_NORMAL = cpu_to_le32(0x00000080),
FILE_ATTRIBUTE_TEMPORARY = cpu_to_le32(0x00000100),
FILE_ATTRIBUTE_SPARSE_FILE = cpu_to_le32(0x00000200),
FILE_ATTRIBUTE_REPARSE_POINT = cpu_to_le32(0x00000400),
FILE_ATTRIBUTE_COMPRESSED = cpu_to_le32(0x00000800),
FILE_ATTRIBUTE_OFFLINE = cpu_to_le32(0x00001000),
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = cpu_to_le32(0x00002000),
FILE_ATTRIBUTE_ENCRYPTED = cpu_to_le32(0x00004000),
FILE_ATTRIBUTE_VALID_FLAGS = cpu_to_le32(0x00007fb7),
/* FILE_ATTRIBUTE_VALID_FLAGS masks out the old DOS VolId and the
FILE_ATTRIBUTE_DEVICE and preserves everything else. This mask
is used to obtain all flags that are valid for reading. */
FILE_ATTRIBUTE_VALID_SET_FLAGS = cpu_to_le32(0x000031a7),
/* FILE_ATTRIBUTE_VALID_SET_FLAGS masks out the old DOS VolId, the
F_A_DEVICE, F_A_DIRECTORY, F_A_SPARSE_FILE, F_A_REPARSE_POINT,
F_A_COMPRESSED and F_A_ENCRYPTED and preserves the rest. This mask
is used to to obtain all flags that are valid for setting. */
FILE_ATTRIBUTE_DUP_FILENAME_INDEX_PRESENT = cpu_to_le32(0x10000000),
/* This is a copy of the corresponding bit from the mft record, telling
us whether this is a directory or not, i.e. whether it has an
index root attribute or not. */
FILE_ATTRIBUTE_DUP_VIEW_INDEX_PRESENT = cpu_to_le32(0x20000000),
/* This is a copy of the corresponding bit from the mft record, telling
us whether this file has a view index present (eg. object id index
or quota index). */
} FILE_ATTRIBUTE_FLAGS;
/*
* NOTE on times in NTFS: All times are in MS standard time format, i.e. they
* are the number of 100-nanosecond intervals since 1st January 1601.
*/
/*
* Attribute: Standard information.
*
* NOTE: Always resident.
* NOTE: Present in all base file records on a volume.
*/
typedef struct {
/*Ofs*/
/* 0*/ __u64 creation_time; /* When the file was created. */
/* 8*/ __u64 last_modification_time; /* Time of last change of data
attribute. */
/* 16*/ __u64 last_change_time; /* Time of last change of this mft
record. */
/* 24*/ __u64 last_access_time; /* Approximate time when the file was
last accessed (obviously this is not
updated on read-only volumes). In
Windows this is only updated when
accessed if some time delta has
passed since the last update. */
/* 30*/ FILE_ATTRIBUTE_FLAGS file_attributes; /* Flags describing the file. */
/*
* Following fields are only present in NTFS v3.0+ (i.e. Win2k+). If a volume
* has been upgraded from a previous NTFS version, then these fields are
* present only if the file has been accessed since the upgrade. Recognize
* the difference by comparing the length of the resident attribute value. If
* it is 48, then the following fields are missing. If it is 72 then the fields
* are present. Maybe just check like this:
* if (resident.ValueLength < sizeof(STANDARD_INFORMATION)) {
* Assume NTFS 1.2- format.
* If (volume version is 3.0+)
* Upgrade attribute to NTFS 3.0 format.
* else
* Use NTFS 1.2- format for access.
* } else
* Use NTFS 3.0 format for access.
* Only problem is that it might be legal to set the length of the value to
* arbitrarily large values thus spoiling this check. - But chkdsk probably
* views that as a corruption, assuming that it behaves like this for all
* attributes.
*/
/* 34*/ __u32 maximum_versions; /* Maximum allowed versions for file. Zero
means that version numbering is disabled. */
/* 38*/ __u32 version_number; /* This file's version (if any). Should make
this zero if maximum_versions is zero. */
/* 42*/ __u32 class_id; /* Class id from bidirectional class id
index (?). */
/* 46*/ __u32 owner_id; /* Id for file owner, from bidir security
index. This is also used to find the quota
associated with this file, probably as an
index into /$Extend/$Quota (?). Is zero if
quotas are disabled. */
/* 50*/ __u32 security_id; /* Security Id for the file. Translate via
bidir index to granted access Acl. Probably
as an index into /$Secure (?). */
/* 54*/ __u64 quota_charged; /* Byte size of the charge to the quota for
all streams of the file. Is zero if quotas
are disabled. */
/* 62*/ __u64 usn; /* Last update sequence number of the file. This
is a direct index into the change (aka Usn)
journal file. It is zero if the journal is
disabled.
NOTE: To disable the journal need to delete
the journal file itself and to then walk the
whole mft and set all Usn entries in all mft
records to zero! (This can take a while!)
The journal is /$Extend/UsnJrnl. Windows 2k
will recreate the journal and initiate
logging if necessary when mounting the
partition. This, in contrast to disabling the
journal is a very fast process, so the user
won't even notice it. */
/* sizeof() = 70 bytes */
} __attribute__ ((__packed__)) STANDARD_INFORMATION;
/*
* Attribute: Attribute list.
*
* The value of the attribute list attribute consists of a sequence of
* variable length, 64-bit aligned ATTRIBUTE_LIST_ENTRY records. The value
* can be either resident or non-resident.
* The attribute list attribute contains one entry for each attribute of the
* file in which the list is located, except for the list attribute itself.
* The list is sorted first by: attribute type, then by attribute name (if
* present) and third by attribute value. In the third case the attribute
* value of the referenced attribute is required to be resident. Also, it is
* not allowed to have two attributes with all three sorting keys equal.
* Further restrictions:
* - If not resident, the vcn to lcn mapping array has to fit inside the
* base mft record.
* - The attribute list attribute value has a maximum size of 256kb. This
* is imposed by the Windows cache manager.
*/
typedef struct {
/*Ofs*/
/* 0*/ ATTRIBUTE_TYPE attribute_type; /* Type of referenced attribute. */
/* 4*/ __u16 record_length; /* Byte size of this entry. */
/* 6*/ __u8 attribute_name_length; /* Size in Unicode chars of the name of
the attribute or 0 if unnamed. */
/* 7*/ __u8 attribute_name_offset; /* Byte offset to beginning of attribute
name (always set this to where the
name would start even if unnamed). */
/* 8*/ __u64 lowest_vcn; /* Lowest virtual cluster number of this portion
of the attribute value. This is usually 0. It
is non-zero for the case where one attribute
does not fit into one mft record and thus
several mft records are allocated to hold
this attribute. In the latter case, each mft
record holds one extent of the attribute and
there is one attribute list entry for each
extent. */
/* 16*/ __u64 mft_reference; /* The reference of the mft record holding the
NONRESIDENT_ATTRIBUTE_RECORD_HEADER structure
for this portion of the attribute value or
holding the RESIDENT_ATTRIBUTE_RECORD_HEADER
structure if the reference points to the
same mft record as the one the attribute
list resides in. */
/* 24*/ __u16 instance; /* The instance of the attribute being
referenced. */
/* 26*/ __u16 attribute_name[0];/* Use when creating only. When reading use
attribute_name_offset to determine the
location of the attribute_name.*/
/* sizeof() = 26 + (attribute_name_length * 2) bytes */
} __attribute__ ((__packed__)) ATTRIBUTE_LIST_ENTRY;
/*
* The maximum allowed length for a file name.
*
* FIXME: Is it 255? In NT4 using explorer can only do up to a maximum of 218
* charcters. (?!?)
*/
#define MAXIMUM_FILENAME_LENGTH 256
/*
* Possible namespaces for filenames in ntfs.
*/
typedef enum {
FILENAME_POSIX = cpu_to_le16(0x0000),
/* This is the largest namespace. It is case sensitive and
allows all Unicode characters except for: '\0' and '/'.
Beware that in WinNT/2k files which eg have the same name
except for their case will not be distinguished by the
standard utilities and thus a "del filename" will delete
both "filename" and "fileName" without warning. */
FILENAME_WIN32 = cpu_to_le16(0x0001),
/* The standard WinNT/2k NTFS long filenames. Case insensitive.
All Unicode chars except: '\0', '"', '*', '/', ':', '<',
'>', '?', '\' and '|'. Further, names cannot end with a '.'
or a space. */
FILENAME_DOS = cpu_to_le16(0x0002),
/* The standard DOS filenames (8.3 format). Uppercase only.
All 8-bit characters greater space, except: '"', '*', '+',
',', '/', ':', ';', '<', '=', '>', '?' and '\'. */
FILENAME_WIN32_AND_DOS = cpu_to_le16(0x0003),
/* 3 means that both the Win32 and the DOS filenames are
identical and hence have been saved in this single filename
record. */
SIZE_INDICATOR_FOR_ATTRIBUTE_PACKED = 0xffff;
/* This is not defined by ntfs but we need it to tell gcc
to make this enum type 16-bit. */
} __attribute__ ((__packed__)) FILENAME_TYPE_FLAGS;
/*
* Attribute: Filename.
*
* NOTE: Always resident. (?)
*/
typedef struct {
__u64 parent_directory_mft_reference; /* Directory this filename is
referenced from. */
__u64 creation_time; /* Time file was created. */
__u64 last_modification_time; /* Time data attribute was
last modified. */
__u64 last_change_time; /* Time mft record was
modified. */
__u64 last_access_time; /* Last time mft record was
accessed. See notes for this
in attribute standard
information above. */
__u64 allocated_size; /* Byte size of allocated space
for the data attribute.
NOTE: Is a multiple of the
cluster size. */
__u64 data_size; /* Byte size of actual data in
data attribute.
NOTE: Only present when
lowest_vcn is 0. */
FILE_ATTRIBUTE_FLAGS file_attributes; /* Flags describing the file.*/
union {
struct {
__u16 reserved; /* Reserved for alignment. */
__u16 packed_ea_size; /* Size of the buffer needed to
pack the extended attributes
(EAs), if such are present.*/
};
__u32 reparse_point_tag; /* Type of reparse point,
present only in reparse
points and only if there are
no EAs. */
};
__u8 filename_length; /* Length of filename in
Unicode characters. */
__u8 filename_type; /* Bit field of FILENAME_TYPE_*
flags. */
__u16 filename[filename_length]; /* Filename in Unicode. */
} __attribute__ ((__packed__)) FILENAME_ATTRIBUTE;
/*
* GUID structures store globally unique identifiers (GUID). A GUID is a
* 128-bit value consisting of one group of eight hexadecimal digits, followed
* by three groups of four hexadecimal digits each, followed by one group of
* twelve hexadecimal digits. GUIDs are Microsoft's implementation of the
* distributed computing environment (DCE) universally unique identifier (UUID).
* Example of a GUID:
* 1F010768-5A73-BC91-0010A52216A7
*/
typedef struct {
__u32 data1; /* The first eight hexadecimal digits of the GUID. */
__u16 data2; /* The first group of four hexadecimal digits. */
__u16 data3; /* The second group of four hexadecimal digits. */
__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: Object id.
*
* NOTE: Always resident.
*/
typedef struct {
//MFT_REFERENCE file_system_reference; /* Is it this structure or */
//__u8 extended_info[48]; /* the one declared below?!? */
//} __attribute__ ((__packed__)) OBJECT_ID_ATTRIBUTE;
GUID object_id; /* Unique id assigned to the
file.*/
union {
struct {
GUID birth_volume_id; /* Unique id of volume on which
the file was first created.
NOTE: Optional. */
GUID birth_object_id; /* Unique id of file when it was
first created.
NOTE: Optional. */
GUID domain_id; /* Reserved.
NOTE: Optional. */
};
__u8 extended_info[48];
};
} __attribute__ ((__packed__)) OBJECT_ID_ATTRIBUTE;
/*
* Attribute: Security descriptor.
*
* NOTE: Always resident.
* NOTE: Not used in NTFS 3.0+. (Not at all?)
*/
typedef struct {
// SID sid; ??? /* A standard self-relative security descriptor. */
} __attribute__ ((__packed__)) SECURITY_DESCRIPTOR_ATTRIBUTE;
/*
* Attribute: Volume name.
*
* NOTE: Always resident.
* NOTE: Present only in FILE_$Volume.
*/
typedef struct {
__u16 name[0]; /* The name of the volume in Unicode. */
} __attribute__ ((__packed__)) VOLUME_NAME;
/*
* Possible flags for the volume (16-bit).
*/
typedef enum {
VOLUME_IS_DIRTY = cpu_to_le16(0x0001),
VOLUME_RESIZE_LOG_FILE = cpu_to_le16(0x0002),
VOLUME_UPGRADE_ON_MOUNT = cpu_to_le16(0x0004),
VOLUME_MOUNTED_ON_NT4 = cpu_to_le16(0x0008),
VOLUME_DELETE_USN_UNDERWAY = cpu_to_le16(0x0010),
VOLUME_REPAIR_OBJECT_ID = cpu_to_le16(0x0020),
VOLUME_MODIFIED_BY_CHKDSK = cpu_to_le16(0x8000),
} __attribute__ ((__packed__)) VOLUME_FLAGS;
/*
* Attribute: Volume information.
*
* NOTE: Always resident.
* NOTE: Present only in FILE_$Volume.
*/
typedef struct {
__u64 reserved; /* Not used (yet?). */
__u8 major_version; /* Major version of the ntfs format. */
__u8 minor_version; /* Minor version of the ntfs format. */
VOLUME_FLAGS flags; /* Bit array of VOLUME_* flags. */
} __attribute__ ((__packed__)) VOLUME_INFORMATION;
/*
* Attribute: Data attribute.
*
* Data contents of a file (unnamed stream) or of a named stream.
*/
typedef struct {
__u8 data[0]; /* The file's data contents. */
} __attribute__ ((__packed__)) DATA_ATTRIBUTE;
/*
* Index header flags.
*/
typedef enum {
NO_INDEX_NODE = cpu_to_le32(0), /* Small directory, i.e. the whole
directory fits inside the index
root attribute and hence there is
no index allocation attribute. */
INDEX_NODE = cpu_to_le32(1), /* Large directory, i.e. it doesn't
fit in the index root attribute
and hence an index allocation
attribute is present. */
} INDEX_HEADER_FLAGS;
typedef enum {
INDEX_ENTRY_NODE = cpu_to_le32(1), /* This entry references an index
allocation attribute value. */
INDEX_ENTRY_END = cpu_to_le32(2), /* This signifies the last entry in
an index buffer. */
} INDEX_ROOT_INDEX_ENTRY_FLAGS;
/*
* Attribute: Bitmap.
*/
typedef struct {
__u8 bitmap[0]; /* Array of bits. */
} __attribute__ ((__packed__)) BITMAP_ATTRIBUTE;
/*
* Attribute: Reparse point.
*
* FIXME: Describe more about reparse points here including the flags in the
* ReparseTag.
*/
typedef struct {
__u32 reparse_tag; /* Reparse point type (inc. flags). */
__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: Extended attribute (EA) information.
*/
typedef struct {
__u16 packed_ea_length; /* Byte size of the buffer needed to
pack the extended attributes. */
__u16 need_ea_count; /* The number of extended attributes
which have the NEED_EA bit set. */
__u32 unpacked_ea_length; /* Byte size of the buffer required to
query the extended attributes. */
} __attribute__ ((__packed__)) EA_INFORMATION;
typedef enum {
// NEED_EA = ???;
} EA_FLAGS;
/*
* Attribute: Extended attribute (EA).
*
* Like the attribute list and the index buffer list, the EA attribute value is
* a sequence of EA_ATTRIBUTE variable length records.
*/
typedef struct {
__u32 next_entry_offset; /* Offset to the next EA_ATTRIBUTE. */
__u8 flags; /* Bit array of EA_FLAGS. */
__u8 ea_name_length; /* Length of the name of the extended
attribute in characters.
FIXME: Unicode? */
__u16 ea_value_length; /* Byte size of the EA's value. */
__u8 ea_name[ea_name_length]; /* Name of the EA.
FIXME: In Unicode? */
__u8 ea_data[ea_value_length]; /* The value of the EA. Immediately
follows the name. */
} __attribute__ ((__packed__)) EA_ATTRIBUTE;
/*
* Attribute: .
*/
typedef struct {
} __attribute__ ((__packed__)) INDEX_HEADER;
/*
* Attribute: .
*/
typedef struct {
} __attribute__ ((__packed__)) INDEX_ROOT;
/*
* Attribute: .
*/
typedef struct {
} __attribute__ ((__packed__)) INDEX_ALLOCATION;
/*
* Attribute: .
*/
typedef struct {
} __attribute__ ((__packed__)) INDEX_ENTRY;
/* min macro used in attrib.c. */
#ifndef min
#define min(a,b) ((a) <= (b) ? (a) : (b))
#endif
typedef struct { /* In memory VCN to LCN mapping structure element. */
__s64 vcn; /* VCN = starting virtual cluster number */
__s64 lcn; /* LCN = starting logical cluster number */
__u64 length; /* run length in clusters */
} run_list_element;
typedef run_list_element *run_list;/*In memory VCN to LCN mapping array.*/
/* run_list notes:
* - The last VCN is recognised by the fact that length == 0.
* - LCN == 0 at any point means that the count VCNs starting at VCN are not
* physically allocated (ie. this is a hole). */
/* FIXME: Should this be a linked list so it is easier/quicker to edit? */
/* Allocate a run_list array and decompress the run-list of the non-resident
* attribute attr into the run_list array.
* Return a pointer to the run_list array or NULL on error.
* Notes: caller has to free the run_list array when finished. */
run_list decompress_run_list(NONRESIDENT_ATTRIBUTE_RECORD_HEADER *attr);
/* Determine the logical cluster number given the virtual cluster number and
* the run list describing the mapping between the LCNs and VCNs.
* Return -ERRNO on error (ERRNO being the error number) and notably -NOENT
* if vcn is outside the boundaries covered by the run list. */
__s64 vcn_to_lcn(run_list rl, __s64 vcn);
/* Set the volume flags in the Mft record b to flags.
* Return 1 on success or 0 on error. */
int set_ntfs_volume_flags(MFT_RECORD_HEADER *b, __u16 flags);
/* Get the location of the desired attribute of type t and name n (n can be
* NULL for unnamed attributes; note that n is a Unicode string). Return a
* pointer to the attribute or NULL if the attribute is not present or an
* error situation exists. */
ATTRIBUTE_RECORD_HEADER *find_attribute(MFT_RECORD_HEADER *b, ATTRIBUTE_TYPE t,
wchar_t *n);
#include "volume.h"
__u64 get_attribute_value_length(ATTRIBUTE_RECORD_HEADER *a);
/* Make a copy of the attribute value of the attribute a into the destination
* buffer b. Note that the size of b has to be at least equal to the value
* returned by get_attribute_value_length(a).
* Return number of bytes copied. If this is zero check errno. If errno is 0
* then nothing was read due to a zero-length attribute value, otherwise
* errno describes the error. */
__u64 get_attribute_value(ntfs_volume *vol, ATTRIBUTE_RECORD_HEADER *a, __u8 *b);
int set_attribute_value(ntfs_volume *vol, ATTRIBUTE_RECORD_HEADER *a,
unsigned char *b, __u64 l);
#endif /* defined ATTRIB_H */
--- NEW FILE ---
/*
* endians.h - Definitions related to handling of byte ordering. Part of the
* Linux-NTFS project.
*
* Copyright (c) 2000,2001 Anton Altaparmakov.
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* 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
* turns out that we do need to use the unaligned access macros on
* architectures requirering aligned memory accesses...
*/
#ifndef ENDIANS_H
#define ENDIANS_H
#include <asm/byteorder.h>
/* Unsigned from LE to CPU conversion. */
#define le16_to_cpu(x) (__u16)__le16_to_cpu((__u16)(x))
#define le32_to_cpu(x) (__u32)__le32_to_cpu((__u32)(x))
#define le64_to_cpu(x) (__u64)__le64_to_cpu((__u64)(x))
#define le16_to_cpup(x) (__u16)__le16_to_cpu(*(__u16*)(x))
#define le32_to_cpup(x) (__u32)__le32_to_cpu(*(__u32*)(x))
#define le64_to_cpup(x) (__u64)__le64_to_cpu(*(__u64*)(x))
/* Signed from LE to CPU conversion. */
#define sle16_to_cpu(x) (__s16)__le16_to_cpu((__s16)(x))
#define sle32_to_cpu(x) (__s32)__le32_to_cpu((__s32)(x))
#define sle64_to_cpu(x) (__s64)__le64_to_cpu((__s64)(x))
#define sle16_to_cpup(x) (__s16)__le16_to_cpu(*(__s16*)(x))
#define sle32_to_cpup(x) (__s32)__le32_to_cpu(*(__s32*)(x))
#define sle64_to_cpup(x) (__s64)__le64_to_cpu(*(__s64*)(x))
/* Unsigned from CPU to LE conversion. */
#define cpu_to_le16(x) (__u16)__cpu_to_le16((__u16)(x))
#define cpu_to_le32(x) (__u32)__cpu_to_le32((__u32)(x))
#define cpu_to_le64(x) (__u64)__cpu_to_le64((__u64)(x))
#define cpu_to_le16p(x) (__u16)__cpu_to_le16(*(__u16*)(x))
#define cpu_to_le32p(x) (__u32)__cpu_to_le32(*(__u32*)(x))
#define cpu_to_le64p(x) (__u64)__cpu_to_le64(*(__u64*)(x))
/* Signed from CPU to LE conversion. */
#define scpu_to_le16(x) (__s16)__cpu_to_le16((__s16)(x))
#define scpu_to_le32(x) (__s32)__cpu_to_le32((__s32)(x))
#define scpu_to_le64(x) (__s64)__cpu_to_le64((__s64)(x))
#define scpu_to_le16p(x) (__s16)__cpu_to_le16(*(__s16*)(x))
#define scpu_to_le32p(x) (__s32)__cpu_to_le32(*(__s32*)(x))
#define scpu_to_le64p(x) (__s64)__cpu_to_le64(*(__s64*)(x))
#endif /* defined ENDIANS_H */
--- NEW FILE ---
/*
* mft.h - Exports for MFT record handling. Part of the Linux-NTFS project.
*
* Copyright (c) 2000,2001 Anton Altaparmakov.
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MFT_H
#define MFT_H
#include "endians.h"
#include "ntfs_rec.h"
#define is_mft_record(x) ( is_file_record(x) )
#define is_mft_recordp(p) ( is_file_recordp(p) )
/*
* These are the so far known MFT_RECORD_* flags which contain information
* about the mft record in which they are present.
*/
typedef enum {
MFT_RECORD_IN_USE = cpu_to_le16(0x0001),
MFT_RECORD_IS_DIRECTORY = cpu_to_le16(0x0002),
} MFT_RECORD_FLAGS;
/*
* mft references (aka file references or file record segment references) are
* used whenever a structure needs to refer to a record in the mft.
*
* A reference consists of the 48-bit index into the mft and the 16-bit
* sequence number used to detect stale references.
*
* The sequence number is a circular counter (skipping 0) describing how many
* times the referenced mft record has been (re)used. This has to match the
* sequence number of the mft record being referenced, otherwise the reference
* is considered stale and removed (FIXME: only ntfsck or the driver itself?).
*
* If the sequence number is zero it is assumed that no sequence number
* consistency checking should be performed.
*
* FIXME: Since inodes are 32-bit as of now, the driver needs to always check
* for high_part being 0 and if not either BUG(), cause a panic() or handle
* the situation in some other way. This shouldn't be a problem as a volume has
* to become HUGE in order to need more than 32 bits worth of mft records.
* Assuming the standard mft records size of 1kb only the records (never mind
* the non-resident attributes, etc.) would require 4Tb of space on their own
* for the first 32 bits worth of records. This is only if some strange person
* doesn't decide to foul play and make the mft sparse which would be a really
* horrible thing to do as it would trash our current driver implementation. )-:
* Do I hear screams "we want 64-bit inodes!" ?!? (-;
*/
typedef union {
struct {
struct {
__u32 low_part; /* Mft record number being referenced split */
__u16 high_part;/* into the low 32-bits and the high 16-bits. */
};
__u16 sequence_number; /* The sequence number, see above. */
};
__u64 mft_reference; /* The whole mft reference as one number. */
} __attribute__ ((__packed__)) MFT_REFERENCE;
/* The mft record header present at the beginning of every record in the mft. */
typedef struct {
/*Ofs*/
/* 0*/ NTFS_RECORD_HEADER ntfs;
/* 8*/ __s64 lsn; /* Log file sequence number for this record. */
/* 16*/ __u16 sequence_number; /* Number of times this mft record has been
reused. (See description for MFT_REFERENCE
above.) NOTE: The increment (skipping zero)
is done when the file is deleted. NOTE: If
this is zero it is left zero. */
/* 18*/ __u16 link_count; /* Number of hard links, i.e. the number of
directory entries referencing this record.
NOTE: When deleting a directory entry we
check the link_count and if it is 1 we
delete the file. Otherwise we delete the
FILENAME_ATTRIBUTE being referenced by the
directory entry from the mft record and
decrement the link_count.
FIXME: Careful with Win32 + DOS names! */
/* 20*/ __u16 attributes_offset;/* Byte offset to the first attribute in this
mft record from the start of the mft record.
NOTE: Must be aligned to 8-byte boundary. */
/* 22*/ __u16 flags; /* Bit array of MFT_RECORD_* flags. When a file
is deleted, the MFT_RECORD_IN_USE flag is
set to zero. */
/* 24*/ __u32 bytes_in_use; /* Number of bytes used in this mft record.
NOTE: Must be aligned to 8-byte boundary. */
/* 28*/ __u32 bytes_allocated; /* Number of bytes allocated for this mft
record. This should be equal to the mft
record size. */
/* 32*/ __u64 base_file_record; /* This is zero for base mft records. When it
is not zero it is a mft reference pointing
to the base mft record to which this record
belongs (this is then used to locate the
attribute list attribute present in the base
record which describes the extension record
and hence might need modification when the
extension record itself is modified). */
/* 40*/ __u16 next_attribute_instance; /* The instance number that will be
assigned to the next attribute added to this
mft record. NOTE: incremented each time
after it is used. NOTE: Every time the mft
record is reused this number is set to zero.
NOTE: The first instance number is always 0.
*/
/* 42 = sizeof() */
} __attribute__ ((__packed__)) MFT_RECORD_HEADER;
/**
* get_mft_record_data_size - return number of bytes used in mft record @b
* @b: the mft record to get the data size of
*
* Takes the mft record @b and returns the number of bytes used in the record
* or 0 on error (i.e. b is not a valid mft record). Zero is not a valid size
* for an mft record as it at least has to have the MFT_RECORD_HEADER thus
* making the minumum size:
* (sizeof(MFT_RECORD_HEADER) + 7) & ~7 + sizeof(ATTRIBUTE_TYPE) = 52 bytes
* Aside: The 8-byte alignment and the 4 bytes for the attribute type are needed
* as each mft record has to have a list of attributes even if it only contains
* the attribute $END which doesn't contain anything else apart from it's type.
* Also, you would expect every mft record to contain an update sequence array
* as well but that could in theory be non-existent (don't know if Windows NTFS
* wouldn't view this as corruption in itself though!).
*/
inline __u32 get_mft_record_data_size(const MFT_RECORD_HEADER *b);
#endif /* defined MFT_H */
--- NEW FILE ---
/*
* ntfs_rec.h - Exports for NTFS record handling. Part of the Linux-NTFS
* project.
*
* Copyright (c) 2000,2001 Anton Altaparmakov.
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef NTFS_REC_H
#define NTFS_REC_H
#include "endians.h"
/*
* Magic identifiers present at the beginning of all ntfs record containing
* records (like mft records for example.
*/
typedef enum {
magic_BAAD = cpu_to_le32(0x44414142), /* "BAAD" == corrupt record */
magic_CHKD = cpu_to_le32(0x424b4843), /* "CHKD" == chkdsk ??? */
magic_FILE = cpu_to_le32(0x454c4946), /* "FILE" == mft entry */
magic_HOLE = cpu_to_le32(0x454c4f48), /* "HOLE" == ??? (NTFS 3.0+?) */
magic_INDX = cpu_to_le32(0x58444e49), /* "INDX" == index buffer */
} NTFS_RECORD_TYPES;
/*
* Generic magic comparison macros. Finally found a use for the ## preprocessor
* operator! (-8
*/
#define is_magic(x, m) ( (__u32)(x) == magic_##m )
#define is_magicp(p, m) ( *(__u32*)(p) == magic_##m )
/*
* Specialised magic comparison macros.
*/
#define is_baad_record(x) ( is_magic (x, BAAD) )
#define is_baad_recordp(p) ( is_magicp(p, BAAD) )
#define is_chkd_record(x) ( is_magic (x, CHKD) )
#define is_chkd_recordp(p) ( is_magicp(p, CHKD) )
#define is_file_record(x) ( is_magic (x, FILE) )
#define is_file_recordp(p) ( is_magicp(p, FILE) )
#define is_hole_record(x) ( is_magic (x, HOLE) )
#define is_hole_recordp(p) ( is_magicp(p, HOLE) )
#define is_indx_record(x) ( is_magic (x, INDX) )
#define is_indx_recordp(p) ( is_magicp(p, INDX) )
/*
* Defines for the NTFS filesystem. Don't want to use BLOCK_SIZE and
* BLOCK_SIZE_BITS from the kernel as that is 1024 and hence too high for us.
*/
#define NTFS_SECTOR_SIZE 512
#define NTFS_SECTOR_SIZE_BITS 9
/*
* The Update Sequence Array (usa) is an array of the __u16 values which belong
* to the end of each sector protected by the update sequence record in which
* this array is contained. Note that the first entry is the Update Sequence
* Number (usn), a cyclic counter of how many times the protected record has
* been written to disk. (The values 0 and -1 (ie. 0xffff) are not used.) All
* last __u16's of each sector have to be equal to the Usn (during reading) or
* are set to it (during writing). If they are not, an incomplete multi sector
* transfer has occured when the data was written.
*/
typedef struct {
NTFS_RECORD_TYPES magic; /* A four-byte magic identifying the record
type and/or status. */
__u16 usa_ofs; /* Offset to the Update Sequence Array (usa)
from the start of the ntfs record. */
__u16 usa_count; /* Number of __u16 sized entries in the usa
including the Update Sequence Number (usn),
thus the number of fixups is the usa_count
minus 1. */
} __attribute__ ((__packed__)) NTFS_RECORD_HEADER;
/**
* post_read_mst_fixup - deprotect multi sector transfer protected data
* @b: pinter to the data to deprotect
* @size: size in bytes of @b
*
* Perform the necessary post read multi sector transfer fixup and detect the
* presence of incomplete multi sector transfers. - In that case, overwrite the
* magic of the ntfs record header being processed with "BAAD" (in memory only!)
* and abort processing.
* Return 1 on success and 0 on error ("BAAD" magic will be present).
* NOTE: We consider the absence / invalidity of an update sequence array to
* mean that the structure is not protected at all and hence doesn't need to
* be fixed up. Thus, we return success and not failure in this case.
*/
int post_read_mst_fixup(NTFS_RECORD_HEADER *b, const __u32 size);
/**
* pre_write_mst_fixup - apply multi sector transfer protection
* @b: pointer to the data to protect
* @size: size in bytes of @b
*
* Perform the necessary pre write multi sector transfer fixup on the data
* pointer to by @b of @size.
* Return 1 if fixup applied (success) or 0 if no fixup was performed
* (assumed not needed).
* NOTE: We consider the absence / invalidity of an update sequence array to
* mean that the structure is not subject to protection and hence doesn't need
* to be fixed up. This means that you have to create a valid update sequence
* array header in the ntfs record before calling this function, otherwise it
* will fail and return 0 (the header needs to contain the position of the
* update seqeuence array together with the number of elements in the array).
* You also need to initialise the update sequence number before calling this
* function otherwise a random word will be used (whatever was in the record
* at that position at that time).
*/
int pre_write_mst_fixup(NTFS_RECORD_HEADER *b, const __u32 size);
#endif /* defined NTFS_REC_H */
--- NEW FILE ---
/*
* volume.h - Exports for NTFS volume handling. Part of the Linux-NTFS project.
*
* Copyright (c) 2000,2001 Anton Altaparmakov.
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef VOLUME_H
#define VOLUME_H
#include "attrib.h"
/*
* FIXME: We should have a volume lock at some point (possibly a spinlock?) for
* the volume structure also a lock for major modifications, much like the big
* kernel lock. These two locks could be one and the same. Later on, we in
* addition, will need finer grained locks to lock individual structures and
* structure elements like the lcn_bitmap, mft_bitmap, etc. These locks will
* need to protect operations like changing a directory, a mft record, etc.
*/
/*
* FIXME: Do we really want to return a pointer to the actual volume structure
* to the user to play with? It would be better to completely abstract the
* structure and provide functions for accessing the public members instead.
* In that case we would return a volume descriptor to the caller.
*
* DECISION: Return the actual structure. In the second release, once
* everything is working, we still have the option of abstracting the volume
* strcture data type.
*/
/*
* FIXME: For RAID stuff will need the fd and dev_name variables to be arrays
* or lists or something... Also will need to know the number of sectors (and
* sector size if not 512) of each device making up the RAID array. Obviously,
* will need RAID information as well like which RAID is used together with
* state information, etc. But that is the far future.
*/
/* The ntfs volume structure describing an open volume. */
typedef struct {
int fd; /* File descriptor associated with volume. */
char *dev_name; /* Name of the device the volume is on. */
char *vol_name; /* Name of the volume from the volume name
attribute. */
/* Version nos. and flags are from the volume information attribute. */
__u8 major_ver; /* Ntfs major version of volume. */
__u8 minor_ver; /* Ntfs minor version of volume. */
__u16 flags; /* Bit array of VOLUME_* flags. */
__s64 number_of_clusters;/* Volume size in clusters, hence also the
number of bits in lcn_bitmap. */
__u32 cluster_size; /* Byte size of a cluster. */
__u32 mft_record_size; /* Byte size of a mft record. */
__s64 mft_lcn; /* Logical cluster number of the data attribute
for FILE_$Mft. */
__s64 mft_mirr_lcn; /* Logical cluster number of the data attribute
for FILE_$MftMirr. */
__u8 cluster_size_bits; /* Log(2) of the byte size of a cluster. */
__u8 mft_record_size_bits;/* Log(2) of the byte size of a mft record. */
__u8 *lcn_bitmap; /* Value of data attribute of FILE_$Bitmap. Each
bit represents a cluster on the volume, bit 0
representing lcn 0 and so on. A set bit means
that the cluster is in use and a zero bit
means the cluster is free. */
__u8 *mft_bitmap; /* Value of bitmap attribute of FILE_$Mft. Has
same interpretation as the lcn_bitmap above
but except that it keeps track of the usage
of the mft recoreds rather than the lcns. */
run_list mft_runlist; /* Decompressed run list of the data attribute
of FILE_$Mft. */
__s64 number_of_mft_records; /* Number of records in the mft, equals
the number of bits in mft_bitmap. */
__u16 *up_case[65536]; /* Upper case equivalents of all 65536
2-byte Unicode characters. Obtained
from FILE_$UpCase. */
__u8 mft_records_per_cluster; /* The number of mft records that fit
into one cluster or 0 if clusters
are smaller than mft records. */
__u8 clusters_per_mft_record; /* The size of a mft record in clusters
or 0 if a mft record is smaller than
a cluster. */
} ntfs_volume;
/**
* ntfs_open - open ntfs volume
* @dev_name: name of device to open
*
* This function opens an ntfs volume. @dev_name should contain the name
* of the device to open as the ntfs volume.
*
* The function opens the device @dev_name and verifies that it contains a
* valid bootsector. Then, it allocates a ntfs_volume structure and initializes
* some of the values inside the structure from the information stored in the
* bootsector. It proceeds to load the necessary system files and completes
* setting up the structure.
*
* ntfs_open() returns a pointer to the allocated ntfs_volume structure.
* On error, the return value is NULL and errno is set appropriately.
*
* Note, that a copy is made of @dev_name, and hence it can be discarded as
* soon as the function returns.
*
* FIXME: Should document all error codes that can be returned and what each
* means.
*/
ntfs_volume *ntfs_open(char *dev_name);
/**
* ntfs_close - close ntfs volume
* @vol: address of ntfs_volume structure of volume to close
* @force: if true force close the volume even if it is busy
*
* Flush buffers, close all files and deallocate all structures (including @vol
* itself) associated with the ntfs volume @vol.
*
* Return 1 on success. On error return zero with errno set appropriately (most
* likely to one of -EAGAIN, -EBUSY or -EINVAL). The -EAGAIN error means that
* an operation is in progress and if you try the close later the operation
* might be completed and the close succeed.
*
* If @force is true (i.e. not zero) this function will close the volume even
* if this means that data might be lost. In this case the function always
* returns 1.
*
* @vol must have previously been returned by a call to ntfs_open().
*
* @vol itself is deallocated and should no longer be referenced after this
* function returns success. If it returns an error then nothing has been done
* so it is safe to continue using @vol.
*
* FIXME: Should document all error codes that can be returned and what each
* means.
*/
int ntfs_close(ntfs_volume *vol, int force);
#endif /* defined VOLUME_H */
|