Bring back ext2 code from branch
authorHervé Poussineau <hpoussin@reactos.org>
Mon, 11 Feb 2008 12:10:35 +0000 (12:10 +0000)
committerHervé Poussineau <hpoussin@reactos.org>
Mon, 11 Feb 2008 12:10:35 +0000 (12:10 +0000)
It does not compile yet

svn path=/trunk/; revision=32283

43 files changed:
1  2 
reactos/drivers/filesystems/ext2/ext2fs.rc
reactos/drivers/filesystems/ext2/inc/errmsg.h
reactos/drivers/filesystems/ext2/inc/ext2_fs.h
reactos/drivers/filesystems/ext2/inc/ext2fsd.h
reactos/drivers/filesystems/ext2/inc/ext2metadata.h
reactos/drivers/filesystems/ext2/inc/protos.h
reactos/drivers/filesystems/ext2/inc/resource.h
reactos/drivers/filesystems/ext2/inc/struct.h
reactos/drivers/filesystems/ext2/src/DiskIO.c
reactos/drivers/filesystems/ext2/src/cleanup.c
reactos/drivers/filesystems/ext2/src/close.c
reactos/drivers/filesystems/ext2/src/create.c
reactos/drivers/filesystems/ext2/src/devcntrl.c
reactos/drivers/filesystems/ext2/src/dircntrl.c
reactos/drivers/filesystems/ext2/src/ext2.rc
reactos/drivers/filesystems/ext2/src/ext2init.c
reactos/drivers/filesystems/ext2/src/fastio.c
reactos/drivers/filesystems/ext2/src/fileinfo.c
reactos/drivers/filesystems/ext2/src/flush.c
reactos/drivers/filesystems/ext2/src/fsctrl.c
reactos/drivers/filesystems/ext2/src/io.c
reactos/drivers/filesystems/ext2/src/metadata.c
reactos/drivers/filesystems/ext2/src/misc.c
reactos/drivers/filesystems/ext2/src/read.c
reactos/drivers/filesystems/ext2/src/shutdown.c
reactos/drivers/filesystems/ext2/src/volinfo.c
reactos/drivers/filesystems/ext2/src/write.c
reactos/drivers/filesystems/fs_rec/ext2.c
reactos/include/reactos/libs/fslib/ext2lib.h
reactos/lib/fslib/ext2lib/Badblock.c
reactos/lib/fslib/ext2lib/Bitmap.c
reactos/lib/fslib/ext2lib/Bitmap.h
reactos/lib/fslib/ext2lib/Disk.c
reactos/lib/fslib/ext2lib/Disk.h
reactos/lib/fslib/ext2lib/Group.c
reactos/lib/fslib/ext2lib/Inode.c
reactos/lib/fslib/ext2lib/Memory.c
reactos/lib/fslib/ext2lib/Mke2fs.c
reactos/lib/fslib/ext2lib/Mke2fs.h
reactos/lib/fslib/ext2lib/Super.c
reactos/lib/fslib/ext2lib/Uuid.c
reactos/lib/fslib/ext2lib/ext2_fs.h
reactos/lib/fslib/ext2lib/types.h

index 0000000,0000000..0cbc172
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++/* $Id: ext2fs.rc 12852 2005-01-06 13:58:04Z mf $ */
++
++#define REACTOS_VERSION_DLL
++#define REACTOS_STR_FILE_DESCRIPTION  "Linux ext2 IFS Driver\0"
++#define REACTOS_STR_INTERNAL_NAME     "ext2fs\0"
++#define REACTOS_STR_ORIGINAL_FILENAME "ext2fs.sys\0"
++#include <reactos/version.rc>
index 0000000,0000000..8f8ac96
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,68 @@@
++/*************************************************************************
++*
++* File:               errmsg.msg
++*
++* Product:            Ext2 FSD
++*
++* Module:             Ext2 FSD Event Log Messages
++*
++* Description:
++*     Contains error strings in a format understandable to the message compiler.
++*     Please compile (using mc) with the -c option which will set the
++*     "Customer" bit in all errors.
++*     Use values beginning at 0xA000 (e.g. 0xA001) for the Ext2 FSD
++*     errors.
++*     Do NOT use %1 for insertion strings. The I/O manager assumes that
++*     the first insertion string is the name of the driver/device.
++*
++*
++*************************************************************************/
++//
++//  Values are 32 bit values layed out as follows:
++//
++//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
++//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
++//  +---+-+-+-----------------------+-------------------------------+
++//  |Sev|C|R|     Facility          |               Code            |
++//  +---+-+-+-----------------------+-------------------------------+
++//
++//  where
++//
++//      Sev - is the severity code
++//
++//          00 - Success
++//          01 - Informational
++//          10 - Warning
++//          11 - Error
++//
++//      C - is the Customer code flag
++//
++//      R - is a reserved bit
++//
++//      Facility - is the facility code
++//
++//      Code - is the facility's status code
++//
++//
++// Define the facility codes
++//
++
++
++//
++// Define the severity codes
++//
++#define STATUS_SEVERITY_WARNING          0x2
++#define STATUS_SEVERITY_SUCCESS          0x0
++#define STATUS_SEVERITY_INFORMATIONAL    0x1
++#define STATUS_SEVERITY_ERROR            0x3
++
++
++//
++// MessageId: EXT2_ERROR_INTERNAL_ERROR
++//
++// MessageText:
++//
++//  The Ext2 FSD encountered an internal error. Please check log data information.
++//
++#define EXT2_ERROR_INTERNAL_ERROR        ((ULONG)0xE004A001L)
++
index 0000000,0000000..4a545d4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,615 @@@
++/*
++ *  linux/include/linux/ext2_fs.h
++ *
++ * Copyright (C) 1992, 1993, 1994, 1995
++ * Remy Card (card@masi.ibp.fr)
++ * Laboratoire MASI - Institut Blaise Pascal
++ * Universite Pierre et Marie Curie (Paris VI)
++ *
++ *  from
++ *
++ *  linux/include/linux/minix_fs.h
++ *
++ *  Copyright (C) 1991, 1992  Linus Torvalds
++ */
++
++#ifndef _LINUX_EXT2_FS_H
++#define _LINUX_EXT2_FS_H
++
++//    #include <linux/types.h>
++
++/*
++ * The second extended filesystem constants/structures
++ */
++
++
++/*
++ * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
++ */
++#define EXT2_PREALLOCATE
++#define EXT2_DEFAULT_PREALLOC_BLOCKS  8
++
++/*
++ * The second extended file system version
++ */
++#define EXT2FS_DATE           "95/08/09"
++#define EXT2FS_VERSION                "0.5b"
++
++/*
++ * Debug code
++ */
++
++/*
++ * Special inodes numbers
++ */
++#define       EXT2_BAD_INO             1      /* Bad blocks inode */
++#define EXT2_ROOT_INO          2      /* Root inode */
++#define EXT2_ACL_IDX_INO       3      /* ACL inode */
++#define EXT2_ACL_DATA_INO      4      /* ACL inode */
++#define EXT2_BOOT_LOADER_INO   5      /* Boot loader inode */
++#define EXT2_UNDEL_DIR_INO     6      /* Undelete directory inode */
++
++/* First non-reserved inode for old ext2 filesystems */
++#define EXT2_GOOD_OLD_FIRST_INO       11
++
++/*
++ * The second extended file system magic number
++ */
++#define EXT2_SUPER_MAGIC      0xEF53
++
++/*
++ * Maximal count of links to a file
++ */
++#define EXT2_LINK_MAX         32000
++
++/*
++ * Macro-instructions used to manage several block sizes
++ */
++#define EXT2_MIN_BLOCK_SIZE           1024
++#define       EXT2_MAX_BLOCK_SIZE             4096
++#define EXT2_MIN_BLOCK_LOG_SIZE                 10
++#ifdef __KERNEL__
++# define EXT2_BLOCK_SIZE(s)           ((s)->s_blocksize)
++#else
++# define EXT2_BLOCK_SIZE(s)           (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
++#endif
++#define EXT2_ACLE_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
++#define       EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
++#ifdef __KERNEL__
++# define EXT2_BLOCK_SIZE_BITS(s)      ((s)->s_blocksize_bits)
++#else
++# define EXT2_BLOCK_SIZE_BITS(s)      ((s)->s_log_block_size + 10)
++#endif
++#ifdef __KERNEL__
++#define       EXT2_ADDR_PER_BLOCK_BITS(s)     ((s)->u.ext2_sb.s_addr_per_block_bits)
++#define EXT2_INODE_SIZE(s)            ((s)->u.ext2_sb.s_inode_size)
++#define EXT2_FIRST_INO(s)             ((s)->u.ext2_sb.s_first_ino)
++#else
++#define EXT2_INODE_SIZE(s)    (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
++                               EXT2_GOOD_OLD_INODE_SIZE : \
++                               (s)->s_inode_size)
++#define EXT2_FIRST_INO(s)     (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
++                               EXT2_GOOD_OLD_FIRST_INO : \
++                               (s)->s_first_ino)
++#endif
++
++/*
++ * Macro-instructions used to manage fragments
++ */
++#define EXT2_MIN_FRAG_SIZE            1024
++#define       EXT2_MAX_FRAG_SIZE              4096
++#define EXT2_MIN_FRAG_LOG_SIZE                  10
++#ifdef __KERNEL__
++# define EXT2_FRAG_SIZE(s)            ((s)->u.ext2_sb.s_frag_size)
++# define EXT2_FRAGS_PER_BLOCK(s)      ((s)->u.ext2_sb.s_frags_per_block)
++#else
++# define EXT2_FRAG_SIZE(s)            (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
++# define EXT2_FRAGS_PER_BLOCK(s)      (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
++#endif
++
++/*
++ * ACL structures
++ */
++struct ext2_acl_header        /* Header of Access Control Lists */
++{
++      __u32   aclh_size;
++      __u32   aclh_file_count;
++      __u32   aclh_acle_count;
++      __u32   aclh_first_acle;
++};
++
++struct ext2_acl_entry /* Access Control List Entry */
++{
++      __u32   acle_size;
++      __u16   acle_perms;     /* Access permissions */
++      __u16   acle_type;      /* Type of entry */
++      __u16   acle_tag;       /* User or group identity */
++      __u16   acle_pad1;
++      __u32   acle_next;      /* Pointer on next entry for the */
++                                      /* same inode or on next free entry */
++};
++
++/*
++ * Structure of a blocks group descriptor
++ */
++struct ext2_group_desc
++{
++      __u32   bg_block_bitmap;                /* Blocks bitmap block */
++      __u32   bg_inode_bitmap;                /* Inodes bitmap block */
++      __u32   bg_inode_table;         /* Inodes table block */
++      __u16   bg_free_blocks_count;   /* Free blocks count */
++      __u16   bg_free_inodes_count;   /* Free inodes count */
++      __u16   bg_used_dirs_count;     /* Directories count */
++      __u16   bg_pad;
++      __u32   bg_reserved[3];
++};
++
++/*
++ * Macro-instructions used to manage group descriptors
++ */
++#ifdef __KERNEL__
++# define EXT2_BLOCKS_PER_GROUP(s)     ((s)->u.ext2_sb.s_blocks_per_group)
++# define EXT2_DESC_PER_BLOCK(s)               ((s)->u.ext2_sb.s_desc_per_block)
++# define EXT2_INODES_PER_GROUP(s)     ((s)->u.ext2_sb.s_inodes_per_group)
++# define EXT2_DESC_PER_BLOCK_BITS(s)  ((s)->u.ext2_sb.s_desc_per_block_bits)
++#else
++# define EXT2_BLOCKS_PER_GROUP(s)     ((s)->s_blocks_per_group)
++# define EXT2_DESC_PER_BLOCK(s)               (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
++# define EXT2_INODES_PER_GROUP(s)     ((s)->s_inodes_per_group)
++#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_NOATIME_FL                       0x00000080 /* do not update atime */
++/* Reserved for compression usage... */
++#define EXT2_DIRTY_FL                 0x00000100
++#define EXT2_COMPRBLK_FL              0x00000200 /* One or more compressed clusters */
++#define EXT2_NOCOMP_FL                        0x00000400 /* Don't compress */
++#define EXT2_ECOMPR_FL                        0x00000800 /* Compression error */
++/* End compression flags --- maybe not all used */    
++#define EXT2_BTREE_FL                 0x00001000 /* btree format dir */
++#define EXT2_RESERVED_FL              0x80000000 /* reserved for ext2 lib */
++
++#define EXT2_FL_USER_VISIBLE          0x00001FFF /* User visible flags */
++#define EXT2_FL_USER_MODIFIABLE               0x000000FF /* User modifiable flags */
++
++/*
++ * ioctl commands
++ */
++#define       EXT2_IOC_GETFLAGS               _IOR('f', 1, long)
++#define       EXT2_IOC_SETFLAGS               _IOW('f', 2, long)
++#define       EXT2_IOC_GETVERSION             _IOR('v', 1, long)
++#define       EXT2_IOC_SETVERSION             _IOW('v', 2, long)
++
++/*
++ * Structure of an inode on the disk
++ */
++struct ext2_inode {
++      __u16   i_mode;         /* File mode */
++      __u16   i_uid;          /* Low 16 bits of Owner Uid */
++      __u32   i_size;         /* Size in bytes */
++      __u32   i_atime;        /* Access time */
++      __u32   i_ctime;        /* Creation time */
++      __u32   i_mtime;        /* Modification time */
++      __u32   i_dtime;        /* Deletion Time */
++      __u16   i_gid;          /* Low 16 bits of Group Id */
++      __u16   i_links_count;  /* Links count */
++      __u32   i_blocks;       /* Blocks count */
++      __u32   i_flags;        /* File flags */
++      union {
++              struct {
++                      __u32  l_i_reserved1;
++              } linux1;
++              struct {
++                      __u32  h_i_translator;
++              } hurd1;
++              struct {
++                      __u32  m_i_reserved1;
++              } masix1;
++      } osd1;                         /* OS dependent 1 */
++      __u32   i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
++      __u32   i_generation;   /* File version (for NFS) */
++      __u32   i_file_acl;     /* File ACL */
++      __u32   i_dir_acl;      /* Directory ACL */
++      __u32   i_faddr;        /* Fragment address */
++      union {
++              struct {
++                      __u8    l_i_frag;       /* Fragment number */
++                      __u8    l_i_fsize;      /* Fragment size */
++                      __u16   i_pad1;
++                      __u16   l_i_uid_high;   /* these 2 fields    */
++                      __u16   l_i_gid_high;   /* were reserved2[0] */
++                      __u32   l_i_reserved2;
++              } linux2;
++              struct {
++                      __u8    h_i_frag;       /* Fragment number */
++                      __u8    h_i_fsize;      /* Fragment size */
++                      __u16   h_i_mode_high;
++                      __u16   h_i_uid_high;
++                      __u16   h_i_gid_high;
++                      __u32   h_i_author;
++              } hurd2;
++              struct {
++                      __u8    m_i_frag;       /* Fragment number */
++                      __u8    m_i_fsize;      /* Fragment size */
++                      __u16   m_pad1;
++                      __u32   m_i_reserved2[2];
++              } masix2;
++      } osd2;                         /* OS dependent 2 */
++};
++
++#define i_size_high   i_dir_acl
++
++#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_uid_low     i_uid
++#define i_gid_low     i_gid
++#define i_uid_high    osd2.linux2.l_i_uid_high
++#define i_gid_high    osd2.linux2.l_i_gid_high
++#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
++
++/*
++ * File system states
++ */
++#define       EXT2_VALID_FS                   0x0001  /* Unmounted cleanly */
++#define       EXT2_ERROR_FS                   0x0002  /* Errors detected */
++
++/*
++ * Mount flags
++ */
++#define EXT2_MOUNT_CHECK              0x0001  /* Do mount-time checks */
++#define EXT2_MOUNT_GRPID              0x0004  /* Create files with directory's group */
++#define EXT2_MOUNT_DEBUG              0x0008  /* Some debugging messages */
++#define EXT2_MOUNT_ERRORS_CONT                0x0010  /* Continue on errors */
++#define EXT2_MOUNT_ERRORS_RO          0x0020  /* Remount fs ro on errors */
++#define EXT2_MOUNT_ERRORS_PANIC               0x0040  /* Panic on errors */
++#define EXT2_MOUNT_MINIX_DF           0x0080  /* Mimics the Minix statfs */
++#define EXT2_MOUNT_NO_UID32           0x0200  /* Disable 32-bit UIDs */
++
++#define clear_opt(o, opt)             o &= ~EXT2_MOUNT_##opt
++#define set_opt(o, opt)                       o |= EXT2_MOUNT_##opt
++#define test_opt(sb, opt)             ((sb)->u.ext2_sb.s_mount_opt & \
++                                       EXT2_MOUNT_##opt)
++/*
++ * Maximal mount counts between two filesystem checks
++ */
++#define EXT2_DFL_MAX_MNT_COUNT                20      /* Allow 20 mounts */
++#define EXT2_DFL_CHECKINTERVAL                0       /* Don't use interval check */
++
++/*
++ * Behaviour when detecting errors
++ */
++#define EXT2_ERRORS_CONTINUE          1       /* Continue execution */
++#define EXT2_ERRORS_RO                        2       /* Remount fs read-only */
++#define EXT2_ERRORS_PANIC             3       /* Panic */
++#define EXT2_ERRORS_DEFAULT           EXT2_ERRORS_CONTINUE
++
++/*
++ * Structure of the super block
++ */
++struct ext2_super_block {
++      __u32   s_inodes_count;         /* Inodes count */
++      __u32   s_blocks_count;         /* Blocks count */
++      __u32   s_r_blocks_count;       /* Reserved blocks count */
++      __u32   s_free_blocks_count;    /* Free blocks count */
++      __u32   s_free_inodes_count;    /* Free inodes count */
++      __u32   s_first_data_block;     /* First Data Block */
++      __u32   s_log_block_size;       /* Block size */
++      __s32   s_log_frag_size;        /* Fragment size */
++      __u32   s_blocks_per_group;     /* # Blocks per group */
++      __u32   s_frags_per_group;      /* # Fragments per group */
++      __u32   s_inodes_per_group;     /* # Inodes per group */
++      __u32   s_mtime;                /* Mount time */
++      __u32   s_wtime;                /* Write time */
++      __u16   s_mnt_count;            /* Mount count */
++      __s16   s_max_mnt_count;        /* Maximal mount count */
++      __u16   s_magic;                /* Magic signature */
++      __u16   s_state;                /* File system state */
++      __u16   s_errors;               /* Behaviour when detecting errors */
++      __u16   s_minor_rev_level;      /* minor revision level */
++      __u32   s_lastcheck;            /* time of last check */
++      __u32   s_checkinterval;        /* max. time between checks */
++      __u32   s_creator_os;           /* OS */
++      __u32   s_rev_level;            /* Revision level */
++      __u16   s_def_resuid;           /* Default uid for reserved blocks */
++      __u16   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...
++       */
++      __u32   s_first_ino;            /* First non-reserved inode */
++      __u16   s_inode_size;           /* size of inode structure */
++      __u16   s_block_group_nr;       /* block group # of this superblock */
++      __u32   s_feature_compat;       /* compatible feature set */
++      __u32   s_feature_incompat;     /* incompatible feature set */
++      __u32   s_feature_ro_compat;    /* readonly-compatible feature set */
++      __u8    s_uuid[16];             /* 128-bit uuid for volume */
++      char    s_volume_name[16];      /* volume name */
++      char    s_last_mounted[64];     /* directory where last mounted */
++      __u32   s_algorithm_usage_bitmap; /* For compression */
++      /*
++       * Performance hints.  Directory preallocation should only
++       * happen if the EXT2_COMPAT_PREALLOC flag is on.
++       */
++      __u8    s_prealloc_blocks;      /* Nr of blocks to try to preallocate*/
++      __u8    s_prealloc_dir_blocks;  /* Nr to preallocate for dirs */
++      __u16   s_padding1;
++      __u32   s_reserved[204];        /* Padding to the end of the block */
++};
++
++#ifdef __KERNEL__
++#define EXT2_SB(sb)   (&((sb)->u.ext2_sb))
++#else
++/* Assume that user mode programs are passing in an ext2fs superblock, not
++ * a kernel struct super_block.  This will allow us to call the feature-test
++ * macros from user land. */
++#define EXT2_SB(sb)   (sb)
++#endif
++
++/*
++ * 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
++
++#define EXT2_GOOD_OLD_INODE_SIZE 128
++
++/*
++ * Feature set definitions
++ */
++
++#define EXT2_HAS_COMPAT_FEATURE(sb,mask)                      \
++      ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
++#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)                   \
++      ( EXT2_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
++#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)                    \
++      ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
++#define EXT2_SET_COMPAT_FEATURE(sb,mask)                      \
++      EXT2_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask)
++#define EXT2_SET_RO_COMPAT_FEATURE(sb,mask)                   \
++      EXT2_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask)
++#define EXT2_SET_INCOMPAT_FEATURE(sb,mask)                    \
++      EXT2_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask)
++#define EXT2_CLEAR_COMPAT_FEATURE(sb,mask)                    \
++      EXT2_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask)
++#define EXT2_CLEAR_RO_COMPAT_FEATURE(sb,mask)                 \
++      EXT2_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask)
++#define EXT2_CLEAR_INCOMPAT_FEATURE(sb,mask)                  \
++      EXT2_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask)
++
++#define EXT2_FEATURE_COMPAT_DIR_PREALLOC      0x0001
++
++#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER   0x0001
++#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE     0x0002
++#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR      0x0004
++
++#define EXT2_FEATURE_INCOMPAT_COMPRESSION     0x0001
++#define EXT2_FEATURE_INCOMPAT_FILETYPE                0x0002
++
++#define EXT2_FEATURE_COMPAT_SUPP      0
++#define EXT2_FEATURE_INCOMPAT_SUPP    EXT2_FEATURE_INCOMPAT_FILETYPE
++#define EXT2_FEATURE_RO_COMPAT_SUPP   (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
++                                       EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
++                                       EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
++
++/*
++ * Default values for user and/or group using reserved blocks
++ */
++#define       EXT2_DEF_RESUID         0
++#define       EXT2_DEF_RESGID         0
++
++/*
++ * Structure of a directory entry
++ */
++#define EXT2_NAME_LEN 255
++
++struct ext2_dir_entry {
++      __u32   inode;                  /* Inode number */
++      __u16   rec_len;                /* Directory entry length */
++      __u16   name_len;               /* Name length */
++      char    name[EXT2_NAME_LEN];    /* File name */
++};
++
++/*
++ * The new version of the directory entry.  Since EXT2 structures are
++ * stored in intel byte order, and the name_len field could never be
++ * bigger than 255 chars, it's safe to reclaim the extra byte for the
++ * file_type field.
++ */
++struct ext2_dir_entry_2 {
++      __u32   inode;                  /* Inode number */
++      __u16   rec_len;                /* Directory entry length */
++      __u8    name_len;               /* Name length */
++      __u8    file_type;
++      char    name[EXT2_NAME_LEN];    /* File name */
++};
++
++/*
++ * Ext2 directory file types.  Only the low 3 bits are used.  The
++ * other bits are reserved for now.
++ */
++#define EXT2_FT_UNKNOWN               0
++#define EXT2_FT_REG_FILE      1
++#define EXT2_FT_DIR                   2
++#define EXT2_FT_CHRDEV                3
++#define EXT2_FT_BLKDEV                4
++#define EXT2_FT_FIFO          5
++#define EXT2_FT_SOCK          6
++#define EXT2_FT_SYMLINK               7
++
++#define EXT2_FT_MAX           8
++
++/*
++ * EXT2_DIR_PAD defines the directory entries boundaries
++ *
++ * NOTE: It must be a multiple of 4
++ */
++#define EXT2_DIR_PAD                  4
++#define EXT2_DIR_ROUND                        (EXT2_DIR_PAD - 1)
++#define EXT2_DIR_REC_LEN(name_len)    (((name_len) + 8 + EXT2_DIR_ROUND) & \
++                                       ~EXT2_DIR_ROUND)
++
++#ifdef __KERNEL__
++/*
++ * Function prototypes
++ */
++
++/*
++ * Ok, these declarations are also in <linux/kernel.h> but none of the
++ * ext2 source programs needs to include it so they are duplicated here.
++ */
++# define NORET_TYPE    /**/
++# define ATTRIB_NORET  __attribute__((noreturn))
++# define NORET_AND     noreturn,
++
++/* acl.c */
++extern int ext2_permission (struct inode *, int);
++
++/* balloc.c */
++extern int ext2_bg_has_super(struct super_block *sb, int group);
++extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
++extern int ext2_new_block (struct inode *, unsigned long,
++                         __u32 *, __u32 *, int *);
++extern void ext2_free_blocks (struct inode *, unsigned long,
++                            unsigned long);
++extern unsigned long ext2_count_free_blocks (struct super_block *);
++extern void ext2_check_blocks_bitmap (struct super_block *);
++extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
++                                                  unsigned int block_group,
++                                                  struct buffer_head ** bh);
++
++/* bitmap.c */
++extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
++
++/* dir.c */
++extern int ext2_check_dir_entry (const char *, struct inode *,
++                               struct ext2_dir_entry_2 *, struct buffer_head *,
++                               unsigned long);
++
++/* file.c */
++extern int ext2_read (struct inode *, struct file *, char *, int);
++extern int ext2_write (struct inode *, struct file *, char *, int);
++
++/* fsync.c */
++extern int ext2_sync_file (struct file *, struct dentry *, int);
++extern int ext2_fsync_inode (struct inode *, int);
++
++/* ialloc.c */
++extern struct inode * ext2_new_inode (const struct inode *, int);
++extern void ext2_free_inode (struct inode *);
++extern unsigned long ext2_count_free_inodes (struct super_block *);
++extern void ext2_check_inodes_bitmap (struct super_block *);
++
++/* inode.c */
++
++extern struct buffer_head * ext2_getblk (struct inode *, long, int, int *);
++extern struct buffer_head * ext2_bread (struct inode *, int, int, int *);
++
++extern void ext2_read_inode (struct inode *);
++extern void ext2_write_inode (struct inode *, int);
++extern void ext2_put_inode (struct inode *);
++extern void ext2_delete_inode (struct inode *);
++extern int ext2_sync_inode (struct inode *);
++extern void ext2_discard_prealloc (struct inode *);
++
++/* ioctl.c */
++extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
++                     unsigned long);
++
++/* namei.c */
++extern struct inode_operations ext2_dir_inode_operations;
++
++/* super.c */
++extern void ext2_error (struct super_block *, const char *, const char *, ...)
++      __attribute__ ((format (printf, 3, 4)));
++extern NORET_TYPE void ext2_panic (struct super_block *, const char *,
++                                 const char *, ...)
++      __attribute__ ((NORET_AND format (printf, 3, 4)));
++extern void ext2_warning (struct super_block *, const char *, const char *, ...)
++      __attribute__ ((format (printf, 3, 4)));
++extern void ext2_update_dynamic_rev (struct super_block *sb);
++extern void ext2_put_super (struct super_block *);
++extern void ext2_write_super (struct super_block *);
++extern int ext2_remount (struct super_block *, int *, char *);
++extern struct super_block * ext2_read_super (struct super_block *,void *,int);
++extern int ext2_statfs (struct super_block *, struct statfs *);
++
++/* truncate.c */
++extern void ext2_truncate (struct inode *);
++
++/*
++ * Inodes and files operations
++ */
++
++/* dir.c */
++extern struct file_operations ext2_dir_operations;
++
++/* file.c */
++extern struct inode_operations ext2_file_inode_operations;
++extern struct file_operations ext2_file_operations;
++
++/* symlink.c */
++extern struct inode_operations ext2_fast_symlink_inode_operations;
++
++extern struct address_space_operations ext2_aops;
++
++#endif        /* __KERNEL__ */
++
++#endif        /* _LINUX_EXT2_FS_H */
index 0000000,0000000..81c246d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,250 @@@
++/*************************************************************************
++*
++* File: ext2fsd.h
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     The main include file for the Ext2 file system driver.
++*
++* Author: Manoj Paul Joseph
++*
++*
++*************************************************************************/
++
++
++#ifndef       _EXT2_FSD_H_
++#define       _EXT2_FSD_H_
++
++#define EXT2_POOL_WITH_TAG
++
++
++// some constant definitions
++#define       EXT2_PANIC_IDENTIFIER           (0x86427531)
++
++// any directory information EXT2 obtains from the local file system
++//    will use a buffer of the following size ... (in KB)
++#define       EXT2_READ_DIR_BUFFER_LENGTH     (512)
++#define       EXT2_MAXCLOSABLE_FCBS_UL        20
++#define       EXT2_MAXCLOSABLE_FCBS_LL        10
++
++//    Some type definitions...
++//    These are used later...
++
++typedef unsigned char UCHAR;
++typedef unsigned int  UINT;
++typedef UCHAR                 BYTE;
++typedef UCHAR                 BOOLEAN;        // winnt
++typedef BOOLEAN *             PBOOLEAN;       // winnt
++typedef void *                        PVOID64;                // winnt
++typedef long                  LONG;
++typedef LONG                  HRESULT;
++
++
++#if defined(_M_IX86)
++#define FASTCALL _fastcall
++#else
++#define FASTCALL
++#endif
++
++
++
++// Common include files - should be in the include dir of the MS supplied IFS Kit
++#include      <ntifs.h>
++#include <ntdddisk.h>
++
++
++/* REACTOS FIXME */
++#undef DeleteFile
++/* This is deprecated and should be changed in the EXT2FS driver. */
++#define RtlLargeIntegerLessThan(a, b) (a).QuadPart < (b).QuadPart
++#define RtlLargeIntegerGreaterThan(a, b) (a).QuadPart > (b).QuadPart
++
++
++// the following include files should be in the inc sub-dir associated with this driver
++#include      "ext2metadata.h"
++#include      "struct.h"
++#include      "protos.h"
++#include      "errmsg.h"
++
++
++// global variables - minimize these
++extern Ext2Data                               Ext2GlobalData;
++
++// try-finally simulation
++#define try_return(S) { S; goto try_exit; }
++#define try_return1(S)        { S; goto try_exit1; }
++#define try_return2(S)        { S; goto try_exit2; }
++
++// some global (helpful) macros
++#define Ext2IsFlagOn(Flags,SingleFlag) ((BOOLEAN)((((Flags) & (SingleFlag)) != 0)))
++#define       Ext2SetFlag(Flag, Value)        ((Flag) |= (Value))
++#define       Ext2ClearFlag(Flag, Value)      ((Flag) &= ~(Value))
++
++#define       Ext2QuadAlign(Value)                    ((((uint32)(Value)) + 7) & 0xfffffff8)
++
++// to perform a bug-check (panic), the following macro is used
++#define       Ext2Panic(arg1, arg2, arg3)                                     \
++      (KeBugCheckEx(EXT2_PANIC_IDENTIFIER, EXT2_BUG_CHECK_ID | __LINE__, (uint32)(arg1), (uint32)(arg2), (uint32)(arg3)))
++
++// a convenient macro (must be invoked in the context of the thread that acquired the resource)
++#define       Ext2ReleaseResource(Resource)   \
++      (ExReleaseResourceForThreadLite((Resource), ExGetCurrentResourceThread()))
++
++// each file has a unique bug-check identifier associated with it.
++//    Here is a list of constant definitions for these identifiers
++#define       EXT2_FILE_INIT                                                                  (0x00000001)
++#define       EXT2_FILE_REGISTRY                                                              (0x00000002)
++#define       EXT2_FILE_CREATE                                                                (0x00000003)
++#define       EXT2_FILE_CLEANUP                                                               (0x00000004)
++#define       EXT2_FILE_CLOSE                                                                 (0x00000005)
++#define       EXT2_FILE_READ                                                                  (0x00000006)
++#define       EXT2_FILE_WRITE                                                                 (0x00000007)
++#define       EXT2_FILE_INFORMATION                                                   (0x00000008)
++#define       EXT2_FILE_FLUSH                                                                 (0x00000009)
++#define       EXT2_FILE_VOL_INFORMATION                                               (0x0000000A)
++#define       EXT2_FILE_DIR_CONTROL                                                   (0x0000000B)
++#define       EXT2_FILE_FILE_CONTROL                                                  (0x0000000C)
++#define       EXT2_FILE_DEVICE_CONTROL                                                (0x0000000D)
++#define       EXT2_FILE_SHUTDOWN                                                              (0x0000000E)
++#define       EXT2_FILE_LOCK_CONTROL                                                  (0x0000000F)
++#define       EXT2_FILE_SECURITY                                                              (0x00000010)
++#define       EXT2_FILE_EXT_ATTR                                                              (0x00000011)
++#define       EXT2_FILE_MISC                                                                  (0x00000012)
++#define       EXT2_FILE_FAST_IO                                                               (0x00000013)
++#define       EXT2_FILE_IO                                                                    (0x00000014)
++#define       EXT2_FILE_METADATA_IO                                                   (0x00000015)
++
++
++
++#if DBG
++#define       Ext2BreakPoint()        DbgBreakPoint()
++#else
++#define       Ext2BreakPoint()
++#endif
++
++#define Ext2RaiseStatus(IRPCONTEXT,STATUS)            \
++{                                                                                             \
++    (IRPCONTEXT)->ExceptionStatus = (STATUS); \
++    ExRaiseStatus( (STATUS) );                                        \
++}
++
++#ifdef EXT2_POOL_WITH_TAG
++      #define Ext2AllocatePool(PoolType,NumberOfBytes)        \
++              ExAllocatePoolWithTag( PoolType, NumberOfBytes, '2txE' ) 
++#else
++      #define Ext2AllocatePool(PoolType,NumberOfBytes)        \
++              ExAllocatePool( PoolType, NumberOfBytes ) 
++#endif
++
++
++#if DBG
++
++//
++//    Trace types...
++//    Any number of these may be enabled...
++//
++#define DEBUG_TRACE_IRQL                   (0x00000001)
++#define DEBUG_TRACE_IRP_ENTRY                  (0x00000002)
++#define DEBUG_TRACE_RESOURCE_ACQUIRE     (0x00000004)
++#define DEBUG_TRACE_RESOURCE_RELEASE     (0x00000008)
++#define DEBUG_TRACE_RESOURCE_RETRY             (0x00000010)
++#define DEBUG_TRACE_ASYNC                (0x00000020)
++#define DEBUG_TRACE_MOUNT                (0x00000040)
++#define DEBUG_TRACE_RESOURCE_STATE       (0x00000080)
++#define DEBUG_TRACE_MISC                 (0x00000100)
++#define DEBUG_TRACE_FILE_OBJ             (0x00000200)
++#define DEBUG_TRACE_FILE_NAME            (0x00000400)
++#define DEBUG_TRACE_SPECIAL              (0x00000800)
++#define DEBUG_TRACE_ERROR                              (0x00001000)
++#define DEBUG_TRACE_READ_DETAILS               (0x00002000)
++#define DEBUG_TRACE_WRITE_DETAILS              (0x00004000)
++#define DEBUG_TRACE_FILEINFO                   (0x00008000)
++#define DEBUG_TRACE_DIRINFO                            (0x00010000)
++#define DEBUG_TRACE_REFERENCE                  (0x00020000)
++#define DEBUG_TRACE_FSCTRL                             (0x00040000)
++#define DEBUG_TRACE_FREE                               (0x00080000)
++#define DEBUG_TRACE_LINENO                 (0x00100000)
++#define DEBUG_TRACE_TRIPLE                 (0x00200000)
++
++#define DEBUG_TRACE_ALL                                        (0xffffffff)
++#define DEBUG_TRACE_NONE                                        0
++//
++//    The permitted DebugTrace types...
++//
++#define PERMITTED_DEBUG_TRACE_TYPES           /* DEBUG_TRACE_TRIPLE */ DEBUG_TRACE_ALL
++/*
++#define PERMITTED_DEBUG_TRACE_TYPES           DEBUG_TRACE_ERROR | DEBUG_TRACE_IRP_ENTRY |             \
++                                                                              DEBUG_TRACE_FILE_NAME | DEBUG_TRACE_SPECIAL     |       \
++                                                                              DEBUG_TRACE_ASYNC
++
++*/
++
++
++#define DebugTrace( TYPE, X, Y )                                                                                      \
++{                                                                                                                                                     \
++      if( ( TYPE ) & ( PERMITTED_DEBUG_TRACE_TYPES ) )                                                \
++      {                                                                                                                                               \
++              DbgPrint("\n    ");                                                                                                     \
++              DbgPrint(X,Y);                                                                                                          \
++              if( ( DEBUG_TRACE_IRQL ) & ( PERMITTED_DEBUG_TRACE_TYPES ) )            \
++              {                                                                                                                                       \
++                      DbgPrint( "  IRQL = %d ", KeGetCurrentIrql( ) );                                \
++              }                                                                                                                                       \
++              if( ( DEBUG_TRACE_LINENO ) & ( PERMITTED_DEBUG_TRACE_TYPES ) )          \
++              {                                                                                                                                       \
++                      DbgPrint( "   [%s] Line No = %ld", __FILE__, __LINE__ );                \
++              }                                                                                                                                       \
++      }                                                                                                                                               \
++}
++
++
++#define DebugTraceState( STR, X1, X2, X3)                                                                                                             \
++{                                                                                                                                                                                             \
++      if( ( DEBUG_TRACE_RESOURCE_STATE ) & ( PERMITTED_DEBUG_TRACE_TYPES ) )                                          \
++      {                                                                                                                                                                                       \
++              DbgPrint("\nState: ");                                                                                                                                  \
++              DbgPrint( STR, X1, X2, X3 );                                                                                                                    \
++              if( ( DEBUG_TRACE_IRQL ) & ( PERMITTED_DEBUG_TRACE_TYPES ) )                                                    \
++              {                                                                                                                                                                               \
++                      DbgPrint( "  IRQL = %d ", KeGetCurrentIrql( ) );                                                                        \
++              }                                                                                                                                                                               \
++      }                                                                                                                                                                                       \
++}
++
++#define AssertFCB( PtrFCB )                                                                                                           \
++{                                                                                                                                                             \
++      if( !(PtrFCB) || (PtrFCB)->NodeIdentifier.NodeType != EXT2_NODE_TYPE_FCB )      \
++      {                                                                                                                                                       \
++              Ext2BreakPoint();                                                                                                               \
++      }                                                                                                                                                       \
++}
++
++#define AssertVCB( PtrVCB )                                                                                                           \
++{                                                                                                                                                             \
++      if( !(PtrVCB) || (PtrVCB)->NodeIdentifier.NodeType != EXT2_NODE_TYPE_VCB )      \
++      {                                                                                                                                                       \
++              Ext2BreakPoint();                                                                                                               \
++      }                                                                                                                                                       \
++}
++
++#define AssertFCBorVCB( PtrVCBorFCB )                                                                                 \
++{                                                                                                                                                             \
++      if( !(PtrVCBorFCB) ||                                                                                                           \
++              ( (PtrVCBorFCB)->NodeIdentifier.NodeType != EXT2_NODE_TYPE_VCB &&               \
++                (PtrVCBorFCB)->NodeIdentifier.NodeType != EXT2_NODE_TYPE_FCB ) )              \
++      {                                                                                                                                                       \
++              Ext2BreakPoint();                                                                                                               \
++      }                                                                                                                                                       \
++}
++
++#else
++      #define DebugTrace( TYPE, X, Y ) 
++      #define DebugTraceState( STR, X1, X2, X3 )
++      #define AssertFCB( PtrFCB )
++      #define AssertVCB( PtrVCB )
++      #define AssertFCBorVCB( PtrVCBorFCB )
++
++#endif
++
++#endif        // _EXT2_FSD_H_
index 0000000,0000000..bbe240e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,115 @@@
++/*************************************************************************
++*
++* File: ext2metadata.h
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     Contains the definitions for the Ext2 Metadata structures.
++*
++* Author: Manoj Paul Joseph
++*
++*
++*************************************************************************/
++
++#ifndef EXT2_METADATA_STRUCTURES
++#define EXT2_METADATA_STRUCTURES
++
++//
++//    Some type definitions...
++//    These are used in the ext2_fs.h header file
++//
++typedef unsigned int          __u32 ;
++typedef signed int                    __s32 ;
++typedef unsigned short int    __u16 ;
++typedef signed short int      __s16 ;
++typedef unsigned char         __u8 ;
++
++//
++//******************************************************
++//
++//    Using Remy Card's (slightly modified) Ext2 header...
++//    
++#include "ext2_fs.h"
++//
++//******************************************************
++//
++
++typedef struct ext2_super_block       EXT2_SUPER_BLOCK;
++typedef EXT2_SUPER_BLOCK *            PEXT2_SUPER_BLOCK;
++
++typedef struct ext2_inode             EXT2_INODE;
++typedef EXT2_INODE *                  PEXT2_INODE;
++
++typedef struct ext2_group_desc        EXT2_GROUP_DESCRIPTOR;
++typedef EXT2_GROUP_DESCRIPTOR *       PEXT2_GROUP_DESCRIPTOR;
++
++typedef struct ext2_dir_entry_2       EXT2_DIR_ENTRY;
++typedef EXT2_DIR_ENTRY *              PEXT2_DIR_ENTRY;
++
++//
++// Ext2 Supported File Types...
++//
++#define IMODE_FIFO            0x01
++#define IMODE_CHARDEV         0x02
++#define IMODE_DIR             0x04
++#define IMODE_BLOCKDEV        0x06
++#define IMODE_FILE            0x08
++#define IMODE_SLINK           0x0A
++#define IMODE_SOCKET          0x0C
++
++#define _MKMODE(m)                                     ( ( (m) >> 12 ) & 0x000F)
++#define Ext2IsModeRegularFile(m)       ( _MKMODE(m) == IMODE_FILE )
++#define Ext2IsModeDirectory(m)                 ( _MKMODE(m) == IMODE_DIR   )
++#define Ext2IsModeSymbolicLink(m)      ( _MKMODE(m) == IMODE_SLINK )
++#define Ext2IsModePipe(m)                      ( _MKMODE(m) == IMODE_FIFO )
++#define Ext2IsModeCharacterDevice(m) ( _MKMODE(m) == IMODE_CHARDEV )
++#define Ext2IsModeBlockDevice(m)       ( _MKMODE(m) == IMODE_BLOCKDEV )
++#define Ext2IsModeSocket(m)                    ( _MKMODE(m) == IMODE_SOCKET )
++
++#define Ext2IsModeHidden(m)                   ( (m & 0x124) == 0)     //      No Read Permission
++#define Ext2IsModeReadOnly(m)         ( (m & 0x92) == 0)      //      No write Permission
++
++#define Ext2SetModeHidden(m)          m = (m & (~0x124));     //      Turn off Read Permission
++#define Ext2SetModeReadOnly(m)                m = (m & (~0x92));      //      Turn off write Permission
++#define Ext2SetModeReadWrite(m)               m = (m & 0x1ff);        //      Set read/write Permission
++
++
++//
++//  Define the Packed and Unpacked BIOS Parameter Block
++//
++typedef struct _PACKED_BIOS_PARAMETER_BLOCK {
++    UCHAR  BytesPerSector[2];                       // offset = 0x000  0
++    UCHAR  SectorsPerCluster[1];                    // offset = 0x002  2
++    UCHAR  ReservedSectors[2];                      // offset = 0x003  3
++    UCHAR  Fats[1];                                 // offset = 0x005  5
++    UCHAR  RootEntries[2];                          // offset = 0x006  6
++    UCHAR  Sectors[2];                              // offset = 0x008  8
++    UCHAR  Media[1];                                // offset = 0x00A 10
++    UCHAR  SectorsPerFat[2];                        // offset = 0x00B 11
++    UCHAR  SectorsPerTrack[2];                      // offset = 0x00D 13
++    UCHAR  Heads[2];                                // offset = 0x00F 15
++    UCHAR  HiddenSectors[4];                        // offset = 0x011 17
++    UCHAR  LargeSectors[4];                         // offset = 0x015 21
++} PACKED_BIOS_PARAMETER_BLOCK;                      // sizeof = 0x019 25
++typedef PACKED_BIOS_PARAMETER_BLOCK *PPACKED_BIOS_PARAMETER_BLOCK;
++
++//
++//  Define the boot sector
++//
++typedef struct _PACKED_BOOT_SECTOR {
++    UCHAR Jump[3];                                  // offset = 0x000   0
++    UCHAR Oem[8];                                   // offset = 0x003   3
++    PACKED_BIOS_PARAMETER_BLOCK PackedBpb;          // offset = 0x00B  11
++    UCHAR PhysicalDriveNumber;                      // offset = 0x024  36
++    UCHAR CurrentHead;                              // offset = 0x025  37
++    UCHAR Signature;                                // offset = 0x026  38
++    UCHAR Id[4];                                    // offset = 0x027  39
++    UCHAR VolumeLabel[11];                          // offset = 0x02B  43
++    UCHAR SystemId[8];                              // offset = 0x036  54
++} PACKED_BOOT_SECTOR;                               // sizeof = 0x03E  62
++
++typedef PACKED_BOOT_SECTOR *PPACKED_BOOT_SECTOR;
++
++
++#endif
index 0000000,0000000..1cb7c13
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,782 @@@
++/*************************************************************************
++*
++* File: protos.h
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     Contains the prototypes for functions in this sample FSD.
++*
++* Author: Manoj Paul Joseph
++*
++*
++*************************************************************************/
++
++#ifndef       _EXT2_PROTOS_H_
++#define       _EXT2_PROTOS_H_
++
++#ifdef __REACTOS__
++typedef PIO_STACK_LOCATION PEXTENDED_IO_STACK_LOCATION;
++#endif
++
++/*************************************************************************
++* Prototypes for the file sfsdinit.c
++*************************************************************************/
++extern NTSTATUS STDCALL DriverEntry(
++      PDRIVER_OBJECT                  DriverObject,           // created by the I/O sub-system
++      PUNICODE_STRING                 RegistryPath);          // path to the registry key
++
++extern void STDCALL Ext2FsdInitializeFunctionPointers(
++      PDRIVER_OBJECT                  DriverObject);          // created by the I/O sub-system
++
++
++extern VOID STDCALL Ext2QueueHandlerThread(
++      IN PVOID                                StartContext);
++                                                                                              
++/*************************************************************************
++* Prototypes for the file fsctrl.c
++*************************************************************************/
++
++extern NTSTATUS STDCALL Ext2FileSystemControl(
++    IN PDEVICE_OBJECT         DeviceObject,
++    IN PIRP                                   Irp
++    );
++
++extern NTSTATUS STDCALL Ext2VerifyVolume (
++      IN PIRP                                 Irp,
++      IN PIO_STACK_LOCATION   IrpSp );
++
++
++/*************************************************************************
++* Prototypes for the file create.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2Create(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                          Irp);                   // I/O Request Packet
++
++extern NTSTATUS STDCALL Ext2CommonCreate(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp,
++BOOLEAN                                               FirstAttempt );
++
++extern NTSTATUS STDCALL Ext2OpenVolume(
++      PtrExt2VCB                              PtrVCB,                         // volume to be opened
++      PtrExt2IrpContext               PtrIrpContext,          // IRP context
++      PIRP                                    PtrIrp,                         // original/user IRP
++      unsigned short                  ShareAccess,            // share access
++      PIO_SECURITY_CONTEXT    PtrSecurityContext,     // caller's context (incl access)
++      PFILE_OBJECT                    PtrNewFileObject);      // I/O Mgr. created file object
++
++extern NTSTATUS STDCALL Ext2OpenRootDirectory(
++      PtrExt2VCB                              PtrVCB,                                 // volume to be opened
++      PtrExt2IrpContext               PtrIrpContext,                  // IRP context
++      PIRP                                    PtrIrp,                                 // original/user IRP
++      unsigned short                  ShareAccess,                    // share access
++      PIO_SECURITY_CONTEXT    PtrSecurityContext,             // caller's context (incl access)
++      PFILE_OBJECT                    PtrNewFileObject);              // I/O Mgr. created file object
++
++extern void STDCALL Ext2InitializeFCB(
++      PtrExt2FCB                              PtrNewFCB,              // FCB structure to be initialized
++      PtrExt2VCB                              PtrVCB,                 // logical volume (VCB) pointer
++      PtrExt2ObjectName               PtrObjectName,  // name of the object
++      uint32                                  Flags,                  // is this a file/directory, etc.
++      PFILE_OBJECT                    PtrFileObject);// optional file object to be initialized
++
++extern PtrExt2FCB     STDCALL Ext2LocateChildFCBInCore(
++      PtrExt2VCB                              PtrVCB, 
++      PUNICODE_STRING                 PtrName, 
++      ULONG                                   ParentInodeNo );
++
++extern PtrExt2FCB     STDCALL Ext2LocateFCBInCore(
++      PtrExt2VCB                              PtrVCB, 
++      ULONG                                   InodeNo );
++
++
++extern ULONG  STDCALL Ext2LocateFileInDisk(
++      PtrExt2VCB                              PtrVCB,
++      PUNICODE_STRING                 PtrCurrentName, 
++      PtrExt2FCB                              PtrParentFCB, 
++      ULONG                                   *Type );
++
++extern ULONG STDCALL Ext2CreateFile(
++      PtrExt2IrpContext               PtrIrpContext,
++      PtrExt2VCB                              PtrVCB,
++      PUNICODE_STRING                 PtrName, 
++      PtrExt2FCB                              PtrParentFCB,
++      ULONG                                   Type);
++
++extern BOOLEAN STDCALL Ext2OverwriteFile(
++      PtrExt2FCB                              PtrFCB,
++      PtrExt2IrpContext               PtrIrpContext);
++
++extern BOOLEAN STDCALL Ext2SupersedeFile(
++      PtrExt2FCB                              PtrFCB,
++      PtrExt2IrpContext               PtrIrpContext);
++
++/*************************************************************************
++* Prototypes for the file misc.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2InitializeZones(
++void);
++
++extern void STDCALL Ext2DestroyZones(
++void);
++
++extern BOOLEAN STDCALL Ext2IsIrpTopLevel(
++PIRP                                                  Irp);                                   // the IRP sent to our dispatch routine
++
++extern long STDCALL Ext2ExceptionFilter(
++PtrExt2IrpContext                     PtrIrpContext,
++PEXCEPTION_POINTERS           PtrExceptionPointers);
++
++extern NTSTATUS STDCALL Ext2ExceptionHandler(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                                  Irp);
++
++extern void STDCALL Ext2LogEvent(
++NTSTATUS                                              Ext2EventLogId, // the Ext2 private message id
++NTSTATUS                                              RC);                                    // any NT error code we wish to log ...
++
++extern PtrExt2ObjectName STDCALL Ext2AllocateObjectName(
++void);
++
++extern void STDCALL Ext2ReleaseObjectName(
++PtrExt2ObjectName                     PtrObjectName);
++
++extern PtrExt2CCB STDCALL Ext2AllocateCCB(
++void );
++
++extern PtrExt2FCB STDCALL Ext2GetUsedFCB( 
++PtrExt2VCB                                    PtrVCB );
++
++extern BOOLEAN STDCALL Ext2CloseClosableFCB( 
++PtrExt2FCB                                    PtrFCB );
++
++extern void STDCALL Ext2ReleaseCCB(
++PtrExt2CCB                                    PtrCCB);
++
++extern PtrExt2FCB STDCALL Ext2AllocateFCB(
++void);
++
++extern NTSTATUS STDCALL Ext2CreateNewFCB(
++PtrExt2FCB                                    *ReturnedFCB,
++LARGE_INTEGER                         AllocationSize,
++LARGE_INTEGER                         EndOfFile,
++PFILE_OBJECT                          PtrFileObject,
++PtrExt2VCB                                    PtrVCB,
++PtrExt2ObjectName                     PtrObjectName);
++
++extern NTSTATUS STDCALL Ext2CreateNewCCB(
++PtrExt2CCB                            *ReturnedCCB,
++PtrExt2FCB                            PtrFCB,
++PFILE_OBJECT                  PtrFileObject);
++
++extern void STDCALL Ext2ReleaseFCB(
++PtrExt2FCB                                    PtrFCB);
++
++extern PtrExt2FileLockInfo STDCALL Ext2AllocateByteLocks(
++void);
++
++extern void STDCALL Ext2ReleaseByteLocks(
++PtrExt2FileLockInfo           PtrByteLocks);
++
++extern PtrExt2IrpContext STDCALL Ext2AllocateIrpContext(
++PIRP                                                  Irp,
++PDEVICE_OBJECT                                PtrTargetDeviceObject);
++
++extern void STDCALL Ext2ReleaseIrpContext(
++PtrExt2IrpContext                     PtrIrpContext);
++
++extern NTSTATUS STDCALL Ext2PostRequest(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp);
++
++extern void STDCALL Ext2CommonDispatch(
++void                                          *Context);      // actually an IRPContext structure
++
++extern void STDCALL Ext2InitializeVCB(
++PDEVICE_OBJECT                                PtrVolumeDeviceObject,
++PDEVICE_OBJECT                                PtrTargetDeviceObject,
++PVPB                                          PtrVPB,
++PLARGE_INTEGER                                AllocationSize);
++
++extern void STDCALL Ext2CompleteRequest(
++    IN PIRP                                   Irp OPTIONAL,
++    IN NTSTATUS                               Status
++    );
++
++extern NTSTATUS STDCALL Ext2DenyAccess( 
++      IN PIRP Irp 
++      );
++extern NTSTATUS STDCALL Ext2GetFCB_CCB_VCB_FromFileObject(
++      IN PFILE_OBJECT                 PtrFileObject,
++      OUT PtrExt2FCB                          *PPtrFCB,
++      OUT PtrExt2CCB                          *PPtrCCB,
++      OUT PtrExt2VCB                          *PPtrVCB        );
++
++extern void STDCALL Ext2CopyUnicodeString( 
++      IN OUT PUNICODE_STRING  PtrDestinationString, 
++      IN PUNICODE_STRING PtrSourceString );
++
++extern void STDCALL Ext2CopyWideCharToUnicodeString( 
++      IN OUT PUNICODE_STRING  PtrDestinationString, 
++      IN PCWSTR PtrSourceString );
++
++extern void STDCALL Ext2CopyCharToUnicodeString( 
++      IN OUT PUNICODE_STRING  PtrDestinationString, 
++      IN PCSTR PtrSourceString,
++      IN USHORT SourceStringLength );
++
++extern void STDCALL Ext2CopyZCharToUnicodeString( 
++      IN OUT PUNICODE_STRING  PtrDestinationString, 
++      IN PCSTR PtrSourceString );
++
++extern void STDCALL Ext2DeallocateUnicodeString( 
++      PUNICODE_STRING         PtrUnicodeString );
++
++extern void STDCALL Ext2ZerooutUnicodeString(
++      PUNICODE_STRING         PtrUnicodeString );
++
++extern BOOLEAN STDCALL Ext2SaveBCB(
++      PtrExt2IrpContext       PtrIrpContext,
++      PBCB                            PtrBCB,
++      PFILE_OBJECT            PtrFileObject);
++
++extern BOOLEAN STDCALL Ext2FlushSavedBCBs(
++      PtrExt2IrpContext       PtrIrpContext);
++
++extern BOOLEAN STDCALL AssertBCB(
++      PBCB                            PtrBCB);
++
++extern ULONG STDCALL Ext2Align(
++      ULONG                           NumberToBeAligned, 
++      ULONG                           Alignment);
++
++extern LONGLONG STDCALL Ext2Align64(
++      LONGLONG                        NumberToBeAligned, 
++      LONGLONG                        Alignment);
++
++extern ULONG STDCALL Ext2GetCurrentTime();
++
++/*************************************************************************
++* Prototypes for the file cleanup.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2Cleanup(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                                  Irp);                                   // I/O Request Packet
++
++extern NTSTATUS       STDCALL Ext2CommonCleanup(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp,
++BOOLEAN                                               FirstAttempt );
++
++/*************************************************************************
++* Prototypes for the file close.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2Close(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                                  Irp);                                   // I/O Request Packet
++
++extern NTSTATUS       STDCALL Ext2CommonClose(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp,
++BOOLEAN                                               FirstAttempt );
++
++/*************************************************************************
++* Prototypes for the file read.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2Read(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                                  Irp);                                   // I/O Request Packet
++
++extern NTSTATUS       STDCALL Ext2CommonRead(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                  PtrIrp,
++BOOLEAN                                               FirstAttempt );
++
++extern void * STDCALL Ext2GetCallersBuffer(
++PIRP                                          PtrIrp);
++
++extern NTSTATUS STDCALL Ext2LockCallersBuffer(
++PIRP                                          PtrIrp,
++BOOLEAN                                               IsReadOperation,
++uint32                                                Length);
++
++extern void STDCALL Ext2MdlComplete(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp,
++PIO_STACK_LOCATION                    PtrIoStackLocation,
++BOOLEAN                                               ReadCompletion);
++
++/*************************************************************************
++* Prototypes for the file write.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2Write(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                                  Irp);                                   // I/O Request Packet
++
++extern NTSTATUS       STDCALL Ext2CommonWrite(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                  PtrIrp);
++
++extern void STDCALL Ext2DeferredWriteCallBack (
++void                                                  *Context1,                      // Should be PtrIrpContext
++void                                                  *Context2);                     // Should be PtrIrp
++
++/*************************************************************************
++* Prototypes for the file fileinfo.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2FileInfo(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                          Irp);                                   // I/O Request Packet
++
++extern NTSTATUS       STDCALL Ext2CommonFileInfo(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp);
++
++extern NTSTATUS       STDCALL Ext2GetBasicInformation(
++      PtrExt2FCB                                      PtrFCB,
++      PFILE_BASIC_INFORMATION         PtrBuffer,
++      long                                            *PtrReturnedLength);
++
++extern NTSTATUS       STDCALL Ext2GetStandardInformation(
++      PtrExt2FCB                                      PtrFCB,
++      PFILE_STANDARD_INFORMATION      PtrStdInformation,
++      long                                            *PtrReturnedLength);
++
++extern NTSTATUS STDCALL Ext2GetNetworkOpenInformation(
++      PtrExt2FCB                                              PtrFCB,
++      PFILE_NETWORK_OPEN_INFORMATION  PtrNetworkOpenInformation,
++      long                                                    *PtrReturnedLength );
++
++extern NTSTATUS       STDCALL Ext2GetFullNameInformation(
++      PtrExt2FCB                              PtrFCB,
++      PtrExt2CCB                              PtrCCB,
++      PFILE_NAME_INFORMATION  PtrNameInformation,
++      long                                    *PtrReturnedLength);
++
++extern NTSTATUS       STDCALL Ext2SetBasicInformation(
++      PtrExt2IrpContext                       PtrIrpContext,
++      PtrExt2FCB                                      PtrFCB,
++      PFILE_OBJECT                            PtrFileObject,
++      PFILE_BASIC_INFORMATION         PtrFileInformation );
++
++extern NTSTATUS       STDCALL Ext2SetDispositionInformation(
++PtrExt2FCB                                    PtrFCB,
++PtrExt2CCB                                    PtrCCB,
++PtrExt2VCB                                    PtrVCB,
++PFILE_OBJECT                          PtrFileObject,
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                                  PtrIrp,
++PFILE_DISPOSITION_INFORMATION PtrBuffer);
++
++extern NTSTATUS       STDCALL Ext2SetAllocationInformation(
++PtrExt2FCB                                    PtrFCB,
++PtrExt2CCB                                    PtrCCB,
++PtrExt2VCB                                    PtrVCB,
++PFILE_OBJECT                          PtrFileObject,
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                                  PtrIrp,
++PFILE_ALLOCATION_INFORMATION  PtrBuffer);
++
++/*************************************************************************
++* Prototypes for the file flush.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2Flush(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                                  Irp);                                   // I/O Request Packet
++
++extern NTSTATUS       STDCALL Ext2CommonFlush(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                                  PtrIrp);
++
++extern void STDCALL Ext2FlushAFile(
++PtrExt2NTRequiredFCB          PtrReqdFCB,
++PIO_STATUS_BLOCK                      PtrIoStatus);
++
++extern void STDCALL Ext2FlushLogicalVolume(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                                  PtrIrp,
++PtrExt2VCB                                    PtrVCB);
++
++extern NTSTATUS STDCALL Ext2FlushCompletion(
++PDEVICE_OBJECT                                PtrDeviceObject,
++PIRP                                                  PtrIrp,
++PVOID                                                 Context);
++
++/*************************************************************************
++* Prototypes for the file dircntrl.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2DirControl(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                                  Irp);                                   // I/O Request Packet
++
++extern NTSTATUS       STDCALL Ext2CommonDirControl(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                                  PtrIrp);
++
++extern NTSTATUS       STDCALL Ext2QueryDirectory(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp,
++PEXTENDED_IO_STACK_LOCATION                   PtrIoStackLocation,
++PFILE_OBJECT                          PtrFileObject,
++PtrExt2FCB                                    PtrFCB,
++PtrExt2CCB                                    PtrCCB);
++
++extern NTSTATUS       STDCALL Ext2NotifyChangeDirectory(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp,
++PEXTENDED_IO_STACK_LOCATION           PtrIoStackLocation,
++PFILE_OBJECT                          PtrFileObject,
++PtrExt2FCB                                    PtrFCB,
++PtrExt2CCB                                    PtrCCB);
++
++/*************************************************************************
++* Prototypes for the file devcntrl.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2DeviceControl(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                          Irp);                                   // I/O Request Packet
++
++extern NTSTATUS STDCALL Ext2CommonDeviceControl(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp);
++
++extern NTSTATUS STDCALL Ext2DevIoctlCompletion(
++PDEVICE_OBJECT                                PtrDeviceObject,
++PIRP                                          PtrIrp,
++void                                          *Context);
++
++extern NTSTATUS STDCALL Ext2HandleQueryPath(
++void                                          *BufferPointer);
++
++/*************************************************************************
++* Prototypes for the file shutdown.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2Shutdown(
++PDEVICE_OBJECT                                DeviceObject,           // the logical volume device object
++PIRP                                          Irp);                   // I/O Request Packet
++
++extern NTSTATUS       STDCALL Ext2CommonShutdown(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp);
++
++/*************************************************************************
++* Prototypes for the file volinfo.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2QueryVolInfo(
++PDEVICE_OBJECT                                DeviceObject,   // the logical volume device object
++PIRP                                          Irp);                   // I/O Request Packet
++
++NTSTATUS STDCALL Ext2SetVolInfo(
++      IN PDEVICE_OBJECT               DeviceObject,   // the logical volume device object
++      IN PIRP                                 Irp);                   // I/O Request Packet
++
++
++/*************************************************************************
++* Prototypes for the file fastio.c
++*************************************************************************/
++extern BOOLEAN STDCALL Ext2FastIoCheckIfPossible(
++IN PFILE_OBJECT                               FileObject,
++IN PLARGE_INTEGER                             FileOffset,
++IN ULONG                                                      Length,
++IN BOOLEAN                                            Wait,
++IN ULONG                                                      LockKey,
++IN BOOLEAN                                            CheckForReadOperation,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoRead(
++IN PFILE_OBJECT                               FileObject,
++IN PLARGE_INTEGER                             FileOffset,
++IN ULONG                                                      Length,
++IN BOOLEAN                                            Wait,
++IN ULONG                                                      LockKey,
++OUT PVOID                                             Buffer,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoWrite(
++IN PFILE_OBJECT                               FileObject,
++IN PLARGE_INTEGER                             FileOffset,
++IN ULONG                                                      Length,
++IN BOOLEAN                                            Wait,
++IN ULONG                                                      LockKey,
++OUT PVOID                                             Buffer,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoQueryBasicInfo(
++IN PFILE_OBJECT                                       FileObject,
++IN BOOLEAN                                                    Wait,
++OUT PFILE_BASIC_INFORMATION   Buffer,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                                     DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoQueryStdInfo(
++IN PFILE_OBJECT                                               FileObject,
++IN BOOLEAN                                                            Wait,
++OUT PFILE_STANDARD_INFORMATION        Buffer,
++OUT PIO_STATUS_BLOCK                          IoStatus,
++IN PDEVICE_OBJECT                                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoLock(
++IN PFILE_OBJECT                               FileObject,
++IN PLARGE_INTEGER                             FileOffset,
++IN PLARGE_INTEGER                             Length,
++PEPROCESS                                             ProcessId,
++ULONG                                                         Key,
++BOOLEAN                                                       FailImmediately,
++BOOLEAN                                                       ExclusiveLock,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoUnlockSingle(
++IN PFILE_OBJECT                               FileObject,
++IN PLARGE_INTEGER                             FileOffset,
++IN PLARGE_INTEGER                             Length,
++PEPROCESS                                             ProcessId,
++ULONG                                                         Key,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoUnlockAll(
++IN PFILE_OBJECT                               FileObject,
++PEPROCESS                                             ProcessId,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoUnlockAllByKey(
++IN PFILE_OBJECT                               FileObject,
++PEPROCESS                                             ProcessId,
++ULONG                                                         Key,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern void STDCALL Ext2FastIoAcqCreateSec(
++IN PFILE_OBJECT                               FileObject);
++
++extern void STDCALL Ext2FastIoRelCreateSec(
++IN PFILE_OBJECT                               FileObject);
++
++extern BOOLEAN STDCALL Ext2AcqLazyWrite(
++IN PVOID                                                      Context,
++IN BOOLEAN                                            Wait);
++
++extern void STDCALL Ext2RelLazyWrite(
++IN PVOID                                                      Context);
++
++extern BOOLEAN STDCALL Ext2AcqReadAhead(
++IN PVOID                                                      Context,
++IN BOOLEAN                                            Wait);
++
++extern void STDCALL Ext2RelReadAhead(
++IN PVOID                                                      Context);
++
++// the remaining are only valid under NT Version 4.0 and later
++#if(_WIN32_WINNT >= 0x0400)
++
++extern BOOLEAN STDCALL Ext2FastIoQueryNetInfo(
++IN PFILE_OBJECT                                                                       FileObject,
++IN BOOLEAN                                                                                    Wait,
++OUT PFILE_NETWORK_OPEN_INFORMATION                    Buffer,
++OUT PIO_STATUS_BLOCK                                                  IoStatus,
++IN PDEVICE_OBJECT                                                                     DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoMdlRead(
++IN PFILE_OBJECT                               FileObject,
++IN PLARGE_INTEGER                             FileOffset,
++IN ULONG                                                      Length,
++IN ULONG                                                      LockKey,
++OUT PMDL                                                      *MdlChain,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoMdlReadComplete(
++IN PFILE_OBJECT                               FileObject,
++OUT PMDL                                                      MdlChain,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoPrepareMdlWrite(
++IN PFILE_OBJECT                               FileObject,
++IN PLARGE_INTEGER                             FileOffset,
++IN ULONG                                                      Length,
++IN ULONG                                                      LockKey,
++OUT PMDL                                                      *MdlChain,
++OUT PIO_STATUS_BLOCK                  IoStatus,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern BOOLEAN STDCALL Ext2FastIoMdlWriteComplete(
++IN PFILE_OBJECT                               FileObject,
++IN PLARGE_INTEGER                             FileOffset,
++OUT PMDL                                                      MdlChain,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern NTSTATUS STDCALL Ext2FastIoAcqModWrite(
++IN PFILE_OBJECT                               FileObject,
++IN PLARGE_INTEGER                             EndingOffset,
++OUT PERESOURCE                                        *ResourceToRelease,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern NTSTATUS STDCALL Ext2FastIoRelModWrite(
++IN PFILE_OBJECT                               FileObject,
++IN PERESOURCE                                 ResourceToRelease,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern NTSTATUS STDCALL Ext2FastIoAcqCcFlush(
++IN PFILE_OBJECT                               FileObject,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++extern NTSTATUS STDCALL Ext2FastIoRelCcFlush(
++IN PFILE_OBJECT                               FileObject,
++IN PDEVICE_OBJECT                             DeviceObject);
++
++#endif        // (_WIN32_WINNT >= 0x0400)
++
++/*************************************************************************
++* Prototypes for the file DiskIO.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2ReadLogicalBlocks(
++PDEVICE_OBJECT                PtrTargetDeviceObject,  //      the Target Device Object
++VOID                          *Buffer,                                //      The Buffer that takes the data read in
++LARGE_INTEGER         StartLogicalBlock,              //      The logical block from which reading is to start
++unsigned int          NoOfLogicalBlocks);             //      The no. of logical blocks to be read
++
++extern NTSTATUS STDCALL Ext2ReadPhysicalBlocks(
++      PDEVICE_OBJECT          PtrTargetDeviceObject,  //      the Target Device Object
++      VOID                            *Buffer,                                //      The Buffer that takes the data read in
++      LARGE_INTEGER           StartBlock,             //      The Physical block from which reading is to start
++      unsigned int            NoOfBlocks);            //      The no. of Physical blocks to be read
++
++/*************************************************************************
++* Prototypes for the file metadata.c
++*************************************************************************/
++
++extern void STDCALL Ext2InitializeFCBInodeInfo (
++      PtrExt2FCB      PtrFCB );
++
++extern NTSTATUS STDCALL Ext2ReadInode(
++      PtrExt2VCB                      PtrVcb,                 //      the Volume Control Block
++      uint32                          InodeNo,                //      The Inode no
++      PEXT2_INODE                     PtrInode );             //      The Inode Buffer
++
++extern NTSTATUS STDCALL Ext2WriteInode(
++      PtrExt2IrpContext       PtrIrpContext,
++      PtrExt2VCB                      PtrVcb,                 //      the Volume Control Block
++      uint32                          InodeNo,                //      The Inode no
++      PEXT2_INODE                     PtrInode                //      The Inode Buffer
++      );                                      
++
++extern ULONG STDCALL Ext2AllocInode( 
++      PtrExt2IrpContext       PtrIrpContext,
++      PtrExt2VCB                      PtrVCB,
++      ULONG                           ParentINodeNo );
++
++extern BOOLEAN STDCALL Ext2DeallocInode( 
++      PtrExt2IrpContext       PtrIrpContext,
++      PtrExt2VCB                      PtrVCB,
++      ULONG                           INodeNo );
++
++extern BOOLEAN STDCALL Ext2MakeNewDirectoryEntry( 
++      PtrExt2IrpContext       PtrIrpContext,          //      The Irp context
++      PtrExt2FCB                      PtrParentFCB,           //      Parent Folder FCB
++      PFILE_OBJECT            PtrFileObject,          //      Parent Folder Object
++      PUNICODE_STRING         PtrName,                        //      New entry's name
++      ULONG                           Type,                           //      The type of the new entry
++      ULONG                           NewInodeNo);            //      The inode no of the new entry...
++
++extern BOOLEAN STDCALL Ext2FreeDirectoryEntry(
++      PtrExt2IrpContext       PtrIrpContext,
++      PtrExt2FCB                      PtrParentFCB,
++      PUNICODE_STRING         PtrName);
++
++extern BOOLEAN STDCALL Ext2AddBlockToFile(
++      PtrExt2IrpContext       PtrIrpContext,
++      PtrExt2VCB                      PtrVCB,
++      PtrExt2FCB                      PtrFCB,
++      PFILE_OBJECT            PtrFileObject,
++      BOOLEAN                         UpdateFileSize);
++
++extern BOOLEAN STDCALL Ext2ReleaseDataBlocks(
++      PtrExt2FCB                      PtrFCB,
++      PtrExt2IrpContext       PtrIrpContext);
++
++extern BOOLEAN STDCALL Ext2TruncateFileAllocationSize(
++      PtrExt2IrpContext       PtrIrpContext,
++      PtrExt2FCB                      PtrFCB,
++      PFILE_OBJECT            PtrFileObject,
++      PLARGE_INTEGER          PtrAllocationSize );
++
++extern ULONG STDCALL Ext2AllocBlock( 
++      PtrExt2IrpContext       PtrIrpContext,
++      PtrExt2VCB                      PtrVCB,
++      ULONG                           Count);
++
++extern BOOLEAN STDCALL Ext2DeallocBlock( 
++      PtrExt2IrpContext       PtrIrpContext,
++      PtrExt2VCB                      PtrVCB,
++      ULONG                           BlockNo);
++
++extern BOOLEAN STDCALL Ext2UpdateFileSize(
++      PtrExt2IrpContext       PtrIrpContext,
++      PFILE_OBJECT            PtrFileObject,
++      PtrExt2FCB                      PtrFCB);
++
++
++extern BOOLEAN STDCALL Ext2DeleteFile(
++      PtrExt2FCB                      PtrFCB,
++      PtrExt2IrpContext       PtrIrpContext);
++
++extern BOOLEAN STDCALL Ext2IsDirectoryEmpty(
++      PtrExt2FCB                      PtrFCB,
++      PtrExt2CCB                      PtrCCB,
++      PtrExt2IrpContext       PtrIrpContext);
++
++extern NTSTATUS STDCALL Ext2RenameOrLinkFile( 
++      PtrExt2FCB                                      PtrSourceFCB, 
++      PFILE_OBJECT                            PtrSourceFileObject,    
++      PtrExt2IrpContext                       PtrIrpContext,
++      PIRP                                            PtrIrp, 
++      PFILE_RENAME_INFORMATION        PtrRenameInfo);
++/*************************************************************************
++* Prototypes for the file io.c
++*************************************************************************/
++extern NTSTATUS STDCALL Ext2PassDownSingleReadWriteIRP(
++      PtrExt2IrpContext       PtrIrpContext,
++      PIRP                            PtrIrp, 
++      PtrExt2VCB                      PtrVCB,
++      LARGE_INTEGER           ByteOffset, 
++      uint32                          ReadWriteLength, 
++      BOOLEAN                         SynchronousIo);
++
++extern NTSTATUS STDCALL Ext2PassDownMultiReadWriteIRP( 
++      PEXT2_IO_RUN                    PtrIoRuns, 
++      UINT                                    Count, 
++      ULONG                                   TotalReadWriteLength,
++      PtrExt2IrpContext               PtrIrpContext,
++      PtrExt2FCB                              PtrFCB,
++      BOOLEAN                                 SynchronousIo);
++
++extern NTSTATUS STDCALL Ext2SingleSyncCompletionRoutine(
++    IN PDEVICE_OBJECT DeviceObject,
++    IN PIRP Irp,
++    IN PVOID Contxt
++    );
++
++extern NTSTATUS STDCALL Ext2SingleAsyncCompletionRoutine (
++    IN PDEVICE_OBJECT DeviceObject,
++    IN PIRP Irp,
++    IN PVOID Contxt
++    );
++
++extern NTSTATUS STDCALL Ext2MultiSyncCompletionRoutine(
++    IN PDEVICE_OBJECT DeviceObject,
++    IN PIRP Irp,
++    IN PVOID Contxt);
++
++extern NTSTATUS STDCALL Ext2MultiAsyncCompletionRoutine(
++    IN PDEVICE_OBJECT DeviceObject,
++    IN PIRP Irp,
++    IN PVOID Contxt);
++
++#endif        // _EXT2_PROTOS_H_
index 0000000,0000000..9c490bf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,16 @@@
++//{{NO_DEPENDENCIES}}
++// Microsoft Developer Studio generated include file.
++// Used by D:\Work\VC\Drivers\ext2FSD\src\ext2.rc
++//
++
++// Next default values for new objects
++// 
++#ifdef APSTUDIO_INVOKED
++#ifndef APSTUDIO_READONLY_SYMBOLS
++#define _APS_NO_MFC                     1
++#define _APS_NEXT_RESOURCE_VALUE        102
++#define _APS_NEXT_COMMAND_VALUE         40001
++#define _APS_NEXT_CONTROL_VALUE         1000
++#define _APS_NEXT_SYMED_VALUE           101
++#endif
++#endif
index 0000000,0000000..1b4e83d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,674 @@@
++/*************************************************************************
++*
++* File: struct.h
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     This file contains structure definitions for the sample file system
++*     driver. Note that all structures are prefixed with the letters
++*     "Ext2". The structures are all aligned using normal alignment
++*     used by the compiler (typically quad-word aligned).
++*
++* Author: Manoj Paul Joseph
++*
++*
++*************************************************************************/
++
++#ifndef       _EXT2_STRUCTURES_H_
++#define       _EXT2_STRUCTURES_H_
++
++/**************************************************************************
++      some useful definitions
++**************************************************************************/
++#ifdef        _CPU_X86_
++typedef       char                                    int8;
++typedef       short                                   int16;
++typedef       int                                             int32;
++
++typedef       unsigned char                   uint8;
++typedef       unsigned short                  uint16;
++typedef       unsigned int                    uint32;
++
++typedef PVOID                                 PBCB;
++
++// we will use the LARGE_INTEGER structure as defined by NT
++
++#else         // Please define appropriate types here
++
++!!!! You must define your types here for compilation to proceed !!!!
++
++#endif        // if _CPU_X86_
++
++/**************************************************************************
++      some empty typedefs defined here so we can reference them easily
++**************************************************************************/
++struct _Ext2Identifier;
++struct _Ext2ObjectName;
++struct _Ext2ContextControlBlock;
++struct _Ext2NTRequiredFCB;
++struct _Ext2DiskDependentFCB;
++struct _Ext2FileControlBlock;
++struct _Ext2FileByteLocks;
++struct _Ext2VolumeControlBlock;
++struct _Ext2IrpContext;
++struct _Ext2Data;
++
++/**************************************************************************
++      each structure has a unique "node type" or signature associated with it
++**************************************************************************/
++#define       EXT2_NODE_TYPE_OBJECT_NAME                      (0xfdecba01)
++#define       EXT2_NODE_TYPE_CCB                                      (0xfdecba02)
++#define       EXT2_NODE_TYPE_FCB                                      (0xfdecba03)
++#define       EXT2_NODE_TYPE_LOCKS                            (0xfdecba04)
++#define       EXT2_NODE_TYPE_VCB                                      (0xfdecba05)
++#define       EXT2_NODE_TYPE_IRP_CONTEXT                      (0xfdecba06)
++#define       EXT2_NODE_TYPE_GLOBAL_DATA                      (0xfdecba07)
++#define       EXT2_NODE_TYPE_IO_CONTEXT                       (0xfdecba08)
++#define       EXT2_NODE_TYPE_SAVED_BCB                        (0xfdecba09)
++#define       EXT2_NODE_TYPE_FREED                            (0x10101010)
++#define       EXT2_NODE_TYPE_INVALID                          (0x10101010)
++
++/**************************************************************************
++      every structure has a node type, and a node size associated with it.
++      The node type serves as a signature field. The size is used for
++      consistency checking ...
++**************************************************************************/
++typedef struct _Ext2Identifier {
++      uint32          NodeType;                       // a 32 bit identifier for the structure
++      uint32          NodeSize;                       // computed as sizeof(structure)
++} Ext2Identifier, *PtrExt2Identifier;
++
++/**************************************************************************
++      Structures for byte-range lock support.
++**************************************************************************/
++typedef struct Ext2FileLockAnchor {
++      LIST_ENTRY                      GrantedFileLockList;
++      LIST_ENTRY                      PendingFileLockList;
++} Ext2FileLockAnchor, *PtrExt2FileLockAnchor;
++
++typedef struct Ext2FileLockInfo {
++      Ext2Identifier                                          NodeIdentifier;
++      uint32                                                          FileLockFlags;
++      PVOID                                                                   OwningProcess;
++      LARGE_INTEGER                                           StartingOffset;
++      LARGE_INTEGER                                           Length;
++      LARGE_INTEGER                                           EndingOffset;
++      ULONG                                                                   Key;
++      BOOLEAN                                                         ExclusiveLock;
++      PIRP                                                                    PendingIRP;
++      LIST_ENTRY                                                      NextFileLockEntry;
++} Ext2FileLockInfo, *PtrExt2FileLockInfo;
++
++#define               EXT2_BYTE_LOCK_NOT_FROM_ZONE                            (0x80000000)
++#define               EXT2_BYTE_LOCK_IS_PENDING                                       (0x00000001)
++
++/**************************************************************************
++      Every open on-disk object must have a name associated with it
++      This name has two components:
++      (a) the path-name (prefix) that leads to this on-disk object
++      (b) the name of the object itself
++      Note that with multiply linked objects, a single object might be
++      associated with more than one name structure.
++      This sample FSD does not correctly support multiply linked objects.
++
++      This structure must be quad-word aligned because it is zone allocated.
++**************************************************************************/
++typedef struct _Ext2ObjectName {
++      Ext2Identifier                                          NodeIdentifier;
++      uint32                                                          ObjectNameFlags;
++      // an absolute pathname of the object is stored below
++      UNICODE_STRING                                          ObjectName;
++} Ext2ObjectName, *PtrExt2ObjectName;
++
++#define               EXT2_OB_NAME_NOT_FROM_ZONE                              (0x80000000)
++
++/**************************************************************************
++      Each file open instance is represented by a context control block.
++      For each successful create/open request; a file object and a CCB will
++      be created.
++      For open operations performed internally by the FSD, there may not
++      exist file objects; but a CCB will definitely be created.
++
++      This structure must be quad-word aligned because it is zone allocated.
++**************************************************************************/
++typedef struct _Ext2ContextControlBlock {
++      Ext2Identifier                                          NodeIdentifier;
++      // ptr to the associated FCB
++      struct _Ext2FileControlBlock    *PtrFCB;
++      // all CCB structures for a FCB are linked together
++      LIST_ENTRY                                                      NextCCB;
++      // each CCB is associated with a file object
++      PFILE_OBJECT                                            PtrFileObject;
++      // flags (see below) associated with this CCB
++      uint32                                                          CCBFlags;
++      // current byte offset is required sometimes
++      LARGE_INTEGER                                           CurrentByteOffset;
++      // if this CCB represents a directory object open, we may
++      //      need to maintain a search pattern
++
++      //      PSTRING                                                         DirectorySearchPattern;
++      UNICODE_STRING                                          DirectorySearchPattern;
++
++      //      The full path name for the file...
++      UNICODE_STRING                  AbsolutePathName;
++
++      //      Rename/Link Target file name
++      //      Used only in a Rename/Link operation
++      UNICODE_STRING                  RenameLinkTargetFileName;
++
++      // we must maintain user specified file time values
++      uint32                                                          UserSpecifiedTime;
++
++
++} Ext2CCB, *PtrExt2CCB;
++
++
++/**************************************************************************
++      the following CCBFlags values are relevant. These flag
++      values are bit fields; therefore we can test whether
++      a bit position is set (1) or not set (0).
++**************************************************************************/
++
++// some on-disk file/directories are opened by EXT2 itself
++//    as opposed to being opened on behalf of a user process
++#define       EXT2_CCB_OPENED_BY_EXT2                                         (0x00000001)
++// the file object specified synchronous access at create/open time.
++//    this implies that EXT2 must maintain the current byte offset
++#define       EXT2_CCB_OPENED_FOR_SYNC_ACCESS                 (0x00000002)
++// file object specified sequential access for this file
++#define       EXT2_CCB_OPENED_FOR_SEQ_ACCESS                  (0x00000004)
++// the CCB has had an IRP_MJ_CLEANUP issued on it. we must
++//    no longer allow the file object / CCB to be used in I/O requests.
++#define       EXT2_CCB_CLEANED                                                                (0x00000008)
++// if we were invoked via the fast i/o path to perform file i/o;
++//    we should set the CCB access/modification time at cleanup
++#define       EXT2_CCB_ACCESSED                                                               (0x00000010)
++#define       EXT2_CCB_MODIFIED                                                               (0x00000020)
++// if an application process set the file date time, we must
++//    honor that request and *not* overwrite the values at cleanup
++#define       EXT2_CCB_ACCESS_TIME_SET                                        (0x00000040)
++#define       EXT2_CCB_MODIFY_TIME_SET                                        (0x00000080)
++#define       EXT2_CCB_CREATE_TIME_SET                                        (0x00000100)
++
++#define       EXT2_CCB_NOT_FROM_ZONE                                          (0x80000000)
++
++// this CCB was allocated for a "volume open" operation
++#define       EXT2_CCB_VOLUME_OPEN                                                    (0x00000100)
++
++/**************************************************************************
++      each open file/directory/volume is represented by a file control block.
++      NOTE: Currently, EXT2 does not handle multiply linked files correctly.
++                      In your FSD implementation, you must be careful about handling
++                      such on-disk files correctly i.e. a single (unique) FCB must
++                      represent an on-disk file/directory regardless of the path used
++                      to access the on-disk object.
++                      With the current EXT2 implementation, an on-disk file object
++                      with more than a single (hard) link will be treated incorrectly!
++
++      Each FCB can logically be divided into two:
++      (a) a structure that must have a field of type FSRTL_COMMON_FCB_HEADER
++               as the first field in the structure.
++               This portion should also contain other structures/resources required
++               by the NT Cache Manager
++               We will call this structure the "NT Required" FCB. Note that this
++               portion of the FCB must be allocated from non-paged pool.
++      (b) the remainder of the FCB is dependent upon the particular FSD
++               requirements.
++               This portion of the FCB could possibly be allocated from paged
++               memory, though in the sample FSD, it will always be allocated
++               from non-paged pool.
++
++      FCB structures are protected by the MainResource as well as the
++      PagingIoResource. Of course, if your FSD implementation requires
++      it, you can associate other syncronization structures with the
++      FCB.
++
++      This structure must be quad-word aligned because it is zone allocated.
++**************************************************************************/
++typedef struct _Ext2NTRequiredFCB 
++{
++    FSRTL_COMMON_FCB_HEADER                   CommonFCBHeader;
++      SECTION_OBJECT_POINTERS                 SectionObject;
++      ERESOURCE                                                       MainResource;
++      ERESOURCE                                                       PagingIoResource;
++} Ext2NTRequiredFCB, *PtrExt2NTRequiredFCB;
++
++typedef struct _Ext2DiskDependentFCB 
++{
++      // although the sample FSD does not maintain on-disk data structures,
++      //      this structure serves as a reminder of the logical separation that
++      //      your FSD can maintain between the disk dependent and the disk
++      //      independent portions of the FCB.
++      uint16                                                          DummyField;             // placeholder
++} Ext2DiskDependentFCB, *PtrExt2DiskDependentFCB;
++
++typedef struct _Ext2FileControlBlock 
++{
++      Ext2Identifier                                          NodeIdentifier;
++      // we will go ahead and embed the "NT Required FCB" right here.
++      //      Note though that it is just as acceptable to simply allocate
++      //      memory separately for the other half of the FCB and store a
++      //      pointer to the "NT Required" portion here instead of embedding
++      //      it ...
++      Ext2NTRequiredFCB                                       NTRequiredFCB;
++      // the disk dependent portion of the FCB is embedded right here
++      Ext2DiskDependentFCB                            DiskDependentFCB;
++      // this FCB belongs to some mounted logical volume
++      struct _Ext2VolumeControlBlock  *PtrVCB;
++      // to be able to access all open file(s) for a volume, we will
++      //      link all FCB structures for a logical volume together
++      LIST_ENTRY                                                      NextFCB;
++
++      //      to be used if this FCB is on the Closable FCB List...
++      struct _ClosableFCBs
++      {
++              LIST_ENTRY                                              ClosableFCBList;
++              BOOLEAN                                                 OnClosableFCBList;
++      }ClosableFCBs;
++
++      // some state information for the FCB is maintained using the
++      //      flags field
++      uint32                                                          FCBFlags;
++      // all CCB's for this particular FCB are linked off the following
++      //      list head.
++      LIST_ENTRY                                                      CCBListHead;
++      // NT requires that a file system maintain and honor the various
++      //      SHARE_ACCESS modes ...
++      SHARE_ACCESS                                            FCBShareAccess;
++      // to identify the lazy writer thread(s) we will grab and store
++      //      the thread id here when a request to acquire resource(s)
++      //      arrives ..
++      uint32                                                          LazyWriterThreadID;
++      // whenever a file stream has a create/open operation performed,
++      //      the Reference count below is incremented AND the OpenHandle count
++      //      below is also incremented.
++      //      When an IRP_MJ_CLEANUP is received, the OpenHandle count below
++      //      is decremented.
++      //      When an IRP_MJ_CLOSE is received, the Reference count below is
++      //      decremented.
++      //      When the Reference count goes down to zero, the FCB can be de-allocated.
++      //      Note that a zero Reference count implies a zero OpenHandle count.
++      //      This invariant must always hold true ... (if it is really an invariant,
++      // shoudn't the previous statement be redundant ... hmmm!!!)
++      LONG                                                            ReferenceCount;
++      LONG                                                            OpenHandleCount;
++      // for the sample fsd, there exists a 1-1 correspondence between an
++      //      object name structure and a FCB
++      PtrExt2ObjectName                                       FCBName;
++      // we will maintain some time information here to make our life easier
++      LARGE_INTEGER                                           CreationTime;
++      LARGE_INTEGER                                           LastAccessTime;
++      LARGE_INTEGER                                           LastWriteTime;
++      // Byte-range file lock support (we roll our own)
++      Ext2FileLockAnchor                              FCBByteRangeLock;
++      // The OPLOCK support package requires the following structure
++      OPLOCK                                                          FCBOplock;
++
++      //      The I-Node no of this file / folder
++      ULONG                   INodeNo;
++      ULONG                   ParentINodeNo;
++      //      Pointers to blocks 
++      uint32                  IBlock[EXT2_N_BLOCKS];
++      
++      USHORT                  LinkCount;
++      union   _DCBFCB
++      {
++              struct
++              {
++                      PFILE_OBJECT    PtrDirFileObject;
++              } Dcb;
++
++              struct _FCB
++              {
++                      PFILE_OBJECT    PtrDirFileObject;
++                      //      FCB specific stuff go here...
++              } Fcb;
++
++      }DcbFcb;
++
++} Ext2FCB, *PtrExt2FCB, Ext2DCB, *PtrExt2DCB;
++
++/**************************************************************************
++      the following FCBFlags values are relevant. These flag
++      values are bit fields; therefore we can test whether
++      a bit position is set (1) or not set (0).
++**************************************************************************/
++#define               EXT2_FCB_IN_INIT                                                        (0x00000001)
++#define               EXT2_FCB_IN_TEARDOWN                                            (0x00000002)
++#define               EXT2_FCB_PAGE_FILE                                                      (0x00000004)
++#define               EXT2_FCB_DIRECTORY                                                      (0x00000008)
++#define               EXT2_FCB_ROOT_DIRECTORY                                         (0x00000018)
++#define               EXT2_FCB_WRITE_THROUGH                                          (0x00000020)
++#define               EXT2_FCB_MAPPED                                                         (0x00000040)
++#define               EXT2_FCB_FAST_IO_READ_IN_PROGESS                        (0x00000080)
++#define               EXT2_FCB_FAST_IO_WRITE_IN_PROGESS                       (0x00000100)
++#define               EXT2_FCB_DELETE_ON_CLOSE                                        (0x00000200)
++#define               EXT2_FCB_MODIFIED                                                       (0x00000400)
++#define               EXT2_FCB_ACCESSED                                                       (0x00000800)
++#define               EXT2_FCB_READ_ONLY                                                      (0x00001000)
++
++#define               EXT2_INITIALIZED_MAIN_RESOURCE                          (0x00002000)
++#define               EXT2_INITIALIZED_PAGING_IO_RESOURCE                     (0x00004000)
++#define               EXT2_FCB_BLOCKS_INITIALIZED                                     (0x00008000)
++#define               EXT2_FCB_SPECIAL_FILE                                           (0x00010000)
++#define               EXT2_FCB_HIDDEN_FILE                                            (0x00020000)
++#define               EXT2_FCB_NOT_FROM_ZONE                                          (0x80000000)
++
++
++typedef struct _GroupDescriptors
++{
++      uint32  InodeTablesBlock;       /* Inodes table block   => bg_inode_table               */
++      uint32  InodeBitmapBlock;       /* Inodes bitmap block  => bg_inode_bitmap      */
++      uint32  BlockBitmapBlock;       /* Blocks bitmap block  => bg_block_bitmap      */
++      uint32  FreeBlocksCount;
++      uint32  FreeInodesCount;
++}Ext2GroupDescriptors, *PtrExt2GroupDescriptors;
++
++
++
++/**************************************************************************
++      A logical volume is represented using the following structure.
++      This structure is allocated as part of the device extension
++      for a device object that this sample FSD will create, to represent
++      the mounted logical volume.
++
++      NOTE: If you were to extend this sample FSD to be a "real" FSD,
++                      you would be worried about allocated clusters/sectiors,
++                      bitmaps providing such information for the mounted volume,
++                      dirty/modified clusters/sectiors etc.
++                      This sample FSD does not maintain such information in the
++                      in-memory VCB, though you may wish to consider it.
++**************************************************************************/
++typedef struct _Ext2VolumeControlBlock 
++{
++      Ext2Identifier                                          NodeIdentifier;
++
++    // Required to use the Cache Manager.
++      FSRTL_COMMON_FCB_HEADER                 CommonVCBHeader;
++      SECTION_OBJECT_POINTERS                 SectionObject;
++      // a resource to protect the fields contained within the VCB
++      ERESOURCE                                                       VCBResource;
++      
++      // a resource to synchronise paging io
++      ERESOURCE                                                       PagingIoResource;
++
++      // Pointer to a stream file object created for the volume information
++      // to be more easily read from secondary storage (with the support of
++      // the NT Cache Manager).
++      PFILE_OBJECT                                            PtrStreamFileObject;
++      
++      // each VCB is accessible off a global linked list
++      LIST_ENTRY                                                      NextVCB;
++      
++      // each VCB points to a VPB structure created by the NT I/O Manager
++      PVPB                                                                    PtrVPB;
++      
++      // a set of flags that might mean something useful
++      uint32                                                          VCBFlags;
++      
++      // A count of the number of open files/directories
++      //      As long as the count is != 0, the volume cannot
++      //      be dismounted or locked.
++      uint32                                                          VCBOpenCount;
++      
++      // a global list of all FCB structures associated with the VCB
++      LIST_ENTRY                                                      FCBListHead;
++
++      //
++      //      a list of FCBs created at the FSD's initiative...
++      //      These FCBs have a reference count of 0
++      //      This list should never be allowed to cross a limit...
++      //
++      struct Ext2ClosableFCB
++      {
++              LIST_ENTRY                                              ClosableFCBListHead;
++              ULONG                                                   Count;
++      }ClosableFCBs;
++      // we will maintain a global list of IRP's that are pending
++      //      because of a directory notify request.
++      LIST_ENTRY                                                      NextNotifyIRP;
++      // the above list is protected only by the mutex declared below
++      KMUTEX                                                          NotifyIRPMutex;
++      // for each mounted volume, we create a device object. Here then
++      //      is a back pointer to that device object
++      PDEVICE_OBJECT                                          VCBDeviceObject;
++      // We also retain a pointer to the physical device object on which we
++      // have mounted ourselves. The I/O Manager passes us a pointer to this
++      // device object when requesting a mount operation.
++      PDEVICE_OBJECT                                          TargetDeviceObject;
++      // the volume structure contains a pointer to the root directory FCB
++      PtrExt2FCB                                                      PtrRootDirectoryFCB;
++      // the complete name of the user visible drive letter we serve
++      uint8                                                                   *PtrVolumePath;
++      // For volume open operations, we do not create a FCB (we use the VCB
++      //      directly instead). Therefore, all CCB structures for the volume
++      //      open operation are linked directly off the VCB
++      LIST_ENTRY                                                      VolumeOpenListHead;
++
++
++      //      Volume information
++      ULONG   BlocksCount;
++      ULONG   InodesCount;
++      ULONG   ReservedBlocksCount;
++      ULONG   FreeBlocksCount;
++      ULONG   FreeInodesCount;
++      ULONG   LogBlockSize;                   //      Block size = 1024 << LogBlockSize
++      
++      //      Group Information Saved up in the VCB...
++      PtrExt2GroupDescriptors PtrGroupDescriptors;
++      ULONG   NoOfGroups;
++
++      uint32  InodesPerGroup;
++      uint32  BlocksPerGroup; 
++
++} Ext2VCB, *PtrExt2VCB;
++
++// some valid flags for the VCB
++#define                       EXT2_VCB_FLAGS_VOLUME_MOUNTED                   (0x00000001)
++#define                       EXT2_VCB_FLAGS_VOLUME_LOCKED                    (0x00000002)
++#define                       EXT2_VCB_FLAGS_BEING_DISMOUNTED         (0x00000004)
++#define                       EXT2_VCB_FLAGS_SHUTDOWN                                 (0x00000008)
++#define                       EXT2_VCB_FLAGS_VOLUME_READ_ONLY         (0x00000010)
++
++#define                       EXT2_VCB_FLAGS_VCB_INITIALIZED          (0x00000020)
++
++typedef struct _EXT2_IO_CONTEXT 
++{
++      Ext2Identifier                  NodeIdentifier;
++      ULONG                                   ReadWriteLength;
++      LONG                                    Count;
++      PIRP                                    PtrMasterIrp;
++      PKEVENT                                 PtrSyncEvent;
++
++} EXT2_IO_CONTEXT, *PEXT2_IO_CONTEXT;
++
++
++typedef struct _Ext2SavedBCBs
++{
++      Ext2Identifier                  NodeIdentifier;
++      PBCB                                    PtrBCB;
++      LIST_ENTRY                              SavedBCBsListEntry;
++
++} EXT2_SAVED_BCBS, *PEXT2_SAVED_BCBS;
++
++
++/**************************************************************************
++      The IRP context encapsulates the current request. This structure is
++      used in the "common" dispatch routines invoked either directly in
++      the context of the original requestor, or indirectly in the context
++      of a system worker thread.
++**************************************************************************/
++typedef struct _Ext2IrpContext
++{
++      Ext2Identifier                  NodeIdentifier;
++      uint32                                  IrpContextFlags;
++      // copied from the IRP
++      uint8                                   MajorFunction;
++      // copied from the IRP
++      uint8                                   MinorFunction;
++
++      // to queue this IRP for asynchronous processing
++      WORK_QUEUE_ITEM                 WorkQueueItem;
++      // the IRP for which this context structure was created
++      PIRP                                    Irp;
++      // the target of the request (obtained from the IRP)
++      PDEVICE_OBJECT                  TargetDeviceObject;
++      // if an exception occurs, we will store the code here
++      NTSTATUS                                SavedExceptionCode;
++      
++      //      This list entry is used if asnchronous processing is required...
++      LIST_ENTRY                              ThreadQueueListEntry;
++
++      //      This list entry is used if BCBs are to be saved and then flushed...
++      //      Could have been put somewhere else...
++      LIST_ENTRY                              SavedBCBsListHead;
++      ULONG                                   SavedCount;
++
++} Ext2IrpContext, *PtrExt2IrpContext;
++
++#define                       EXT2_IRP_CONTEXT_CAN_BLOCK                              (0x00000001)
++#define                       EXT2_IRP_CONTEXT_WRITE_THROUGH          (0x00000002)
++#define                       EXT2_IRP_CONTEXT_EXCEPTION                              (0x00000004)
++#define                       EXT2_IRP_CONTEXT_DEFERRED_WRITE         (0x00000008)
++#define                       EXT2_IRP_CONTEXT_ASYNC_PROCESSING       (0x00000010)
++#define                       EXT2_IRP_CONTEXT_NOT_TOP_LEVEL          (0x00000020)
++
++#define                       EXT2_IRP_CONTEXT_NOT_FROM_ZONE          (0x80000000)
++
++typedef struct _Ext2ThreadQueue
++{
++      HANDLE                          QueueHandlerThread;
++      
++      LIST_ENTRY                      ThreadQueueListHead;    //      This holds the Contexts 
++                                                                                              //      that are to be scheduled
++      KSPIN_LOCK                      SpinLock;                               //      To synchronize access to 
++                                                                                              //      the list
++      KEVENT                          QueueEvent;                             //      The Worker thread queue 
++                                                                                              //      package waits on this event
++}     Ext2ThreadQueue;
++
++/**************************************************************************
++      we will store all of our global variables in one structure.
++      Global variables are not specific to any mounted volume BUT
++      by definition are required for successful operation of the
++      FSD implementation.
++**************************************************************************/
++typedef struct _Ext2Data 
++{
++      Ext2Identifier                          NodeIdentifier;
++      // the fields in this list are protected by the following resource
++      ERESOURCE                                       GlobalDataResource;
++      // each driver has a driver object created for it by the NT I/O Mgr.
++      //      we are no exception to this rule.
++      PDRIVER_OBJECT                          Ext2DriverObject;
++      // we will create a device object for our FSD as well ...
++      //      Although not really required, it helps if a helper application
++      //      writen by us wishes to send us control information via
++      //      IOCTL requests ...
++      PDEVICE_OBJECT                          Ext2DeviceObject;
++      // we will keep a list of all logical volumes for our sample FSD
++      LIST_ENTRY                                      NextVCB;
++      // the NT Cache Manager, the I/O Manager and we will conspire
++      //      to bypass IRP usage using the function pointers contained
++      //      in the following structure
++      FAST_IO_DISPATCH                        Ext2FastIoDispatch;
++      // The NT Cache Manager uses the following call backs to ensure
++      //      correct locking hierarchy is maintained
++      CACHE_MANAGER_CALLBACKS CacheMgrCallBacks;
++      // structures allocated from a zone need some fields here. Note
++      //      that under version 4.0, it might be better to use lookaside
++      //      lists
++      KSPIN_LOCK                                      ZoneAllocationSpinLock;
++      ZONE_HEADER                                     ObjectNameZoneHeader;
++      ZONE_HEADER                                     CCBZoneHeader;
++      ZONE_HEADER                                     FCBZoneHeader;
++      ZONE_HEADER                                     ByteLockZoneHeader;
++      ZONE_HEADER                                     IrpContextZoneHeader;
++      void                                            *ObjectNameZone;
++      void                                            *CCBZone;
++      void                                            *FCBZone;
++      void                                            *ByteLockZone;
++      void                                            *IrpContextZone;
++      
++      //      currently, there is a single default zone size value used for
++      //      all zones. This should ideally be changed by you to be 1 per
++      //      type of zone (e.g. a default size for the FCB zone might be
++      //      different from the default size for the ByteLock zone).
++
++      //      Of course, you will need to use different values (min/max)
++      //      for lookaside lists (if you decide to use them instead)
++      uint32                                          DefaultZoneSizeInNumStructs;
++      
++      // some state information is maintained in the flags field
++      uint32                                          Ext2Flags;
++      
++      // Handle returned by the MUP is stored here.
++      HANDLE                                          MupHandle;
++      
++      //      Time difference 
++      LARGE_INTEGER                           TimeDiff;
++
++      //      The Worker Thread package uses this structure...
++      Ext2ThreadQueue                         ThreadQueue;
++
++}Ext2Data, *PtrExt2Data;
++
++// valid flag values for the global data structure
++#define               EXT2_DATA_FLAGS_RESOURCE_INITIALIZED            (0x00000001)
++#define               EXT2_DATA_FLAGS_ZONES_INITIALIZED                       (0x00000002)
++
++// a default size of the number of pages of non-paged pool allocated
++//    for each of the zones ...
++
++//    Note that the values are absolutely arbitrary, the only information
++//    worth using from the values themselves is that they increase for
++//    larger systems (i.e. systems with more memory)
++#define               EXT2_DEFAULT_ZONE_SIZE_SMALL_SYSTEM                     (0x4)
++#define               EXT2_DEFAULT_ZONE_SIZE_MEDIUM_SYSTEM            (0x8)
++#define               EXT2_DEFAULT_ZONE_SIZE_LARGE_SYSTEM                     (0xc)
++
++// another simplistic (brain dead ? :-) method used is to simply double
++//    the values for a "server" machine
++
++//    So, for all you guys who "modified" the registry ;-) to change the
++//    wkstation into a server, tough luck !
++#define               EXT2_NTAS_MULTIPLE                                                              (0x2)
++
++/***************************************************************************
++The following locking hierarchy is maintained in this sample filesystem
++driver:
++
++(a) the global structure resource can be acquired at any time. However,
++    it is an "end resource" i.e. once acquired, no other resource can
++       be obtained until the global structure resource is released.
++(b) the logical volume resource must be acquired (if required) before
++       any of the other resources are acquired.
++(c) a file control block can be acquired next (if required). If two
++    FCB structures need to be acquired, the FCB "higher" in the directory
++       tree must be acquired first.
++       For a FCB, the "main resource" must be acquired first before a
++       "paging i/o" resource is acquired.
++
++Whenever a file is opened, the logical volume structure is referenced.
++This ensures that the volume cannot be dismounted while any file is open.
++
++***************************************************************************/
++
++typedef struct _IO_RUN
++{
++      UINT LogicalBlock;
++      UINT StartOffset;
++      UINT EndOffset;
++      PIRP PtrAssociatedIrp;
++
++} EXT2_IO_RUN, *PEXT2_IO_RUN;
++
++typedef struct _SIBlocks
++{
++      PBCB    PtrBCB;
++      ULONG * PtrSIBlocks;
++} EXT2_SIBLOCKS, *PEXT2_SIBLOCKS;
++
++#endif        // has this file been included?
++
index 0000000,0000000..81ca894
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,215 @@@
++/*************************************************************************
++*
++* File: DiskIO.c
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     Should contain code to handle Disk IO.
++*
++*
++* Author: Manoj Paul Joseph
++*
++*
++*************************************************************************/
++
++#include                      "ext2fsd.h"
++
++#define                       EXT2_BUG_CHECK_ID                               EXT2_FILE_DISK_IO
++
++#define                       DEBUG_LEVEL                                             ( DEBUG_TRACE_DISKIO )
++
++
++/*************************************************************************
++*
++* Function: Ext2ReadLogicalBlocks()
++*
++* Description:
++*     The higherlevel functions will use this to read in logical blocks
++*     This function deals with the logical to physical block translation
++*
++*     LogicalBlock -  This is a 1 based index.
++*                                     That is, the first block is Block 1
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL 
++*
++* Return Value: The Status of the Read IO
++*
++*************************************************************************/
++NTSTATUS Ext2ReadLogicalBlocks (
++      PDEVICE_OBJECT          PtrTargetDeviceObject,  //      the Target Device Object
++      VOID                            *Buffer,                                //      The Buffer that takes the data read in
++      LARGE_INTEGER           StartLogicalBlock,              //      The logical block from which reading is to start
++      unsigned int            NoOfLogicalBlocks               //      The no. of logical blocks to be read
++      )                                       
++{
++      //      The Status to be returned...
++      NTSTATUS Status = STATUS_SUCCESS;
++
++      //      The Device Object representing the mounted volume
++      PDEVICE_OBJECT PtrVolumeDeviceObject = NULL;
++      
++      //      Volume Control Block
++      PtrExt2VCB PtrVCB = NULL;
++
++      //      Logical Block Size
++      ULONG LogicalBlockSize;
++
++      // Physical Block Size
++      ULONG PhysicalBlockSize;
++
++      //      The starting Physical Block No...
++      LARGE_INTEGER StartPhysicalBlock;
++
++      unsigned int            NoOfPhysicalBlocks;
++
++
++
++      //      Done with declerations...
++      //      Now for some code ;)
++
++      //      Getting the Logical and Physical Sector sizes
++      PtrVolumeDeviceObject = PtrTargetDeviceObject->Vpb->DeviceObject;
++      ASSERT( PtrVolumeDeviceObject );
++      PtrVCB = (PtrExt2VCB)(PtrVolumeDeviceObject->DeviceExtension);
++      ASSERT(PtrVCB);
++      ASSERT(PtrVCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB);
++
++      LogicalBlockSize = EXT2_MIN_BLOCK_SIZE << PtrVCB->LogBlockSize;
++      PhysicalBlockSize = PtrTargetDeviceObject->SectorSize;
++      
++      NoOfPhysicalBlocks = NoOfLogicalBlocks * LogicalBlockSize / PhysicalBlockSize;
++
++      StartPhysicalBlock.QuadPart = ( StartLogicalBlock.QuadPart ) * 
++                                                                      ( LogicalBlockSize / PhysicalBlockSize );
++
++      Status = Ext2ReadPhysicalBlocks( PtrTargetDeviceObject,
++                                      Buffer, StartPhysicalBlock,     NoOfPhysicalBlocks );
++              
++      return Status;
++}
++
++/*************************************************************************
++*
++* Function: Ext2ReadPhysicalBlocks()
++*
++* Description:
++*     The higherlevel functions will use this to read in physical blocks
++*
++*     PhysicalBlock - This is a 0 based number.
++*                                     That is, the first block is Block 0
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL 
++*
++* Return Value: The Status of the Read IO
++*
++*************************************************************************/
++NTSTATUS Ext2ReadPhysicalBlocks (
++      PDEVICE_OBJECT          PtrTargetDeviceObject,  //      the Target Device Object
++      VOID                            *Buffer,                                //      The Buffer that takes the data read in
++      LARGE_INTEGER           StartPhysicalBlock,             //      The block from which reading is to start
++      unsigned int            NoOfBlocks              //      The no. of blocks to be read
++      )                                       
++{
++      //      The Status to be returned...
++      NTSTATUS Status = STATUS_SUCCESS;
++
++      // Physical Block Size
++      ULONG PhysicalBlockSize;
++
++      // No of bytes to read
++      ULONG NumberOfBytesToRead;
++
++      //      Synchronisation Event
++      KEVENT Event;
++
++      //      IRP
++    PIRP Irp;
++
++      //      Status Block
++    IO_STATUS_BLOCK Iosb;
++
++      //      Byte Offset
++      LARGE_INTEGER ByteOffset;
++
++      //      Done with declerations...
++      //      Now for some code ;)
++
++      //      Getting the Physical Sector size
++      PhysicalBlockSize = PtrTargetDeviceObject->SectorSize;
++      
++      NumberOfBytesToRead = PhysicalBlockSize * NoOfBlocks;
++
++      ByteOffset.QuadPart = StartPhysicalBlock.QuadPart * PhysicalBlockSize;
++
++      try
++      {
++              //
++              //  Initialize the event we're going to use
++              //
++              KeInitializeEvent( &Event, NotificationEvent, FALSE );
++
++              //
++              //  Build the irp for the operation and also set the overrride flag
++              //
++              Irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ,
++                                                                                      PtrTargetDeviceObject,
++                                                                                      Buffer,
++                                                                                      NumberOfBytesToRead,
++                                                                                      &ByteOffset ,
++                                                                                      &Event,
++                                                                                      &Iosb );
++
++              if ( Irp == NULL ) 
++              {
++                      DebugTrace(DEBUG_TRACE_MISC,   " !!!! Unable to create an IRP", 0 );
++                      Status = STATUS_INSUFFICIENT_RESOURCES;
++                      try_return( Status );
++              }
++
++              //
++              //  Call the device to do the read and wait for it to finish.
++              //
++              Status = IoCallDriver( PtrTargetDeviceObject, Irp );
++
++              //
++              //      Check if it is done already!!!!
++              //
++              if (Status == STATUS_PENDING) 
++              {
++                      //
++                      //      Read not done yet...
++                      //      Wait till it is...
++                      //
++                      (VOID)KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, (PLARGE_INTEGER)NULL );
++                      Status = Iosb.Status;
++              }
++
++              try_exit:       NOTHING;
++      }
++      finally
++      {
++              if (!NT_SUCCESS(Status)) 
++              {
++                      if( Status == STATUS_VERIFY_REQUIRED )
++                      {
++                              DebugTrace(DEBUG_TRACE_MISC,   " !!!! Verify Required! Failed to read disk",0 );
++                      }
++                      else if (Status == STATUS_INVALID_PARAMETER) 
++                      {
++                              DebugTrace(DEBUG_TRACE_MISC,   " !!!! Invalid Parameter! Failed to read disk",0 );
++                      }
++                      else 
++                      {
++                              DebugTrace(DEBUG_TRACE_MISC,   " !!!! Failed to read disk! Status returned = %d", Status );
++                      }
++              }
++      }
++      return Status;
++}
++
++
index 0000000,0000000..50a2ab0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,400 @@@
++/*************************************************************************
++*
++* File: cleanup.c
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     Should contain code to handle the "Cleanup" dispatch entry point.
++*     This file serves as a placeholder. Please update this file as part
++*     of designing and implementing your FSD.
++*
++* Author: Manoj Paul Joseph
++*
++*
++*************************************************************************/
++
++#include                      "ext2fsd.h"
++
++// define the file specific bug-check id
++#define                       EXT2_BUG_CHECK_ID                               EXT2_FILE_CLEANUP
++#define                       DEBUG_LEVEL                                             (DEBUG_TRACE_CLEANUP)
++
++
++/*************************************************************************
++*
++* Function: Ext2Cleanup()
++*
++* Description:
++*     The I/O Manager will invoke this routine to handle a cleanup
++*     request
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
++*     to be deferred to a worker thread context)
++*
++* Return Value: Does not matter!
++*
++*************************************************************************/
++NTSTATUS Ext2Cleanup(
++PDEVICE_OBJECT                DeviceObject,           // the logical volume device object
++PIRP                                  Irp)                                    // I/O Request Packet
++{
++      NTSTATUS                                RC = STATUS_SUCCESS;
++    PtrExt2IrpContext PtrIrpContext = NULL;
++      BOOLEAN                         AreWeTopLevel = FALSE;
++
++      DebugTrace( DEBUG_TRACE_IRP_ENTRY, "Cleanup IRP Received...", 0);
++
++      FsRtlEnterFileSystem();
++      ASSERT(DeviceObject);
++      ASSERT(Irp);
++
++      // set the top level context
++      AreWeTopLevel = Ext2IsIrpTopLevel(Irp);
++
++      try
++      {
++
++              // get an IRP context structure and issue the request
++              PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject);
++              ASSERT(PtrIrpContext);
++
++              RC = Ext2CommonCleanup(PtrIrpContext, Irp, TRUE);
++
++      } 
++      except( Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation() ) ) 
++      {
++
++              RC = Ext2ExceptionHandler(PtrIrpContext, Irp);
++
++              Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC);
++      }
++
++      if (AreWeTopLevel) 
++      {
++              IoSetTopLevelIrp(NULL);
++      }
++
++      FsRtlExitFileSystem();
++
++      return(RC);
++}
++
++/*************************************************************************
++*
++* Function: Ext2CommonCleanup()
++*
++* Description:
++*     The actual work is performed here. This routine may be invoked in one'
++*     of the two possible contexts:
++*     (a) in the context of a system worker thread
++*     (b) in the context of the original caller
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL
++*
++* Return Value: Does not matter!
++*
++*************************************************************************/
++NTSTATUS      Ext2CommonCleanup(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp,
++BOOLEAN                                               FirstAttempt )
++{
++
++      NTSTATUS                                        RC = STATUS_SUCCESS;
++      PIO_STACK_LOCATION      PtrIoStackLocation = NULL;
++      PFILE_OBJECT                    PtrFileObject = NULL;
++      PtrExt2FCB                              PtrFCB = NULL;
++      PtrExt2CCB                              PtrCCB = NULL;
++      PtrExt2VCB                              PtrVCB = NULL;
++      PtrExt2NTRequiredFCB    PtrReqdFCB = NULL;
++      PERESOURCE                              PtrResourceAcquired = NULL;
++      IO_STATUS_BLOCK                 LocalIoStatus;
++
++      BOOLEAN                                 CompleteIrp = TRUE;
++      BOOLEAN                                 PostRequest = FALSE;
++      BOOLEAN                                 AcquiredVCB = FALSE;
++      BOOLEAN                                 CanWait = FALSE;
++      BOOLEAN                                 BlockForResource;
++      int                                             i = 1;
++
++      try 
++      {
++              // First, get a pointer to the current I/O stack location
++              PtrIoStackLocation = IoGetCurrentIrpStackLocation(PtrIrp);
++              ASSERT(PtrIoStackLocation);
++
++              PtrFileObject = PtrIoStackLocation->FileObject;
++              ASSERT(PtrFileObject);
++
++              if( !PtrFileObject->FsContext2 )
++              {
++                      //      This must be a Cleanup request received 
++                      //      as a result of IoCreateStreamFileObject
++                      //      Only such a File object would have a NULL CCB
++
++                      DebugTrace( DEBUG_TRACE_MISC, " === Cleanup with NULL CCB", 0);
++                      if( PtrFileObject )
++                      {
++                              DebugTrace( DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject);
++                      }
++                      try_return( RC );
++              }
++              
++
++              Ext2GetFCB_CCB_VCB_FromFileObject ( 
++                      PtrFileObject, &PtrFCB, &PtrCCB, &PtrVCB );
++
++              if( PtrFCB && PtrFCB->FCBName && PtrFCB->FCBName->ObjectName.Length && PtrFCB->FCBName->ObjectName.Buffer )
++              //if( PtrFileObject->FileName.Length && PtrFileObject->FileName.Buffer )
++              {
++                      DebugTrace( DEBUG_TRACE_FILE_NAME, " === Cleanup File Name : -%S-", PtrFCB->FCBName->ObjectName.Buffer );
++              }
++              else
++              {
++                      DebugTrace( DEBUG_TRACE_FILE_NAME, " === Cleanup Volume", 0);
++              }
++
++
++              PtrVCB = (PtrExt2VCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
++              ASSERT(PtrVCB);
++              ASSERT(PtrVCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB);
++              
++              //      (a) Acquiring the VCBResource Exclusively...
++              //      This is done to synchronise with the close and cleanup routines...
++              BlockForResource = !FirstAttempt;
++              if( !FirstAttempt )
++              {
++                      
++                      DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** Going into a block to acquire VCB Exclusively [Cleanup]", 0);
++              }
++              else
++              {
++                      DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** Attempting to acquire VCB Exclusively [Cleanup]", 0);
++              }
++
++              if( PtrFileObject )
++              {
++                      DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject);
++              }
++
++              i = 1;
++              while( !AcquiredVCB )
++              {
++                      DebugTraceState("VCB       AC:0x%LX   SW:0x%LX   EX:0x%LX   [Cleanup]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters );
++                      if( ! ExAcquireResourceExclusiveLite( &(PtrVCB->VCBResource), FALSE ) )
++                      {
++                              DebugTrace( DEBUG_TRACE_RESOURCE_ACQUIRE, "*** VCB Acquisition FAILED [Cleanup]", 0);
++                              if( BlockForResource && i != 1000 )
++                              {
++                                      LARGE_INTEGER Delay;
++                                      Delay.QuadPart = -500 * i;
++                                      KeDelayExecutionThread( KernelMode, FALSE, &Delay );
++                                      DebugTrace(DEBUG_TRACE_RESOURCE_RETRY, "*** Retrying... after 50 * %ld ms [Cleanup]", i);
++                              }
++                              else
++                              {
++                                      if( i == 1000 )
++                                              DebugTrace(DEBUG_TRACE_RESOURCE_RETRY, "*** Reposting... [Cleanup]", 0 );
++                                      PostRequest = TRUE;
++                                      try_return( RC = STATUS_PENDING );
++                              }
++                      }
++                      else
++                      {
++                              DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** VCB Acquired in [Cleanup]", 0);
++                              AcquiredVCB = TRUE;
++                      }
++                      i *= 10;
++              }
++
++
++              //      (b) Acquire the file (FCB) exclusively
++              if( PtrFCB && PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_FCB )
++              {
++                      //      This FCB is an FCB indeed. ;)
++                      //      So acquiring it exclusively...
++                      //      This is done to synchronise with read/write routines...
++                      if( !FirstAttempt )
++                      {
++                              DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** Going into a block to acquire FCB Exclusively [Cleanup]", 0);
++                      }
++                      else
++                      {
++                              DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** Attempting to acquire FCB Exclusively [Cleanup]", 0);
++                      }
++                      if( PtrFileObject )
++                      {
++                              DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject);
++                      }
++
++                      i = 1;
++                      while( !PtrResourceAcquired )
++                      {
++                              PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
++                              DebugTraceState( "FCBMain   AC:0x%LX   SW:0x%LX   EX:0x%LX   [Cleanup]", PtrReqdFCB->MainResource.ActiveCount, PtrReqdFCB->MainResource.NumberOfExclusiveWaiters, PtrReqdFCB->MainResource.NumberOfSharedWaiters );
++                              if(! ExAcquireResourceExclusiveLite( &(PtrFCB->NTRequiredFCB.MainResource ), FALSE ) )
++                              {
++                                      DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** FCB Acquisition FAILED [Cleanup]", 0);
++                                      if( BlockForResource && i != 1000 )
++                                      {
++                                              LARGE_INTEGER Delay;
++                                              Delay.QuadPart = -500 * i;
++                                              KeDelayExecutionThread( KernelMode, FALSE, &Delay );
++                                              DebugTrace(DEBUG_TRACE_RESOURCE_RETRY, "*** Retrying... after 50 * %ld ms [Cleanup]", i);
++                                      }
++                                      else
++                                      {
++                                              if( i == 1000 )
++                                                      DebugTrace(DEBUG_TRACE_RESOURCE_RETRY, "*** Reposting... [Cleanup]", 0 );
++                                              PostRequest = TRUE;
++                                              try_return( RC = STATUS_PENDING );
++                                      }
++                              }
++                              else
++                              {
++                                      DebugTrace(DEBUG_TRACE_RESOURCE_ACQUIRE, "*** FCB acquired [Cleanup]", 0);
++                                      PtrResourceAcquired = & ( PtrFCB->NTRequiredFCB.MainResource );
++                              }
++                              i *= 10;
++                      }
++      
++                      // (c) Flush file data to disk
++                      if ( PtrFileObject->PrivateCacheMap != NULL) 
++                      {
++                              IO_STATUS_BLOCK Status;
++                              CcFlushCache( PtrFileObject->SectionObjectPointer, NULL, 0, &Status );
++                      }
++
++                      // (d) Talk to the FSRTL package (if you use it) about pending oplocks.
++                      // (e) Notify the FSRTL package (if you use it) for use with pending
++                      //               notification IRPs
++                      // (f) Unlock byte-range locks (if any were acquired by process)
++                      
++                      // (g) Attempting to update time stamp values
++                      //      Errors are ignored...
++                      //      Not considered as critical errors...
++
++                      /*
++                      if( PtrFCB->OpenHandleCount == 1 )
++                      {
++                              ULONG                   CreationTime, AccessTime, ModificationTime;
++                              EXT2_INODE              Inode;
++
++                              CreationTime = (ULONG) ( (PtrFCB->CreationTime.QuadPart 
++                                                              - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 );
++                              AccessTime = (ULONG) ( (PtrFCB->LastAccessTime.QuadPart 
++                                                              - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 );
++                              ModificationTime = (ULONG) ( (PtrFCB->LastWriteTime.QuadPart
++                                                              - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 );
++                              if( NT_SUCCESS( Ext2ReadInode( PtrVCB, PtrFCB->INodeNo, &Inode ) ) )
++                              {
++                                      //      Update time stamps in the inode...
++                                      Inode.i_ctime = CreationTime;
++                                      Inode.i_atime = AccessTime;
++                                      Inode.i_mtime = ModificationTime;
++
++                                      //      Updating the inode...
++                                      Ext2WriteInode( PtrIrpContext, PtrVCB, PtrFCB->INodeNo, &Inode );
++                              }
++                      }
++                      */
++                      
++                      // (h) Inform the Cache Manager to uninitialize Cache Maps ...
++                      CcUninitializeCacheMap( PtrFileObject, NULL, NULL );
++
++                      // (i) Decrementing the Open Handle count...
++                      if( PtrFCB->OpenHandleCount )
++                      {
++                              InterlockedDecrement( &PtrFCB->OpenHandleCount );
++                      }
++                      else
++                      {
++                              Ext2BreakPoint();
++                      }
++
++                      PtrFCB->FCBFlags |= FO_CLEANUP_COMPLETE;
++                      
++                      DebugTrace(DEBUG_TRACE_REFERENCE, "^^^^^ReferenceCount  = 0x%lX [Cleanup]", PtrFCB->ReferenceCount );   
++                      DebugTrace(DEBUG_TRACE_REFERENCE, "^^^^^OpenHandleCount = 0x%lX [Cleanup]", PtrFCB->OpenHandleCount );
++
++                      //      (j) Remove share access...
++                      //              Will do that later ;)
++
++                      //      (k) Is this a close on delete file?
++                      //              If so, delete the file...
++                      if( Ext2IsFlagOn( PtrFCB->FCBFlags, EXT2_FCB_DELETE_ON_CLOSE) && 
++                              !PtrFCB->OpenHandleCount )
++                      {
++                              //
++                              //      Have to delete this file...
++                              //
++                              Ext2DeleteFile( PtrFCB, PtrIrpContext );
++                              PtrFCB->NTRequiredFCB.CommonFCBHeader.FileSize.QuadPart = 0;
++                              PtrFCB->INodeNo = 0;
++                      }
++              }
++              else
++              {
++                      //      This must be a volume close...
++                      //      Just go ahead and complete this IRP...
++                      PtrVCB->VCBOpenCount--;
++                      DebugTrace(DEBUG_TRACE_MISC,   "VCB Cleanup Requested !!!", 0);
++                      CompleteIrp = TRUE;
++              }
++              
++              try_return( RC );
++
++              try_exit:       NOTHING;
++
++      }
++      finally 
++      {
++              if(PtrResourceAcquired) 
++              {
++                      Ext2ReleaseResource(PtrResourceAcquired);
++                      DebugTrace(DEBUG_TRACE_RESOURCE_RELEASE, "*** Resource Released [Cleanup]", 0);
++                      DebugTraceState( "Resource     AC:0x%LX   SW:0x%LX   EX:0x%LX   [Cleanup]", 
++                              PtrResourceAcquired->ActiveCount, 
++                              PtrResourceAcquired->NumberOfExclusiveWaiters, 
++                              PtrResourceAcquired->NumberOfSharedWaiters );
++
++                      if( PtrFileObject )
++                      {
++                              DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject);
++                      }
++                      
++              }
++
++              if( AcquiredVCB )
++              {
++                      ASSERT(PtrVCB);
++                      Ext2ReleaseResource(&(PtrVCB->VCBResource));
++                      DebugTrace(DEBUG_TRACE_RESOURCE_RELEASE, "*** VCB Released [Cleanup]", 0);
++                      DebugTraceState( "VCB       AC:0x%LX   SW:0x%LX   EX:0x%LX   [Cleanup]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters );
++                      AcquiredVCB = FALSE;
++                      if( PtrFileObject )
++                      {
++                              DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject);
++                      }
++                      
++              }
++
++              if( PostRequest )
++              {
++                      RC = Ext2PostRequest(PtrIrpContext, PtrIrp);
++              }
++              if( RC != STATUS_PENDING )
++              {
++                      Ext2ReleaseIrpContext( PtrIrpContext );
++                      // complete the IRP
++                      IoCompleteRequest( PtrIrp, IO_DISK_INCREMENT );
++              }
++      } // end of "finally" processing
++
++      return(RC);
++}
index 0000000,0000000..8b83497
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,459 @@@
++/*************************************************************************
++*
++* File: close.c
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     Should contain code to handle the "Close" dispatch entry point.
++*     This file serves as a placeholder. Please update this file as part
++*     of designing and implementing your FSD.
++*
++* Author: Manoj Paul Joseph
++*
++*
++*************************************************************************/
++
++#include                      "ext2fsd.h"
++
++// define the file specific bug-check id
++#define                       EXT2_BUG_CHECK_ID                               EXT2_FILE_CLOSE
++
++#define                       DEBUG_LEVEL                                             (DEBUG_TRACE_CLOSE)
++
++
++/*************************************************************************
++*
++* Function: Ext2Close()
++*
++* Description:
++*     The I/O Manager will invoke this routine to handle a close
++*     request
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
++*     to be deferred to a worker thread context)
++*
++* Return Value: Does not matter!
++*
++*************************************************************************/
++NTSTATUS Ext2Close(
++PDEVICE_OBJECT                DeviceObject,           // the logical volume device object
++PIRP                                  Irp)                                    // I/O Request Packet
++{
++      NTSTATUS                                RC = STATUS_SUCCESS;
++      PtrExt2IrpContext       PtrIrpContext = NULL;
++      BOOLEAN                         AreWeTopLevel = FALSE;
++
++      DebugTrace(DEBUG_TRACE_IRP_ENTRY, "Close IRP Received...", 0);
++      
++
++      FsRtlEnterFileSystem();
++
++      ASSERT(DeviceObject);
++      ASSERT(Irp);
++
++      // set the top level context
++      AreWeTopLevel = Ext2IsIrpTopLevel(Irp);
++
++      try 
++      {
++
++              // get an IRP context structure and issue the request
++              PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject);
++              ASSERT(PtrIrpContext);
++
++              RC = Ext2CommonClose(PtrIrpContext, Irp, TRUE);
++
++      }
++      except (Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation())) 
++      {
++
++              RC = Ext2ExceptionHandler(PtrIrpContext, Irp);
++              Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC);
++      }
++
++      if (AreWeTopLevel) 
++      {
++              IoSetTopLevelIrp(NULL);
++      }
++
++      FsRtlExitFileSystem();
++
++      return(RC);
++}
++
++
++/*************************************************************************
++*
++* Function: Ext2CommonClose()
++*
++* Description:
++*     The actual work is performed here. This routine may be invoked in one'
++*     of the two possible contexts:
++*     (a) in the context of a system worker thread
++*     (b) in the context of the original caller
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL
++*
++* Return Value: Does not matter!
++*
++*************************************************************************/
++NTSTATUS      Ext2CommonClose(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp,
++BOOLEAN                                               FirstAttempt )
++{
++      NTSTATUS                                        RC = STATUS_SUCCESS;
++      PIO_STACK_LOCATION      PtrIoStackLocation = NULL;
++      PFILE_OBJECT                    PtrFileObject = NULL;
++      PtrExt2FCB                              PtrFCB = NULL;
++      PtrExt2CCB                              PtrCCB = NULL;
++      PtrExt2VCB                              PtrVCB = NULL;
++      PtrExt2NTRequiredFCB    PtrReqdFCB = NULL;
++      PERESOURCE                              PtrResourceAcquired = NULL;
++      IO_STATUS_BLOCK         LocalIoStatus;
++
++      BOOLEAN                                 CompleteIrp = TRUE;
++      BOOLEAN                                 PostRequest = FALSE;
++      BOOLEAN                                 AcquiredVCB = FALSE;
++      BOOLEAN                                 CanWait = FALSE;
++      BOOLEAN                                 BlockForResource;
++      int                                             i = 1;
++
++      try 
++      {
++              // First, get a pointer to the current I/O stack location
++              PtrIoStackLocation = IoGetCurrentIrpStackLocation(PtrIrp);
++              ASSERT(PtrIoStackLocation);
++
++              PtrFileObject = PtrIoStackLocation->FileObject;
++              ASSERT(PtrFileObject);
++
++              if( !PtrFileObject->FsContext2 )
++              {
++                      //      This must be a Cleanup request received 
++                      //      as a result of IoCreateStreamFileObject
++                      //      Only such a File object would have a NULL CCB
++
++                      DebugTrace( DEBUG_TRACE_SPECIAL, " === Close with NULL CCB", 0);
++                      if( PtrFileObject )
++                      {
++                              DebugTrace( DEBUG_TRACE_SPECIAL, "###### File Pointer 0x%LX [Close]", PtrFileObject);
++                      }
++                      Ext2BreakPoint();
++                      try_return( RC );
++              }
++
++              // Get the FCB and CCB pointers
++
++              Ext2GetFCB_CCB_VCB_FromFileObject ( 
++                      PtrFileObject, &PtrFCB, &PtrCCB, &PtrVCB );
++
++              PtrVCB = (PtrExt2VCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
++              ASSERT( PtrVCB );
++
++              if( PtrFCB && PtrFCB->FCBName && PtrFCB->FCBName->ObjectName.Length && PtrFCB->FCBName->ObjectName.Buffer )
++              //if( PtrFileObject->FileName.Length && PtrFileObject->FileName.Buffer )
++              {
++                      DebugTrace(DEBUG_TRACE_FILE_NAME, " === Close File Name : -%S-", PtrFCB->FCBName->ObjectName.Buffer );
++              }
++              else
++              {
++                      DebugTrace(DEBUG_TRACE_FILE_NAME,   " === Close File Name : -null-", 0);
++              }
++
++              //      (a) Acquiring the VCBResource Exclusively...
++              //      This is done to synchronise with the close and cleanup routines...
++//            if( ExTryToAcquireResourceExclusiveLite(&(PtrVCB->VCBResource) ) )
++
++              BlockForResource = !FirstAttempt;
++              if( !FirstAttempt )
++              {
++                      DebugTrace(DEBUG_TRACE_MISC, "*** Going into a block to acquire VCB Exclusively [Close]", 0);
++              }
++              else
++              {
++                      DebugTrace(DEBUG_TRACE_MISC, "*** Attempting to acquire VCB Exclusively [Close]", 0);
++              }
++              if( PtrFileObject )
++              {
++                      DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
++              }
++              i = 1;
++              while( !AcquiredVCB )
++              {
++                      DebugTraceState( "VCB       AC:0x%LX   SW:0x%LX   EX:0x%LX   [Close]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters );
++                      if(! ExAcquireResourceExclusiveLite( &(PtrVCB->VCBResource), FALSE ) )
++                      {
++                              DebugTrace(DEBUG_TRACE_MISC,   "*** VCB Acquisition FAILED [Close]", 0);
++                              if( BlockForResource && i != 1000 )
++                              {
++                                      LARGE_INTEGER Delay;
++                                      
++                                      //KeSetPriorityThread( PsGetCurrentThread(),LOW_REALTIME_PRIORITY       );
++
++                                      Delay.QuadPart = -500 * i;
++                                      KeDelayExecutionThread( KernelMode, FALSE, &Delay );
++                                      DebugTrace(DEBUG_TRACE_MISC,  "*** Retrying... after 50 * %ld ms [Close]", i);
++                              }
++                              else
++                              {
++                                      if( i == 1000 )
++                                              DebugTrace(DEBUG_TRACE_MISC,  "*** Reposting... [Close]", 0 );
++                                      PostRequest = TRUE;
++                                      try_return( RC = STATUS_PENDING );
++                              }
++                      }
++                      else
++                      {
++                              DebugTrace(DEBUG_TRACE_MISC,  "*** VCB Acquired in [Close]", 0);
++                              AcquiredVCB = TRUE;
++                      }
++                      i *= 10;
++              }
++
++              //      (b) Acquire the file (FCB) exclusively
++              if( PtrFCB && PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_FCB )
++              {
++                      //      This FCB is an FCB indeed. ;)
++                      //      So acquiring it exclusively...
++                      //      This is done to synchronise with read/write routines...
++                      if( !FirstAttempt )
++                      {
++                              DebugTrace(DEBUG_TRACE_MISC,   "*** Going into a block to acquire FCB Exclusively [Close]", 0);
++                      }
++                      else
++                      {
++                              DebugTrace(DEBUG_TRACE_MISC,  "*** Attempting to acquire FCB Exclusively [Close]", 0);
++                      }
++                      if( PtrFileObject )
++                      {
++                              DebugTrace(DEBUG_TRACE_FILE_OBJ,  "###### File Pointer 0x%LX [Close]", PtrFileObject);
++                      }
++                      i = 1;
++                      while( !PtrResourceAcquired )
++                      {
++                              PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
++
++                              DebugTraceState( "FCBMain   AC:0x%LX   SW:0x%LX   EX:0x%LX   [Close]", PtrReqdFCB->MainResource.ActiveCount, PtrReqdFCB->MainResource.NumberOfExclusiveWaiters, PtrReqdFCB->MainResource.NumberOfSharedWaiters );
++                              if(! ExAcquireResourceExclusiveLite( &(PtrFCB->NTRequiredFCB.MainResource ), FALSE ) )
++                              {
++                                      DebugTrace(DEBUG_TRACE_MISC,   "*** FCB Acquisition FAILED [Close]", 0);
++                                      if( BlockForResource && i != 1000 )
++                                      {
++                                              LARGE_INTEGER Delay;
++                                              
++                                              //KeSetPriorityThread( PsGetCurrentThread(),LOW_REALTIME_PRIORITY       );
++
++                                              Delay.QuadPart = -500 * i;
++                                              KeDelayExecutionThread( KernelMode, FALSE, &Delay );
++                                              DebugTrace(DEBUG_TRACE_MISC,  "*** Retrying... after 50 * %ld ms [Close]", i);
++                                      }
++                                      else
++                                      {
++                                              if( i == 1000 )
++                                                      DebugTrace(DEBUG_TRACE_MISC,  "*** Reposting... [Close]", 0 );
++                                              PostRequest = TRUE;
++                                              try_return( RC = STATUS_PENDING );
++                                      }
++                              }
++                              else
++                              {
++                                      DebugTrace(DEBUG_TRACE_MISC,  "*** FCB acquired [Close]", 0);
++                                      PtrResourceAcquired = & ( PtrFCB->NTRequiredFCB.MainResource );
++                              }
++                              i *= 10;
++                      }
++
++                      // (c) Delete the CCB structure (free memory)
++                      RemoveEntryList( &PtrCCB->NextCCB );
++                      Ext2ReleaseCCB( PtrCCB );
++                      PtrFileObject->FsContext2 = NULL;
++
++                      // (d) Decrementing the Reference Count...
++                      if( PtrFCB->ReferenceCount )
++                      {
++                              InterlockedDecrement( &PtrFCB->ReferenceCount );
++                      }
++                      else
++                      {
++                              Ext2BreakPoint();
++                      }       
++                      DebugTrace(DEBUG_TRACE_REFERENCE,  "^^^^^ReferenceCount = 0x%lX [Close]", PtrFCB->ReferenceCount );
++                      DebugTrace(DEBUG_TRACE_REFERENCE,  "^^^^^OpenHandleCount = 0x%lX [Close]", PtrFCB->OpenHandleCount );
++                      if( PtrFCB->ReferenceCount == 0 )
++                      {
++
++                              //      Attempting to update time stamp values
++                              //      Errors are ignored...
++                              //      Not considered as critical errors...
++                              
++                              {
++                                      ULONG                   CreationTime, AccessTime, ModificationTime;
++                                      EXT2_INODE              Inode;
++
++                                      CreationTime = (ULONG) ( (PtrFCB->CreationTime.QuadPart 
++                                                                      - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 );
++                                      AccessTime = (ULONG) ( (PtrFCB->LastAccessTime.QuadPart 
++                                                                      - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 );
++                                      ModificationTime = (ULONG) ( (PtrFCB->LastWriteTime.QuadPart
++                                                                      - Ext2GlobalData.TimeDiff.QuadPart) / 10000000 );
++                                      if( NT_SUCCESS( Ext2ReadInode( PtrVCB, PtrFCB->INodeNo, &Inode ) ) )
++                                      {
++                                              //      Update time stamps in the inode...
++                                              Inode.i_ctime = CreationTime;
++                                              Inode.i_atime = AccessTime;
++                                              Inode.i_mtime = ModificationTime;
++
++                                              //      Updating the inode...
++                                              Ext2WriteInode( NULL, PtrVCB, PtrFCB->INodeNo, &Inode );
++                                      }
++                              }
++
++
++                              if( PtrFCB->INodeNo == EXT2_ROOT_INO )
++                              {
++                                      //
++                                      //      Root Directory FCB
++                                      //      Preserve this
++                                      //      FSD has a File Object for this FCB...
++                                      //
++                                      DebugTrace(DEBUG_TRACE_MISC,  "^^^^^Root Directory FCB ; leaveing it alone[Close]", 0);
++                                      //      Do nothing...
++                                      
++                              }
++                              else if( PtrFCB->DcbFcb.Dcb.PtrDirFileObject )
++                              {
++                                      //
++                                      //      If this is a FCB created on the FSD's initiative
++                                      //      Leave it alone
++                                      //
++                                      DebugTrace(DEBUG_TRACE_MISC,  "^^^^^FCB Created  on the FSD's initiative; leaveing it alone[Close]", 0);
++                                      if( !PtrFCB->ClosableFCBs.OnClosableFCBList )
++                                      {
++                                              InsertTailList( &PtrVCB->ClosableFCBs.ClosableFCBListHead,
++                                                      &PtrFCB->ClosableFCBs.ClosableFCBList );
++                                              PtrVCB->ClosableFCBs.Count++;
++
++                                              PtrFCB->ClosableFCBs.OnClosableFCBList = TRUE;
++                                      }
++                                      
++                                      if( PtrVCB->ClosableFCBs.Count > EXT2_MAXCLOSABLE_FCBS_UL )
++                                      {
++                                              PtrExt2FCB              PtrTempFCB = NULL;
++                                              //      Checking if Closable FCBs are too many in number...
++                                              //      Shouldn't block the 
++                                              //      Should do this asynchronously...
++                                              //      Maybe later...
++                                              PLIST_ENTRY             PtrEntry = NULL;
++
++                                              PtrEntry = RemoveHeadList( &PtrVCB->ClosableFCBs.ClosableFCBListHead );
++                                              
++                                              PtrTempFCB = CONTAINING_RECORD( PtrEntry, Ext2FCB, ClosableFCBs.ClosableFCBList );
++                                              if( Ext2CloseClosableFCB( PtrTempFCB ) )
++                                              {
++                                                      DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [Close]", PtrTempFCB );
++                                                      ExFreePool( PtrTempFCB );
++                                                      PtrVCB->ClosableFCBs.Count--;
++                                              }
++                                              else
++                                              {
++                                                      //      Put the FCB back in the list...
++                                                      InsertHeadList( &PtrVCB->ClosableFCBs.ClosableFCBListHead,
++                                                              &PtrTempFCB->ClosableFCBs.ClosableFCBList );
++                                              }
++                                              DebugTrace( DEBUG_TRACE_SPECIAL, "ClosableFCBs Count = %ld [Close]", PtrVCB->ClosableFCBs.Count );
++                                      }
++                              }
++                              else
++                              {
++                                      //      Remove this FCB as well...
++                                      DebugTrace(DEBUG_TRACE_MISC,  "^^^^^Deleting FCB  [Close]", 0);
++                                      RemoveEntryList( &PtrFCB->NextFCB );
++
++                                      if ( PtrResourceAcquired ) 
++                                      {
++                                              Ext2ReleaseResource(PtrResourceAcquired);
++                                              DebugTrace(DEBUG_TRACE_MISC,  "*** FCB Released [Close]", 0);
++                                              DebugTraceState( "Resource     AC:0x%LX   SW:0x%LX   EX:0x%LX   [Close]", 
++                                                      PtrResourceAcquired->ActiveCount, 
++                                                      PtrResourceAcquired->NumberOfExclusiveWaiters, 
++                                                      PtrResourceAcquired->NumberOfSharedWaiters );
++
++                                              if( PtrFileObject )
++                                              {
++                                                      DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
++                                              }
++                                              PtrResourceAcquired = FALSE;
++                                      }
++                                      Ext2ReleaseFCB( PtrFCB );
++                              }
++
++                      }
++                      CompleteIrp = TRUE;
++              }
++              else
++              {
++                      //      This must be a volume close...
++                      //      What do I do now? ;)
++                      DebugTrace(DEBUG_TRACE_MISC,   "VCB Close Requested !!!", 0);
++                      CompleteIrp = TRUE;
++              }
++              try_return( RC );
++              
++              try_exit:       NOTHING;
++
++      } 
++      finally 
++      {
++              if ( PtrResourceAcquired ) 
++              {
++                      Ext2ReleaseResource(PtrResourceAcquired);
++                      DebugTrace(DEBUG_TRACE_MISC,  "*** FCB Released [Close]", 0);
++                      DebugTraceState( "Resource     AC:0x%LX   SW:0x%LX   EX:0x%LX   [Close]", 
++                              PtrResourceAcquired->ActiveCount, 
++                              PtrResourceAcquired->NumberOfExclusiveWaiters, 
++                              PtrResourceAcquired->NumberOfSharedWaiters );
++
++                      if( PtrFileObject )
++                      {
++                              DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
++                      }
++                      PtrResourceAcquired = FALSE;
++              }
++
++              if (AcquiredVCB) 
++              {
++                      ASSERT(PtrVCB);
++                      Ext2ReleaseResource(&(PtrVCB->VCBResource));
++                      DebugTraceState( "VCB       AC:0x%LX   SW:0x%LX   EX:0x%LX   [Close]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters );
++                      DebugTrace(DEBUG_TRACE_MISC,   "*** VCB Released [Close]", 0);
++
++                      AcquiredVCB = FALSE;
++                      if( PtrFileObject )
++                      {
++                              DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
++                      }
++                      
++              }
++
++              if( PostRequest )
++              {
++                      RC = Ext2PostRequest(PtrIrpContext, PtrIrp);
++              }
++              else if( CompleteIrp && RC != STATUS_PENDING )
++              {
++                      // complete the IRP
++                      IoCompleteRequest( PtrIrp, IO_DISK_INCREMENT );
++
++                      Ext2ReleaseIrpContext( PtrIrpContext );
++              }
++
++      } // end of "finally" processing
++
++      return(RC);
++}
index 0000000,0000000..13fe4e1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1681 @@@
++/*************************************************************************
++*
++* File: create.c
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     Contains code to handle the "Create"/"Open" dispatch entry point.
++*
++* Author: Manoj Paul Joseph
++*
++*
++*************************************************************************/
++
++#include                      "ext2fsd.h"
++
++// define the file specific bug-check id
++#define                       EXT2_BUG_CHECK_ID                               EXT2_FILE_CREATE
++
++#define                       DEBUG_LEVEL                                             (DEBUG_TRACE_CREATE)
++ 
++
++/*************************************************************************
++*
++* Function: Ext2Create()
++*
++* Description: 
++*     The I/O Manager will invoke this routine to handle a create/open
++*     request
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
++*     to be deferred to a worker thread context)
++*
++* Return Value: STATUS_SUCCESS/Error
++*
++*************************************************************************/
++NTSTATUS Ext2Create(
++PDEVICE_OBJECT                DeviceObject,           // the logical volume device object
++PIRP                                  Irp)                                    // I/O Request Packet
++{
++      NTSTATUS                                RC = STATUS_SUCCESS;
++    PtrExt2IrpContext PtrIrpContext;
++      BOOLEAN                         AreWeTopLevel = FALSE;
++
++      DebugTrace( DEBUG_TRACE_IRP_ENTRY, "Create Control IRP received...", 0);
++
++      FsRtlEnterFileSystem();
++      
++      //      Ext2BreakPoint();
++
++      ASSERT(DeviceObject);
++      ASSERT(Irp);
++
++      // sometimes, we may be called here with the device object representing
++      //      the file system (instead of the device object created for a logical
++      //      volume. In this case, there is not much we wish to do (this create
++      //      typically will happen 'cause some process has to open the FSD device
++      //      object so as to be able to send an IOCTL to the FSD)
++
++      //      All of the logical volume device objects we create have a device
++      //      extension whereas the device object representing the FSD has no
++      //      device extension. This seems like a good enough method to identify
++      //      between the two device objects ...
++      if (DeviceObject->Size == (unsigned short)(sizeof(DEVICE_OBJECT))) 
++      {
++              // this is an open of the FSD itself
++              DebugTrace( DEBUG_TRACE_MISC, " === Open for the FSD itself", 0);
++              Irp->IoStatus.Status = RC;
++              Irp->IoStatus.Information = FILE_OPENED;
++
++              IoCompleteRequest(Irp, IO_NO_INCREMENT);
++              return(RC);
++      }
++
++      // set the top level context
++      AreWeTopLevel = Ext2IsIrpTopLevel(Irp);
++
++      try 
++      {
++
++              // get an IRP context structure and issue the request
++              PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject);
++              ASSERT(PtrIrpContext);
++
++              RC = Ext2CommonCreate(PtrIrpContext, Irp, TRUE );
++
++      } 
++      except (Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation())) 
++      {
++
++              RC = Ext2ExceptionHandler(PtrIrpContext, Irp);
++
++              Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC);
++      }
++
++      if (AreWeTopLevel) 
++      {
++              IoSetTopLevelIrp(NULL);
++      }
++      
++      FsRtlExitFileSystem();
++
++      return(RC);
++}
++
++
++
++/*************************************************************************
++*
++* Function: Ext2CommonCreate()
++*
++* Description:
++*     The actual work is performed here. This routine may be invoked in one'
++*     of the two possible contexts:
++*     (a) in the context of a system worker thread
++*     (b) in the context of the original caller
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL
++*
++* Return Value: STATUS_SUCCESS/Error
++*
++*************************************************************************/
++NTSTATUS Ext2CommonCreate(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                          PtrIrp,
++BOOLEAN                                               FirstAttempt)
++{
++      NTSTATUS                                RC = STATUS_SUCCESS;
++      PIO_STACK_LOCATION              PtrIoStackLocation = NULL;
++      PIO_SECURITY_CONTEXT    PtrSecurityContext = NULL;
++      PFILE_OBJECT                    PtrNewFileObject = NULL;
++      PFILE_OBJECT                    PtrRelatedFileObject = NULL;
++      uint32                                  AllocationSize = 0;     // if we create a new file
++      PFILE_FULL_EA_INFORMATION       PtrExtAttrBuffer = NULL;
++      unsigned long                   RequestedOptions = 0;
++      unsigned long                   RequestedDisposition = 0;
++      uint8                                   FileAttributes = 0;
++      unsigned short                  ShareAccess = 0;
++      unsigned long                   ExtAttrLength = 0;
++      ACCESS_MASK                             DesiredAccess;
++
++      BOOLEAN                                 DeferredProcessing = FALSE;
++
++      PtrExt2VCB                              PtrVCB = NULL;
++      BOOLEAN                                 AcquiredVCB = FALSE;
++
++      BOOLEAN                                 DirectoryOnlyRequested = FALSE;
++      BOOLEAN                                 FileOnlyRequested = FALSE;
++      BOOLEAN                                 NoBufferingSpecified = FALSE;
++      BOOLEAN                                 WriteThroughRequested = FALSE;
++      BOOLEAN                                 DeleteOnCloseSpecified = FALSE;
++      BOOLEAN                                 NoExtAttrKnowledge = FALSE;
++      BOOLEAN                                 CreateTreeConnection = FALSE;
++      BOOLEAN                                 OpenByFileId    = FALSE;
++
++      BOOLEAN                                 SequentialOnly  = FALSE;
++      BOOLEAN                                 RandomAccess    = FALSE;
++      
++      // Are we dealing with a page file?
++      BOOLEAN                                 PageFileManipulation = FALSE;
++
++      // Is this open for a target directory (used in rename operations)?
++      BOOLEAN                                 OpenTargetDirectory = FALSE;
++
++      // Should we ignore case when attempting to locate the object?
++      BOOLEAN                                 IgnoreCaseWhenChecking = FALSE;
++
++      PtrExt2CCB                              PtrRelatedCCB = NULL, PtrNewCCB = NULL;
++      PtrExt2FCB                              PtrRelatedFCB = NULL, PtrNewFCB = NULL;
++
++      unsigned long                   ReturnedInformation = -1;
++
++      UNICODE_STRING                  TargetObjectName;
++      UNICODE_STRING                  RelatedObjectName;
++
++      UNICODE_STRING                  AbsolutePathName;
++      UNICODE_STRING                  RenameLinkTargetFileName;
++
++      LARGE_INTEGER                   FileAllocationSize, FileEndOfFile;
++
++
++      ASSERT(PtrIrpContext);
++      ASSERT(PtrIrp);
++
++      try 
++      {
++
++              AbsolutePathName.Buffer = NULL;
++              AbsolutePathName.Length = AbsolutePathName.MaximumLength = 0;
++
++              // Getting a pointer to the current I/O stack location
++              PtrIoStackLocation = IoGetCurrentIrpStackLocation(PtrIrp);
++              ASSERT(PtrIoStackLocation);
++
++              // Can we block?
++              if (!(PtrIrpContext->IrpContextFlags & EXT2_IRP_CONTEXT_CAN_BLOCK)) 
++              {
++                      //      Asynchronous processing required...
++                      RC = Ext2PostRequest(PtrIrpContext, PtrIrp);
++                      DeferredProcessing = TRUE;
++                      try_return(RC);
++              }
++
++              // Obtaining the parameters specified by the user.
++              PtrNewFileObject        = PtrIoStackLocation->FileObject;
++              TargetObjectName        = PtrNewFileObject->FileName;
++              PtrRelatedFileObject = PtrNewFileObject->RelatedFileObject;
++
++              if( PtrNewFileObject->FileName.Length && PtrNewFileObject->FileName.Buffer )
++              {
++                      if( PtrNewFileObject->FileName.Buffer[ PtrNewFileObject->FileName.Length/2 ] != 0 )
++                      {
++                              DebugTrace(DEBUG_TRACE_MISC, "&&&&&&&&&  PtrFileObject->FileName not NULL terminated! [Create]", 0 );
++                      }
++                      DebugTrace( DEBUG_TRACE_FILE_NAME, " === Create/Open File Name : -%S- [Create]", PtrNewFileObject->FileName.Buffer );
++              }
++              else
++              {
++                      DebugTrace( DEBUG_TRACE_FILE_NAME, " === Create/Open File Name : -null- [Create]", 0);
++              }
++
++              // Is this a Relative Create/Open?
++              if (PtrRelatedFileObject) 
++              {
++                      PtrRelatedCCB = (PtrExt2CCB)(PtrRelatedFileObject->FsContext2);
++                      ASSERT(PtrRelatedCCB);
++                      ASSERT(PtrRelatedCCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_CCB);
++                      // each CCB in turn points to a FCB
++                      PtrRelatedFCB = PtrRelatedCCB->PtrFCB;
++                      ASSERT(PtrRelatedFCB);
++                      if( PtrRelatedFCB->NodeIdentifier.NodeType != EXT2_NODE_TYPE_FCB &&
++                              PtrRelatedFCB->NodeIdentifier.NodeType != EXT2_NODE_TYPE_VCB    )
++                      {
++                              //      How the hell can this happen!!!
++                              Ext2BreakPoint();
++                      }
++
++                      AssertFCBorVCB( PtrRelatedFCB );
++
++                      RelatedObjectName = PtrRelatedFileObject->FileName;
++
++                      if( PtrRelatedFileObject->FileName.Length && PtrRelatedFileObject->FileName.Buffer )
++                      {
++                              DebugTrace( DEBUG_TRACE_FILE_NAME, " === Relative to : -%S-", PtrRelatedFileObject->FileName.Buffer );
++                      }
++                      else
++                      {
++                              DebugTrace( DEBUG_TRACE_FILE_NAME, " === Relative to : -null-",0);
++                      }
++
++              }
++
++
++              AllocationSize    = PtrIrp->Overlay.AllocationSize.LowPart;
++              //      Only 32 bit file sizes supported...
++
++              if (PtrIrp->Overlay.AllocationSize.HighPart) 
++              {
++                      RC = STATUS_INVALID_PARAMETER;
++                      try_return(RC);
++              }
++
++              // Getting a pointer to the supplied security context
++              PtrSecurityContext = PtrIoStackLocation->Parameters.Create.SecurityContext;
++
++              // Obtaining the desired access 
++              DesiredAccess = PtrSecurityContext->DesiredAccess;
++
++              //      Getting the options supplied by the user...
++              RequestedOptions = (PtrIoStackLocation->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS);
++              RequestedDisposition = ((PtrIoStackLocation->Parameters.Create.Options >> 24) & 0xFF);
++
++              FileAttributes  = (uint8)(PtrIoStackLocation->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS);
++              ShareAccess     = PtrIoStackLocation->Parameters.Create.ShareAccess;
++              PtrExtAttrBuffer        = PtrIrp->AssociatedIrp.SystemBuffer;
++
++              ExtAttrLength           = PtrIoStackLocation->Parameters.Create.EaLength;
++
++              SequentialOnly      = ((RequestedOptions & FILE_SEQUENTIAL_ONLY ) ? TRUE : FALSE);
++              RandomAccess            = ((RequestedOptions & FILE_RANDOM_ACCESS ) ? TRUE : FALSE);
++              
++
++              DirectoryOnlyRequested = ((RequestedOptions & FILE_DIRECTORY_FILE) ? TRUE : FALSE);
++              FileOnlyRequested = ((RequestedOptions & FILE_NON_DIRECTORY_FILE) ? TRUE : FALSE);
++              NoBufferingSpecified = ((RequestedOptions & FILE_NO_INTERMEDIATE_BUFFERING) ? TRUE : FALSE);
++              WriteThroughRequested = ((RequestedOptions & FILE_WRITE_THROUGH) ? TRUE : FALSE);
++              DeleteOnCloseSpecified = ((RequestedOptions & FILE_DELETE_ON_CLOSE) ? TRUE : FALSE);
++              NoExtAttrKnowledge = ((RequestedOptions & FILE_NO_EA_KNOWLEDGE) ? TRUE : FALSE);
++              CreateTreeConnection = ((RequestedOptions & FILE_CREATE_TREE_CONNECTION) ? TRUE : FALSE);
++              OpenByFileId = ((RequestedOptions & FILE_OPEN_BY_FILE_ID) ? TRUE : FALSE);
++              PageFileManipulation = ((PtrIoStackLocation->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE);
++              OpenTargetDirectory = ((PtrIoStackLocation->Flags & SL_OPEN_TARGET_DIRECTORY) ? TRUE : FALSE);
++              IgnoreCaseWhenChecking = ((PtrIoStackLocation->Flags & SL_CASE_SENSITIVE) ? TRUE : FALSE);
++
++              // Ensure that the operation has been directed to a valid VCB ...
++              PtrVCB =        (PtrExt2VCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
++              ASSERT(PtrVCB);
++              ASSERT(PtrVCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB);
++
++              
++              if( !PtrNewFileObject->Vpb )
++              {
++                      PtrNewFileObject->Vpb = PtrVCB->PtrVPB;
++              }
++
++              //      Acquiring the VCBResource Exclusively...
++              //      This is done to synchronise with the close and cleanup routines...
++              
++              DebugTrace(DEBUG_TRACE_MISC,  "*** Going into a block to acquire VCB Exclusively [Create]", 0);
++              
++              DebugTraceState( "VCB       AC:0x%LX   SW:0x%LX   EX:0x%LX   [Create]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters );
++              ExAcquireResourceExclusiveLite(&(PtrVCB->VCBResource), TRUE);
++                              
++              AcquiredVCB = TRUE;
++
++              DebugTrace(DEBUG_TRACE_MISC,   "*** VCB Acquired in Create", 0);
++              if( PtrNewFileObject )
++              {
++                      DebugTrace(DEBUG_TRACE_FILE_OBJ,  "###### File Pointer 0x%LX [Create]", PtrNewFileObject);
++              }
++
++              //      Verify Volume...
++              //      if (!NT_SUCCESS(RC = Ext2VerifyVolume(PtrVCB))) 
++              //      {
++              //              try_return(RC);
++              //      }
++
++              // If the volume has been locked, fail the request
++
++              if (PtrVCB->VCBFlags & EXT2_VCB_FLAGS_VOLUME_LOCKED) 
++              {
++                      DebugTrace(DEBUG_TRACE_MISC,   "Volume locked. Failing Create", 0 );
++                      RC = STATUS_ACCESS_DENIED;
++                      try_return(RC);
++              }
++
++
++              if ((PtrNewFileObject->FileName.Length == 0) && ((PtrRelatedFileObject == NULL) ||
++                        (PtrRelatedFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB))) 
++              {
++                      //
++                      //      >>>>>>>>>>>>>   Volume Open requested. <<<<<<<<<<<<<
++                      //
++
++                      //      Performing validity checks...
++                      if ((OpenTargetDirectory) || (PtrExtAttrBuffer)) 
++                      {
++                              RC = STATUS_INVALID_PARAMETER;
++                              try_return(RC);
++                      }
++
++                      if (DirectoryOnlyRequested) 
++                      {
++                              // a volume is not a directory
++                              RC = STATUS_NOT_A_DIRECTORY;
++                              try_return(RC);
++                      }
++
++                      if ((RequestedDisposition != FILE_OPEN) && (RequestedDisposition != FILE_OPEN_IF)) 
++                      {
++                              // cannot create a new volume, I'm afraid ...
++                              RC = STATUS_ACCESS_DENIED;
++                              try_return(RC);
++                      }
++                      DebugTrace(DEBUG_TRACE_MISC,   "Volume open requested", 0 );
++                      RC = Ext2OpenVolume(PtrVCB, PtrIrpContext, PtrIrp, ShareAccess, PtrSecurityContext, PtrNewFileObject);
++                      ReturnedInformation = PtrIrp->IoStatus.Information;
++
++                      try_return(RC);
++              }
++
++              if (OpenByFileId) 
++              {
++                      DebugTrace(DEBUG_TRACE_MISC, "Open by File Id requested", 0 );
++                      RC = STATUS_ACCESS_DENIED;
++                      try_return(RC);
++              }
++
++              // Relative path name specified...
++              if (PtrRelatedFileObject)
++              {
++
++                      if (!(PtrRelatedFCB->FCBFlags & EXT2_FCB_DIRECTORY)) 
++                      {
++                              // we must have a directory as the "related" object
++                              RC = STATUS_INVALID_PARAMETER;
++                              try_return(RC);
++                      }
++
++                      //      Performing validity checks...
++                      if ((RelatedObjectName.Length == 0) || (RelatedObjectName.Buffer[0] != L'\\')) 
++                      {
++                              RC = STATUS_INVALID_PARAMETER;
++                              try_return(RC);
++                      }
++
++                      if ((TargetObjectName.Length != 0) && (TargetObjectName.Buffer[0] == L'\\')) 
++                      {
++                              RC = STATUS_INVALID_PARAMETER;
++                              try_return(RC);
++                      }
++
++                      // Creating an absolute path-name.
++                      {
++                              AbsolutePathName.MaximumLength = TargetObjectName.Length + RelatedObjectName.Length + sizeof(WCHAR);
++                              if (!(AbsolutePathName.Buffer = Ext2AllocatePool(PagedPool, AbsolutePathName.MaximumLength ))) 
++                              {
++                                      RC = STATUS_INSUFFICIENT_RESOURCES;
++                                      try_return(RC);
++                              }
++
++                              RtlZeroMemory(AbsolutePathName.Buffer, AbsolutePathName.MaximumLength);
++
++                              RtlCopyMemory((void *)(AbsolutePathName.Buffer), (void *)(RelatedObjectName.Buffer), RelatedObjectName.Length);
++                              AbsolutePathName.Length = RelatedObjectName.Length;
++                              RtlAppendUnicodeToString(&AbsolutePathName, L"\\");
++                              RtlAppendUnicodeToString(&AbsolutePathName, TargetObjectName.Buffer);
++                      }
++
++              }
++              //      Absolute Path name specified...
++              else 
++              {
++                      
++
++                      // Validity Checks...
++                      if (TargetObjectName.Buffer[0] != L'\\') 
++                      {
++                              RC = STATUS_INVALID_PARAMETER;
++                              try_return(RC);
++                      }
++
++                      {
++                              AbsolutePathName.MaximumLength = TargetObjectName.Length;
++                              if (!(AbsolutePathName.Buffer = Ext2AllocatePool(PagedPool, AbsolutePathName.MaximumLength ))) {
++                                      RC = STATUS_INSUFFICIENT_RESOURCES;
++                                      try_return(RC);
++                              }
++
++                              RtlZeroMemory(AbsolutePathName.Buffer, AbsolutePathName.MaximumLength);
++
++                              RtlCopyMemory((void *)(AbsolutePathName.Buffer), (void *)(TargetObjectName.Buffer), TargetObjectName.Length);
++                              AbsolutePathName.Length = TargetObjectName.Length;
++                      }
++              }
++
++
++              //      Parsing the path...
++              if (AbsolutePathName.Length == 2) 
++              {
++                      
++                      // this is an open of the root directory, ensure that   the caller has not requested a file only
++                      if (FileOnlyRequested || (RequestedDisposition == FILE_SUPERSEDE) || (RequestedDisposition == FILE_OVERWRITE) ||
++                               (RequestedDisposition == FILE_OVERWRITE_IF)) 
++                      {
++                              RC = STATUS_FILE_IS_A_DIRECTORY;
++                              try_return(RC);
++                      }
++
++                      RC = Ext2OpenRootDirectory(PtrVCB, PtrIrpContext, PtrIrp, ShareAccess, PtrSecurityContext, PtrNewFileObject);
++                      DebugTrace(DEBUG_TRACE_MISC,   " === Root directory opened", 0 );
++                      try_return(RC);
++              }
++
++
++              {
++                      //      Used during parsing the file path...
++                      UNICODE_STRING                  RemainingName;
++                      UNICODE_STRING                  CurrentName;
++                      UNICODE_STRING                  NextRemainingName;
++                      PEXT2_INODE                             PtrNextInode = NULL;
++                      ULONG                                   CurrInodeNo = 0;
++                      PtrExt2FCB                              PtrCurrFCB = NULL;
++                      PtrExt2FCB                              PtrNextFCB = NULL;
++                      PFILE_OBJECT                    PtrCurrFileObject = NULL;
++                      UINT                                    NameBufferIndex;
++                      ULONG                                   Type = 0;
++                      LARGE_INTEGER ZeroSize;
++                      BOOLEAN Found           = FALSE;
++                      
++                      ZeroSize.QuadPart = 0;
++                      if ( PtrRelatedFileObject ) 
++                      {
++                              CurrInodeNo = PtrRelatedFCB->INodeNo;
++                              PtrCurrFCB = PtrRelatedFCB;
++                      }
++                      else 
++                      {
++                              CurrInodeNo = PtrVCB->PtrRootDirectoryFCB->INodeNo;
++                              PtrCurrFCB = PtrVCB->PtrRootDirectoryFCB;
++
++                      }
++
++                      //      Ext2ZerooutUnicodeString( &RemainingName );
++                      Ext2ZerooutUnicodeString( &CurrentName );
++                      Ext2ZerooutUnicodeString( &NextRemainingName );
++
++                      RemainingName = TargetObjectName;
++              
++                      while ( !Found && CurrInodeNo ) 
++                      {
++                              FsRtlDissectName ( RemainingName, &CurrentName, &NextRemainingName );
++
++                              RemainingName = NextRemainingName;
++                              //      CurrInodeNo is the parent inode for the entry I am searching for
++                              //      PtrCurrFCB      is the parent's FCB
++                              //      Current Name is its name...
++
++
++                              PtrNextFCB = Ext2LocateChildFCBInCore ( PtrVCB, &CurrentName, CurrInodeNo );
++                              
++                              if( PtrNextFCB )
++                              {
++                                      CurrInodeNo = PtrNextFCB->INodeNo;
++      
++                                      if( NextRemainingName.Length == 0 )
++                                      {
++                                              //
++                                              //      Done Parsing...
++                                              //      Found the file...
++                                              //
++                                              Found = TRUE;
++                                              
++                                              if( OpenTargetDirectory )
++                                              {
++                                                      int i;
++                                                      //
++                                                      //      This is for a rename/move operation...
++                                                      //
++                                                      ReturnedInformation = FILE_EXISTS;
++
++                                                      //      Now replace the file name field with that of the 
++                                                      //      Target file name...
++                                                      Ext2CopyUnicodeString( 
++                                                              &RenameLinkTargetFileName,
++                                                              &CurrentName );
++                                                      /*
++                                                      
++                                                      for( i = 0; i < (CurrentName.Length/2); i++ )
++                                                      {
++                                                              PtrNewFileObject->FileName.Buffer[i] = CurrentName.Buffer[i];
++                                                      }
++                                                      PtrNewFileObject->FileName.Length = CurrentName.Length;
++                                                      */
++                                                      //      Now open the Parent Directory...
++                                                      PtrNextFCB = PtrCurrFCB;
++                                                      CurrInodeNo = PtrNextFCB->INodeNo;
++                                              }
++
++                                              //      
++                                              //      Relating the FCB to the New File Object
++                                              //
++                                              PtrNewFileObject->Vpb = PtrVCB->PtrVPB;
++                                              PtrNewFileObject->PrivateCacheMap = NULL;
++                                              PtrNewFileObject->FsContext = (void *)( &(PtrNextFCB->NTRequiredFCB.CommonFCBHeader) );
++                                              PtrNewFileObject->SectionObjectPointer = &(PtrNextFCB->NTRequiredFCB.SectionObject) ;
++                                              break;
++                                      }
++
++                                      else if( !Ext2IsFlagOn( PtrNextFCB->FCBFlags, EXT2_FCB_DIRECTORY ) )
++                                      {
++                                              //      Invalid path...
++                                              //      Can have only a directory in the middle of the path...
++                                              //
++                                              RC = STATUS_OBJECT_PATH_NOT_FOUND;
++                                              try_return( RC );
++                                      }
++                              }
++                              else    //      searching on the disk...
++                              {
++                                      CurrInodeNo = Ext2LocateFileInDisk( PtrVCB, &CurrentName, PtrCurrFCB, &Type );
++                                      if( !CurrInodeNo )
++                                      {
++                                              //
++                                              //      Not found...
++                                              //      Quit searching...
++                                              //      
++                                      
++                                              if( ( NextRemainingName.Length == 0 ) &&
++                                                      ( RequestedDisposition == FILE_CREATE ) ||
++                                                      ( RequestedDisposition == FILE_OPEN_IF) ||
++                                                      ( RequestedDisposition == FILE_OVERWRITE_IF) ) 
++
++                                              {
++                                                      //
++                                                      //      Just the last component was not found...
++                                                      //      A create was requested...
++                                                      //
++                                                      if( DirectoryOnlyRequested )
++                                                      {
++                                                              Type = EXT2_FT_DIR;
++                                                      }
++                                                      else
++                                                      {
++                                                              Type = EXT2_FT_REG_FILE;
++                                                      }
++
++                                                      CurrInodeNo = Ext2CreateFile( PtrIrpContext, PtrVCB, 
++                                                              &CurrentName, PtrCurrFCB, Type );
++                                                      
++                                                      if(     !CurrInodeNo )
++                                                      {
++                                                              RC = STATUS_OBJECT_PATH_NOT_FOUND;
++                                                              try_return( RC );
++                                                      }
++                                                      // Set the allocation size for the object is specified
++                                                      //IoSetShareAccess(DesiredAccess, ShareAccess, PtrNewFileObject, &(PtrNewFCB->FCBShareAccess));
++                                                      //      RC = STATUS_SUCCESS;
++                                                      ReturnedInformation = FILE_CREATED;
++                                                      
++                                                      //      Should also create a CCB structure...
++                                                      //      Doing that a little fathre down... ;)
++
++                                              }
++                                              else if( NextRemainingName.Length == 0 && OpenTargetDirectory )
++                                              { 
++                                                      int i;
++                                                      //
++                                                      //      This is for a rename/move operation...
++                                                      //      Just the last component was not found...
++                                                      //
++                                                      ReturnedInformation = FILE_DOES_NOT_EXIST;
++
++                                                      //      Now replace the file name field with that of the 
++                                                      //      Target file name...
++                                                      Ext2CopyUnicodeString( 
++                                                              &RenameLinkTargetFileName,
++                                                              &CurrentName );
++                                                      /*
++                                                      for( i = 0; i < (CurrentName.Length/2); i++ )
++                                                      {
++                                                              PtrNewFileObject->FileName.Buffer[i] = CurrentName.Buffer[i];
++                                                      }
++                                                      PtrNewFileObject->FileName.Length = CurrentName.Length;
++                                                      */
++
++                                                      //      Now open the Parent Directory...
++                                                      PtrNextFCB = PtrCurrFCB;
++                                                      CurrInodeNo = PtrNextFCB->INodeNo;
++                                                      //      Initialize the FsContext
++                                                      PtrNewFileObject->FsContext = &PtrNextFCB->NTRequiredFCB.CommonFCBHeader;
++                                                      //      Initialize the section object pointer...
++                                                      PtrNewFileObject->SectionObjectPointer = &(PtrNextFCB->NTRequiredFCB.SectionObject);
++                                                      PtrNewFileObject->Vpb = PtrVCB->PtrVPB;
++                                                      PtrNewFileObject->PrivateCacheMap = NULL;                                                       
++
++                                                      break;
++                                              }
++                                              else
++                                              {
++                                                      RC = STATUS_OBJECT_PATH_NOT_FOUND;
++                                                      try_return( RC );
++                                              }
++                                      }
++
++                                      if( NextRemainingName.Length )
++                                      {
++                                              //      Should be a directory...
++                                              if( Type != EXT2_FT_DIR )
++                                              {
++                                                      //      Invalid path...
++                                                      //      Can have only a directory in the middle of the path...
++                                                      //
++                                                      RC = STATUS_OBJECT_PATH_NOT_FOUND;
++                                                      try_return( RC );
++                                              }
++
++                                              PtrCurrFileObject = NULL;
++                                      }
++                                      else
++                                      {
++                                              //
++                                              //      Done Parsing...
++                                              //      Found the file...
++                                              //
++                                              Found = TRUE;
++                                              
++                                              //
++                                              //      Was I supposed to create a new file?
++                                              //
++                                              if (RequestedDisposition == FILE_CREATE &&
++                                                      ReturnedInformation != FILE_CREATED ) 
++                                              {
++                                                      ReturnedInformation = FILE_EXISTS;
++                                                      RC = STATUS_OBJECT_NAME_COLLISION;
++                                                      try_return(RC);
++                                              }
++                                              
++                                              //      Is this the type of file I was looking for?
++                                              //      Do some checking here...
++
++                                              if( Type != EXT2_FT_DIR && Type != EXT2_FT_REG_FILE )
++                                              {
++                                                      //      Deny access!
++                                                      //      Cannot open a special file...
++                                                      RC = STATUS_ACCESS_DENIED;
++                                                      try_return( RC );
++
++                                              }
++                                              if( DirectoryOnlyRequested && Type != EXT2_FT_DIR )
++                                              {
++                                                      RC = STATUS_NOT_A_DIRECTORY;
++                                                      try_return( RC );
++                                              }
++                                              if( FileOnlyRequested && Type == EXT2_FT_DIR )
++                                              {
++                                                      RC = STATUS_FILE_IS_A_DIRECTORY;
++                                                      try_return(RC);
++                                              }
++
++                                              PtrCurrFileObject = PtrNewFileObject;
++                                              //      Things seem to be ok enough!
++                                              //      Proceeing with the Open/Create...
++                                              
++                                      }
++
++                              
++                                      //
++                                      //      Create an FCB and initialise it...
++                                      //
++                                      {
++                                              PtrExt2ObjectName               PtrObjectName;
++                                              
++                                              //      Initialising the object name...
++                                              PtrObjectName = Ext2AllocateObjectName();
++                                              Ext2CopyUnicodeString( &PtrObjectName->ObjectName, &CurrentName ); 
++                                              //      RtlInitUnicodeString( &PtrObjectName->ObjectName, CurrentName.Buffer );
++
++                                              if( !NT_SUCCESS( Ext2CreateNewFCB( 
++                                                      &PtrNextFCB,                            //      the new FCB
++                                                      ZeroSize,                                       //      AllocationSize,
++                                                      ZeroSize,                                       //      EndOfFile,
++                                      PtrCurrFileObject,                      //      The File Object
++                                                      PtrVCB,
++                                                      PtrObjectName  )  )  )
++                                              {
++                                                      RC = STATUS_INSUFFICIENT_RESOURCES;
++                                                      try_return(RC);
++                                              }
++
++                                              if( Type == EXT2_FT_DIR )
++                                                      PtrNextFCB->FCBFlags |= EXT2_FCB_DIRECTORY;
++                                              else if( Type != EXT2_FT_REG_FILE )
++                                                      PtrNextFCB->FCBFlags |= EXT2_FCB_SPECIAL_FILE;
++
++                                              PtrNextFCB->INodeNo = CurrInodeNo ;
++                                              PtrNextFCB->ParentINodeNo = PtrCurrFCB->INodeNo;
++
++                                              if( PtrCurrFileObject == NULL && CurrInodeNo != EXT2_ROOT_INO )
++                                              {
++                                                      //      This is an FCB created to cache the reads done while parsing
++                                                      //      Put this FCB on the ClosableFCBList 
++                                                      if( !PtrNextFCB->ClosableFCBs.OnClosableFCBList )
++                                                      {
++                                                                      InsertTailList( &PtrVCB->ClosableFCBs.ClosableFCBListHead,
++                                                                              &PtrNextFCB->ClosableFCBs.ClosableFCBList );
++                                                                      PtrVCB->ClosableFCBs.Count++;
++                                                                      PtrNextFCB->ClosableFCBs.OnClosableFCBList = TRUE;
++                                                      }
++                                              }
++                                      }
++                              }
++      
++                              //
++                              //      Still not done parsing...
++                              //      miles to go before I open... ;)
++                              //
++                              PtrCurrFCB = PtrNextFCB;
++                      }
++
++                      PtrNewFCB = PtrNextFCB;
++              }
++              
++
++              //      If I get this far...
++              //      it means, I have located the file...
++              //      I even have an FCB to represent it!!!
++
++              if ( NT_SUCCESS (RC) ) 
++              {
++
++                      if ((PtrNewFCB->FCBFlags & EXT2_FCB_DIRECTORY) && ((RequestedDisposition == FILE_SUPERSEDE) ||
++                                (RequestedDisposition == FILE_OVERWRITE) || (RequestedDisposition == FILE_OVERWRITE_IF ))) 
++                      {
++                              RC = STATUS_FILE_IS_A_DIRECTORY;
++                              try_return(RC);
++                      }
++              
++                      
++                      // Check share access and fail if the share conflicts with an existing
++                      // open.
++                      
++                      if (PtrNewFCB->OpenHandleCount > 0) 
++                      {
++                              // The FCB is currently in use by some thread.
++                              // We must check whether the requested access/share access
++                              // conflicts with the existing open operations.
++
++                              if (!NT_SUCCESS(RC = IoCheckShareAccess(DesiredAccess, ShareAccess, PtrNewFileObject,
++                                                                                              &(PtrNewFCB->FCBShareAccess), TRUE))) 
++                              {
++                                      // Ext2CloseCCB(PtrNewCCB);
++                                      try_return(RC);
++                              }
++                      } 
++                      else 
++                      {
++                              IoSetShareAccess(DesiredAccess, ShareAccess, PtrNewFileObject, &(PtrNewFCB->FCBShareAccess));
++                      }
++
++                      //
++                      //      Allocating a new CCB Structure...
++                      //      
++                      Ext2CreateNewCCB( &PtrNewCCB, PtrNewFCB, PtrNewFileObject);
++                      PtrNewFileObject->FsContext2 = (void *) PtrNewCCB;
++                      Ext2CopyUnicodeString( &(PtrNewCCB->AbsolutePathName), &AbsolutePathName );
++
++                      if( ReturnedInformation == -1 )
++                      {
++                              //      
++                              //      ReturnedInformation has not been set so far...
++                              //
++                              ReturnedInformation = FILE_OPENED;
++                      }
++
++                      // If a supersede or overwrite was requested, do so now ...
++                      if (RequestedDisposition == FILE_SUPERSEDE) 
++                      {
++                              // Attempt the operation here ...
++                              if( Ext2SupersedeFile( PtrNewFCB, PtrIrpContext) )
++                              {
++                                      ReturnedInformation = FILE_SUPERSEDED;
++                              }
++                      }
++                      
++                      else if ((RequestedDisposition == FILE_OVERWRITE) || (RequestedDisposition == FILE_OVERWRITE_IF))
++                      {
++                              // Attempt the overwrite operation...
++                              if( Ext2OverwriteFile( PtrNewFCB, PtrIrpContext) )
++                              {
++                                      ReturnedInformation = FILE_OVERWRITTEN;
++                              }
++                      }
++                      if( AllocationSize )
++                      {
++                              if( ReturnedInformation == FILE_CREATED ||
++                                      ReturnedInformation == FILE_SUPERSEDED )
++                              {
++                                      ULONG CurrentSize;
++                                      ULONG LogicalBlockSize = EXT2_MIN_BLOCK_SIZE << PtrVCB->LogBlockSize;
++                                      
++                                      for( CurrentSize = 0; CurrentSize < AllocationSize; CurrentSize += LogicalBlockSize )
++                                      {
++                                              Ext2AddBlockToFile( PtrIrpContext, PtrVCB, PtrNewFCB, PtrNewFileObject, FALSE );
++                                      }
++                              }
++                      }
++
++                      if( ReturnedInformation == FILE_CREATED )
++                      {
++                              //      Allocate some data blocks if 
++                              //              1. initial file size has been specified...
++                              //              2. if the file is a Directory...
++                              //                      In case of (2) make entries for '.' and '..'
++                              //      Zero out the Blocks...
++
++                              UNICODE_STRING          Name;
++
++                              if( DirectoryOnlyRequested )
++                              {
++
++                                      Ext2CopyCharToUnicodeString( &Name, ".", 1 );
++                                      Ext2MakeNewDirectoryEntry( PtrIrpContext, PtrNewFCB, PtrNewFileObject, &Name, EXT2_FT_DIR, PtrNewFCB->INodeNo);
++
++                                      Name.Buffer[1] = '.';
++                                      Name.Buffer[2] = '\0';
++                                      Name.Length += 2;
++                                      Ext2MakeNewDirectoryEntry( PtrIrpContext, PtrNewFCB, PtrNewFileObject, &Name, EXT2_FT_DIR, PtrNewFCB->ParentINodeNo );
++                                      Ext2DeallocateUnicodeString( &Name );
++                              }
++                      }
++                      if( OpenTargetDirectory )
++                      {
++                              //
++                              //      Save the taget file name in the CCB...
++                              //
++                              Ext2CopyUnicodeString( 
++                                      &PtrNewCCB->RenameLinkTargetFileName,
++                                      &RenameLinkTargetFileName );
++                              Ext2DeallocateUnicodeString( &RenameLinkTargetFileName );
++                      }
++              }
++
++              try_exit:       NOTHING;
++
++      }
++      finally 
++      {
++              if (AcquiredVCB) 
++              {
++                      ASSERT(PtrVCB);
++                      Ext2ReleaseResource(&(PtrVCB->VCBResource));
++
++                      AcquiredVCB = FALSE;
++                      DebugTrace(DEBUG_TRACE_MISC,   "*** VCB released [Create]", 0);
++
++                      if( PtrNewFileObject )
++                      {
++                              DebugTrace(DEBUG_TRACE_FILE_OBJ,  "###### File Pointer 0x%LX [Create]", PtrNewFileObject);
++                      }
++              }
++
++              if (AbsolutePathName.Buffer != NULL) 
++              {
++                      DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [Create]", AbsolutePathName.Buffer );
++                      ExFreePool(AbsolutePathName.Buffer);
++              }
++
++              // Complete the request unless we are here as part of unwinding
++              //      when an exception condition was encountered, OR
++              //      if the request has been deferred (i.e. posted for later handling)
++              if (RC != STATUS_PENDING) 
++              {
++                      // If we acquired any FCB resources, release them now ...
++
++                      // If any intermediate (directory) open operations were performed,
++                      //      implement the corresponding close (do *not* however close
++                      //      the target you have opened on behalf of the caller ...).
++
++                      if (NT_SUCCESS(RC)) 
++                      {
++                              // Update the file object such that:
++                              //      (a) the FsContext field points to the NTRequiredFCB field
++                              //               in the FCB
++                              //      (b) the FsContext2 field points to the CCB created as a
++                              //               result of the open operation
++
++                              // If write-through was requested, then mark the file object
++                              //      appropriately
++                              if (WriteThroughRequested) 
++                              {
++                                      PtrNewFileObject->Flags |= FO_WRITE_THROUGH;
++                              }
++                              DebugTrace( DEBUG_TRACE_SPECIAL,   " === Create/Open successful", 0 );
++                      } 
++                      else 
++                      {
++                              DebugTrace( DEBUG_TRACE_SPECIAL,   " === Create/Open failed", 0 );
++                              // Perform failure related post-processing now
++                      }
++
++                      // As long as this unwinding is not being performed as a result of
++                      //      an exception condition, complete the IRP ...
++                      if (!(PtrIrpContext->IrpContextFlags & EXT2_IRP_CONTEXT_EXCEPTION)) 
++                      {
++                              PtrIrp->IoStatus.Status = RC;
++                              PtrIrp->IoStatus.Information = ReturnedInformation;
++                      
++                              // Free up the Irp Context
++                              Ext2ReleaseIrpContext(PtrIrpContext);
++                              
++                              // complete the IRP
++                              IoCompleteRequest(PtrIrp, IO_DISK_INCREMENT);
++                      }
++              }
++      }
++      return(RC);
++}
++
++
++/*************************************************************************
++*
++* Function: Ext2OpenVolume()
++*
++* Description:
++*     Open a logical volume for the caller.
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL
++*
++* Return Value: STATUS_SUCCESS/Error
++*
++*************************************************************************/
++NTSTATUS Ext2OpenVolume(
++PtrExt2VCB                            PtrVCB,                                 // volume to be opened
++PtrExt2IrpContext             PtrIrpContext,                  // IRP context
++PIRP                                          PtrIrp,                                 // original/user IRP
++unsigned short                        ShareAccess,                    // share access
++PIO_SECURITY_CONTEXT  PtrSecurityContext,     // caller's context (incl access)
++PFILE_OBJECT                  PtrNewFileObject)               // I/O Mgr. created file object
++{
++      NTSTATUS                                RC = STATUS_SUCCESS;
++      PtrExt2CCB                      PtrCCB = NULL;
++
++      try {
++              // check for exclusive open requests (using share modes supplied)
++              //      and determine whether it is even possible to open the volume
++              //      with the specified share modes (e.g. if caller does not
++              //      wish to share read or share write ...)
++      
++              //      Use IoCheckShareAccess() and IoSetShareAccess() here ...        
++              //      They are defined in the DDK.
++
++              //      You might also wish to check the caller's security context
++              //      to see whether you wish to allow the volume open or not.
++              //      Use the SeAccessCheck() routine described in the DDK for        this purpose.
++      
++              // create a new CCB structure
++              if (!(PtrCCB = Ext2AllocateCCB())) 
++              {
++                      RC = STATUS_INSUFFICIENT_RESOURCES;
++                      try_return(RC);
++              }
++
++              // initialize the CCB
++              PtrCCB->PtrFCB = (PtrExt2FCB)(PtrVCB);
++              InsertTailList(&(PtrVCB->VolumeOpenListHead), &(PtrCCB->NextCCB));
++
++              // initialize the CCB to point to the file object
++              PtrCCB->PtrFileObject = PtrNewFileObject;
++
++              Ext2SetFlag(PtrCCB->CCBFlags, EXT2_CCB_VOLUME_OPEN);
++
++              // initialize the file object appropriately
++              PtrNewFileObject->FsContext = (void *)( &(PtrVCB->CommonVCBHeader) );
++              PtrNewFileObject->FsContext2 = (void *)(PtrCCB);
++
++              // increment the number of outstanding open operations on this
++              //      logical volume (i.e. volume cannot be dismounted)
++
++              //      You might be concerned about 32 bit wrap-around though I would
++              //      argue that it is unlikely ... :-)
++              (PtrVCB->VCBOpenCount)++;
++      
++              // now set the IoStatus Information value correctly in the IRP
++              //      (caller will set the status field)
++              PtrIrp->IoStatus.Information = FILE_OPENED;
++      
++              try_exit:       NOTHING;
++      } 
++      finally 
++      {
++              NOTHING;
++      }
++
++      return(RC);
++}
++
++/*************************************************************************
++*
++* Function: Ext2InitializeFCB()
++*
++* Description:
++*     Initialize a new FCB structure and also the sent-in file object
++*     (if supplied)
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL
++*
++* Return Value: None
++*
++*************************************************************************
++void Ext2InitializeFCB(
++PtrExt2FCB                            PtrNewFCB,              // FCB structure to be initialized
++PtrExt2VCB                            PtrVCB,                 // logical volume (VCB) pointer
++PtrExt2ObjectName             PtrObjectName,  // name of the object
++uint32                                        Flags,                  // is this a file/directory, etc.
++PFILE_OBJECT                  PtrFileObject)  // optional file object to be initialized
++{
++      // Initialize the disk dependent portion as you see fit
++
++      // Initialize the two ERESOURCE objects
++      ExInitializeResourceLite(&(PtrNewFCB->NTRequiredFCB.MainResource));
++      ExInitializeResourceLite(&(PtrNewFCB->NTRequiredFCB.PagingIoResource));
++
++      PtrNewFCB->FCBFlags |= EXT2_INITIALIZED_MAIN_RESOURCE | EXT2_INITIALIZED_PAGING_IO_RESOURCE | Flags;
++
++      PtrNewFCB->PtrVCB = PtrVCB;
++
++      // caller MUST ensure that VCB has been acquired exclusively
++      InsertTailList(&(PtrVCB->FCBListHead), &(PtrNewFCB->NextFCB));
++
++      // initialize the various list heads
++      InitializeListHead(&(PtrNewFCB->CCBListHead));
++
++//    PtrNewFCB->ReferenceCount = 1;
++//    PtrNewFCB->OpenHandleCount = 1;
++
++      if( PtrObjectName )
++      {
++              PtrNewFCB->FCBName = PtrObjectName;
++      }
++
++      if ( PtrFileObject )
++      {
++              PtrFileObject->FsContext = (void *)(&(PtrNewFCB->NTRequiredFCB));
++      }
++
++      return;
++}
++*/
++
++/*************************************************************************
++*
++* Function: Ext2OpenRootDirectory()
++*
++* Description:
++*     Open the root directory for a volume
++*     
++*
++* Expected Interrupt Level (for execution) :
++*
++*  ???
++*
++* Return Value: None
++*
++*************************************************************************/
++NTSTATUS Ext2OpenRootDirectory(
++      PtrExt2VCB                              PtrVCB,                                 // volume 
++      PtrExt2IrpContext               PtrIrpContext,                  // IRP context
++      PIRP                                    PtrIrp,                                 // original/user IRP
++      unsigned short                  ShareAccess,                    // share access
++      PIO_SECURITY_CONTEXT    PtrSecurityContext,             // caller's context (incl access)
++      PFILE_OBJECT                    PtrNewFileObject                // I/O Mgr. created file object
++      )
++{
++      //      Declerations...
++      PtrExt2CCB PtrCCB;
++      
++      ASSERT( PtrVCB );
++      ASSERT( PtrVCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB);
++      ASSERT( PtrVCB->PtrRootDirectoryFCB );
++      AssertFCB( PtrVCB->PtrRootDirectoryFCB );
++              
++      PtrVCB->PtrRootDirectoryFCB->INodeNo = EXT2_ROOT_INO;
++      
++      //      Create a new CCB...
++      Ext2CreateNewCCB( &PtrCCB, PtrVCB->PtrRootDirectoryFCB, PtrNewFileObject);
++      PtrNewFileObject->FsContext = (void *) &(PtrVCB->PtrRootDirectoryFCB->NTRequiredFCB.CommonFCBHeader);
++      PtrVCB->PtrRootDirectoryFCB->FCBFlags |= EXT2_FCB_DIRECTORY;
++      PtrNewFileObject->FsContext2 = (void *) PtrCCB;
++      PtrNewFileObject->SectionObjectPointer = &PtrVCB->PtrRootDirectoryFCB->NTRequiredFCB.SectionObject;
++      PtrNewFileObject->Vpb = PtrVCB->PtrVPB;
++
++      Ext2CopyUnicodeString( &(PtrCCB->AbsolutePathName), &PtrVCB->PtrRootDirectoryFCB->FCBName->ObjectName );
++
++
++      return STATUS_SUCCESS;
++}
++
++
++
++PtrExt2FCB Ext2LocateChildFCBInCore(
++      PtrExt2VCB                              PtrVCB, 
++      PUNICODE_STRING                 PtrName, 
++      ULONG                                   ParentInodeNo )
++{
++
++      PtrExt2FCB PtrFCB = NULL;
++      ULONG InodeNo = 0;
++      PLIST_ENTRY     PtrEntry;
++
++      if( IsListEmpty( &(PtrVCB->FCBListHead) ) )
++      {
++              return NULL;    //      Failure;
++      }
++
++      for( PtrEntry = PtrVCB->FCBListHead.Flink; 
++                      PtrEntry != &PtrVCB->FCBListHead; 
++                      PtrEntry = PtrEntry->Flink )
++      {
++              PtrFCB = CONTAINING_RECORD( PtrEntry, Ext2FCB, NextFCB );
++              ASSERT( PtrFCB );
++              if( PtrFCB->ParentINodeNo == ParentInodeNo )
++              {
++                      if( RtlCompareUnicodeString( &PtrFCB->FCBName->ObjectName, PtrName, TRUE ) == 0 )
++                              return PtrFCB;
++              }
++      }
++
++      return NULL;
++}
++
++PtrExt2FCB    Ext2LocateFCBInCore(
++      PtrExt2VCB                              PtrVCB, 
++      ULONG                                   InodeNo )
++{
++      PtrExt2FCB PtrFCB = NULL;
++      PLIST_ENTRY     PtrEntry;
++
++      if( IsListEmpty( &(PtrVCB->FCBListHead) ) )
++      {
++              return NULL;    //      Failure;
++      }
++
++      for( PtrEntry = PtrVCB->FCBListHead.Flink; 
++                      PtrEntry != &PtrVCB->FCBListHead; 
++                      PtrEntry = PtrEntry->Flink )
++      {
++              PtrFCB = CONTAINING_RECORD( PtrEntry, Ext2FCB, NextFCB );
++              ASSERT( PtrFCB );
++              if( PtrFCB->INodeNo == InodeNo )
++              {
++                      return PtrFCB;
++              }
++      }
++
++      return NULL;
++}
++
++
++ULONG Ext2LocateFileInDisk (
++      PtrExt2VCB                              PtrVCB,
++      PUNICODE_STRING                 PtrCurrentName, 
++      PtrExt2FCB                              PtrParentFCB,
++      ULONG                                   *Type )
++{
++
++      PtrExt2FCB                      PtrNewFCB = NULL;
++      PFILE_OBJECT            PtrFileObject = NULL;
++      ULONG                           InodeNo = 0;
++      
++      *Type = EXT2_FT_UNKNOWN;
++
++      //      1. 
++      //      Initialize the Blocks in the FCB...
++      //
++      Ext2InitializeFCBInodeInfo( PtrParentFCB );
++
++      
++      //      2.
++      //      Is there a file object I can use for caching??
++      //      If not create one...
++      //
++      if( !PtrParentFCB->DcbFcb.Dcb.PtrDirFileObject )
++      {
++              //
++              //      No Directory File Object?
++              //      No problem, will create one...
++              //
++
++              //      Acquire the MainResource first though...
++                      
++                      PtrParentFCB->DcbFcb.Dcb.PtrDirFileObject = IoCreateStreamFileObject(NULL, PtrVCB->TargetDeviceObject );
++                      PtrFileObject = PtrParentFCB->DcbFcb.Dcb.PtrDirFileObject;
++                      
++                      if( !PtrFileObject )
++                      {
++                              Ext2BreakPoint();
++                              return 0;
++                      }
++                      PtrFileObject->ReadAccess = TRUE;
++                      PtrFileObject->WriteAccess = TRUE;
++
++                      //      Associate the file stream with the Volume parameter block...
++                      PtrFileObject->Vpb = PtrVCB->PtrVPB;
++
++                      //      No caching as yet...
++                      PtrFileObject->PrivateCacheMap = NULL;
++
++                      //      this establishes the FCB - File Object connection...
++                      PtrFileObject->FsContext = (void *)( & (PtrParentFCB->NTRequiredFCB.CommonFCBHeader) );
++
++                      //      Initialize the section object pointer...
++                      PtrFileObject->SectionObjectPointer = &(PtrParentFCB->NTRequiredFCB.SectionObject);
++      }
++      else
++      {
++              //      
++              //      I do have a file object... 
++              //      I am using it now!
++              //
++              PtrFileObject = PtrParentFCB->DcbFcb.Dcb.PtrDirFileObject;
++      }
++
++      //      3.
++      //      Got hold of a file object? Good ;)
++      //      Now initiating Caching, pinned access to be precise ...
++      //
++      if (PtrFileObject->PrivateCacheMap == NULL) 
++      {
++                      CcInitializeCacheMap(PtrFileObject, (PCC_FILE_SIZES)(&(PtrParentFCB->NTRequiredFCB.CommonFCBHeader.AllocationSize)),
++                              TRUE,           // We utilize pin access for directories
++                              &(Ext2GlobalData.CacheMgrCallBacks), // callbacks
++                              PtrParentFCB );         // The context used in callbacks
++      }
++
++      //      4.
++      //      Getting down to the real business now... ;)
++      //      Read in the directory contents and do a search 
++      //      a sequential search to be precise...
++      //      Wish Mm'm Renuga were reading this
++      //      Would feel proud...     ;)
++      //
++      {
++              LARGE_INTEGER   StartBufferOffset;
++              ULONG                   PinBufferLength;
++              ULONG                   BufferIndex;
++              PBCB                    PtrBCB = NULL;
++              BYTE *                  PtrPinnedBlockBuffer = NULL;
++              PEXT2_DIR_ENTRY PtrDirEntry = NULL;
++              BOOLEAN                 Found;
++              int                             i;
++
++
++              StartBufferOffset.QuadPart = 0;
++
++              //
++              //      Read in the whole damn directory
++              //      **Bad programming**
++              //      Will do for now.
++              //
++              PinBufferLength = PtrParentFCB->NTRequiredFCB.CommonFCBHeader.FileSize.LowPart;
++              if (!CcMapData( PtrFileObject,
++                  &StartBufferOffset,
++                  PinBufferLength,
++                  TRUE,
++                  &PtrBCB,
++                  (PVOID*)&PtrPinnedBlockBuffer ) )
++              {
++
++                      
++              }
++              //
++              //      Walking through now...
++              //
++              
++              for( BufferIndex = 0, Found = FALSE; !Found && BufferIndex < ( PtrParentFCB->NTRequiredFCB.CommonFCBHeader.FileSize.QuadPart - 1) ; BufferIndex += PtrDirEntry->rec_len )
++              {
++                      PtrDirEntry = (PEXT2_DIR_ENTRY) &PtrPinnedBlockBuffer[ BufferIndex ];
++                      if( PtrDirEntry->name_len == 0 || PtrDirEntry->rec_len == 0 || PtrDirEntry->inode == 0)
++                      {
++                              //      Invalid entry...
++                              //  Ignore...
++                              continue;
++                      }
++                      //
++                      //      Comparing ( case sensitive )
++                      //      Directory entry is not NULL terminated...
++                      //      nor is the CurrentName...
++                      //
++                      if( PtrDirEntry->name_len != (PtrCurrentName->Length / 2) )
++                              continue;
++                      
++                      for( i = 0, Found = TRUE ; i < PtrDirEntry->name_len ; i++ )
++                      {
++                              if( PtrDirEntry->name[ i ] != PtrCurrentName->Buffer[ i ] )
++                              {
++                                      Found = FALSE;
++                                      break;
++
++                              }
++                      }
++                      
++              }
++              if( Found )
++              {
++                      InodeNo = PtrDirEntry->inode;
++
++                      if( PtrDirEntry->file_type == EXT2_FT_UNKNOWN )
++                      {
++
++                              //      Old Fashioned Directory entries...
++                              //      Will have to read in the Inode to determine the File Type...
++                              EXT2_INODE      Inode;
++                              //      PtrInode = Ext2AllocatePool( NonPagedPool, sizeof( EXT2_INODE )  );
++                              Ext2ReadInode( PtrVCB, InodeNo, &Inode );       
++
++                              if( Ext2IsModeRegularFile( Inode.i_mode ) )
++                              {
++                                      *Type = EXT2_FT_REG_FILE;
++                              }
++                              else if ( Ext2IsModeDirectory( Inode.i_mode) )
++                              {
++                                      //      Directory...
++                                      *Type = EXT2_FT_DIR;
++                              }
++                              else if( Ext2IsModeSymbolicLink(Inode.i_mode) )
++                              {
++                                      *Type = EXT2_FT_SYMLINK;
++                              }
++                              else if( Ext2IsModePipe(Inode.i_mode) )
++                              {
++                                      *Type = EXT2_FT_FIFO;
++                              }
++                              else if( Ext2IsModeCharacterDevice(Inode.i_mode) )
++                              {
++                                      *Type = EXT2_FT_CHRDEV;
++                              }
++                              else if( Ext2IsModeBlockDevice(Inode.i_mode) )
++                              {
++                                      *Type = EXT2_FT_BLKDEV;
++                              }
++                              else if( Ext2IsModeSocket(Inode.i_mode) )
++                              {
++                                      *Type = EXT2_FT_SOCK;
++                              }
++                              else
++                              {
++                                      *Type = EXT2_FT_UNKNOWN;
++                              }
++                              
++                              //DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [Create]", PtrInode );
++                              //ExFreePool( PtrInode );
++                      }
++                      else
++                      {
++                              *Type = PtrDirEntry->file_type;
++                      }
++              }
++
++              CcUnpinData( PtrBCB );
++              PtrBCB = NULL;
++
++              return InodeNo;
++      }
++}
++
++
++/*************************************************************************
++*
++* Function: Ext2CreateFile()
++*
++* Description:
++*     Creates a new file on the disk
++*     
++* Expected Interrupt Level (for execution) :
++*     IRQL_PASSIVE_LEVEL
++*
++* Restrictions:
++*     Expects the VCB to be acquired Exclusively before being invoked
++*
++* Return Value: None
++*
++*************************************************************************/
++ULONG Ext2CreateFile( 
++      PtrExt2IrpContext               PtrIrpContext,
++      PtrExt2VCB                              PtrVCB,
++      PUNICODE_STRING                 PtrName, 
++      PtrExt2FCB                              PtrParentFCB,
++      ULONG                                   Type)
++{
++      EXT2_INODE      Inode, ParentInode;
++
++      ULONG           NewInodeNo = 0;
++      BOOLEAN         FCBAcquired = FALSE;
++
++      ULONG           LogicalBlockSize = 0;
++
++      try
++      {
++              
++
++              //      0. Verify if the creation is possible,,,
++              if( Type != EXT2_FT_DIR && Type != EXT2_FT_REG_FILE )
++              {
++                      //
++                      //      Can create only a directory or a regular file...
++                      //
++                      return 0;
++              }
++              
++              //      1. Allocate an i-node...
++              
++              NewInodeNo = Ext2AllocInode( PtrIrpContext, PtrVCB, PtrParentFCB->INodeNo );
++              
++              //      NewInodeNo = 12;
++
++              if( !NewInodeNo )
++              {
++                      return 0;
++              }
++              
++              //      2. Acquire the Parent FCB Exclusively...
++              if( !ExAcquireResourceExclusiveLite(&( PtrParentFCB->NTRequiredFCB.MainResource ), TRUE) )
++              {
++                      Ext2DeallocInode( PtrIrpContext, PtrVCB, NewInodeNo );
++                      try_return( NewInodeNo = 0);
++              }
++              FCBAcquired = TRUE;
++
++              //      3. Make an entry in the parent Directory...             
++              ASSERT( PtrParentFCB->DcbFcb.Dcb.PtrDirFileObject );
++              
++              Ext2MakeNewDirectoryEntry(
++                      PtrIrpContext,
++                      PtrParentFCB, 
++                      PtrParentFCB->DcbFcb.Dcb.PtrDirFileObject, 
++                      PtrName, Type, NewInodeNo );
++      
++              
++              //      4. Initialize an inode entry and  write it to disk...
++              LogicalBlockSize = EXT2_MIN_BLOCK_SIZE << PtrVCB->LogBlockSize;
++
++              {
++                      //      To be deleted
++                      Ext2ReadInode( PtrVCB, NewInodeNo, &Inode );
++              }
++
++              RtlZeroMemory( &Inode, sizeof( EXT2_INODE ) );
++              if( Type == EXT2_FT_DIR )
++              {
++                      Inode.i_mode = 0x41ff;
++
++                      //      In addition to the usual link, 
++                      //      there will be an additional link in the directory itself - the '.' entry
++                      Inode.i_links_count = 2;
++
++                      //      Incrementing the link count for the parent as well...
++                      Ext2ReadInode( PtrVCB, PtrParentFCB->INodeNo, &ParentInode );
++                      ParentInode.i_links_count++;
++                      Ext2WriteInode( PtrIrpContext, PtrVCB, PtrParentFCB->INodeNo, &ParentInode );
++
++              }
++              else
++              {
++                      Inode.i_mode = 0x81ff;
++                      Inode.i_links_count = 1;
++              }
++
++
++              {
++                      //
++                      //      Setting the time fields in the inode...
++                      //
++                      ULONG Time;
++                      Time = Ext2GetCurrentTime();
++                      Inode.i_ctime = Time;
++                      Inode.i_atime = Time;
++                      Inode.i_mtime = Time;
++                      Inode.i_dtime = 0;                      //      Deleted time;
++              }
++
++              Ext2WriteInode( PtrIrpContext, PtrVCB, NewInodeNo, &Inode );
++
++              try_exit:       NOTHING;
++      }
++      finally 
++      {
++              if( FCBAcquired )
++              {
++                      Ext2ReleaseResource( &(PtrParentFCB->NTRequiredFCB.MainResource) );
++              }
++      }
++
++      return NewInodeNo ;
++}
++
++/*************************************************************************
++*
++* Function: Ext2CreateFile()
++*
++* Description:
++*     Overwrites an existing file on the disk
++*     
++* Expected Interrupt Level (for execution) :
++*     IRQL_PASSIVE_LEVEL
++*
++* Restrictions:
++*     Expects the VCB to be acquired Exclusively before being invoked
++*
++* Return Value: None
++*
++*************************************************************************/
++BOOLEAN Ext2OverwriteFile(
++      PtrExt2FCB                      PtrFCB,
++      PtrExt2IrpContext       PtrIrpContext)
++{
++      EXT2_INODE                      Inode;
++      PtrExt2VCB                      PtrVCB = PtrFCB->PtrVCB;
++      ULONG                           i;
++      ULONG   Time;
++      Time = Ext2GetCurrentTime();
++
++      Ext2InitializeFCBInodeInfo( PtrFCB );
++      //      1.
++      //      Update the inode...
++      if( !NT_SUCCESS( Ext2ReadInode( PtrVCB, PtrFCB->INodeNo, &Inode ) ) )
++      {
++              return FALSE;
++      }
++
++      Inode.i_size = 0;
++      Inode.i_blocks = 0;
++      Inode.i_atime = Time;
++      Inode.i_mtime = Time;
++      Inode.i_dtime = 0;
++
++      for( i = 0; i < EXT2_N_BLOCKS; i++ )
++      {
++              Inode.i_block[ i ] = 0;
++      }
++
++      if( !NT_SUCCESS( Ext2WriteInode( PtrIrpContext, PtrVCB, PtrFCB->INodeNo, &Inode ) ) )
++      {
++              return FALSE;
++      }
++
++      //      2.
++      //      Release all the data blocks...
++      if( !Ext2ReleaseDataBlocks( PtrFCB, PtrIrpContext) )
++      {
++              return FALSE;
++      }
++      
++      Ext2ClearFlag( PtrFCB->FCBFlags, EXT2_FCB_BLOCKS_INITIALIZED );
++      Ext2InitializeFCBInodeInfo( PtrFCB );
++      
++      return TRUE;
++}
++
++/*************************************************************************
++*
++* Function: Ext2SupersedeFile()
++*
++* Description:
++*     Supersedes an existing file on the disk
++*     
++* Expected Interrupt Level (for execution) :
++*     IRQL_PASSIVE_LEVEL
++*
++* Restrictions:
++*     Expects the VCB to be acquired Exclusively before being invoked
++*
++* Return Value: None
++*
++*************************************************************************/
++BOOLEAN Ext2SupersedeFile(
++      PtrExt2FCB                      PtrFCB,
++      PtrExt2IrpContext       PtrIrpContext)
++{
++      EXT2_INODE                      Inode;
++      PtrExt2VCB                      PtrVCB = PtrFCB->PtrVCB;
++      ULONG                           i;
++
++      Ext2InitializeFCBInodeInfo( PtrFCB );
++
++      //      1.
++      //      Initialize the inode...
++      RtlZeroMemory( &Inode, sizeof( EXT2_INODE ) );
++
++      //      Setting the file mode...
++      //      This operation is allowed only for a regular file...
++      Inode.i_mode = 0x81ff;
++
++      //      Maintaining the old link count...
++      Inode.i_links_count = PtrFCB->LinkCount;
++
++      //      Setting the time fields in the inode...
++      {
++              ULONG Time;
++              Time = Ext2GetCurrentTime();
++              Inode.i_ctime = Time;
++              Inode.i_atime = Time;
++              Inode.i_mtime = Time;
++              Inode.i_dtime = 0;                      //      Deleted time;
++      }
++
++      if( !NT_SUCCESS( Ext2WriteInode( PtrIrpContext, PtrVCB, PtrFCB->INodeNo, &Inode ) ) )
++      {
++              return FALSE;
++      }
++
++      //      2.
++      //      Release all the data blocks...
++      if( !Ext2ReleaseDataBlocks( PtrFCB, PtrIrpContext) )
++      {
++              return FALSE;
++      }
++      
++      Ext2ClearFlag( PtrFCB->FCBFlags, EXT2_FCB_BLOCKS_INITIALIZED );
++      Ext2InitializeFCBInodeInfo( PtrFCB );
++      
++      return TRUE;
++}
index 0000000,0000000..0238986
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,210 @@@
++/*************************************************************************
++*
++* File: devcntrl.c
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     Contains code to handle the "Device IOCTL" dispatch entry point.
++*
++* Author: Manoj Paul Joseph
++*
++*
++*************************************************************************/
++
++#include                      "ext2fsd.h"
++
++// define the file specific bug-check id
++#define                       EXT2_BUG_CHECK_ID                               EXT2_FILE_DEVICE_CONTROL
++#define                       DEBUG_LEVEL                                             DEBUG_TRACE_DEVCTRL
++
++
++#if(_WIN32_WINNT < 0x0400)
++#define IOCTL_REDIR_QUERY_PATH   CTL_CODE(FILE_DEVICE_NETWORK_FILE_SYSTEM, 99, METHOD_NEITHER, FILE_ANY_ACCESS)
++
++typedef struct _QUERY_PATH_REQUEST 
++{
++    ULONG PathNameLength;
++    PIO_SECURITY_CONTEXT SecurityContext;
++    WCHAR FilePathName[1];
++} QUERY_PATH_REQUEST, *PQUERY_PATH_REQUEST;
++
++typedef struct _QUERY_PATH_RESPONSE 
++{
++    ULONG LengthAccepted;
++} QUERY_PATH_RESPONSE, *PQUERY_PATH_RESPONSE;
++#endif
++
++
++/*************************************************************************
++*
++* Function: Ext2DeviceControl()
++*
++* Description:
++*     The I/O Manager will invoke this routine to handle a Device IOCTL
++*     request
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
++*     to be deferred to a worker thread context)
++*
++* Return Value: STATUS_SUCCESS/Error
++*
++*************************************************************************/
++NTSTATUS Ext2DeviceControl(
++PDEVICE_OBJECT                DeviceObject,           // the logical volume device object
++PIRP                                  Irp)                                    // I/O Request Packet
++{
++      NTSTATUS                                RC = STATUS_SUCCESS;
++   PtrExt2IrpContext  PtrIrpContext = NULL;
++      BOOLEAN                         AreWeTopLevel = FALSE;
++
++      //      Ext2BreakPoint();
++      
++      DebugTrace(DEBUG_TRACE_IRP_ENTRY,   "Device Control IRP Received...", 0);
++
++      FsRtlEnterFileSystem();
++      ASSERT(DeviceObject);
++      ASSERT(Irp);
++
++      // set the top level context
++      AreWeTopLevel = Ext2IsIrpTopLevel(Irp);
++
++      try {
++
++              // get an IRP context structure and issue the request
++              PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject);
++              ASSERT(PtrIrpContext);
++
++              RC = Ext2CommonDeviceControl(PtrIrpContext, Irp);
++
++      } except (Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
++
++              RC = Ext2ExceptionHandler(PtrIrpContext, Irp);
++
++              Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC);
++      }
++
++      if (AreWeTopLevel) {
++              IoSetTopLevelIrp(NULL);
++      }
++
++      FsRtlExitFileSystem();
++
++      return(RC);
++}
++
++
++/*************************************************************************
++*
++* Function: Ext2CommonDeviceControl()
++*
++* Description:
++*     The actual work is performed here. This routine may be invoked in one'
++*     of the two possible contexts:
++*     (a) in the context of a system worker thread
++*     (b) in the context of the original caller
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL
++*
++* Return Value: STATUS_SUCCESS/Error
++*
++*************************************************************************/
++NTSTATUS      Ext2CommonDeviceControl(
++PtrExt2IrpContext                     PtrIrpContext,
++PIRP                                                  PtrIrp)
++{
++      NTSTATUS                                        RC = STATUS_SUCCESS;
++      PIO_STACK_LOCATION      PtrIoStackLocation = NULL;
++      PIO_STACK_LOCATION      PtrNextIoStackLocation = NULL;
++      PFILE_OBJECT                    PtrFileObject = NULL;
++      PtrExt2FCB                              PtrFCB = NULL;
++      PtrExt2CCB                              PtrCCB = NULL;
++      PtrExt2VCB                              PtrVCB = NULL;
++      ULONG                                           IoControlCode = 0;
++      void                                            *BufferPointer = NULL;
++
++      try 
++      {
++              // First, get a pointer to the current I/O stack location
++              PtrIoStackLocation = IoGetCurrentIrpStackLocation(PtrIrp);
++              ASSERT(PtrIoStackLocation);
++
++              PtrFileObject = PtrIoStackLocation->FileObject;
++              ASSERT(PtrFileObject);
++
++              PtrCCB = (PtrExt2CCB)(PtrFileObject->FsContext2);
++              ASSERT(PtrCCB);
++              PtrFCB = PtrCCB->PtrFCB;
++              ASSERT(PtrFCB);
++              
++
++              if( PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB )
++              {
++                      PtrVCB = (PtrExt2VCB)(PtrFCB);
++              }
++              else
++              {
++                      AssertFCB( PtrFCB );
++                      ASSERT(PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_FCB);
++                      PtrVCB = PtrFCB->PtrVCB;
++              }
++
++              // Get the IoControlCode value
++              IoControlCode = PtrIoStackLocation->Parameters.DeviceIoControl.IoControlCode;
++
++              // You may wish to allow only   volume open operations.
++
++              // Invoke the lower level driver in the chain.
++              PtrNextIoStackLocation = IoGetNextIrpStackLocation(PtrIrp);
++              *PtrNextIoStackLocation = *PtrIoStackLocation;
++              // Set a completion routine.
++              IoSetCompletionRoutine(PtrIrp, Ext2DevIoctlCompletion, NULL, TRUE, TRUE, TRUE);
++              // Send the request.
++              RC = IoCallDriver(PtrVCB->TargetDeviceObject, PtrIrp);
++
++              try_exit:       NOTHING;
++
++      } 
++      finally 
++      {
++              // Release the IRP context
++              if (!(PtrIrpContext->IrpContextFlags & EXT2_IRP_CONTEXT_EXCEPTION)) 
++              {
++                      // Free up the Irp Context
++                      Ext2ReleaseIrpContext(PtrIrpContext);
++              }
++      }
++
++      return(RC);
++}
++
++
++/*************************************************************************
++*
++* Function: Ext2DevIoctlCompletion()
++*
++* Description:
++*     Completion routine.
++*     
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL
++*
++* Return Value: STATUS_SUCCESS
++*
++*************************************************************************/
++NTSTATUS Ext2DevIoctlCompletion(
++PDEVICE_OBJECT                        PtrDeviceObject,
++PIRP                                          PtrIrp,
++void                                          *Context)
++{
++      if (PtrIrp->PendingReturned) {
++              IoMarkIrpPending(PtrIrp);
++      }
++
++      return(STATUS_SUCCESS);
++}
index 0000000,0000000..cadc35f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,116 @@@
++//Microsoft Developer Studio generated resource script.
++//
++#include "../inc/resource.h"
++
++#define APSTUDIO_READONLY_SYMBOLS
++/////////////////////////////////////////////////////////////////////////////
++//
++// Generated from the TEXTINCLUDE 2 resource.
++//
++#define APSTUDIO_HIDDEN_SYMBOLS
++#include "windows.h"
++#undef APSTUDIO_HIDDEN_SYMBOLS
++/* REACTOS FIXME */
++/* #include "ntverp.h" */
++
++/////////////////////////////////////////////////////////////////////////////
++#undef APSTUDIO_READONLY_SYMBOLS
++
++/////////////////////////////////////////////////////////////////////////////
++// English (U.S.) resources
++
++#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
++#ifdef _WIN32
++LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
++#pragma code_page(1252)
++#endif //_WIN32
++
++#ifdef APSTUDIO_INVOKED
++/////////////////////////////////////////////////////////////////////////////
++//
++// TEXTINCLUDE
++//
++
++1 TEXTINCLUDE DISCARDABLE 
++BEGIN
++    "..\\inc\\resource.h\0"
++END
++
++2 TEXTINCLUDE DISCARDABLE 
++BEGIN
++    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
++    "#include ""windows.h""\r\n"
++    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
++    "#include ""ntverp.h""\r\n"
++    "\0"
++END
++
++3 TEXTINCLUDE DISCARDABLE 
++BEGIN
++    "\r\n"
++    "\0"
++END
++
++#endif    // APSTUDIO_INVOKED
++
++
++#ifndef _MAC
++/////////////////////////////////////////////////////////////////////////////
++//
++// Version
++//
++
++VS_VERSION_INFO VERSIONINFO
++ FILEVERSION 0,0,0,3
++ PRODUCTVERSION 0,0,0,3
++ FILEFLAGSMASK 0x3fL
++#ifdef _DEBUG
++ FILEFLAGS 0x29L
++#else
++ FILEFLAGS 0x28L
++#endif
++ FILEOS 0x40004L
++ FILETYPE 0x3L
++ FILESUBTYPE 0x7L
++BEGIN
++    BLOCK "StringFileInfo"
++    BEGIN
++        BLOCK "040904b0"
++        BEGIN
++            VALUE "Comments", "Ext2 File System Driver\0"
++            VALUE "CompanyName", "Purayidathil\0"
++            VALUE "FileDescription", "Ext2 File System Driver\0"
++            VALUE "FileVersion", "0, 0, 0, 3\0"
++            VALUE "InternalName", "ext2.sys\0"
++            VALUE "LegalCopyright", "Copyright © 2002 Manoj Paul Joseph\0"
++            VALUE "LegalTrademarks", " - \0"
++            VALUE "OriginalFilename", "ext2.sys\0"
++            VALUE "PrivateBuild", " - \0"
++            VALUE "ProductName", "Ext2 File System Driver for Windows NT\0"
++            VALUE "ProductVersion", "0, 0, 0, 3\0"
++            VALUE "SpecialBuild", " - \0"
++        END
++    END
++    BLOCK "VarFileInfo"
++    BEGIN
++        VALUE "Translation", 0x409, 1200
++    END
++END
++
++#endif    // !_MAC
++
++#endif    // English (U.S.) resources
++/////////////////////////////////////////////////////////////////////////////
++
++
++
++#ifndef APSTUDIO_INVOKED
++/////////////////////////////////////////////////////////////////////////////
++//
++// Generated from the TEXTINCLUDE 3 resource.
++//
++
++
++/////////////////////////////////////////////////////////////////////////////
++#endif    // not APSTUDIO_INVOKED
++
index 0000000,0000000..3df67ef
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,381 @@@
++/*************************************************************************
++*
++* File: ext2init.c
++*
++* Module: Ext2 File System Driver (Kernel mode execution only)
++*
++* Description:
++*     This file contains the initialization code for the kernel mode
++*     Ext2 FSD module. The DriverEntry() routine is called by the I/O
++*     sub-system to initialize the FSD.
++*
++* Author: Manoj Paul Joseph
++*
++*************************************************************************/
++
++ 
++#include                      "ext2fsd.h"
++
++// define the file specific bug-check id
++#define                       EXT2_BUG_CHECK_ID                               EXT2_FILE_INIT
++#define                       DEBUG_LEVEL                                             (DEBUG_TRACE_INIT)
++
++#define                       EXT2_FS_NAME                                    L"\\ext2"
++
++// global variables are declared here
++Ext2Data                                      Ext2GlobalData;
++
++
++/*************************************************************************
++*
++* Function: DriverEntry()
++*
++* Description:
++*     This routine is the standard entry point for all kernel mode drivers.
++*     The routine is invoked at IRQL PASSIVE_LEVEL in the context of a
++*     system worker thread.
++*     All FSD specific data structures etc. are initialized here.
++*
++* Expected Interrupt Level (for execution) :
++*
++*  IRQL_PASSIVE_LEVEL
++*
++* Return Value: STATUS_SUCCESS/Error (will cause driver to be unloaded).
++*
++*************************************************************************/
++NTSTATUS DriverEntry(
++PDRIVER_OBJECT                DriverObject,           // created by the I/O sub-system
++PUNICODE_STRING       RegistryPath)           // path to the registry key
++{
++      NTSTATUS                RC = STATUS_SUCCESS;
++      UNICODE_STRING  DriverDeviceName;
++      BOOLEAN                 RegisteredShutdown = FALSE;
++
++#if 0
++      Ext2BreakPoint();
++#endif
++
++      try 
++      {
++              try 
++              {
++                      
++                      DebugTrace(DEBUG_TRACE_IRP_ENTRY, "Ext2 File System Driver Entry <<<<<<<", 0);
++                      // initialize the global data structure
++                      RtlZeroMemory(&Ext2GlobalData, sizeof(Ext2GlobalData));
++
++                      // initialize some required fields
++                      Ext2GlobalData.NodeIdentifier.NodeType = EXT2_NODE_TYPE_GLOBAL_DATA;
++                      Ext2GlobalData.NodeIdentifier.NodeSize = sizeof(Ext2GlobalData);
++
++                      // initialize the global data resource and remember the fact that
++                      //      the resource has been initialized
++                      RC = ExInitializeResourceLite(&(Ext2GlobalData.GlobalDataResource));
++                      ASSERT(NT_SUCCESS(RC));
++                      Ext2SetFlag(Ext2GlobalData.Ext2Flags, EXT2_DATA_FLAGS_RESOURCE_INITIALIZED);
++
++                      // keep a ptr to the driver object sent to us by the I/O Mgr
++                      Ext2GlobalData.Ext2DriverObject = DriverObject;
++
++                      // initialize the mounted logical volume list head
++                      InitializeListHead( &( Ext2GlobalData.NextVCB ) );
++
++                      // before we proceed with any more initialization, read in
++                      //      user supplied configurable values ...
++                      // if (!NT_SUCCESS(RC = Ext2ObtainRegistryValues(RegistryPath))) {
++                                      // in your commercial driver implementation, it would be
++                                      //      advisable for your driver to print an appropriate error
++                                      //      message to the system error log before leaving
++                      //              try_return(RC);
++                      //      }
++
++                      // we should have the registry data (if any), allocate zone memory ...
++                      //      This is an example of when FSD implementations try to pre-allocate
++                      //      some fixed amount of memory to avoid internal fragmentation and/or waiting
++                      //      later during run-time ...
++
++#ifdef USE_ZONES
++                      
++                      if (!NT_SUCCESS(RC = Ext2InitializeZones())) 
++                      {
++                              // we failed, print a message and leave ...
++                              try_return(RC);
++                      }
++#endif
++
++                      //
++                      //      Initialize the Thread queue structure...
++                      //
++                      KeInitializeEvent( 
++                              &Ext2GlobalData.ThreadQueue.QueueEvent,
++                              SynchronizationEvent,
++                              FALSE
++                              );
++                      KeInitializeSpinLock( &Ext2GlobalData.ThreadQueue.SpinLock );
++                      InitializeListHead( &Ext2GlobalData.ThreadQueue.ThreadQueueListHead );
++
++                      //
++                      //      Done Initializing...
++                      //      Now Creating a worker thread to handle Worker threads...
++                      //
++                      PsCreateSystemThread( 
++                              &Ext2GlobalData.ThreadQueue.QueueHandlerThread, (ACCESS_MASK) 0L, 
++                              NULL, NULL, NULL, Ext2QueueHandlerThread, NULL );
++
++                      // initialize the IRP major function table, and the fast I/O table
++                      Ext2FsdInitializeFunctionPointers(DriverObject);
++
++