mirror of
https://github.com/reactos/reactos.git
synced 2024-09-06 10:52:52 +00:00
290 lines
9 KiB
C
290 lines
9 KiB
C
#include <ntddk.h>
|
|
#include <ntifs.h>
|
|
|
|
BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
|
IN ULONG DiskSector,
|
|
IN ULONG SectorCount,
|
|
IN PVOID Buffer);
|
|
|
|
#define BLOCKSIZE (1024)
|
|
|
|
struct ext2_super_block {
|
|
ULONG s_inodes_count; /* Inodes count */
|
|
ULONG s_blocks_count; /* Blocks count */
|
|
ULONG s_r_blocks_count; /* Reserved blocks count */
|
|
ULONG s_free_blocks_count; /* Free blocks count */
|
|
ULONG s_free_inodes_count; /* Free inodes count */
|
|
ULONG s_first_data_block; /* First Data Block */
|
|
ULONG s_log_block_size; /* Block size */
|
|
LONG s_log_frag_size; /* Fragment size */
|
|
ULONG s_blocks_per_group; /* # Blocks per group */
|
|
ULONG s_frags_per_group; /* # Fragments per group */
|
|
ULONG s_inodes_per_group; /* # Inodes per group */
|
|
ULONG s_mtime; /* Mount time */
|
|
ULONG s_wtime; /* Write time */
|
|
USHORT s_mnt_count; /* Mount count */
|
|
SHORT s_max_mnt_count; /* Maximal mount count */
|
|
USHORT s_magic; /* Magic signature */
|
|
USHORT s_state; /* File system state */
|
|
USHORT s_errors; /* Behaviour when detecting errors */
|
|
USHORT s_minor_rev_level; /* minor revision level */
|
|
ULONG s_lastcheck; /* time of last check */
|
|
ULONG s_checkinterval; /* max. time between checks */
|
|
ULONG s_creator_os; /* OS */
|
|
ULONG s_rev_level; /* Revision level */
|
|
USHORT s_def_resuid; /* Default uid for reserved blocks */
|
|
USHORT s_def_resgid; /* Default gid for reserved blocks */
|
|
/*
|
|
* These fields are for EXT2_DYNAMIC_REV superblocks only.
|
|
*
|
|
* Note: the difference between the compatible feature set and
|
|
* the incompatible feature set is that if there is a bit set
|
|
* in the incompatible feature set that the kernel doesn't
|
|
* know about, it should refuse to mount the filesystem.
|
|
*
|
|
* e2fsck's requirements are more strict; if it doesn't know
|
|
* about a feature in either the compatible or incompatible
|
|
* feature set, it must abort and not try to meddle with
|
|
* things it doesn't understand...
|
|
*/
|
|
ULONG s_first_ino; /* First non-reserved inode */
|
|
USHORT s_inode_size; /* size of inode structure */
|
|
USHORT s_block_group_nr; /* block group # of this superblock */
|
|
ULONG s_feature_compat; /* compatible feature set */
|
|
ULONG s_feature_incompat; /* incompatible feature set */
|
|
ULONG s_feature_ro_compat; /* readonly-compatible feature set */
|
|
ULONG s_reserved[230]; /* Padding to the end of the block */
|
|
};
|
|
|
|
/*
|
|
* Codes for operating systems
|
|
*/
|
|
#define EXT2_OS_LINUX 0
|
|
#define EXT2_OS_HURD 1
|
|
#define EXT2_OS_MASIX 2
|
|
#define EXT2_OS_FREEBSD 3
|
|
#define EXT2_OS_LITES 4
|
|
|
|
/*
|
|
* Revision levels
|
|
*/
|
|
#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
|
|
#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
|
|
|
|
#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
|
|
#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
|
|
|
|
/*
|
|
* The second extended file system magic number
|
|
*/
|
|
#define EXT2_SUPER_MAGIC 0xEF53
|
|
|
|
/*
|
|
* Constants relative to the data blocks
|
|
*/
|
|
#define EXT2_NDIR_BLOCKS 12
|
|
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
|
|
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
|
|
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
|
|
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
|
|
|
|
|
|
/*
|
|
* Structure of an inode on the disk
|
|
*/
|
|
struct ext2_inode {
|
|
USHORT i_mode; /* File mode */
|
|
USHORT i_uid; /* Owner Uid */
|
|
ULONG i_size; /* Size in bytes */
|
|
ULONG i_atime; /* Access time */
|
|
ULONG i_ctime; /* Creation time */
|
|
ULONG i_mtime; /* Modification time */
|
|
ULONG i_dtime; /* Deletion Time */
|
|
USHORT i_gid; /* Group Id */
|
|
USHORT i_links_count; /* Links count */
|
|
ULONG i_blocks; /* Blocks count */
|
|
ULONG i_flags; /* File flags */
|
|
union {
|
|
struct {
|
|
ULONG l_i_reserved1;
|
|
} linux1;
|
|
struct {
|
|
ULONG h_i_translator;
|
|
} hurd1;
|
|
struct {
|
|
ULONG m_i_reserved1;
|
|
} masix1;
|
|
} osd1; /* OS dependent 1 */
|
|
ULONG i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
|
|
ULONG i_version; /* File version (for NFS) */
|
|
ULONG i_file_acl; /* File ACL */
|
|
ULONG i_dir_acl; /* Directory ACL */
|
|
ULONG i_faddr; /* Fragment address */
|
|
union {
|
|
struct {
|
|
UCHAR l_i_frag; /* Fragment number */
|
|
UCHAR l_i_fsize; /* Fragment size */
|
|
USHORT i_pad1;
|
|
ULONG l_i_reserved2[2];
|
|
} linux2;
|
|
struct {
|
|
UCHAR h_i_frag; /* Fragment number */
|
|
UCHAR h_i_fsize; /* Fragment size */
|
|
USHORT h_i_mode_high;
|
|
USHORT h_i_uid_high;
|
|
USHORT h_i_gid_high;
|
|
ULONG h_i_author;
|
|
} hurd2;
|
|
struct {
|
|
UCHAR m_i_frag; /* Fragment number */
|
|
UCHAR m_i_fsize; /* Fragment size */
|
|
USHORT m_pad1;
|
|
ULONG m_i_reserved2[2];
|
|
} masix2;
|
|
} osd2; /* OS dependent 2 */
|
|
};
|
|
|
|
#if defined(__KERNEL__) || defined(__linux__)
|
|
#define i_reserved1 osd1.linux1.l_i_reserved1
|
|
#define i_frag osd2.linux2.l_i_frag
|
|
#define i_fsize osd2.linux2.l_i_fsize
|
|
#define i_reserved2 osd2.linux2.l_i_reserved2
|
|
#endif
|
|
|
|
#ifdef __hurd__
|
|
#define i_translator osd1.hurd1.h_i_translator
|
|
#define i_frag osd2.hurd2.h_i_frag;
|
|
#define i_fsize osd2.hurd2.h_i_fsize;
|
|
#define i_uid_high osd2.hurd2.h_i_uid_high
|
|
#define i_gid_high osd2.hurd2.h_i_gid_high
|
|
#define i_author osd2.hurd2.h_i_author
|
|
#endif
|
|
|
|
#ifdef __masix__
|
|
#define i_reserved1 osd1.masix1.m_i_reserved1
|
|
#define i_frag osd2.masix2.m_i_frag
|
|
#define i_fsize osd2.masix2.m_i_fsize
|
|
#define i_reserved2 osd2.masix2.m_i_reserved2
|
|
#endif
|
|
|
|
/*
|
|
* Constants relative to the data blocks
|
|
*/
|
|
#define EXT2_NDIR_BLOCKS 12
|
|
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
|
|
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
|
|
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
|
|
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
|
|
|
|
/*
|
|
* Inode flags
|
|
*/
|
|
#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
|
|
#define EXT2_UNRM_FL 0x00000002 /* Undelete */
|
|
#define EXT2_COMPR_FL 0x00000004 /* Compress file */
|
|
#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
|
|
#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
|
|
#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
|
|
#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
|
|
#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
|
|
|
|
|
|
/*
|
|
* Structure of a blocks group descriptor
|
|
*/
|
|
struct ext2_group_desc
|
|
{
|
|
ULONG bg_block_bitmap; /* Blocks bitmap block */
|
|
ULONG bg_inode_bitmap; /* Inodes bitmap block */
|
|
ULONG bg_inode_table; /* Inodes table block */
|
|
USHORT bg_free_blocks_count; /* Free blocks count */
|
|
USHORT bg_free_inodes_count; /* Free inodes count */
|
|
USHORT bg_used_dirs_count; /* Directories count */
|
|
USHORT bg_pad;
|
|
ULONG bg_reserved[3];
|
|
};
|
|
|
|
#define EXT2_NAME_LEN 255
|
|
|
|
struct ext2_dir_entry {
|
|
ULONG inode; /* Inode number */
|
|
USHORT rec_len; /* Directory entry length */
|
|
USHORT name_len; /* Name length */
|
|
char name[EXT2_NAME_LEN]; /* File name */
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
PDEVICE_OBJECT StorageDevice;
|
|
struct ext2_super_block* superblock;
|
|
PFILE_OBJECT FileObject;
|
|
PBCB Bcb;
|
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
|
|
|
typedef struct _EXT2_GROUP_DESC
|
|
{
|
|
ERESOURCE Lock;
|
|
struct ext2_group_desc* desc;
|
|
PCACHE_SEGMENT CacheSeg;
|
|
PVOID BaseAddress;
|
|
} EXT2_GROUP_DESC, *PEXT2_GROUP_DESC;
|
|
|
|
PEXT2_GROUP_DESC Ext2LoadGroup(PDEVICE_EXTENSION DeviceExt,
|
|
ULONG BlockGrp);
|
|
VOID Ext2ReleaseGroup(PDEVICE_EXTENSION DeviceExt,
|
|
PEXT2_GROUP_DESC GrpDesc);
|
|
|
|
VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
|
|
ULONG ino,
|
|
struct ext2_inode* inode);
|
|
struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
|
|
ULONG block_group);
|
|
|
|
typedef struct _EXT2_INODE
|
|
{
|
|
struct ext2_inode* inode;
|
|
PVOID BaseAddress;
|
|
PCACHE_SEGMENT CacheSeg;
|
|
} EXT2_INODE, *PEXT2_INODE;
|
|
|
|
typedef struct _EXT2_FCB
|
|
{
|
|
ULONG inode;
|
|
EXT2_INODE i;
|
|
PBCB Bcb;
|
|
} EXT2_FCB, *PEXT2_FCB;
|
|
|
|
ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,
|
|
struct ext2_inode* inode,
|
|
ULONG offset);
|
|
NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|
PWSTR FileName);
|
|
NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
|
|
PFILE_OBJECT FileObject,
|
|
PVOID Buffer,
|
|
ULONG Length,
|
|
LARGE_INTEGER Offset);
|
|
NTSTATUS STDCALL Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2QueryQuota(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2SetQuota(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2SetSecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2QuerySecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2SetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2QueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2Cleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2FlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS STDCALL Ext2Shutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
NTSTATUS Ext2ReadPage(PDEVICE_EXTENSION DeviceExt,
|
|
PEXT2_FCB Fcb,
|
|
PVOID Buffer,
|
|
ULONG Offset);
|
|
VOID Ext2LoadInode(PDEVICE_EXTENSION DeviceExt,
|
|
ULONG ino,
|
|
PEXT2_INODE Inode);
|
|
VOID Ext2ReleaseInode(PDEVICE_EXTENSION DeviceExt,
|
|
PEXT2_INODE Inode);
|
|
|