[EXT2]
authorPierre Schweitzer <pierre@reactos.org>
Sat, 17 Oct 2015 22:35:20 +0000 (22:35 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Sat, 17 Oct 2015 22:35:20 +0000 (22:35 +0000)
[EXT2_NEW]
Get rid of old ext2 driver and use new one

svn path=/trunk/; revision=69576

148 files changed:
reactos/drivers/filesystems/CMakeLists.txt
reactos/drivers/filesystems/ext2/CMakeLists.txt
reactos/drivers/filesystems/ext2/ext2fs_reg.inf [moved from reactos/drivers/filesystems/ext2_new/ext2fs_reg.inf with 100% similarity]
reactos/drivers/filesystems/ext2/inc/asm/page.h [moved from reactos/drivers/filesystems/ext2_new/inc/asm/page.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/asm/semaphore.h [moved from reactos/drivers/filesystems/ext2_new/inc/asm/semaphore.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/asm/uaccess.h [moved from reactos/drivers/filesystems/ext2_new/inc/asm/uaccess.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/common.h [moved from reactos/drivers/filesystems/ext2_new/inc/common.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/ext2fs.h [moved from reactos/drivers/filesystems/ext2_new/inc/ext2fs.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/atomic.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/atomic.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/bit_spinlock.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/bit_spinlock.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/bitops.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/bitops.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/buffer_head.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/buffer_head.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/config.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/config.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/debugfs.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/debugfs.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/errno.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/errno.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/ext2_fs.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/ext2_fs.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/ext3_fs.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/ext3_fs_i.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs_i.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/ext3_fs_sb.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/ext3_fs_sb.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/ext3_jbd.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/ext3_jbd.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/ext4.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/ext4.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/ext4_ext.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/ext4_ext.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/ext4_jbd2.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/ext4_jbd2.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/freezer.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/freezer.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/fs.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/fs.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/group.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/group.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/highmem.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/highmem.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/init.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/init.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/jbd.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/jbd.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/journal-head.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/journal-head.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/kernel.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/kernel.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/kthread.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/kthread.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/list.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/list.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/lockdep.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/lockdep.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/log2.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/log2.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/magic.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/magic.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/mm.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/mm.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/module.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/module.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/mutex.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/mutex.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/nls.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/nls.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/pagemap.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/pagemap.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/poison.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/poison.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/proc_fs.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/proc_fs.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/rbtree.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/rbtree.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/sched.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/sched.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/slab.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/slab.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/spinlock.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/spinlock.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/stddef.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/stddef.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/string.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/string.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/time.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/time.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/timer.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/timer.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/types.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/types.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/linux/version.h [moved from reactos/drivers/filesystems/ext2_new/inc/linux/version.h with 100% similarity]
reactos/drivers/filesystems/ext2/inc/resource.h
reactos/drivers/filesystems/ext2/src/block.c [moved from reactos/drivers/filesystems/ext2_new/src/block.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/cleanup.c
reactos/drivers/filesystems/ext2/src/close.c
reactos/drivers/filesystems/ext2/src/cmcb.c [moved from reactos/drivers/filesystems/ext2_new/src/cmcb.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/create.c
reactos/drivers/filesystems/ext2/src/debug.c [moved from reactos/drivers/filesystems/ext2_new/src/debug.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/devctl.c [moved from reactos/drivers/filesystems/ext2_new/src/devctl.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/dirctl.c [moved from reactos/drivers/filesystems/ext2_new/src/dirctl.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/dispatch.c [moved from reactos/drivers/filesystems/ext2_new/src/dispatch.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/except.c [moved from reactos/drivers/filesystems/ext2_new/src/except.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/ext2.rc
reactos/drivers/filesystems/ext2/src/ext3/generic.c [moved from reactos/drivers/filesystems/ext2_new/src/ext3/generic.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/ext3/htree.c [moved from reactos/drivers/filesystems/ext2_new/src/ext3/htree.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/ext3/indirect.c [moved from reactos/drivers/filesystems/ext2_new/src/ext3/indirect.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/ext3/recover.c [moved from reactos/drivers/filesystems/ext2_new/src/ext3/recover.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/ext4/ext4_bh.c [moved from reactos/drivers/filesystems/ext2_new/src/ext4/ext4_bh.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/ext4/ext4_extents.c [moved from reactos/drivers/filesystems/ext2_new/src/ext4/ext4_extents.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/ext4/ext4_jbd2.c [moved from reactos/drivers/filesystems/ext2_new/src/ext4/ext4_jbd2.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/ext4/extents.c [moved from reactos/drivers/filesystems/ext2_new/src/ext4/extents.c with 100% similarity]
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/fsctl.c [moved from reactos/drivers/filesystems/ext2_new/src/fsctl.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/init.c [moved from reactos/drivers/filesystems/ext2_new/src/init.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/jbd/recovery.c [moved from reactos/drivers/filesystems/ext2_new/src/jbd/recovery.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/jbd/replay.c [moved from reactos/drivers/filesystems/ext2_new/src/jbd/replay.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/jbd/revoke.c [moved from reactos/drivers/filesystems/ext2_new/src/jbd/revoke.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/linux.c [moved from reactos/drivers/filesystems/ext2_new/src/linux.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/lock.c [moved from reactos/drivers/filesystems/ext2_new/src/lock.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/memory.c [moved from reactos/drivers/filesystems/ext2_new/src/memory.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/misc.c
reactos/drivers/filesystems/ext2/src/nls.c [moved from reactos/drivers/filesystems/ext2_new/src/nls.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_ascii.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_ascii.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_base.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_base.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp1250.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp1250.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp1251.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp1251.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp1255.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp1255.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp437.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp437.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp737.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp737.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp775.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp775.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp850.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp850.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp852.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp852.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp855.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp855.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp857.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp857.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp860.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp860.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp861.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp861.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp862.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp862.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp863.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp863.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp864.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp864.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp865.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp865.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp866.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp866.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp869.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp869.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp874.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp874.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp932.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp932.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp936.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp936.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp949.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp949.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_cp950.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_cp950.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_euc-jp.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_euc-jp.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-1.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-1.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-13.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-13.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-14.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-14.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-15.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-15.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-2.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-2.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-3.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-3.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-4.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-4.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-5.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-5.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-6.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-6.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-7.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-7.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_iso8859-9.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_iso8859-9.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_koi8-r.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_koi8-r.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_koi8-ru.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_koi8-ru.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_koi8-u.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_koi8-u.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/nls/nls_utf8.c [moved from reactos/drivers/filesystems/ext2_new/src/nls/nls_utf8.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/pnp.c [moved from reactos/drivers/filesystems/ext2_new/src/pnp.c with 100% similarity]
reactos/drivers/filesystems/ext2/src/rbtree.c [moved from reactos/drivers/filesystems/ext2_new/src/rbtree.c with 100% similarity]
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/ext2_new/CMakeLists.txt [deleted file]
reactos/drivers/filesystems/ext2_new/ext2fs.rc [deleted file]
reactos/drivers/filesystems/ext2_new/inc/resource.h [deleted file]
reactos/drivers/filesystems/ext2_new/src/cleanup.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/close.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/create.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/ext2.rc [deleted file]
reactos/drivers/filesystems/ext2_new/src/fastio.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/fileinfo.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/flush.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/misc.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/read.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/shutdown.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/volinfo.c [deleted file]
reactos/drivers/filesystems/ext2_new/src/write.c [deleted file]

index 1df81cc..4a89a8e 100644 (file)
@@ -1,7 +1,6 @@
 
 add_subdirectory(cdfs)
 add_subdirectory(ext2)
-#add_subdirectory(ext2_new)
 add_subdirectory(fastfat)
 #add_subdirectory(fastfat_new)
 add_subdirectory(fs_rec)
@@ -10,3 +9,4 @@ add_subdirectory(mup)
 add_subdirectory(npfs)
 add_subdirectory(ntfs)
 add_subdirectory(udfs)
+add_subdirectory(registryfs)
index 8e1f952..f02de3c 100644 (file)
 
-include_directories(inc)
+include_directories(${REACTOS_SOURCE_DIR}/include/reactos/drivers
+                    inc)
 
 list(APPEND SOURCE
-    src/volinfo.c
+    src/init.c
+    src/ext3/generic.c
+    src/ext3/htree.c
+    src/ext3/indirect.c
+    src/ext3/recover.c
+    src/ext4/ext4_bh.c
+    src/ext4/ext4_extents.c
+    src/ext4/ext4_jbd2.c
+    src/ext4/extents.c
+    src/jbd/recovery.c
+    src/jbd/replay.c
+    src/jbd/revoke.c
+    src/nls/nls_ascii.c
+    src/nls/nls_base.c
+    src/nls/nls_cp437.c
+    src/nls/nls_cp737.c
+    src/nls/nls_cp775.c
+    src/nls/nls_cp850.c
+    src/nls/nls_cp852.c
+    src/nls/nls_cp855.c
+    src/nls/nls_cp857.c
+    src/nls/nls_cp860.c
+    src/nls/nls_cp861.c
+    src/nls/nls_cp862.c
+    src/nls/nls_cp863.c
+    src/nls/nls_cp864.c
+    src/nls/nls_cp865.c
+    src/nls/nls_cp866.c
+    src/nls/nls_cp869.c
+    src/nls/nls_cp874.c
+    src/nls/nls_cp932.c
+    src/nls/nls_cp936.c
+    src/nls/nls_cp949.c
+    src/nls/nls_cp950.c
+    src/nls/nls_cp1250.c
+    src/nls/nls_cp1251.c
+    src/nls/nls_cp1255.c
+    src/nls/nls_euc-jp.c
+    src/nls/nls_iso8859-1.c
+    src/nls/nls_iso8859-2.c
+    src/nls/nls_iso8859-3.c
+    src/nls/nls_iso8859-4.c
+    src/nls/nls_iso8859-5.c
+    src/nls/nls_iso8859-6.c
+    src/nls/nls_iso8859-7.c
+    src/nls/nls_iso8859-9.c
+    src/nls/nls_iso8859-13.c
+    src/nls/nls_iso8859-14.c
+    src/nls/nls_iso8859-15.c
+    src/nls/nls_koi8-r.c
+    src/nls/nls_koi8-ru.c
+    src/nls/nls_koi8-u.c
+    src/nls/nls_utf8.c
+    src/block.c
+    src/cleanup.c
+    src/close.c
+    src/cmcb.c
     src/create.c
-    src/write.c
-    src/metadata.c
+    src/debug.c
+    src/devctl.c
+    src/dirctl.c
+    src/dispatch.c
+    src/except.c
     src/fastio.c
-    src/dircntrl.c
-    src/DiskIO.c
-    src/fsctrl.c
-    src/devcntrl.c
-    src/flush.c
-    src/ext2init.c
-    src/io.c
-    src/close.c
     src/fileinfo.c
-    src/read.c
-    src/cleanup.c
+    src/flush.c
+    src/fsctl.c
+    src/linux.c
+    src/lock.c
+    src/memory.c
     src/misc.c
+    src/nls.c
+    src/pnp.c
+    src/rbtree.c
+    src/read.c
     src/shutdown.c
-    inc/ext2fsd.h)
+    src/volinfo.c
+    src/write.c
+    inc/ext2fs.h)
 
-add_library(ext2fs SHARED ${SOURCE})
+add_library(ext2fs SHARED ${SOURCE} ext2fs.rc)
 
-if((NOT MSVC) AND (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang"))
-    add_target_compile_flags(ext2fs "-Wno-unused-but-set-variable")
+if(NOT MSVC)
+    add_target_compile_flags(ext2fs "-Wno-pointer-sign -Wno-unused-function")
+    if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
+        replace_compile_flags("-Werror" " ")
+        add_target_compile_flags(ext2fs "-Wno-unused-but-set-variable -Wno-unused-variable -Wno-missing-braces")
+    endif()
+else()
+    #disable warnings: "unreferenced local variable", "initialized, but not used variable", "benign include"
+    replace_compile_flags("/we\"4189\"" " ")
+    add_target_compile_flags(ext2fs "/wd\"4189\" /wd\"4142\" /wd\"4101\"")
 endif()
 
-target_link_libraries(ext2fs ${PSEH_LIB})
-add_pch(ext2fs inc/ext2fsd.h SOURCE)
+target_link_libraries(ext2fs memcmp ${PSEH_LIB})
+add_definitions(-D__KERNEL__ -D_X86_)
 set_module_type(ext2fs kernelmodedriver)
 add_importlibs(ext2fs ntoskrnl hal)
+add_pch(ext2fs inc/ext2fs.h SOURCE)
 add_cd_file(TARGET ext2fs DESTINATION reactos/system32/drivers NO_CAB FOR all)
index 9c490bf..f330897 100644 (file)
@@ -1,14 +1,13 @@
 //{{NO_DEPENDENCIES}}
 // Microsoft Developer Studio generated include file.
-// Used by D:\Work\VC\Drivers\ext2FSD\src\ext2.rc
+// Used by ext2fsd.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_RESOURCE_VALUE        104
 #define _APS_NEXT_COMMAND_VALUE         40001
 #define _APS_NEXT_CONTROL_VALUE         1000
 #define _APS_NEXT_SYMED_VALUE           101
index d5d33c5..2c04b8d 100644 (file)
-/*************************************************************************
-*
-* 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 NTAPI 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
-       {
+/*
+ * COPYRIGHT:        See COPYRIGHT.TXT
+ * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
+ * FILE:             cleanup.c
+ * PROGRAMMER:       Matt Wu <mattwu@163.com>
+ * HOMEPAGE:         http://www.ext2fsd.com
+ * UPDATE HISTORY:
+ */
 
-               // get an IRP context structure and issue the request
-               PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject);
-               ASSERT(PtrIrpContext);
+/* INCLUDES *****************************************************************/
 
-               RC = Ext2CommonCleanup(PtrIrpContext, Irp, TRUE);
+#include "ext2fs.h"
 
-       } 
-       except( Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation() ) ) 
-       {
+/* GLOBALS ***************************************************************/
 
-               RC = Ext2ExceptionHandler(PtrIrpContext, Irp);
+extern PEXT2_GLOBAL Ext2Global;
 
-               Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC);
-       }
+/* DEFINITIONS *************************************************************/
 
-       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 NTAPI Ext2CommonCleanup(
-PtrExt2IrpContext                      PtrIrpContext,
-PIRP                                           PtrIrp,
-BOOLEAN                                                FirstAttempt )
+NTSTATUS
+Ext2Cleanup (IN PEXT2_IRP_CONTEXT IrpContext)
 {
-
-       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;
-
-       BOOLEAN                                 CompleteIrp = TRUE;
-       BOOLEAN                                 PostRequest = FALSE;
-       BOOLEAN                                 AcquiredVCB = 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();
-               }
-               
-
-               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();
-
-               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);
+    PDEVICE_OBJECT  DeviceObject;
+    NTSTATUS        Status = STATUS_SUCCESS;
+    PEXT2_VCB       Vcb;
+    PFILE_OBJECT    FileObject;
+    PEXT2_FCB       Fcb;
+    PEXT2_CCB       Ccb;
+    PIRP            Irp;
+    PEXT2_MCB       Mcb;
+
+
+    BOOLEAN         VcbResourceAcquired = FALSE;
+    BOOLEAN         FcbResourceAcquired = FALSE;
+    BOOLEAN         FcbPagingIoResourceAcquired = FALSE;
+
+    _SEH2_TRY {
+
+        ASSERT(IrpContext != NULL);
+        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
+               (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
+
+        DeviceObject = IrpContext->DeviceObject;
+        if (IsExt2FsDevice(DeviceObject))  {
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+
+        Irp = IrpContext->Irp;
+        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
+        ASSERT(Vcb != NULL);
+        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
+               (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
+
+        if (!IsVcbInited(Vcb)) {
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+
+        FileObject = IrpContext->FileObject;
+        Fcb = (PEXT2_FCB) FileObject->FsContext;
+        if (!Fcb || (Fcb->Identifier.Type != EXT2VCB &&
+                     Fcb->Identifier.Type != EXT2FCB)) {
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+        Mcb = Fcb->Mcb;
+        Ccb = (PEXT2_CCB) FileObject->FsContext2;
+
+        if (IsFlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE)) {
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+
+        VcbResourceAcquired =
+            ExAcquireResourceExclusiveLite(
+                &Vcb->MainResource,
+                IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)
+            );
+
+        if (Fcb->Identifier.Type == EXT2VCB) {
+
+            if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) &&
+                Vcb->LockFile == FileObject ){
+
+                ClearFlag(Vcb->Flags, VCB_VOLUME_LOCKED);
+                Vcb->LockFile = NULL;
+                Ext2ClearVpbFlag(Vcb->Vpb, VPB_LOCKED);
+            }
+
+            if (Ccb) {
+                Ext2DerefXcb(&Vcb->OpenHandleCount);
+                Ext2DerefXcb(&Vcb->OpenVolumeCount);
+            }
+
+            IoRemoveShareAccess(FileObject, &Vcb->ShareAccess);
+
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+
+        ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
+               (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
+
+        if (IsFlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE)) {
+            if (IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) &&
+                    IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK) &&
+                    !IsVcbReadOnly(Vcb) ) {
+                Status = Ext2FlushFile(IrpContext, Fcb, Ccb);
+            }
+            _SEH2_LEAVE;
+        }
+
+        if (Ccb == NULL) {
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+
+        if (IsDirectory(Fcb)) {
+            if (IsFlagOn(Ccb->Flags, CCB_DELETE_ON_CLOSE))  {
+                SetLongFlag(Fcb->Flags, FCB_DELETE_PENDING);
+
+                FsRtlNotifyFullChangeDirectory(
+                    Vcb->NotifySync,
+                    &Vcb->NotifyList,
+                    Ccb,
+                    NULL,
+                    FALSE,
+                    FALSE,
+                    0,
+                    NULL,
+                    NULL,
+                    NULL );
+            }
+
+            FsRtlNotifyCleanup(Vcb->NotifySync, &Vcb->NotifyList, Ccb);
+
+        }
+
+        ExReleaseResourceLite(&Vcb->MainResource);
+        VcbResourceAcquired = FALSE;
+
+        FcbResourceAcquired =
+            ExAcquireResourceExclusiveLite(
+                &Fcb->MainResource,
+                IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)
+            );
+
+        ASSERT((Ccb->Identifier.Type == EXT2CCB) &&
+               (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
+
+        Ext2DerefXcb(&Vcb->OpenHandleCount);
+        Ext2DerefXcb(&Fcb->OpenHandleCount);
+
+        if (IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED)) {
+            Fcb->Mcb->FileAttr |= FILE_ATTRIBUTE_ARCHIVE;
+        }
+
+        if (IsDirectory(Fcb)) {
+
+            ext3_release_dir(Fcb->Inode, &Ccb->filp);
+
+        } else {
+
+            if ( IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) &&
+                    !IsFlagOn(Ccb->Flags, CCB_LAST_WRITE_UPDATED)) {
+
+                LARGE_INTEGER   SysTime;
+                KeQuerySystemTime(&SysTime);
+
+                Fcb->Inode->i_atime =
+                    Fcb->Inode->i_mtime = Ext2LinuxTime(SysTime);
+                Fcb->Mcb->LastAccessTime =
+                    Fcb->Mcb->LastWriteTime = Ext2NtTime(Fcb->Inode->i_atime);
+
+                Ext2SaveInode(IrpContext, Vcb, Fcb->Inode);
+
+                Ext2NotifyReportChange(
+                    IrpContext,
+                    Vcb,
+                    Fcb->Mcb,
+                    FILE_NOTIFY_CHANGE_ATTRIBUTES |
+                    FILE_NOTIFY_CHANGE_LAST_WRITE |
+                    FILE_NOTIFY_CHANGE_LAST_ACCESS,
+                    FILE_ACTION_MODIFIED );
+            }
+
+            FsRtlCheckOplock( &Fcb->Oplock,
+                              Irp,
+                              IrpContext,
+                              NULL,
+                              NULL );
+
+            Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
+
+            if (!IsFlagOn(FileObject->Flags, FO_CACHE_SUPPORTED)) {
+                Fcb->NonCachedOpenCount--;
+            }
+
+            if (IsFlagOn(Ccb->Flags, CCB_DELETE_ON_CLOSE))  {
+                SetLongFlag(Fcb->Flags, FCB_DELETE_PENDING);
+            }
+
+            //
+            // Drop any byte range locks this process may have on the file.
+            //
+
+            FsRtlFastUnlockAll(
+                &Fcb->FileLockAnchor,
+                FileObject,
+                IoGetRequestorProcess(Irp),
+                NULL  );
+
+            //
+            // If there are no byte range locks owned by other processes on the
+            // file the fast I/O read/write functions doesn't have to check for
+            // locks so we set IsFastIoPossible to FastIoIsPossible again.
+            //
+            if (!FsRtlGetNextFileLock(&Fcb->FileLockAnchor, TRUE)) {
+                if (Fcb->Header.IsFastIoPossible != FastIoIsPossible) {
+#if EXT2_DEBUG
+                    DEBUG(DL_INF, (": %-16.16s %-31s %wZ\n",
+                                   Ext2GetCurrentProcessName(),
+                                   "FastIoIsPossible",
+                                   &Fcb->Mcb->FullName
+                                  ));
+#endif
+
+                    Fcb->Header.IsFastIoPossible = FastIoIsPossible;
+                }
+            }
+
+            if (Fcb->OpenHandleCount == 0 && FlagOn(Fcb->Flags, FCB_ALLOC_IN_CREATE |
+                                                                FCB_ALLOC_IN_SETINFO) ){
+
+                if (FlagOn(Fcb->Flags, FCB_ALLOC_IN_SETINFO)) {
+                    if (Fcb->Header.ValidDataLength.QuadPart < Fcb->Header.FileSize.QuadPart) {
+                        if (!INODE_HAS_EXTENT(Fcb->Inode)) {
+                        #if EXT2_PRE_ALLOCATION_SUPPORT
+                            CcZeroData(FileObject, &Fcb->Header.ValidDataLength,
+                                       &Fcb->Header.AllocationSize, TRUE);
+                        #endif
+                        }
+                    }
+                }
+
+                if (FlagOn(Fcb->Flags, FCB_ALLOC_IN_CREATE)) {
+
+                    LARGE_INTEGER Size;
+
+                    ExAcquireResourceExclusiveLite(&Fcb->PagingIoResource, TRUE);
+                    FcbPagingIoResourceAcquired = TRUE;
+
+                    Size.QuadPart = CEILING_ALIGNED(ULONGLONG,
+                                                    (ULONGLONG)Fcb->Mcb->Inode.i_size,
+                                                    (ULONGLONG)BLOCK_SIZE);
+                    if (!IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING)) {
+
+                        Ext2TruncateFile(IrpContext, Vcb, Fcb->Mcb, &Size);
+                        Fcb->Header.AllocationSize = Size;
+                        Fcb->Header.FileSize.QuadPart = Mcb->Inode.i_size;
+                        if (Fcb->Header.ValidDataLength.QuadPart > Fcb->Header.FileSize.QuadPart)
+                            Fcb->Header.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart;
+                        if (CcIsFileCached(FileObject)) {
+                            CcSetFileSizes(FileObject,
+                                           (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
+                        }
+                    }
+                    ClearLongFlag(Fcb->Flags, FCB_ALLOC_IN_CREATE|FCB_ALLOC_IN_WRITE|FCB_ALLOC_IN_SETINFO);
+                    ExReleaseResourceLite(&Fcb->PagingIoResource);
+                    FcbPagingIoResourceAcquired = FALSE;
+                }
+            }
+        }
+
+        if (IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING)) {
+
+            if (Fcb->OpenHandleCount == 0 || (Mcb = Ccb->SymLink)) {
+
+                //
+                // Ext2DeleteFile will acquire these lock inside
+                //
+
+                if (FcbResourceAcquired) {
+                    ExReleaseResourceLite(&Fcb->MainResource);
+                    FcbResourceAcquired = FALSE;
+                }
+
+                //
+                //  this file is to be deleted ...
+                //
+                if (Ccb->SymLink) {
+                    Mcb = Ccb->SymLink;
+                    FileObject->DeletePending = FALSE;
+                }
+
+                Status = Ext2DeleteFile(IrpContext, Vcb, Fcb, Mcb);
+
+                if (NT_SUCCESS(Status)) {
+                    if (IsMcbDirectory(Mcb)) {
+                        Ext2NotifyReportChange( IrpContext, Vcb, Mcb,
+                                                FILE_NOTIFY_CHANGE_DIR_NAME,
+                                                FILE_ACTION_REMOVED );
+                    } else {
+                        Ext2NotifyReportChange( IrpContext, Vcb, Mcb,
+                                                FILE_NOTIFY_CHANGE_FILE_NAME,
+                                                FILE_ACTION_REMOVED );
+                    }
+                }
+
+                //
+                // re-acquire the main resource lock
+                //
+
+                FcbResourceAcquired =
+                    ExAcquireResourceExclusiveLite(
+                        &Fcb->MainResource,
+                        IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)
+                    );
+
+                SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
+                if (CcIsFileCached(FileObject)) {
+                    CcSetFileSizes(FileObject,
+                                   (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
+                }
+            }
+        }
+
+        if (!IsDirectory(Fcb)) {
+
+            if ( IsFlagOn(FileObject->Flags, FO_CACHE_SUPPORTED) &&
+                    (Fcb->NonCachedOpenCount + 1 == Fcb->ReferenceCount) &&
+                    (Fcb->SectionObject.DataSectionObject != NULL)) {
+
+                if (!IsVcbReadOnly(Vcb)) {
+                    CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL);
+                    ClearLongFlag(Fcb->Flags, FCB_FILE_MODIFIED);
+                }
+
+                if (ExAcquireResourceExclusiveLite(&(Fcb->PagingIoResource), TRUE)) {
+                    ExReleaseResourceLite(&(Fcb->PagingIoResource));
+                }
+
+                CcPurgeCacheSection( &Fcb->SectionObject,
+                                     NULL,
+                                     0,
+                                     FALSE );
+            }
+
+            CcUninitializeCacheMap(FileObject, NULL, NULL);
+        }
+
+        IoRemoveShareAccess(FileObject, &Fcb->ShareAccess);
+
+        DEBUG(DL_INF, ( "Ext2Cleanup: OpenCount=%u ReferCount=%u NonCahcedCount=%xh %wZ\n",
+                        Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->NonCachedOpenCount, &Fcb->Mcb->FullName));
+
+        Status = STATUS_SUCCESS;
+
+        if (FileObject) {
+            SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE);
+        }
+
+    } _SEH2_FINALLY {
+
+        if (FcbPagingIoResourceAcquired) {
+            ExReleaseResourceLite(&Fcb->PagingIoResource);
+        }
+
+        if (FcbResourceAcquired) {
+            ExReleaseResourceLite(&Fcb->MainResource);
+        }
+
+        if (VcbResourceAcquired) {
+            ExReleaseResourceLite(&Vcb->MainResource);
+        }
+
+        if (!IrpContext->ExceptionInProgress) {
+            if (Status == STATUS_PENDING) {
+                Ext2QueueRequest(IrpContext);
+            } else {
+                IrpContext->Irp->IoStatus.Status = Status;
+                Ext2CompleteIrpContext(IrpContext, Status);
+            }
+        }
+    } _SEH2_END;
+
+    return Status;
 }
index 1674bf0..de2d687 100644 (file)
-/*************************************************************************
-*
-* 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 NTAPI Ext2Close(
-PDEVICE_OBJECT         DeviceObject,           // the logical volume device object
-PIRP                                   Irp)                                    // I/O Request Packet
+/*
+ * COPYRIGHT:        See COPYRIGHT.TXT
+ * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
+ * FILE:             close.c
+ * PROGRAMMER:       Matt Wu <mattwu@163.com>
+ * HOMEPAGE:         http://www.ext2fsd.com
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "ext2fs.h"
+
+/* GLOBALS ***************************************************************/
+
+extern PEXT2_GLOBAL Ext2Global;
+
+/* DEFINITIONS *************************************************************/
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, Ext2QueueCloseRequest)
+#pragma alloc_text(PAGE, Ext2DeQueueCloseRequest)
+#endif
+
+NTSTATUS
+Ext2Close (IN PEXT2_IRP_CONTEXT IrpContext)
 {
-       NTSTATUS                                RC = STATUS_SUCCESS;
-       PtrExt2IrpContext       PtrIrpContext = NULL;
-       BOOLEAN                         AreWeTopLevel = FALSE;
+    PDEVICE_OBJECT  DeviceObject;
+    NTSTATUS        Status = STATUS_SUCCESS;
+    PEXT2_VCB       Vcb = NULL;
+    BOOLEAN         VcbResourceAcquired = FALSE;
+    PFILE_OBJECT    FileObject;
+    PEXT2_FCB       Fcb;
+    BOOLEAN         FcbResourceAcquired = FALSE;
+    PEXT2_CCB       Ccb;
+    BOOLEAN         bDeleteVcb = FALSE;
+    BOOLEAN         bBeingClosed = FALSE;
+    BOOLEAN         bSkipLeave = FALSE;
+
+    _SEH2_TRY {
+
+        ASSERT(IrpContext != NULL);
+        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
+               (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
+
+        DeviceObject = IrpContext->DeviceObject;
+        if (IsExt2FsDevice(DeviceObject)) {
+            Status = STATUS_SUCCESS;
+            Vcb = NULL;
+            _SEH2_LEAVE;
+        }
+
+        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
+        ASSERT(Vcb != NULL);
+        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
+               (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
+
+        if (!ExAcquireResourceExclusiveLite(
+                    &Vcb->MainResource,
+                    IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
+            DEBUG(DL_INF, ("Ext2Close: PENDING ... Vcb: %xh/%xh\n",
+                           Vcb->OpenHandleCount, Vcb->ReferenceCount));
+
+            Status = STATUS_PENDING;
+            _SEH2_LEAVE;
+        }
+        VcbResourceAcquired = TRUE;
+
+        bSkipLeave = TRUE;
+        if (IsFlagOn(Vcb->Flags, VCB_BEING_CLOSED)) {
+            bBeingClosed = TRUE;
+        } else {
+            SetLongFlag(Vcb->Flags, VCB_BEING_CLOSED);
+            bBeingClosed = FALSE;
+        }
+
+        if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE)) {
+
+            FileObject = NULL;
+            Fcb = IrpContext->Fcb;
+            Ccb = IrpContext->Ccb;
+
+        } else {
+
+            FileObject = IrpContext->FileObject;
+            Fcb = (PEXT2_FCB) FileObject->FsContext;
+            if (!Fcb) {
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+            ASSERT(Fcb != NULL);
+            Ccb = (PEXT2_CCB) FileObject->FsContext2;
+        }
+
+        DEBUG(DL_INF, ( "Ext2Close: (VCB) bBeingClosed = %d Vcb = %p ReferCount = %d\n",
+                        bBeingClosed, Vcb, Vcb->ReferenceCount));
+
+        if (Fcb->Identifier.Type == EXT2VCB) {
+
+            if (Ccb) {
+
+                Ext2DerefXcb(&Vcb->ReferenceCount);
+                Ext2FreeCcb(Vcb, Ccb);
+
+                if (FileObject) {
+                    FileObject->FsContext2 = Ccb = NULL;
+                }
+            }
+
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+
+        if ( Fcb->Identifier.Type != EXT2FCB ||
+                Fcb->Identifier.Size != sizeof(EXT2_FCB)) {
+            _SEH2_LEAVE;
+        }
+
+        if (!ExAcquireResourceExclusiveLite(
+                    &Fcb->MainResource,
+                    IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
+            Status = STATUS_PENDING;
+            _SEH2_LEAVE;
+        }
+        FcbResourceAcquired = TRUE;
+
+        Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
+
+        if (!Ccb) {
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+
+        ASSERT((Ccb->Identifier.Type == EXT2CCB) &&
+               (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
+
+        if (IsFlagOn(Fcb->Flags, FCB_STATE_BUSY)) {
+            SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_FILE_BUSY);
+            DEBUG(DL_WRN, ( "Ext2Close: busy bit set: %wZ\n", &Fcb->Mcb->FullName ));
+            Status = STATUS_PENDING;
+            _SEH2_LEAVE;
+        }
+
+        DEBUG(DL_INF, ( "Ext2Close: Fcb = %p OpenHandleCount= %u ReferenceCount=%u NonCachedCount=%u %wZ\n",
+                        Fcb, Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->NonCachedOpenCount, &Fcb->Mcb->FullName ));
+
+        if (Ccb) {
+
+            Ext2FreeCcb(Vcb, Ccb);
+
+            if (FileObject) {
+                FileObject->FsContext2 = Ccb = NULL;
+            }
+        }
+
+        if (0 == Ext2DerefXcb(&Fcb->ReferenceCount)) {
+
+            //
+            // Remove Fcb from Vcb->FcbList ...
+            //
+
+            if (FcbResourceAcquired) {
+                ExReleaseResourceLite(&Fcb->MainResource);
+                FcbResourceAcquired = FALSE;
+            }
+
+            Ext2FreeFcb(Fcb);
+
+            if (FileObject) {
+                FileObject->FsContext = Fcb = NULL;
+            }
+        }
+
+        Ext2DerefXcb(&Vcb->ReferenceCount);
+        Status = STATUS_SUCCESS;
 
-       DebugTrace(DEBUG_TRACE_IRP_ENTRY, "Close IRP Received...", 0);
-       
+    } _SEH2_FINALLY {
 
-       FsRtlEnterFileSystem();
+        if (NT_SUCCESS(Status) && Vcb != NULL && IsVcbInited(Vcb)) {
+            /* for Ext2Fsd driver open/close, Vcb is NULL */
+            if ((!bBeingClosed) && (Vcb->ReferenceCount == 0)&&
+                (!IsMounted(Vcb) || IsDispending(Vcb))) {
+                bDeleteVcb = TRUE;
+            }
+        }
 
-       ASSERT(DeviceObject);
-       ASSERT(Irp);
+        if (bSkipLeave && !bBeingClosed) {
+            ClearFlag(Vcb->Flags, VCB_BEING_CLOSED);
+        }
 
-       // set the top level context
-       AreWeTopLevel = Ext2IsIrpTopLevel(Irp);
+        if (FcbResourceAcquired) {
+            ExReleaseResourceLite(&Fcb->MainResource);
+        }
 
-       try 
-       {
+        if (VcbResourceAcquired) {
+            ExReleaseResourceLite(&Vcb->MainResource);
+        }
 
-               // get an IRP context structure and issue the request
-               PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject);
-               ASSERT(PtrIrpContext);
+        if (!IrpContext->ExceptionInProgress) {
 
-               RC = Ext2CommonClose(PtrIrpContext, Irp, TRUE);
+            if (Status == STATUS_PENDING) {
 
-       }
-       except (Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation())) 
-       {
+                Ext2QueueCloseRequest(IrpContext);
 
-               RC = Ext2ExceptionHandler(PtrIrpContext, Irp);
-               Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC);
-       }
+            } else {
 
-       if (AreWeTopLevel) 
-       {
-               IoSetTopLevelIrp(NULL);
-       }
+                Ext2CompleteIrpContext(IrpContext, Status);
 
-       FsRtlExitFileSystem();
+                if (bDeleteVcb) {
 
-       return(RC);
+                    PVPB Vpb = Vcb->Vpb;
+                    DEBUG(DL_DBG, ( "Ext2Close: Try to free Vcb %p and Vpb %p\n",
+                                    Vcb, Vpb));
+
+                    Ext2CheckDismount(IrpContext, Vcb, FALSE);
+                }
+            }
+        }
+    } _SEH2_END;
+
+    return Status;
 }
 
+VOID
+Ext2QueueCloseRequest (IN PEXT2_IRP_CONTEXT IrpContext)
+{
+    ASSERT(IrpContext);
+    ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
+           (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
+
+    if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE)) {
+
+        if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FILE_BUSY)) {
+            Ext2Sleep(500); /* 0.5 sec*/
+        } else {
+            Ext2Sleep(50);  /* 0.05 sec*/
+        }
 
-/*************************************************************************
-*
-* 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 NTAPI Ext2CommonClose(
-PtrExt2IrpContext                      PtrIrpContext,
-PIRP                                           PtrIrp,
-BOOLEAN                                                FirstAttempt )
+    } else {
+
+        SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
+        SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE);
+
+        IrpContext->Fcb = (PEXT2_FCB) IrpContext->FileObject->FsContext;
+        IrpContext->Ccb = (PEXT2_CCB) IrpContext->FileObject->FsContext2;
+    }
+
+    ExInitializeWorkItem(
+        &IrpContext->WorkQueueItem,
+        Ext2DeQueueCloseRequest,
+        IrpContext);
+
+    ExQueueWorkItem(&IrpContext->WorkQueueItem, DelayedWorkQueue);
+}
+
+VOID NTAPI
+Ext2DeQueueCloseRequest (IN PVOID Context)
 {
-       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;
-       PERESOURCE                              PtrPagingIoResourceAcquired = NULL;
-
-       BOOLEAN                                 CompleteIrp = TRUE;
-       BOOLEAN                                 PostRequest = FALSE;
-       BOOLEAN                                 AcquiredVCB = 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);
-                       }
-                       try_return();
-               }
-
-               // 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   EX:0x%LX   SW: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);
-                       }
-
-                       PtrReqdFCB = &PtrFCB->NTRequiredFCB;
-
-                       i = 1;
-                       while( !PtrResourceAcquired )
-                       {
-                               DebugTraceState( "FCBMain   AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]", PtrReqdFCB->MainResource.ActiveCount, PtrReqdFCB->MainResource.NumberOfExclusiveWaiters, PtrReqdFCB->MainResource.NumberOfSharedWaiters );
-                               if(! ExAcquireResourceExclusiveLite( &(PtrReqdFCB->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 = & ( PtrReqdFCB->MainResource );
-                               }
-                               i *= 10;
-                       }
-
-                       i = 1;
-                       while( !PtrPagingIoResourceAcquired )
-                       {
-                               DebugTraceState( "FCBPaging   AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]", PtrReqdFCB->PagingIoResource.ActiveCount, PtrReqdFCB->PagingIoResource.NumberOfExclusiveWaiters, PtrReqdFCB->PagingIoResource.NumberOfSharedWaiters );
-                               if(! ExAcquireResourceExclusiveLite( &(PtrReqdFCB->PagingIoResource), 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);
-                                       PtrPagingIoResourceAcquired = & ( PtrReqdFCB->PagingIoResource );
-                               }
-                               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 ( PtrPagingIoResourceAcquired )
-                                       {
-                                               Ext2ReleaseResource(PtrPagingIoResourceAcquired);
-                                               DebugTraceState( "Resource     AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]",
-                                                       PtrPagingIoResourceAcquired->ActiveCount, 
-                                                       PtrPagingIoResourceAcquired->NumberOfExclusiveWaiters, 
-                                                       PtrPagingIoResourceAcquired->NumberOfSharedWaiters );
-
-                                               PtrPagingIoResourceAcquired = NULL;
-                                       }
-
-                                       if ( PtrResourceAcquired ) 
-                                       {
-                                               Ext2ReleaseResource(PtrResourceAcquired);
-                                               DebugTrace(DEBUG_TRACE_MISC,  "*** FCB Released [Close]", 0);
-                                               DebugTraceState( "Resource     AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]",
-                                                       PtrResourceAcquired->ActiveCount, 
-                                                       PtrResourceAcquired->NumberOfExclusiveWaiters, 
-                                                       PtrResourceAcquired->NumberOfSharedWaiters );
-
-                                               if( PtrFileObject )
-                                               {
-                                                       DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
-                                               }
-                                               PtrResourceAcquired = NULL;
-                                       }
-
-                                       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();
-               
-               try_exit:       NOTHING;
-
-       } 
-       finally 
-       {
-               if ( PtrPagingIoResourceAcquired )
-               {
-                       Ext2ReleaseResource(PtrPagingIoResourceAcquired);
-                       DebugTraceState( "Resource     AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]",
-                               PtrPagingIoResourceAcquired->ActiveCount,
-                               PtrPagingIoResourceAcquired->NumberOfExclusiveWaiters,
-                               PtrPagingIoResourceAcquired->NumberOfSharedWaiters );
-
-                       PtrPagingIoResourceAcquired = NULL;
-               }
-
-               if ( PtrResourceAcquired ) 
-               {
-                       Ext2ReleaseResource(PtrResourceAcquired);
-                       DebugTrace(DEBUG_TRACE_MISC,  "*** FCB Released [Close]", 0);
-                       DebugTraceState( "Resource     AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]",
-                               PtrResourceAcquired->ActiveCount, 
-                               PtrResourceAcquired->NumberOfExclusiveWaiters, 
-                               PtrResourceAcquired->NumberOfSharedWaiters );
-
-                       if( PtrFileObject )
-                       {
-                               DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
-                       }
-                       PtrResourceAcquired = NULL;
-               }
-
-               if (AcquiredVCB) 
-               {
-                       ASSERT(PtrVCB);
-                       Ext2ReleaseResource(&(PtrVCB->VCBResource));
-                       DebugTraceState( "VCB       AC:0x%LX   EX:0x%LX   SW: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);
+    PEXT2_IRP_CONTEXT IrpContext;
+
+    IrpContext = (PEXT2_IRP_CONTEXT) Context;
+    ASSERT(IrpContext);
+    ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
+           (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
+
+    _SEH2_TRY {
+
+        _SEH2_TRY {
+
+            FsRtlEnterFileSystem();
+            Ext2Close(IrpContext);
+
+        } _SEH2_EXCEPT (Ext2ExceptionFilter(IrpContext, _SEH2_GetExceptionInformation())) {
+
+            Ext2ExceptionHandler(IrpContext);
+        } _SEH2_END;
+
+    } _SEH2_FINALLY {
+
+        FsRtlExitFileSystem();
+    } _SEH2_END;
 }
index 13aeafd..43703ea 100644 (file)
-/*************************************************************************
-*
-* 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 NTAPI Ext2Create(
-PDEVICE_OBJECT         DeviceObject,           // the logical volume device object
-PIRP                                   Irp)                                    // I/O Request Packet
-{
-       NTSTATUS                                RC = STATUS_SUCCESS;
-    PtrExt2IrpContext  PtrIrpContext;
-       BOOLEAN                         AreWeTopLevel = FALSE;
+/*
+ * COPYRIGHT:        See COPYRIGHT.TXT
+ * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
+ * FILE:             create.c
+ * PROGRAMMER:       Matt Wu <mattwu@163.com>
+ * HOMEPAGE:         http://www.ext2fsd.com
+ * UPDATE HISTORY:
+ */
 
-       DebugTrace( DEBUG_TRACE_IRP_ENTRY, "Create Control IRP received...", 0);
+/* INCLUDES *****************************************************************/
 
-       FsRtlEnterFileSystem();
-       
-       //      Ext2BreakPoint();
+#include "ext2fs.h"
 
-       ASSERT(DeviceObject);
-       ASSERT(Irp);
+/* GLOBALS *****************************************************************/
 
-       // 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)
+extern PEXT2_GLOBAL Ext2Global;
 
-       //      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;
+/* DEFINITIONS *************************************************************/
 
-               IoCompleteRequest(Irp, IO_NO_INCREMENT);
-               return(RC);
-       }
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, Ext2IsNameValid)
+#pragma alloc_text(PAGE, Ext2FollowLink)
+#pragma alloc_text(PAGE, Ext2IsSpecialSystemFile)
+#pragma alloc_text(PAGE, Ext2LookupFile)
+#pragma alloc_text(PAGE, Ext2ScanDir)
+#pragma alloc_text(PAGE, Ext2CreateFile)
+#pragma alloc_text(PAGE, Ext2CreateVolume)
+#pragma alloc_text(PAGE, Ext2Create)
+#pragma alloc_text(PAGE, Ext2CreateInode)
+#pragma alloc_text(PAGE, Ext2SupersedeOrOverWriteFile)
+#endif
 
-       // set the top level context
-       AreWeTopLevel = Ext2IsIrpTopLevel(Irp);
 
-       try 
-       {
+BOOLEAN
+Ext2IsNameValid(PUNICODE_STRING FileName)
+{
+    USHORT  i = 0;
+    PUSHORT pName = (PUSHORT) FileName->Buffer;
 
-               // get an IRP context structure and issue the request
-               PtrIrpContext = Ext2AllocateIrpContext(Irp, DeviceObject);
-               ASSERT(PtrIrpContext);
+    if (FileName == NULL) {
+        return FALSE;
+    }
 
-               RC = Ext2CommonCreate(PtrIrpContext, Irp, TRUE );
+    while (i < (FileName->Length / sizeof(WCHAR))) {
 
-       } 
-       except (Ext2ExceptionFilter(PtrIrpContext, GetExceptionInformation())) 
-       {
+        if (pName[i] == 0) {
+            break;
+        }
 
-               RC = Ext2ExceptionHandler(PtrIrpContext, Irp);
+        if (pName[i] == L'|'  || pName[i] == L':'  ||
+                pName[i] == L'/'  || pName[i] == L'*'  ||
+                pName[i] == L'?'  || pName[i] == L'\"' ||
+                pName[i] == L'<'  || pName[i] == L'>'   ) {
 
-               Ext2LogEvent(EXT2_ERROR_INTERNAL_ERROR, RC);
-       }
+            return FALSE;
+        }
 
-       if (AreWeTopLevel) 
-       {
-               IoSetTopLevelIrp(NULL);
-       }
-       
-       FsRtlExitFileSystem();
+        i++;
+    }
 
-       return(RC);
+    return TRUE;
 }
 
 
+NTSTATUS
+Ext2FollowLink (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Parent,
+    IN PEXT2_MCB            Mcb,
+    IN USHORT               Linkdep
+)
+{
+    NTSTATUS        Status = STATUS_LINK_FAILED;
+
+    UNICODE_STRING  UniName;
+    OEM_STRING      OemName;
+    BOOLEAN         bOemBuffer = FALSE;
+
+    PEXT2_MCB       Target = NULL;
+
+    USHORT          i;
+
+    _SEH2_TRY {
+
+        RtlZeroMemory(&UniName, sizeof(UNICODE_STRING));
+        RtlZeroMemory(&OemName, sizeof(OEM_STRING));
+
+        /* exit if we jump into a possible symlink forever loop */
+        if ((Linkdep + 1) > EXT2_MAX_NESTED_LINKS ||
+                IoGetRemainingStackSize() < 1024) {
+            _SEH2_LEAVE;
+        }
+
+        /* read the symlink target path */
+        if (Mcb->Inode.i_size < EXT2_LINKLEN_IN_INODE) {
+
+            OemName.Buffer = (PUCHAR) (&Mcb->Inode.i_block[0]);
+            OemName.Length = (USHORT)Mcb->Inode.i_size;
+            OemName.MaximumLength = OemName.Length + 1;
+
+        } else {
+
+            OemName.Length = (USHORT)Mcb->Inode.i_size;
+            OemName.MaximumLength = OemName.Length + 1;
+            OemName.Buffer = Ext2AllocatePool(PagedPool,
+                                              OemName.MaximumLength,
+                                              'NL2E');
+            if (OemName.Buffer == NULL) {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                _SEH2_LEAVE;
+            }
+            bOemBuffer = TRUE;
+            RtlZeroMemory(OemName.Buffer, OemName.MaximumLength);
+
+            Status = Ext2ReadInode(
+                         IrpContext,
+                         Vcb,
+                         Mcb,
+                         (ULONGLONG)0,
+                         OemName.Buffer,
+                         (ULONG)(Mcb->Inode.i_size),
+                         FALSE,
+                         NULL);
+            if (!NT_SUCCESS(Status)) {
+                _SEH2_LEAVE;
+            }
+        }
+
+        /* convert Linux slash to Windows backslash */
+        for (i=0; i < OemName.Length; i++) {
+            if (OemName.Buffer[i] == '/') {
+                OemName.Buffer[i] = '\\';
+            }
+        }
+
+        /* convert oem string to unicode string */
+        UniName.MaximumLength = (USHORT)Ext2OEMToUnicodeSize(Vcb, &OemName);
+        if (UniName.MaximumLength <= 0) {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            _SEH2_LEAVE;
+        }
+
+        UniName.MaximumLength += 2;
+        UniName.Buffer = Ext2AllocatePool(PagedPool,
+                                          UniName.MaximumLength,
+                                          'NL2E');
+        if (UniName.Buffer == NULL) {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            _SEH2_LEAVE;
+        }
+        RtlZeroMemory(UniName.Buffer, UniName.MaximumLength);
+        Status = Ext2OEMToUnicode(Vcb, &UniName, &OemName);
+        if (!NT_SUCCESS(Status)) {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            _SEH2_LEAVE;
+        }
+
+        /* search the real target */
+        Status = Ext2LookupFile(
+                     IrpContext,
+                     Vcb,
+                     &UniName,
+                     Parent,
+                     &Target,
+                     Linkdep
+                 );
+        if (Target == NULL) {
+            Status = STATUS_LINK_FAILED;
+        }
+
+        if (Target == NULL /* link target doesn't exist */      ||
+                Target == Mcb  /* symlink points to itself */       ||
+                IsMcbSpecialFile(Target) /* target not resolved*/   ||
+                IsFileDeleted(Target)  /* target deleted */         ) {
+
+            if (Target) {
+                ASSERT(Target->Refercount > 0);
+                Ext2DerefMcb(Target);
+            }
+            ClearLongFlag(Mcb->Flags, MCB_TYPE_SYMLINK);
+            SetLongFlag(Mcb->Flags, MCB_TYPE_SPECIAL);
+            Mcb->FileAttr = FILE_ATTRIBUTE_NORMAL;
+            Mcb->Target = NULL;
+
+        } else if (IsMcbSymLink(Target)) {
+
+            ASSERT(Target->Refercount > 0);
+            ASSERT(Target->Target != NULL);
+            Ext2ReferMcb(Target->Target);
+            Mcb->Target = Target->Target;
+            Ext2DerefMcb(Target);
+            ASSERT(!IsMcbSymLink(Target->Target));
+            SetLongFlag(Mcb->Flags, MCB_TYPE_SYMLINK);
+            ClearLongFlag(Mcb->Flags, MCB_TYPE_SPECIAL);
+            ASSERT(Mcb->Target->Refercount > 0);
+            Mcb->FileAttr = Target->FileAttr;
+
+        } else {
+
+            Mcb->Target = Target;
+            SetLongFlag(Mcb->Flags, MCB_TYPE_SYMLINK);
+            ClearLongFlag(Mcb->Flags, MCB_TYPE_SPECIAL);
+            ASSERT(Mcb->Target->Refercount > 0);
+            Mcb->FileAttr = Target->FileAttr;
+        }
+
+    } _SEH2_FINALLY {
+
+        if (bOemBuffer) {
+            Ext2FreePool(OemName.Buffer, 'NL2E');
+        }
+
+        if (UniName.Buffer) {
+            Ext2FreePool(UniName.Buffer, 'NL2E');
+        }
+    } _SEH2_END;
+
+    return Status;
+}
+
+BOOLEAN
+Ext2IsSpecialSystemFile(
+    IN PUNICODE_STRING FileName,
+    IN BOOLEAN         bDirectory
+)
+{
+    PWSTR SpecialFileList[] = {
+        L"pagefile.sys",
+        L"swapfile.sys",
+        L"hiberfil.sys",
+        NULL
+    };
+
+    PWSTR SpecialDirList[] = {
+        L"Recycled",
+        L"RECYCLER",
+        L"$RECYCLE.BIN",
+        NULL
+    };
+
+    PWSTR   entryName;
+    ULONG   length;
+    int     i;
+
+    for (i = 0; TRUE; i++) {
+
+        if (bDirectory) {
+            entryName = SpecialDirList[i];
+        } else {
+            entryName = SpecialFileList[i];
+        }
+
+        if (NULL == entryName) {
+            break;
+        }
+
+        length = wcslen(entryName) * sizeof(WCHAR);
+        if (FileName->Length == length) {
+            if ( 0 == _wcsnicmp( entryName,
+                                 FileName->Buffer,
+                                 length / sizeof(WCHAR) )) {
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
 
-/*************************************************************************
-*
-* 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 NTAPI Ext2CommonCreate(
-PtrExt2IrpContext                      PtrIrpContext,
-PIRP                                           PtrIrp,
-BOOLEAN                                                FirstAttempt)
+NTSTATUS
+Ext2LookupFile (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PUNICODE_STRING      FullName,
+    IN PEXT2_MCB            Parent,
+    OUT PEXT2_MCB *         Ext2Mcb,
+    IN USHORT               Linkdep
+)
 {
-       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;
-
-    /* Silence GCC warnings */
-    RtlZeroMemory(&RelatedObjectName, sizeof(UNICODE_STRING));
-
-
-       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();
-               }
-
-               // 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();
-               }
-
-               // 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();
-               //      }
-
-               // 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();
-               }
-
-
-               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();
-                       }
-
-                       if (DirectoryOnlyRequested) 
-                       {
-                               // a volume is not a directory
-                               RC = STATUS_NOT_A_DIRECTORY;
-                               try_return();
-                       }
-
-                       if ((RequestedDisposition != FILE_OPEN) && (RequestedDisposition != FILE_OPEN_IF)) 
-                       {
-                               // cannot create a new volume, I'm afraid ...
-                               RC = STATUS_ACCESS_DENIED;
-                               try_return();
-                       }
-                       DebugTrace(DEBUG_TRACE_MISC,   "Volume open requested", 0 );
-                       RC = Ext2OpenVolume(PtrVCB, PtrIrpContext, PtrIrp, ShareAccess, PtrSecurityContext, PtrNewFileObject);
-                       ReturnedInformation = PtrIrp->IoStatus.Information;
-
-                       try_return();
-               }
-
-               if (OpenByFileId) 
-               {
-                       DebugTrace(DEBUG_TRACE_MISC, "Open by File Id requested", 0 );
-                       RC = STATUS_ACCESS_DENIED;
-                       try_return();
-               }
-
-               // 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();
-                       }
-
-                       //      Performing validity checks...
-                       if ((RelatedObjectName.Length == 0) || (RelatedObjectName.Buffer[0] != L'\\')) 
-                       {
-                               RC = STATUS_INVALID_PARAMETER;
-                               try_return();
-                       }
-
-                       if ((TargetObjectName.Length != 0) && (TargetObjectName.Buffer[0] == L'\\')) 
-                       {
-                               RC = STATUS_INVALID_PARAMETER;
-                               try_return();
-                       }
-
-                       // 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();
-                               }
-
-                               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();
-                       }
-
-                       {
-                               AbsolutePathName.MaximumLength = TargetObjectName.Length;
-                               if (!(AbsolutePathName.Buffer = Ext2AllocatePool(PagedPool, AbsolutePathName.MaximumLength ))) {
-                                       RC = STATUS_INSUFFICIENT_RESOURCES;
-                                       try_return();
-                               }
-
-                               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 = Ext2OpenRootDirectory(PtrVCB, PtrIrpContext, PtrIrp, ShareAccess, PtrSecurityContext, PtrNewFileObject);
-                       DebugTrace(DEBUG_TRACE_MISC,   " === Root directory opened", 0 );
-                       try_return();
-               }
-
-
-               {
-                       //      Used during parsing the file path...
-                       UNICODE_STRING                  RemainingName;
-                       UNICODE_STRING                  CurrentName;
-                       UNICODE_STRING                  NextRemainingName;
-                       ULONG                                   CurrInodeNo = 0;
-                       PtrExt2FCB                              PtrCurrFCB = NULL;
-                       PtrExt2FCB                              PtrNextFCB = NULL;
-                       PFILE_OBJECT                    PtrCurrFileObject = NULL;
-                       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 )
-                                               {
-                                                       //
-                                                       //      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();
-                                       }
-                               }
-                               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();
-                                                       }
-                                                       // 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 )
-                                               { 
-                                                       //
-                                                       //      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();
-                                               }
-                                       }
-
-                                       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();
-                                               }
-
-                                               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();
-                                               }
-                                               
-                                               //      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();
-
-                                               }
-                                               if( DirectoryOnlyRequested && Type != EXT2_FT_DIR )
-                                               {
-                                                       RC = STATUS_NOT_A_DIRECTORY;
-                                                       try_return();
-                                               }
-                                               if( FileOnlyRequested && Type == EXT2_FT_DIR )
-                                               {
-                                                       RC = STATUS_FILE_IS_A_DIRECTORY;
-                                                       try_return();
-                                               }
-
-                                               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();
-                                               }
-
-                                               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();
-                       }
-               
-                       
-                       // 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();
-                               }
-                       } 
-                       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);
+    NTSTATUS        Status = STATUS_OBJECT_NAME_NOT_FOUND;
+    UNICODE_STRING  FileName;
+    PEXT2_MCB       Mcb = NULL;
+    struct dentry  *de = NULL;
+
+    USHORT          i = 0, End;
+    ULONG           Inode;
+
+    BOOLEAN         bParent = FALSE;
+    BOOLEAN         bDirectory = FALSE;
+    BOOLEAN         LockAcquired = FALSE;
+
+    _SEH2_TRY {
+
+        ExAcquireResourceExclusiveLite(&Vcb->McbLock, TRUE);
+        LockAcquired = TRUE;
+
+        *Ext2Mcb = NULL;
+
+        DEBUG(DL_RES, ("Ext2LookupFile: %wZ\n", FullName));
+
+        /* check names and parameters */
+        if (FullName->Buffer[0] == L'\\') {
+            Parent = Vcb->McbTree;
+        } else if (Parent) {
+            bParent = TRUE;
+        } else {
+            Parent = Vcb->McbTree;
+        }
+
+        /* make sure the parent is NULL */
+        if (!IsMcbDirectory(Parent)) {
+            Status =  STATUS_NOT_A_DIRECTORY;
+            _SEH2_LEAVE;
+        }
+
+        /* use symlink's target as parent directory */
+        if (IsMcbSymLink(Parent)) {
+            Parent = Parent->Target;
+            ASSERT(!IsMcbSymLink(Parent));
+            if (IsFileDeleted(Parent)) {
+                Status =  STATUS_NOT_A_DIRECTORY;
+                _SEH2_LEAVE;
+            }
+        }
+
+        if (NULL == Parent) {
+            Status =  STATUS_NOT_A_DIRECTORY;
+            _SEH2_LEAVE;
+        }
+
+        /* default is the parent Mcb*/
+        Ext2ReferMcb(Parent);
+        Mcb = Parent;
+
+        /* is empty file name or root node */
+        End = FullName->Length/sizeof(WCHAR);
+        if ( (End == 0) || (End == 1 &&
+                            FullName->Buffer[0] == L'\\')) {
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+
+        /* is a directory expected ? */
+        if (FullName->Buffer[End - 1] == L'\\') {
+            bDirectory = TRUE;
+        }
+
+        /* loop with every sub name */
+        while (i < End) {
+
+            USHORT Start = 0;
+
+            /* zero the prefix '\' */
+            while (i < End && FullName->Buffer[i] == L'\\') i++;
+            Start = i;
+
+            /* zero the suffix '\' */
+            while (i < End && (FullName->Buffer[i] != L'\\')) i++;
+
+            if (i > Start) {
+
+                FileName = *FullName;
+                FileName.Buffer += Start;
+                FileName.Length = (USHORT)((i - Start) * 2);
+
+                /* make sure the parent is NULL */
+                if (!IsMcbDirectory(Parent)) {
+                    Status =  STATUS_NOT_A_DIRECTORY;
+                    Ext2DerefMcb(Parent);
+                    break;
+                }
+
+                if (IsMcbSymLink(Parent)) {
+                    if (IsFileDeleted(Parent->Target)) {
+                        Status =  STATUS_NOT_A_DIRECTORY;
+                        Ext2DerefMcb(Parent);
+                        break;
+                    } else {
+                        Ext2ReferMcb(Parent->Target);
+                        Ext2DerefMcb(Parent);
+                        Parent = Parent->Target;
+                    }
+                }
+
+                /* search cached Mcb nodes */
+                Mcb = Ext2SearchMcbWithoutLock(Parent, &FileName);
+
+                if (Mcb) {
+
+                    /* derefer the parent Mcb */
+                    Ext2DerefMcb(Parent);
+                    Status = STATUS_SUCCESS;
+                    Parent = Mcb;
+
+                    if (IsMcbSymLink(Mcb) && IsFileDeleted(Mcb->Target) &&
+                            (Mcb->Refercount == 1)) {
+
+                        ASSERT(Mcb->Target);
+                        ASSERT(Mcb->Target->Refercount > 0);
+                        Ext2DerefMcb(Mcb->Target);
+                        Mcb->Target = NULL;
+                        ClearLongFlag(Mcb->Flags, MCB_TYPE_SYMLINK);
+                        SetLongFlag(Mcb->Flags, MCB_TYPE_SPECIAL);
+                        Mcb->FileAttr = FILE_ATTRIBUTE_NORMAL;
+                    }
+
+                } else {
+
+                    /* need create new Mcb node */
+
+                    /* is a valid ext2 name */
+                    if (!Ext2IsNameValid(&FileName)) {
+                        Status = STATUS_OBJECT_NAME_INVALID;
+                        Ext2DerefMcb(Parent);
+                        break;
+                    }
+
+                    /* seach the disk */
+                    de = NULL;
+                    Status = Ext2ScanDir (
+                                 IrpContext,
+                                 Vcb,
+                                 Parent,
+                                 &FileName,
+                                 &Inode,
+                                 &de);
+
+                    if (NT_SUCCESS(Status)) {
+
+                        /* check it's real parent */
+                        ASSERT (!IsMcbSymLink(Parent));
+
+                        /* allocate Mcb ... */
+                        Mcb = Ext2AllocateMcb(Vcb, &FileName, &Parent->FullName, 0);
+                        if (!Mcb) {
+                            Status = STATUS_INSUFFICIENT_RESOURCES;
+                            Ext2DerefMcb(Parent);
+                            break;
+                        }
+                        Mcb->de = de;
+                        Mcb->de->d_inode = &Mcb->Inode;
+                        Mcb->Inode.i_ino = Inode;
+                        Mcb->Inode.i_sb = &Vcb->sb;
+                        de = NULL;
+
+                        /* load inode information */
+                        if (!Ext2LoadInode(Vcb, &Mcb->Inode)) {
+                            Status = STATUS_CANT_WAIT;
+                            Ext2DerefMcb(Parent);
+                            Ext2FreeMcb(Vcb, Mcb);
+                            break;
+                        }
+
+                        /* set inode attribute */
+                        if (!CanIWrite(Vcb) && Ext2IsOwnerReadOnly(Mcb->Inode.i_mode)) {
+                            SetFlag(Mcb->FileAttr, FILE_ATTRIBUTE_READONLY);
+                        }
+
+                        if (S_ISDIR(Mcb->Inode.i_mode)) {
+                            SetFlag(Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY);
+                        } else {
+                            SetFlag(Mcb->FileAttr, FILE_ATTRIBUTE_NORMAL);
+                            if (!S_ISREG(Mcb->Inode.i_mode) &&
+                                    !S_ISLNK(Mcb->Inode.i_mode)) {
+                                SetLongFlag(Mcb->Flags, MCB_TYPE_SPECIAL);
+                            }
+                        }
+
+                        /* process special files under root directory */
+                        if (IsMcbRoot(Parent)) {
+                            /* set hidden and system attributes for
+                               Recycled / RECYCLER / pagefile.sys */
+                            BOOLEAN IsDirectory = IsMcbDirectory(Mcb);
+                            if (Ext2IsSpecialSystemFile(&Mcb->ShortName, IsDirectory)) {
+                                SetFlag(Mcb->FileAttr, FILE_ATTRIBUTE_HIDDEN);
+                                SetFlag(Mcb->FileAttr, FILE_ATTRIBUTE_SYSTEM);
+                            }
+                        }
+
+                        Mcb->CreationTime = Ext2NtTime(Mcb->Inode.i_ctime);
+                        Mcb->LastAccessTime = Ext2NtTime(Mcb->Inode.i_atime);
+                        Mcb->LastWriteTime = Ext2NtTime(Mcb->Inode.i_mtime);
+                        Mcb->ChangeTime = Ext2NtTime(Mcb->Inode.i_mtime);
+
+                        /* process symlink */
+                        if (S_ISLNK(Mcb->Inode.i_mode)) {
+                            Ext2FollowLink( IrpContext,
+                                            Vcb,
+                                            Parent,
+                                            Mcb,
+                                            Linkdep+1
+                                          );
+                        }
+
+                        /* add reference ... */
+                        Ext2ReferMcb(Mcb);
+
+                        /* add Mcb to it's parent tree*/
+                        Ext2InsertMcb(Vcb, Parent, Mcb);
+
+                        /* it's safe to deref Parent Mcb */
+                        Ext2DerefMcb(Parent);
+
+                        /* linking this Mcb*/
+                        Ext2LinkTailMcb(Vcb, Mcb);
+
+                        /* set parent to preare re-scan */
+                        Parent = Mcb;
+
+                    } else {
+
+                        /* derefernce it's parent */
+                        Ext2DerefMcb(Parent);
+                        break;
+                    }
+                }
+
+            } else {
+
+                /* there seems too many \ or / */
+                /* Mcb should be already set to Parent */
+                ASSERT(Mcb == Parent);
+                Status = STATUS_SUCCESS;
+                break;
+            }
+        }
+
+    } _SEH2_FINALLY {
+
+        if (de) {
+            Ext2FreeEntry(de);
+        }
+
+        if (NT_SUCCESS(Status)) {
+            if (bDirectory) {
+                if (IsMcbDirectory(Mcb)) {
+                    *Ext2Mcb = Mcb;
+                } else {
+                    Ext2DerefMcb(Mcb);
+                    Status = STATUS_NOT_A_DIRECTORY;
+                }
+            } else {
+                *Ext2Mcb = Mcb;
+            }
+        }
+
+        if (LockAcquired) {
+            ExReleaseResourceLite(&Vcb->McbLock);
+        }
+    } _SEH2_END;
+
+    return Status;
 }
 
 
-/*************************************************************************
-*
-* Function: Ext2OpenVolume()
-*
-* Description:
-*      Open a logical volume for the caller.
-*
-* Expected Interrupt Level (for execution) :
-*
-*  IRQL_PASSIVE_LEVEL
-*
-* Return Value: STATUS_SUCCESS/Error
-*
-*************************************************************************/
-NTSTATUS NTAPI 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
+Ext2ScanDir (
+    IN PEXT2_IRP_CONTEXT    IrpContext,
+    IN PEXT2_VCB            Vcb,
+    IN PEXT2_MCB            Parent,
+    IN PUNICODE_STRING      FileName,
+    OUT PULONG              Inode,
+    OUT struct dentry     **dentry
+)
+{
+    struct ext3_dir_entry_2 *dir_entry = NULL;
+    struct buffer_head     *bh = NULL;
+    struct dentry          *de = NULL;
+
+    NTSTATUS                Status = STATUS_NO_SUCH_FILE;
+
+    DEBUG(DL_RES, ("Ext2ScanDir: %wZ\\%wZ\n", &Parent->FullName, FileName));
+
+    _SEH2_TRY {
+
+        /* grab parent's reference first */
+        Ext2ReferMcb(Parent);
+
+        /* bad request ! Can a man be pregnant ? Maybe:) */
+        if (!IsMcbDirectory(Parent)) {
+            Status = STATUS_NOT_A_DIRECTORY;
+            _SEH2_LEAVE;
+        }
+
+        /* parent is a symlink ? */
+        if IsMcbSymLink(Parent) {
+            if (Parent->Target) {
+                Ext2ReferMcb(Parent->Target);
+                Ext2DerefMcb(Parent);
+                Parent = Parent->Target;
+                ASSERT(!IsMcbSymLink(Parent));
+            } else {
+                DbgBreak();
+                Status = STATUS_NOT_A_DIRECTORY;
+                _SEH2_LEAVE;
+            }
+        }
+
+        de = Ext2BuildEntry(Vcb, Parent, FileName);
+        if (!de) {
+            DEBUG(DL_ERR, ( "Ex2ScanDir: failed to allocate dentry.\n"));
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            _SEH2_LEAVE;
+        }
+
+        bh = ext3_find_entry(IrpContext, de, &dir_entry);
+        if (dir_entry) {
+            Status = STATUS_SUCCESS;
+            *Inode = dir_entry->inode;
+            *dentry = de;
+        }
+
+    } _SEH2_FINALLY {
+
+        Ext2DerefMcb(Parent);
+
+        if (bh)
+            brelse(bh);
+
+        if (!NT_SUCCESS(Status)) {
+            if (de)
+                Ext2FreeEntry(de);
+        }
+    } _SEH2_END;
+
+    return Status;
+}
+
+NTSTATUS Ext2AddDotEntries(struct ext2_icb *icb, struct inode *dir,
+                           struct inode *inode)
 {
-       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();
-               }
-
-               // 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);
+    struct ext3_dir_entry_2 * de;
+    struct buffer_head * bh;
+    ext3_lblk_t block = 0;
+    int rc = 0;
+
+    bh = ext3_append(icb, inode, &block, &rc);
+    if (!bh) {
+        goto errorout;
+    }
+
+    de = (struct ext3_dir_entry_2 *) bh->b_data;
+    de->inode = cpu_to_le32(inode->i_ino);
+    de->name_len = 1;
+    de->rec_len = cpu_to_le16(EXT3_DIR_REC_LEN(de->name_len));
+    strcpy (de->name, ".");
+    ext3_set_de_type(inode->i_sb, de, S_IFDIR);
+    de = (struct ext3_dir_entry_2 *)
+         ((char *) de + le16_to_cpu(de->rec_len));
+    de->inode = cpu_to_le32(dir->i_ino);
+    de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize-EXT3_DIR_REC_LEN(1));
+    de->name_len = 2;
+    strcpy (de->name, "..");
+    ext3_set_de_type(inode->i_sb, de, S_IFDIR);
+    inode->i_nlink = 2;
+    set_buffer_dirty(bh);
+    ext3_mark_inode_dirty(icb, inode);
+
+errorout:
+    if (bh)
+        brelse (bh);
+
+    return Ext2WinntError(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
+NTSTATUS
+Ext2CreateFile(
+    PEXT2_IRP_CONTEXT IrpContext,
+    PEXT2_VCB         Vcb,
+    PBOOLEAN          OpPostIrp
+)
 {
-       // Initialize the disk dependent portion as you see fit
+    NTSTATUS            Status = STATUS_UNSUCCESSFUL;
+    PIO_STACK_LOCATION  IrpSp;
+    PEXT2_FCB           Fcb = NULL;
+    PEXT2_MCB           Mcb = NULL;
+    PEXT2_MCB           SymLink = NULL;
+    PEXT2_CCB           Ccb = NULL;
 
-       // Initialize the two ERESOURCE objects
-       ExInitializeResourceLite(&(PtrNewFCB->NTRequiredFCB.MainResource));
-       ExInitializeResourceLite(&(PtrNewFCB->NTRequiredFCB.PagingIoResource));
+    PEXT2_FCB           ParentFcb = NULL;
+    PEXT2_MCB           ParentMcb = NULL;
 
-       PtrNewFCB->FCBFlags |= EXT2_INITIALIZED_MAIN_RESOURCE | EXT2_INITIALIZED_PAGING_IO_RESOURCE | Flags;
+    UNICODE_STRING      FileName;
+    PIRP                Irp;
+
+    ULONG               Options;
+    ULONG               CreateDisposition;
+
+    BOOLEAN             bParentFcbCreated = FALSE;
+
+#ifndef __REACTOS__
+    BOOLEAN             bDir = FALSE;
+#endif
+    BOOLEAN             bFcbAllocated = FALSE;
+    BOOLEAN             bCreated = FALSE;
+    BOOLEAN             bMainResourceAcquired = FALSE;
 
-       PtrNewFCB->PtrVCB = PtrVCB;
+    BOOLEAN             OpenDirectory;
+    BOOLEAN             OpenTargetDirectory;
+    BOOLEAN             CreateDirectory;
+    BOOLEAN             SequentialOnly;
+    BOOLEAN             NoIntermediateBuffering;
+    BOOLEAN             IsPagingFile;
+    BOOLEAN             DirectoryFile;
+    BOOLEAN             NonDirectoryFile;
+    BOOLEAN             NoEaKnowledge;
+    BOOLEAN             DeleteOnClose;
+    BOOLEAN             TemporaryFile;
+    BOOLEAN             CaseSensitive;
 
-       // caller MUST ensure that VCB has been acquired exclusively
-       InsertTailList(&(PtrVCB->FCBListHead), &(PtrNewFCB->NextFCB));
+    ACCESS_MASK         DesiredAccess;
+    ULONG               ShareAccess;
 
-       // initialize the various list heads
-       InitializeListHead(&(PtrNewFCB->CCBListHead));
+    RtlZeroMemory(&FileName, sizeof(UNICODE_STRING));
 
-//     PtrNewFCB->ReferenceCount = 1;
-//     PtrNewFCB->OpenHandleCount = 1;
+    Irp = IrpContext->Irp;
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
-       if( PtrObjectName )
-       {
-               PtrNewFCB->FCBName = PtrObjectName;
-       }
+    Options  = IrpSp->Parameters.Create.Options;
 
-       if ( PtrFileObject )
-       {
-               PtrFileObject->FsContext = (void *)(&(PtrNewFCB->NTRequiredFCB));
-       }
+    DirectoryFile = IsFlagOn(Options, FILE_DIRECTORY_FILE);
+    OpenTargetDirectory = IsFlagOn(IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
 
-       return;
+    NonDirectoryFile = IsFlagOn(Options, FILE_NON_DIRECTORY_FILE);
+    SequentialOnly = IsFlagOn(Options, FILE_SEQUENTIAL_ONLY);
+    NoIntermediateBuffering = IsFlagOn( Options, FILE_NO_INTERMEDIATE_BUFFERING );
+    NoEaKnowledge = IsFlagOn(Options, FILE_NO_EA_KNOWLEDGE);
+    DeleteOnClose = IsFlagOn(Options, FILE_DELETE_ON_CLOSE);
+
+    CaseSensitive = IsFlagOn(IrpSp->Flags, SL_CASE_SENSITIVE);
+
+    TemporaryFile = IsFlagOn(IrpSp->Parameters.Create.FileAttributes,
+                             FILE_ATTRIBUTE_TEMPORARY );
+
+    CreateDisposition = (Options >> 24) & 0x000000ff;
+
+    IsPagingFile = IsFlagOn(IrpSp->Flags, SL_OPEN_PAGING_FILE);
+
+    CreateDirectory = (BOOLEAN)(DirectoryFile &&
+                                ((CreateDisposition == FILE_CREATE) ||
+                                 (CreateDisposition == FILE_OPEN_IF)));
+
+    OpenDirectory   = (BOOLEAN)(DirectoryFile &&
+                                ((CreateDisposition == FILE_OPEN) ||
+                                 (CreateDisposition == FILE_OPEN_IF)));
+
+    DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
+    ShareAccess   = IrpSp->Parameters.Create.ShareAccess;
+
+    *OpPostIrp = FALSE;
+
+    _SEH2_TRY {
+
+        FileName.MaximumLength = IrpSp->FileObject->FileName.MaximumLength;
+        FileName.Length = IrpSp->FileObject->FileName.Length;
+
+        if (IrpSp->FileObject->RelatedFileObject) {
+            ParentFcb = (PEXT2_FCB)(IrpSp->FileObject->RelatedFileObject->FsContext);
+        }
+
+        if (ParentFcb) {
+            ParentMcb = ParentFcb->Mcb;
+            SetLongFlag(ParentFcb->Flags, FCB_STATE_BUSY);
+            Ext2ReferMcb(ParentMcb);
+        }
+
+        if (FileName.Length == 0) {
+
+            if (ParentFcb) {
+                Mcb = ParentFcb->Mcb;
+                Ext2ReferMcb(Mcb);
+                Status = STATUS_SUCCESS;
+                goto McbExisting;
+            } else {
+                DbgBreak();
+                Status = STATUS_INVALID_PARAMETER;
+                _SEH2_LEAVE;
+            }
+        }
+
+        FileName.Buffer = Ext2AllocatePool(
+                              PagedPool,
+                              FileName.MaximumLength,
+                              EXT2_FNAME_MAGIC
+                          );
+
+        if (!FileName.Buffer) {
+            DEBUG(DL_ERR, ( "Ex2CreateFile: failed to allocate FileName.\n"));
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            _SEH2_LEAVE;
+        }
+
+        INC_MEM_COUNT(PS_FILE_NAME, FileName.Buffer, FileName.MaximumLength);
+
+        RtlZeroMemory(FileName.Buffer, FileName.MaximumLength);
+        RtlCopyMemory(FileName.Buffer, IrpSp->FileObject->FileName.Buffer, FileName.Length);
+
+        if (ParentFcb && FileName.Buffer[0] == L'\\') {
+            Status = STATUS_INVALID_PARAMETER;
+            _SEH2_LEAVE;
+        }
+
+        if ((FileName.Length > sizeof(WCHAR)) &&
+                (FileName.Buffer[1] == L'\\') &&
+                (FileName.Buffer[0] == L'\\')) {
+
+            FileName.Length -= sizeof(WCHAR);
+
+            RtlMoveMemory( &FileName.Buffer[0],
+                           &FileName.Buffer[1],
+                           FileName.Length );
+
+            //
+            //  Bad Name if there are still beginning backslashes.
+            //
+
+            if ((FileName.Length > sizeof(WCHAR)) &&
+                    (FileName.Buffer[1] == L'\\') &&
+                    (FileName.Buffer[0] == L'\\')) {
+
+                Status = STATUS_OBJECT_NAME_INVALID;
+                _SEH2_LEAVE;
+            }
+        }
+
+        if (IsFlagOn(Options, FILE_OPEN_BY_FILE_ID)) {
+            Status = STATUS_NOT_IMPLEMENTED;
+            _SEH2_LEAVE;
+        }
+
+        DEBUG(DL_INF, ( "Ext2CreateFile: %wZ Paging=%d Option: %xh:"
+                        "Dir=%d NonDir=%d OpenTarget=%d NC=%d DeleteOnClose=%d\n",
+                        &FileName, IsPagingFile, IrpSp->Parameters.Create.Options,
+                        DirectoryFile, NonDirectoryFile, OpenTargetDirectory,
+                        NoIntermediateBuffering, DeleteOnClose ));
+
+        DEBUG(DL_RES, ("Ext2CreateFile: Lookup 1st: %wZ at %S\n",
+                       &FileName, ParentMcb ? ParentMcb->FullName.Buffer : L" "));
+        Status = Ext2LookupFile(
+                     IrpContext,
+                     Vcb,
+                     &FileName,
+                     ParentMcb,
+                     &Mcb,
+                     0 );
+McbExisting:
+
+        if (!NT_SUCCESS(Status)) {
+
+            UNICODE_STRING  PathName;
+            UNICODE_STRING  RealName;
+            UNICODE_STRING  RemainName;
+
+#ifndef __REACTOS__
+            LONG            i = 0;
+#endif
+            PathName = FileName;
+            Mcb = NULL;
+
+            if (PathName.Buffer[PathName.Length/2 - 1] == L'\\') {
+                if (DirectoryFile) {
+                    PathName.Length -=2;
+                    PathName.Buffer[PathName.Length/2] = 0;
+                } else {
+                    DirectoryFile = TRUE;
+                }
+            }
+
+            if (!ParentMcb) {
+                if (PathName.Buffer[0] != L'\\') {
+                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
+                    _SEH2_LEAVE;
+                } else {
+                    ParentMcb = Vcb->McbTree;
+                    Ext2ReferMcb(ParentMcb);
+                }
+            }
+
+Dissecting:
+
+            FsRtlDissectName(PathName, &RealName, &RemainName);
+
+            if (((RemainName.Length != 0) && (RemainName.Buffer[0] == L'\\')) ||
+                    (RealName.Length >= 256 * sizeof(WCHAR))) {
+                Status = STATUS_OBJECT_NAME_INVALID;
+                _SEH2_LEAVE;
+            }
+
+            if (RemainName.Length != 0) {
+
+                PEXT2_MCB   RetMcb = NULL;
+
+                DEBUG(DL_RES, ("Ext2CreateFile: Lookup 2nd: %wZ\\%wZ\n",
+                               &ParentMcb->FullName, &RealName));
+
+                Status = Ext2LookupFile (
+                             IrpContext,
+                             Vcb,
+                             &RealName,
+                             ParentMcb,
+                             &RetMcb,
+                             0);
+
+                /* quit name resolving loop */
+                if (!NT_SUCCESS(Status)) {
+                    if (Status == STATUS_NO_SUCH_FILE && RemainName.Length != 0) {
+                        Status = STATUS_OBJECT_PATH_NOT_FOUND;
+                    }
+                    _SEH2_LEAVE;
+                }
+
+                /* deref ParentMcb */
+                Ext2DerefMcb(ParentMcb);
+
+                /* RetMcb is already refered */
+                ParentMcb = RetMcb;
+                PathName  = RemainName;
+
+                /* symlink must use it's target */
+                if (IsMcbSymLink(ParentMcb)) {
+                    Ext2ReferMcb(ParentMcb->Target);
+                    Ext2DerefMcb(ParentMcb);
+                    ParentMcb = ParentMcb->Target;
+                    ASSERT(!IsMcbSymLink(ParentMcb));
+                }
+
+                goto Dissecting;
+            }
+
+            /* is name valid */
+            if ( FsRtlDoesNameContainWildCards(&RealName) ||
+                    !Ext2IsNameValid(&RealName)) {
+                Status = STATUS_OBJECT_NAME_INVALID;
+                _SEH2_LEAVE;
+            }
+
+            /* clear BUSY bit from original ParentFcb */
+            if (ParentFcb) {
+                ClearLongFlag(ParentFcb->Flags, FCB_STATE_BUSY);
+            }
+
+            /* get the ParentFcb, allocate it if needed ... */
+            ParentFcb = ParentMcb->Fcb;
+            if (!ParentFcb) {
+                ParentFcb = Ext2AllocateFcb(Vcb, ParentMcb);
+                if (!ParentFcb) {
+                    Status = STATUS_INSUFFICIENT_RESOURCES;
+                    _SEH2_LEAVE;
+                }
+                bParentFcbCreated = TRUE;
+                Ext2ReferXcb(&ParentFcb->ReferenceCount);
+            }
+            SetLongFlag(ParentFcb->Flags, FCB_STATE_BUSY);
+
+            // We need to create a new one ?
+            if ((CreateDisposition == FILE_CREATE ) ||
+                    (CreateDisposition == FILE_SUPERSEDE) ||
+                    (CreateDisposition == FILE_OPEN_IF) ||
+                    (CreateDisposition == FILE_OVERWRITE_IF)) {
+
+                if (IsVcbReadOnly(Vcb)) {
+                    Status = STATUS_MEDIA_WRITE_PROTECTED;
+                    _SEH2_LEAVE;
+                }
+
+                if (!CanIWrite(Vcb) && Ext2IsOwnerReadOnly(ParentFcb->Mcb->Inode.i_mode)) {
+                    Status = STATUS_ACCESS_DENIED;
+                    _SEH2_LEAVE;
+                }
+
+                if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
+                    IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
+                                                  Vcb->Vpb->RealDevice );
+                    SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
+                    Ext2RaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
+                }
+
+                if (DirectoryFile) {
+                    if (TemporaryFile) {
+                        DbgBreak();
+                        Status = STATUS_INVALID_PARAMETER;
+                        _SEH2_LEAVE;
+                    }
+                }
+
+                if (!ParentFcb) {
+                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
+                    _SEH2_LEAVE;
+                }
+
+                /* allocate inode and construct entry for this file */
+                Status = Ext2CreateInode(
+                             IrpContext,
+                             Vcb,
+                             ParentFcb,
+                             DirectoryFile ? EXT2_FT_DIR : EXT2_FT_REG_FILE,
+                             IrpSp->Parameters.Create.FileAttributes,
+                             &RealName
+                         );
+
+                if (!NT_SUCCESS(Status)) {
+                    DbgBreak();
+                    _SEH2_LEAVE;
+                }
+
+                bCreated = TRUE;
+                DEBUG(DL_RES, ("Ext2CreateFile: Confirm creation: %wZ\\%wZ\n",
+                               &ParentMcb->FullName, &RealName));
+
+                Irp->IoStatus.Information = FILE_CREATED;
+                Status = Ext2LookupFile (
+                             IrpContext,
+                             Vcb,
+                             &RealName,
+                             ParentMcb,
+                             &Mcb,
+                             0);
+                if (!NT_SUCCESS(Status)) {
+                    DbgBreak();
+                }
+
+            } else if (OpenTargetDirectory) {
+
+                if (IsVcbReadOnly(Vcb)) {
+                    Status = STATUS_MEDIA_WRITE_PROTECTED;
+                    _SEH2_LEAVE;
+                }
+
+                if (!ParentFcb) {
+                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
+                    _SEH2_LEAVE;
+                }
+
+                RtlZeroMemory( IrpSp->FileObject->FileName.Buffer,
+                               IrpSp->FileObject->FileName.MaximumLength);
+                IrpSp->FileObject->FileName.Length = RealName.Length;
+
+                RtlCopyMemory( IrpSp->FileObject->FileName.Buffer,
+                               RealName.Buffer,
+                               RealName.Length );
+
+                Fcb = ParentFcb;
+                Mcb = Fcb->Mcb;
+                Ext2ReferMcb(Mcb);
+
+                Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
+                Status = STATUS_SUCCESS;
+
+            } else {
+
+                Status = STATUS_OBJECT_NAME_NOT_FOUND;
+                _SEH2_LEAVE;
+            }
+
+        } else { // File / Dir already exists.
+
+            /* here already get Mcb referred */
+            if (OpenTargetDirectory) {
+
+                UNICODE_STRING  RealName = FileName;
+                USHORT          i = 0;
+
+                while (RealName.Buffer[RealName.Length/2 - 1] == L'\\') {
+                    RealName.Length -= sizeof(WCHAR);
+                    RealName.Buffer[RealName.Length/2] = 0;
+                }
+                i = RealName.Length/2;
+                while (i > 0 && RealName.Buffer[i - 1] != L'\\')
+                    i--;
+
+                if (IsVcbReadOnly(Vcb)) {
+                    Status = STATUS_MEDIA_WRITE_PROTECTED;
+                    Ext2DerefMcb(Mcb);
+                    _SEH2_LEAVE;
+                }
+
+                Irp->IoStatus.Information = FILE_EXISTS;
+                Status = STATUS_SUCCESS;
+
+                RtlZeroMemory( IrpSp->FileObject->FileName.Buffer,
+                               IrpSp->FileObject->FileName.MaximumLength);
+                IrpSp->FileObject->FileName.Length = RealName.Length - i * sizeof(WCHAR);
+                RtlCopyMemory( IrpSp->FileObject->FileName.Buffer, &RealName.Buffer[i],
+                               IrpSp->FileObject->FileName.Length );
+
+                // use's it's parent since it's open-target operation
+                Ext2ReferMcb(Mcb->Parent);
+                Ext2DerefMcb(Mcb);
+                Mcb = Mcb->Parent;
+
+                goto Openit;
+            }
+
+            // We can not create if one exists
+            if (CreateDisposition == FILE_CREATE) {
+                Irp->IoStatus.Information = FILE_EXISTS;
+                Status = STATUS_OBJECT_NAME_COLLISION;
+                Ext2DerefMcb(Mcb);
+                _SEH2_LEAVE;
+            }
+
+            /* directory forbits us to do the followings ... */
+            if (IsMcbDirectory(Mcb)) {
+
+                if ((CreateDisposition != FILE_OPEN) &&
+                        (CreateDisposition != FILE_OPEN_IF)) {
+
+                    Status = STATUS_OBJECT_NAME_COLLISION;
+                    Ext2DerefMcb(Mcb);
+                    _SEH2_LEAVE;
+                }
+
+                if (NonDirectoryFile) {
+                    Status = STATUS_FILE_IS_A_DIRECTORY;
+                    Ext2DerefMcb(Mcb);
+                    _SEH2_LEAVE;
+                }
+
+                if (Mcb->Inode.i_ino == EXT2_ROOT_INO) {
+
+                    if (OpenTargetDirectory) {
+                        DbgBreak();
+                        Status = STATUS_INVALID_PARAMETER;
+                        Ext2DerefMcb(Mcb);
+                        _SEH2_LEAVE;
+                    }
+                }
+
+            } else {
+
+                if (DirectoryFile) {
+                    Status = STATUS_NOT_A_DIRECTORY;;
+                    Ext2DerefMcb(Mcb);
+                    _SEH2_LEAVE;
+                }
+            }
+
+            Irp->IoStatus.Information = FILE_OPENED;
+        }
+
+Openit:
+        /* Mcb should already be referred and symlink is too */
+        if (Mcb) {
+
+            ASSERT(Mcb->Refercount > 0);
+
+            /* refer it's target if it's a symlink, so both refered */
+            if (IsMcbSymLink(Mcb)) {
+                if (IsFileDeleted(Mcb->Target)) {
+                    DbgBreak();
+                    SetLongFlag(Mcb->Flags, MCB_TYPE_SPECIAL);
+                    ClearLongFlag(Mcb->Flags, MCB_TYPE_SYMLINK);
+                    Ext2DerefMcb(Mcb->Target);
+                    Mcb->Target = NULL;
+                } else {
+                    SymLink = Mcb;
+                    Mcb = Mcb->Target;
+                    Ext2ReferMcb(Mcb);
+                    ASSERT (!IsMcbSymLink(Mcb));
+                }
+            }
+
+            // Check readonly flag
+            if (!CanIWrite(Vcb) && Ext2IsOwnerReadOnly(Mcb->Inode.i_mode)) {
+                if (BooleanFlagOn(DesiredAccess,  FILE_WRITE_DATA | FILE_APPEND_DATA |
+                                  FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD)) {
+                    Status = STATUS_ACCESS_DENIED;
+                    _SEH2_LEAVE;
+                } else if (IsFlagOn(Options, FILE_DELETE_ON_CLOSE )) {
+                    Status = STATUS_CANNOT_DELETE;
+                    _SEH2_LEAVE;
+                }
+            }
+
+            Fcb = Mcb->Fcb;
+            if (Fcb == NULL) {
+
+                /* allocate Fcb for this file */
+                Fcb = Ext2AllocateFcb (Vcb, Mcb);
+                if (Fcb) {
+                    bFcbAllocated = TRUE;
+                } else {
+                    Status = STATUS_INSUFFICIENT_RESOURCES;
+                }
+            } else {
+                if (IsPagingFile) {
+                    Status = STATUS_SHARING_VIOLATION;
+                    Fcb = NULL;
+                }
+            }
+
+            /* Now it's safe to defer Mcb */
+            Ext2DerefMcb(Mcb);
+        }
+
+        if (Fcb) {
+
+            /* grab Fcb's reference first to avoid the race between
+               Ext2Close  (it could free the Fcb we are accessing) */
+            Ext2ReferXcb(&Fcb->ReferenceCount);
+
+            ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
+            bMainResourceAcquired = TRUE;
+
+            /* Open target directory ? */
+            if (NULL == Mcb) {
+                DbgBreak();
+                Mcb = Fcb->Mcb;
+            }
+
+            /* check Mcb reference */
+            ASSERT(Fcb->Mcb->Refercount > 0);
+
+            /* file delted ? */
+            if (IsFlagOn(Fcb->Mcb->Flags, MCB_FILE_DELETED)) {
+                Status = STATUS_FILE_DELETED;
+                _SEH2_LEAVE;
+            }
+
+            if (DeleteOnClose && NULL == SymLink) {
+                Status = Ext2IsFileRemovable(IrpContext, Vcb, Fcb, Ccb);
+                if (!NT_SUCCESS(Status)) {
+                    _SEH2_LEAVE;
+                }
+            }
+
+            /* check access and oplock access for opened files */
+            if (!bFcbAllocated  && !IsDirectory(Fcb)) {
+
+                /* whether there's batch oplock grabed on the file */
+                if (FsRtlCurrentBatchOplock(&Fcb->Oplock)) {
+
+                    Irp->IoStatus.Information = FILE_OPBATCH_BREAK_UNDERWAY;
+
+                    /* break the batch lock if the sharing check fails */
+                    Status = FsRtlCheckOplock( &Fcb->Oplock,
+                                               IrpContext->Irp,
+                                               IrpContext,
+                                               Ext2OplockComplete,
+                                               Ext2LockIrp );
+
+                    if ( Status != STATUS_SUCCESS &&
+                            Status != STATUS_OPLOCK_BREAK_IN_PROGRESS) {
+                        *OpPostIrp = TRUE;
+                        _SEH2_LEAVE;
+                    }
+                }
+            }
+
+            if (bCreated) {
+
+                //
+                //  This file is just created.
+                //
+
+                if (DirectoryFile) {
+
+                    Status = Ext2AddDotEntries(IrpContext, &ParentMcb->Inode, &Mcb->Inode);
+                    if (!NT_SUCCESS(Status)) {
+                        Ext2DeleteFile(IrpContext, Vcb, Fcb, Mcb);
+                        _SEH2_LEAVE;
+                    }
+
+                } else {
+
+                    if ((LONGLONG)ext3_free_blocks_count(SUPER_BLOCK) <=
+                            Ext2TotalBlocks(Vcb, &Irp->Overlay.AllocationSize, NULL)) {
+                        DbgBreak();
+                        Status = STATUS_DISK_FULL;
+                        _SEH2_LEAVE;
+                    }
+
+                    /* disable data blocks allocation */
+#if 0
+                    Fcb->Header.AllocationSize.QuadPart =
+                        Irp->Overlay.AllocationSize.QuadPart;
+
+                    if (Fcb->Header.AllocationSize.QuadPart > 0) {
+                        Status = Ext2ExpandFile(IrpContext,
+                                                Vcb,
+                                                Fcb->Mcb,
+                                                &(Fcb->Header.AllocationSize)
+                                               );
+                        SetLongFlag(Fcb->Flags, FCB_ALLOC_IN_CREATE);
+                        if (!NT_SUCCESS(Status)) {
+                            Fcb->Header.AllocationSize.QuadPart = 0;
+                            Ext2TruncateFile(IrpContext, Vcb, Fcb->Mcb,
+                                             &Fcb->Header.AllocationSize);
+                            _SEH2_LEAVE;
+                        }
+                    }
+#endif
+                }
+
+            } else {
+
+                //
+                //  This file alreayd exists.
+                //
+
+                if (DeleteOnClose) {
+
+                    if (IsVcbReadOnly(Vcb)) {
+                        Status = STATUS_MEDIA_WRITE_PROTECTED;
+                        _SEH2_LEAVE;
+                    }
+
+                    if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
+                        Status = STATUS_MEDIA_WRITE_PROTECTED;
+
+                        IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
+                                                      Vcb->Vpb->RealDevice );
+
+                        SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
+
+                        Ext2RaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
+                    }
+
+                } else {
+
+                    //
+                    // Just to Open file (Open/OverWrite ...)
+                    //
+
+                    if ((!IsDirectory(Fcb)) && (IsFlagOn(IrpSp->FileObject->Flags,
+                                                         FO_NO_INTERMEDIATE_BUFFERING))) {
+                        Fcb->Header.IsFastIoPossible = FastIoIsPossible;
+
+                        if (Fcb->SectionObject.DataSectionObject != NULL) {
+
+                            if (Fcb->NonCachedOpenCount == Fcb->OpenHandleCount) {
+
+                                if (!IsVcbReadOnly(Vcb)) {
+                                    CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL);
+                                    ClearLongFlag(Fcb->Flags, FCB_FILE_MODIFIED);
+                                }
+
+                                CcPurgeCacheSection(&Fcb->SectionObject,
+                                                    NULL,
+                                                    0,
+                                                    FALSE );
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (!IsDirectory(Fcb)) {
+
+                if (!IsVcbReadOnly(Vcb)) {
+                    if ((CreateDisposition == FILE_SUPERSEDE) && !IsPagingFile) {
+                        DesiredAccess |= DELETE;
+                    } else if (((CreateDisposition == FILE_OVERWRITE) ||
+                                (CreateDisposition == FILE_OVERWRITE_IF)) && !IsPagingFile) {
+                        DesiredAccess |= (FILE_WRITE_DATA | FILE_WRITE_EA |
+                                          FILE_WRITE_ATTRIBUTES );
+                    }
+                }
+
+                if (!bFcbAllocated) {
+
+                    //
+                    //  check the oplock state of the file
+                    //
+                    Status = FsRtlCheckOplock(  &Fcb->Oplock,
+                                                IrpContext->Irp,
+                                                IrpContext,
+                                                Ext2OplockComplete,
+                                                Ext2LockIrp );
+
+                    if ( Status != STATUS_SUCCESS &&
+                            Status != STATUS_OPLOCK_BREAK_IN_PROGRESS) {
+                        *OpPostIrp = TRUE;
+                        _SEH2_LEAVE;
+                    }
+                }
+            }
+
+            if (Fcb->OpenHandleCount > 0) {
+
+                /* check the shrae access conflicts */
+                Status = IoCheckShareAccess( DesiredAccess,
+                                             ShareAccess,
+                                             IrpSp->FileObject,
+                                             &(Fcb->ShareAccess),
+                                             TRUE );
+                if (!NT_SUCCESS(Status)) {
+                    _SEH2_LEAVE;
+                }
+
+            } else {
+
+                /* set share access rights */
+                IoSetShareAccess( DesiredAccess,
+                                  ShareAccess,
+                                  IrpSp->FileObject,
+                                  &(Fcb->ShareAccess) );
+            }
+
+            Ccb = Ext2AllocateCcb(SymLink);
+            if (!Ccb) {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                DbgBreak();
+                _SEH2_LEAVE;
+            }
+
+            if (DeleteOnClose)
+                SetLongFlag(Ccb->Flags, CCB_DELETE_ON_CLOSE);
+
+            if (SymLink)
+                Ccb->filp.f_dentry = SymLink->de;
+            else
+                Ccb->filp.f_dentry = Fcb->Mcb->de;
+
+            Ccb->filp.f_version = Fcb->Mcb->Inode.i_version;
+            Ext2ReferXcb(&Fcb->OpenHandleCount);
+            Ext2ReferXcb(&Fcb->ReferenceCount);
+
+            if (!IsDirectory(Fcb)) {
+                if (NoIntermediateBuffering) {
+                    Fcb->NonCachedOpenCount++;
+                    SetFlag(IrpSp->FileObject->Flags, FO_CACHE_SUPPORTED);
+                } else {
+                    SetFlag(IrpSp->FileObject->Flags, FO_CACHE_SUPPORTED);
+                }
+            }
+
+            Ext2ReferXcb(&Vcb->OpenHandleCount);
+            Ext2ReferXcb(&Vcb->ReferenceCount);
+
+            IrpSp->FileObject->FsContext = (void*) Fcb;
+            IrpSp->FileObject->FsContext2 = (void*) Ccb;
+            IrpSp->FileObject->PrivateCacheMap = NULL;
+            IrpSp->FileObject->SectionObjectPointer = &(Fcb->SectionObject);
+
+            DEBUG(DL_INF, ( "Ext2CreateFile: %wZ OpenCount=%u ReferCount=%u NonCachedCount=%u\n",
+                            &Fcb->Mcb->FullName, Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->NonCachedOpenCount));
+
+            Status = STATUS_SUCCESS;
+
+            if (bCreated) {
+
+                if (IsDirectory(Fcb)) {
+                    Ext2NotifyReportChange(
+                        IrpContext,
+                        Vcb,
+                        Fcb->Mcb,
+                        FILE_NOTIFY_CHANGE_DIR_NAME,
+                        FILE_ACTION_ADDED );
+                } else {
+                    Ext2NotifyReportChange(
+                        IrpContext,
+                        Vcb,
+                        Fcb->Mcb,
+                        FILE_NOTIFY_CHANGE_FILE_NAME,
+                        FILE_ACTION_ADDED );
+                }
+
+            } else if (!IsDirectory(Fcb)) {
+
+                if ( DeleteOnClose ||
+                        IsFlagOn(DesiredAccess, FILE_WRITE_DATA) ||
+                        (CreateDisposition == FILE_OVERWRITE) ||
+                        (CreateDisposition == FILE_OVERWRITE_IF)) {
+                    if (!MmFlushImageSection( &Fcb->SectionObject,
+                                              MmFlushForWrite )) {
+
+                        Status = DeleteOnClose ? STATUS_CANNOT_DELETE :
+                                 STATUS_SHARING_VIOLATION;
+                        _SEH2_LEAVE;
+                    }
+                }
+
+                if ((CreateDisposition == FILE_SUPERSEDE) ||
+                        (CreateDisposition == FILE_OVERWRITE) ||
+                        (CreateDisposition == FILE_OVERWRITE_IF)) {
+
+                    if (IsDirectory(Fcb)) {
+                        Status = STATUS_FILE_IS_A_DIRECTORY;
+                        _SEH2_LEAVE;
+                    }
+
+                    if (SymLink != NULL) {
+                        DbgBreak();
+                        Status = STATUS_INVALID_PARAMETER;
+                        _SEH2_LEAVE;
+                    }
+
+                    if (IsVcbReadOnly(Vcb)) {
+                        Status = STATUS_MEDIA_WRITE_PROTECTED;
+                        _SEH2_LEAVE;
+                    }
+
+                    if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
+
+                        IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
+                                                      Vcb->Vpb->RealDevice );
+                        SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
+                        Ext2RaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
+                    }
+
+                    Status = Ext2SupersedeOrOverWriteFile(
+                                 IrpContext,
+                                 IrpSp->FileObject,
+                                 Vcb,
+                                 Fcb,
+                                 &Irp->Overlay.AllocationSize,
+                                 CreateDisposition );
+
+                    if (!NT_SUCCESS(Status)) {
+                        DbgBreak();
+                        _SEH2_LEAVE;
+                    }
+
+                    Ext2NotifyReportChange(
+                        IrpContext,
+                        Vcb,
+                        Fcb->Mcb,
+                        FILE_NOTIFY_CHANGE_LAST_WRITE |
+                        FILE_NOTIFY_CHANGE_ATTRIBUTES |
+                        FILE_NOTIFY_CHANGE_SIZE,
+                        FILE_ACTION_MODIFIED );
+
+
+                    if (CreateDisposition == FILE_SUPERSEDE) {
+                        Irp->IoStatus.Information = FILE_SUPERSEDED;
+                    } else {
+                        Irp->IoStatus.Information = FILE_OVERWRITTEN;
+                    }
+                }
+            }
+
+        } else {
+            DbgBreak();
+            _SEH2_LEAVE;
+        }
+
+    } _SEH2_FINALLY {
+
+
+        if (ParentMcb) {
+            Ext2DerefMcb(ParentMcb);
+        }
+
+        /* cleanup Fcb and Ccb, Mcb if necessary */
+        if (!NT_SUCCESS(Status)) {
+
+            if (Ccb != NULL) {
+
+                DbgBreak();
+
+                ASSERT(Fcb != NULL);
+                ASSERT(Fcb->Mcb != NULL);
+
+                DEBUG(DL_ERR, ("Ext2CreateFile: failed to create %wZ status = %xh\n",
+                               &Fcb->Mcb->FullName, Status));
+
+                Ext2DerefXcb(&Fcb->OpenHandleCount);
+                Ext2DerefXcb(&Fcb->ReferenceCount);
+
+                if (!IsDirectory(Fcb)) {
+                    if (NoIntermediateBuffering) {
+                        Fcb->NonCachedOpenCount--;
+                    } else {
+                        ClearFlag(IrpSp->FileObject->Flags, FO_CACHE_SUPPORTED);
+                    }
+                }
+
+                Ext2DerefXcb(&Vcb->OpenHandleCount);
+                Ext2DerefXcb(&Vcb->ReferenceCount);
+
+                IoRemoveShareAccess(IrpSp->FileObject, &Fcb->ShareAccess);
+
+                IrpSp->FileObject->FsContext = NULL;
+                IrpSp->FileObject->FsContext2 = NULL;
+                IrpSp->FileObject->PrivateCacheMap = NULL;
+                IrpSp->FileObject->SectionObjectPointer = NULL;
+
+                Ext2FreeCcb(Vcb, Ccb);
+            }
+        }
+
+        if (Fcb && Ext2DerefXcb(&Fcb->ReferenceCount) == 0) {
+
+            if (IsFlagOn(Fcb->Flags, FCB_ALLOC_IN_CREATE)) {
+
+                LARGE_INTEGER Size;
+                ExAcquireResourceExclusiveLite(&Fcb->PagingIoResource, TRUE);
+                _SEH2_TRY {
+                    Size.QuadPart = 0;
+                    Ext2TruncateFile(IrpContext, Vcb, Fcb->Mcb, &Size);
+                } _SEH2_FINALLY {
+                    ExReleaseResourceLite(&Fcb->PagingIoResource);
+                } _SEH2_END;
+            }
+
+            if (bCreated) {
+                Ext2DeleteFile(IrpContext, Vcb, Fcb, Mcb);
+            }
+
+            Ext2FreeFcb(Fcb);
+            Fcb = NULL;
+            bMainResourceAcquired = FALSE;
+        }
+
+        if (bMainResourceAcquired) {
+            ExReleaseResourceLite(&Fcb->MainResource);
+        }
+
+        /* free file name buffer */
+        if (FileName.Buffer) {
+            DEC_MEM_COUNT(PS_FILE_NAME, FileName.Buffer, FileName.MaximumLength);
+            Ext2FreePool(FileName.Buffer, EXT2_FNAME_MAGIC);
+        }
+
+        /* dereference parent Fcb, free it if it goes to zero */
+        if (ParentFcb) {
+            ClearLongFlag(ParentFcb->Flags, FCB_STATE_BUSY);
+            if (bParentFcbCreated) {
+                if (Ext2DerefXcb(&ParentFcb->ReferenceCount) == 0) {
+                    Ext2FreeFcb(ParentFcb);
+                }
+            }
+        }
+
+        /* drop SymLink's refer: If succeeds, Ext2AllocateCcb should refer
+           it already. It fails, we need release the refer to let it freed */
+        if (SymLink) {
+            Ext2DerefMcb(SymLink);
+        }
+    } _SEH2_END;
+
+    return Status;
 }
-*/
-
-/*************************************************************************
-*
-* Function: Ext2OpenRootDirectory()
-*
-* Description:
-*      Open the root directory for a volume
-*      
-*
-* Expected Interrupt Level (for execution) :
-*
-*  ???
-*
-* Return Value: None
-*
-*************************************************************************/
-NTSTATUS NTAPI 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
-       )
+
+NTSTATUS
+Ext2CreateVolume(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb)
 {
-       //      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;
-}
+    PIO_STACK_LOCATION  IrpSp;
+    PIRP                Irp;
+    PEXT2_CCB           Ccb;
 
+    NTSTATUS            Status;
 
+    ACCESS_MASK         DesiredAccess;
+    ULONG               ShareAccess;
 
-PtrExt2FCB NTAPI Ext2LocateChildFCBInCore(
-       PtrExt2VCB                              PtrVCB, 
-       PUNICODE_STRING                 PtrName, 
-       ULONG                                   ParentInodeNo )
-{
+    ULONG               Options;
+    BOOLEAN             DirectoryFile;
+    BOOLEAN             OpenTargetDirectory;
 
-       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->ParentINodeNo == ParentInodeNo )
-               {
-                       if( RtlCompareUnicodeString( &PtrFCB->FCBName->ObjectName, PtrName, TRUE ) == 0 )
-                               return PtrFCB;
-               }
-       }
-
-       return NULL;
-}
+    ULONG               CreateDisposition;
 
-PtrExt2FCB NTAPI 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;
-}
+    Irp = IrpContext->Irp;
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
+    Options  = IrpSp->Parameters.Create.Options;
 
-ULONG NTAPI Ext2LocateFileInDisk (
-       PtrExt2VCB                              PtrVCB,
-       PUNICODE_STRING                 PtrCurrentName, 
-       PtrExt2FCB                              PtrParentFCB,
-       ULONG                                   *Type )
-{
+    DirectoryFile = IsFlagOn(Options, FILE_DIRECTORY_FILE);
+    OpenTargetDirectory = IsFlagOn(IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
 
-       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;
-       }
+    CreateDisposition = (Options >> 24) & 0x000000ff;
+
+    DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
+    ShareAccess   = IrpSp->Parameters.Create.ShareAccess;
+
+    if (DirectoryFile) {
+        return STATUS_NOT_A_DIRECTORY;
+    }
+
+    if (OpenTargetDirectory) {
+        DbgBreak();
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    if ( (CreateDisposition != FILE_OPEN) &&
+            (CreateDisposition != FILE_OPEN_IF) ) {
+        return STATUS_ACCESS_DENIED;
+    }
+
+    if ( !FlagOn(ShareAccess, FILE_SHARE_READ) &&
+            Vcb->OpenVolumeCount  != 0 ) {
+        return STATUS_SHARING_VIOLATION;
+    }
+
+    Ccb = Ext2AllocateCcb(NULL);
+    if (Ccb == NULL) {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto errorout;
+    }
+
+    Status = STATUS_SUCCESS;
+
+    if (Vcb->OpenVolumeCount > 0) {
+        Status = IoCheckShareAccess( DesiredAccess, ShareAccess,
+                                     IrpSp->FileObject,
+                                     &(Vcb->ShareAccess), TRUE);
+
+        if (!NT_SUCCESS(Status)) {
+            goto errorout;
+        }
+    } else {
+        IoSetShareAccess( DesiredAccess, ShareAccess,
+                          IrpSp->FileObject,
+                          &(Vcb->ShareAccess)   );
+    }
+
+
+    if (Vcb->OpenVolumeCount == 0 &&
+        !IsFlagOn(ShareAccess, FILE_SHARE_READ)  &&
+        !IsFlagOn(ShareAccess, FILE_SHARE_WRITE) ){
+
+        if (!IsVcbReadOnly(Vcb)) {
+            Ext2FlushFiles(IrpContext, Vcb, FALSE);
+            Ext2FlushVolume(IrpContext, Vcb, FALSE);
+        }
+
+        SetLongFlag(Vcb->Flags, VCB_VOLUME_LOCKED);
+        Vcb->LockFile = IrpSp->FileObject;
+    } else {
+        if (FlagOn(DesiredAccess, FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA) ) {
+            if (!IsVcbReadOnly(Vcb)) {
+                Ext2FlushFiles(IrpContext, Vcb, FALSE);
+                Ext2FlushVolume(IrpContext, Vcb, FALSE);
+            }
+        }
+    }
+
+    IrpSp->FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
+    IrpSp->FileObject->FsContext  = Vcb;
+    IrpSp->FileObject->FsContext2 = Ccb;
+    IrpSp->FileObject->Vpb = Vcb->Vpb;
+
+    Ext2ReferXcb(&Vcb->ReferenceCount);
+    Ext2ReferXcb(&Vcb->OpenHandleCount);
+    Ext2ReferXcb(&Vcb->OpenVolumeCount);
+
+    Irp->IoStatus.Information = FILE_OPENED;
+
+errorout:
+
+    return Status;
 }
 
 
-/*************************************************************************
-*
-* 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 NTAPI Ext2CreateFile( 
-       PtrExt2IrpContext               PtrIrpContext,
-       PtrExt2VCB                              PtrVCB,
-       PUNICODE_STRING                 PtrName, 
-       PtrExt2FCB                              PtrParentFCB,
-       ULONG                                   Type)
+NTSTATUS
+Ext2Create (IN PEXT2_IRP_CONTEXT IrpContext)
 {
-       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 ;
+    PDEVICE_OBJECT      DeviceObject;
+    PIRP                Irp;
+    PIO_STACK_LOCATION  IrpSp;
+    PEXT2_VCB           Vcb = 0;
+    NTSTATUS            Status = STATUS_OBJECT_NAME_NOT_FOUND;
+    PEXT2_FCBVCB        Xcb = NULL;
+    BOOLEAN             PostIrp = FALSE;
+    BOOLEAN             VcbResourceAcquired = FALSE;
+
+    DeviceObject = IrpContext->DeviceObject;
+    Irp = IrpContext->Irp;
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    Xcb = (PEXT2_FCBVCB) (IrpSp->FileObject->FsContext);
+
+    if (IsExt2FsDevice(DeviceObject)) {
+
+        DEBUG(DL_INF, ( "Ext2Create: Create on main device object.\n"));
+
+        Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = FILE_OPENED;
+
+        Ext2CompleteIrpContext(IrpContext, Status);
+
+        return Status;
+    }
+
+    _SEH2_TRY {
+
+        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
+        ASSERT(Vcb->Identifier.Type == EXT2VCB);
+        IrpSp->FileObject->Vpb = Vcb->Vpb;
+
+        if (!IsMounted(Vcb)) {
+            DbgBreak();
+            if (IsFlagOn(Vcb->Flags, VCB_DEVICE_REMOVED)) {
+                Status = STATUS_NO_SUCH_DEVICE;
+            } else {
+                Status = STATUS_VOLUME_DISMOUNTED;
+            }
+            _SEH2_LEAVE;
+        }
+
+        if (!ExAcquireResourceExclusiveLite(
+                    &Vcb->MainResource, TRUE)) {
+            Status = STATUS_PENDING;
+            _SEH2_LEAVE;
+        }
+        VcbResourceAcquired = TRUE;
+
+        Ext2VerifyVcb(IrpContext, Vcb);
+
+        if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
+            Status = STATUS_ACCESS_DENIED;
+            if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
+                Status = STATUS_VOLUME_DISMOUNTED;
+            }
+            _SEH2_LEAVE;
+        }
+
+        if ( ((IrpSp->FileObject->FileName.Length == 0) &&
+                (IrpSp->FileObject->RelatedFileObject == NULL)) ||
+                (Xcb && Xcb->Identifier.Type == EXT2VCB)  ) {
+            Status = Ext2CreateVolume(IrpContext, Vcb);
+        } else {
+
+            Status = Ext2CreateFile(IrpContext, Vcb, &PostIrp);
+        }
+
+    } _SEH2_FINALLY {
+
+        if (VcbResourceAcquired) {
+            ExReleaseResourceLite(&Vcb->MainResource);
+        }
+
+        if (!IrpContext->ExceptionInProgress && !PostIrp)  {
+            if ( Status == STATUS_PENDING ||
+                    Status == STATUS_CANT_WAIT) {
+                Status = Ext2QueueRequest(IrpContext);
+            } else {
+                Ext2CompleteIrpContext(IrpContext, Status);
+            }
+        }
+    } _SEH2_END;
+
+    return Status;
 }
 
-/*************************************************************************
-*
-* 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 NTAPI Ext2OverwriteFile(
-       PtrExt2FCB                      PtrFCB,
-       PtrExt2IrpContext       PtrIrpContext)
+NTSTATUS
+Ext2CreateInode(
+    PEXT2_IRP_CONTEXT   IrpContext,
+    PEXT2_VCB           Vcb,
+    PEXT2_FCB           Parent,
+    ULONG               Type,
+    ULONG               FileAttr,
+    PUNICODE_STRING     FileName)
 {
-       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;
+    NTSTATUS    Status;
+    ULONG       iGrp;
+    ULONG       iNo;
+    struct inode Inode = { 0 };
+    struct dentry *Dentry = NULL;
+
+    LARGE_INTEGER   SysTime;
+
+    iGrp = (Parent->Inode->i_ino - 1) / BLOCKS_PER_GROUP;
+
+    DEBUG(DL_INF, ("Ext2CreateInode: %S in %S(Inode=%xh)\n",
+                   FileName->Buffer,
+                   Parent->Mcb->ShortName.Buffer,
+                   Parent->Inode->i_ino));
+
+    Status = Ext2NewInode(IrpContext, Vcb, iGrp, Type, &iNo);
+    if (!NT_SUCCESS(Status)) {
+        goto errorout;
+    }
+
+    KeQuerySystemTime(&SysTime)