Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matt-wu/Ext3Fsd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Wu <matt@ext2fsd.com>2014-05-25 13:48:55 +0400
committerMatt Wu <matt@ext2fsd.com>2014-05-25 13:48:55 +0400
commit982843f889ebcac93c802ba329e9f8e61aabc82a (patch)
treef92029e3099456482a601a03577f19a0db6b3037 /Ext3Fsd
parent3efc213a7cbc000fa759c881d29d58663779d0c2 (diff)
Version 0.53
1, Enable writing with global or volume ext3-force-writing set 2, Support ext4 dir hash (UNSIGNED cases for legacy/half_md4/tea) 3, Kill several warnings reported by scan.coverity.com
Diffstat (limited to 'Ext3Fsd')
-rw-r--r--Ext3Fsd/Ext3fsd.rc8
-rw-r--r--Ext3Fsd/create.c8
-rw-r--r--Ext3Fsd/devctl.c8
-rw-r--r--Ext3Fsd/dirctl.c2
-rw-r--r--Ext3Fsd/ext3/htree.c222
-rw-r--r--Ext3Fsd/fsctl.c4
-rw-r--r--Ext3Fsd/include/ext2fs.h15
-rw-r--r--Ext3Fsd/include/linux/ext3_fs.h14
-rw-r--r--Ext3Fsd/memory.c5
-rw-r--r--Ext3Fsd/read.c2
-rw-r--r--Ext3Fsd/shutdown.c2
11 files changed, 183 insertions, 107 deletions
diff --git a/Ext3Fsd/Ext3fsd.rc b/Ext3Fsd/Ext3fsd.rc
index e8a0146..ccc48ff 100644
--- a/Ext3Fsd/Ext3fsd.rc
+++ b/Ext3Fsd/Ext3fsd.rc
@@ -19,8 +19,8 @@
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,52,5,12
- PRODUCTVERSION 0,52,5,12
+ FILEVERSION 0,53,5,25
+ PRODUCTVERSION 0,53,5,25
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -38,14 +38,14 @@ BEGIN
VALUE "Comments", "Matt Wu <matt@ext2fsd.com>\0"
VALUE "CompanyName", "www.ext2fsd.com\0"
VALUE "FileDescription", "Ext2 File System Driver for Windows\0"
- VALUE "FileVersion", "0.52\0"
+ VALUE "FileVersion", "0.53\0"
VALUE "InternalName", "Ext2Fsd.sys\0"
VALUE "LegalCopyright", "GPLv2\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "Ext2Fsd.sys\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Ext2 File System Driver\0"
- VALUE "ProductVersion", "0.52\0"
+ VALUE "ProductVersion", "0.53\0"
VALUE "SpecialBuild", "\0"
END
END
diff --git a/Ext3Fsd/create.c b/Ext3Fsd/create.c
index dfa1253..4bb2cd4 100644
--- a/Ext3Fsd/create.c
+++ b/Ext3Fsd/create.c
@@ -450,7 +450,7 @@ Ext2LookupFile (
}
/* set inode attribute */
- if (Ext2IsOwnerReadOnly(Mcb->Inode.i_mode)) {
+ if (!CanIWrite(Vcb) && Ext2IsOwnerReadOnly(Mcb->Inode.i_mode)) {
SetFlag(Mcb->FileAttr, FILE_ATTRIBUTE_READONLY);
}
@@ -958,10 +958,10 @@ Dissecting:
__leave;
}
- if (Ext2IsOwnerReadOnly(ParentFcb->Mcb->Inode.i_mode)) {
+ if (!CanIWrite(Vcb) && Ext2IsOwnerReadOnly(ParentFcb->Mcb->Inode.i_mode)) {
Status = STATUS_ACCESS_DENIED;
__leave;
- }
+ }
if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
@@ -1147,7 +1147,7 @@ Openit:
}
// Check readonly flag
- if (Ext2IsOwnerReadOnly(Mcb->Inode.i_mode)) {
+ 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;
diff --git a/Ext3Fsd/devctl.c b/Ext3Fsd/devctl.c
index e99dbca..6d578c7 100644
--- a/Ext3Fsd/devctl.c
+++ b/Ext3Fsd/devctl.c
@@ -388,6 +388,10 @@ Ext2ProcessVolumeProperty(
} else {
+ if (Property->bExt3Writable) {
+ SetLongFlag(Vcb->Flags, VCB_FORCE_WRITING);
+ }
+
if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
SetLongFlag(Vcb->Flags, VCB_READ_ONLY);
} else if (!Vcb->IsExt3fs) {
@@ -447,9 +451,9 @@ Ext2ProcessVolumeProperty(
RtlZeroMemory(Property->Codepage, CODEPAGE_MAXLEN);
if (Vcb->Codepage.PageTable) {
- strcpy(Property->Codepage, Vcb->Codepage.PageTable->charset);
+ strncpy(Property->Codepage, Vcb->Codepage.PageTable->charset, CODEPAGE_MAXLEN);
} else {
- strcpy(Property->Codepage, "default");
+ strncpy(Property->Codepage, "default", CODEPAGE_MAXLEN);
}
if (Property->Command == APP_CMD_QUERY_PROPERTY2) {
diff --git a/Ext3Fsd/dirctl.c b/Ext3Fsd/dirctl.c
index 3d9a37e..6e6995e 100644
--- a/Ext3Fsd/dirctl.c
+++ b/Ext3Fsd/dirctl.c
@@ -184,7 +184,7 @@ Ext2ProcessEntry(
FileAttributes = FILE_ATTRIBUTE_NORMAL;
}
- if (Ext2IsOwnerReadOnly(Inode.i_mode)) {
+ if (!CanIWrite(Vcb) && Ext2IsOwnerReadOnly(Inode.i_mode)) {
SetFlag(FileAttributes, FILE_ATTRIBUTE_READONLY);
}
}
diff --git a/Ext3Fsd/ext3/htree.c b/Ext3Fsd/ext3/htree.c
index 7a6bff5..d1ecd0b 100644
--- a/Ext3Fsd/ext3/htree.c
+++ b/Ext3Fsd/ext3/htree.c
@@ -110,45 +110,95 @@ static void TEA_transform(__u32 buf[4], __u32 const in[])
/* The old legacy hash */
-static __u32 dx_hack_hash (const char *name, int len)
+static __u32 dx_hack_hash_unsigned(const char *name, int len)
{
- __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
- while (len--) {
- __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
+ __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
+ const unsigned char *ucp = (const unsigned char *) name;
- if (hash & 0x80000000) hash -= 0x7fffffff;
- hash1 = hash0;
- hash0 = hash;
- }
- return (hash0 << 1);
+ while (len--) {
+ hash = hash1 + (hash0 ^ (((int) *ucp++) * 7152373));
+
+ if (hash & 0x80000000)
+ hash -= 0x7fffffff;
+ hash1 = hash0;
+ hash0 = hash;
+ }
+ return hash0 << 1;
}
-static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
-{
- __u32 pad, val;
- int i;
-
- pad = (__u32)len | ((__u32)len << 8);
- pad |= pad << 16;
-
- val = pad;
- if (len > num*4)
- len = num * 4;
- for (i=0; i < len; i++) {
- if ((i % 4) == 0)
- val = pad;
- val = msg[i] + (val << 8);
- if ((i % 4) == 3) {
- *buf++ = val;
- val = pad;
- num--;
- }
- }
- if (--num >= 0)
- *buf++ = val;
- while (--num >= 0)
- *buf++ = pad;
+static __u32 dx_hack_hash_signed(const char *name, int len)
+{
+ __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
+ const signed char *scp = (const signed char *) name;
+
+ while (len--) {
+ hash = hash1 + (hash0 ^ (((int) *scp++) * 7152373));
+
+ if (hash & 0x80000000)
+ hash -= 0x7fffffff;
+ hash1 = hash0;
+ hash0 = hash;
+ }
+ return hash0 << 1;
}
+
+static void str2hashbuf_signed(const char *msg, int len, __u32 *buf, int num)
+{
+ __u32 pad, val;
+ int i;
+ const signed char *scp = (const signed char *) msg;
+
+ pad = (__u32)len | ((__u32)len << 8);
+ pad |= pad << 16;
+
+ val = pad;
+ if (len > num*4)
+ len = num * 4;
+ for (i = 0; i < len; i++) {
+ if ((i % 4) == 0)
+ val = pad;
+ val = ((int) scp[i]) + (val << 8);
+ if ((i % 4) == 3) {
+ *buf++ = val;
+ val = pad;
+ num--;
+ }
+ }
+ if (--num >= 0)
+ *buf++ = val;
+ while (--num >= 0)
+ *buf++ = pad;
+}
+
+static void str2hashbuf_unsigned(const char *msg, int len, __u32 *buf, int num)
+{
+ __u32 pad, val;
+ int i;
+ const unsigned char *ucp = (const unsigned char *) msg;
+
+ pad = (__u32)len | ((__u32)len << 8);
+ pad |= pad << 16;
+
+ val = pad;
+ if (len > num*4)
+ len = num * 4;
+ for (i = 0; i < len; i++) {
+ if ((i % 4) == 0)
+ val = pad;
+ val = ((int) ucp[i]) + (val << 8);
+ if ((i % 4) == 3) {
+ *buf++ = val;
+ val = pad;
+ num--;
+ }
+ }
+ if (--num >= 0)
+ *buf++ = val;
+ while (--num >= 0)
+ *buf++ = pad;
+}
+
+
#endif /* EXT2_HTREE_INDEX */
__u32 ext3_current_time(struct inode *in)
@@ -428,58 +478,68 @@ int ext3_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
int i;
__u32 in[8], buf[4];
+ void (*str2hashbuf)(const char *, int, __u32 *, int) =
+ str2hashbuf_signed;
+
/* Initialize the default seed for the hash checksum functions */
buf[0] = 0x67452301;
buf[1] = 0xefcdab89;
buf[2] = 0x98badcfe;
buf[3] = 0x10325476;
- /* Check to see if the seed is all zero's */
- if (hinfo->seed) {
- for (i=0; i < 4; i++) {
- if (hinfo->seed[i])
- break;
- }
- if (i < 4)
- memcpy(buf, hinfo->seed, sizeof(buf));
- }
-
- switch (hinfo->hash_version) {
- case DX_HASH_LEGACY:
- hash = dx_hack_hash(name, len);
- break;
- case DX_HASH_HALF_MD4:
- p = name;
- while (len > 0) {
- str2hashbuf(p, len, in, 8);
- half_md4_transform(buf, in);
- len -= 32;
- p += 32;
- }
- minor_hash = buf[2];
- hash = buf[1];
- break;
- case DX_HASH_TEA:
- p = name;
- while (len > 0) {
- str2hashbuf(p, len, in, 4);
- TEA_transform(buf, in);
- len -= 16;
- p += 16;
- }
- hash = buf[0];
- minor_hash = buf[1];
- break;
- default:
- hinfo->hash = 0;
- return -1;
- }
- hash = hash & ~1;
- if (hash == (EXT3_HTREE_EOF << 1))
- hash = (EXT3_HTREE_EOF - 1) << 1;
- hinfo->hash = hash;
- hinfo->minor_hash = minor_hash;
- return 0;
+ /* Check to see if the seed is all zero's */
+ if (hinfo->seed) {
+ for (i = 0; i < 4; i++) {
+ if (hinfo->seed[i])
+ break;
+ }
+ if (i < 4)
+ memcpy(buf, hinfo->seed, sizeof(buf));
+ }
+
+ switch (hinfo->hash_version) {
+ case DX_HASH_LEGACY_UNSIGNED:
+ hash = dx_hack_hash_unsigned(name, len);
+ break;
+ case DX_HASH_LEGACY:
+ hash = dx_hack_hash_signed(name, len);
+ break;
+ case DX_HASH_HALF_MD4_UNSIGNED:
+ str2hashbuf = str2hashbuf_unsigned;
+ case DX_HASH_HALF_MD4:
+ p = name;
+ while (len > 0) {
+ (*str2hashbuf)(p, len, in, 8);
+ half_md4_transform(buf, in);
+ len -= 32;
+ p += 32;
+ }
+ minor_hash = buf[2];
+ hash = buf[1];
+ break;
+ case DX_HASH_TEA_UNSIGNED:
+ str2hashbuf = str2hashbuf_unsigned;
+ case DX_HASH_TEA:
+ p = name;
+ while (len > 0) {
+ (*str2hashbuf)(p, len, in, 4);
+ TEA_transform(buf, in);
+ len -= 16;
+ p += 16;
+ }
+ hash = buf[0];
+ minor_hash = buf[1];
+ break;
+ default:
+ hinfo->hash = 0;
+ return -1;
+ }
+ hash = hash & ~1;
+ if (hash == (EXT4_HTREE_EOF_32BIT << 1))
+ hash = (EXT4_HTREE_EOF_32BIT - 1) << 1;
+ hinfo->hash = hash;
+ hinfo->minor_hash = minor_hash;
+ return 0;
}
EXPORT_SYMBOL(ext3_dirhash);
@@ -1365,7 +1425,7 @@ struct buffer_head *
struct ext3_dir_entry_2 **res_dir, int *err)
{
struct super_block * sb;
- struct dx_hash_info hinfo;
+ struct dx_hash_info hinfo = {0};
u32 hash;
struct dx_frame frames[2], *frame;
struct ext3_dir_entry_2 *de, *top;
diff --git a/Ext3Fsd/fsctl.c b/Ext3Fsd/fsctl.c
index e9d7cde..ab64ad3 100644
--- a/Ext3Fsd/fsctl.c
+++ b/Ext3Fsd/fsctl.c
@@ -734,7 +734,7 @@ Ext2QueryExtentMappings(
MappedRuns = PartialRuns;
/* walk all the Mcb runs in Extent */
- for (;Extent != NULL; Extent = Extent->Next) {
+ for (; Extent != NULL; Extent = Extent->Next) {
MappedRuns[i*2 + 0].QuadPart = Vbn + Extent->Offset;
MappedRuns[i*2 + 1].QuadPart = Extent->Lba;
i = i+1;
@@ -1729,7 +1729,6 @@ Ext2VerifyVolume (IN PEXT2_IRP_CONTEXT IrpContext)
PEXT2_VCB Vcb = NULL;
BOOLEAN VcbResourceAcquired = FALSE;
PIRP Irp;
- PIO_STACK_LOCATION IoStackLocation;
ULONG ChangeCount = 0;
ULONG dwBytes;
@@ -1786,7 +1785,6 @@ Ext2VerifyVolume (IN PEXT2_IRP_CONTEXT IrpContext)
}
Irp = IrpContext->Irp;
- IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
Status = Ext2LoadSuper(Vcb, TRUE, &ext2_sb);
diff --git a/Ext3Fsd/include/ext2fs.h b/Ext3Fsd/include/ext2fs.h
index 3717445..2297fbe 100644
--- a/Ext3Fsd/include/ext2fs.h
+++ b/Ext3Fsd/include/ext2fs.h
@@ -40,7 +40,7 @@
/* STRUCTS & CONSTS******************************************************/
-#define EXT2FSD_VERSION "0.52"
+#define EXT2FSD_VERSION "0.53"
//
@@ -358,9 +358,11 @@ Ext2ClearFlag(PULONG Flags, ULONG FlagBit)
#define Ext2SetReadable(m) do {(m) = (m) | (S_IRUSR | S_IRGRP | S_IROTH);} while(0)
#define Ext2SetWritable(m) do {(m) = (m) | (S_IWUSR | S_IWGRP | S_IWOTH);} while(0)
-#define Ext2SetOwnerWritable(m) do {(m) |= S_IWUSR;} while(0)
+#define Ext2SetOwnerWritable(m) do {(m) |= S_IWUSR;} while(0)
#define Ext2SetOwnerReadOnly(m) do {(m) &= ~S_IWUSR;} while(0)
-#define Ext2IsOwnerReadOnly(m) (!((m) & S_IWUSR))
+
+#define Ext2IsOwnerWritable(m) (((m) & S_IWUSR) == S_IWUSR)
+#define Ext2IsOwnerReadOnly(m) (!(Ext2IsOwnerWritable(m)))
#define Ext2SetReadOnly(m) do {(m) &= ~(S_IWUSR | S_IWGRP | S_IWOTH);} while(0)
@@ -690,6 +692,7 @@ typedef struct _EXT2_VCB {
#define VCB_NEW_VPB 0x00000010
#define VCB_BEING_CLOSED 0x00000020
+#define VCB_FORCE_WRITING 0x00004000
#define VCB_DEVICE_REMOVED 0x00008000
#define VCB_JOURNAL_RECOVER 0x00080000
#define VCB_ARRIVAL_NOTIFIED 0x00800000
@@ -703,6 +706,12 @@ typedef struct _EXT2_VCB {
#define IsVcbInited(Vcb) (IsFlagOn((Vcb)->Flags, VCB_INITIALIZED))
#define IsMounted(Vcb) (IsFlagOn((Vcb)->Flags, VCB_MOUNTED))
#define IsDispending(Vcb) (IsFlagOn((Vcb)->Flags, VCB_DISMOUNT_PENDING))
+#define IsVcbReadOnly(Vcb) (IsFlagOn((Vcb)->Flags, VCB_READ_ONLY))
+
+
+#define IsExt3ForceWrite() (IsFlagOn(Ext2Global->Flags, EXT3_FORCE_WRITING))
+#define IsVcbForceWrite(Vcb) (IsFlagOn((Vcb)->Flags, VCB_FORCE_WRITING))
+#define CanIWrite(Vcb) (IsExt3ForceWrite() || (!IsVcbReadOnly(Vcb) && IsVcbForceWrite(Vcb)))
//
// EXT2_FCB File Control Block
diff --git a/Ext3Fsd/include/linux/ext3_fs.h b/Ext3Fsd/include/linux/ext3_fs.h
index df33baa..ffe56d5 100644
--- a/Ext3Fsd/include/linux/ext3_fs.h
+++ b/Ext3Fsd/include/linux/ext3_fs.h
@@ -912,9 +912,13 @@ static inline __le16 ext3_rec_len_to_disk(unsigned len)
/* Legal values for the dx_root hash_version field: */
-#define DX_HASH_LEGACY 0
-#define DX_HASH_HALF_MD4 1
-#define DX_HASH_TEA 2
+#define DX_HASH_LEGACY 0
+#define DX_HASH_HALF_MD4 1
+#define DX_HASH_TEA 2
+#define DX_HASH_LEGACY_UNSIGNED 3
+#define DX_HASH_HALF_MD4_UNSIGNED 4
+#define DX_HASH_TEA_UNSIGNED 5
+
#ifdef __KERNEL__
@@ -929,6 +933,10 @@ struct dx_hash_info
#define EXT3_HTREE_EOF 0x7fffffff
+/* 32 and 64 bit signed EOF for dx directories */
+#define EXT4_HTREE_EOF_32BIT ((1UL << (32 - 1)) - 1)
+#define EXT4_HTREE_EOF_64BIT ((1ULL << (64 - 1)) - 1
+
/*
* Control parameters used by ext3_htree_next_block
*/
diff --git a/Ext3Fsd/memory.c b/Ext3Fsd/memory.c
index f51b89e..88a03de 100644
--- a/Ext3Fsd/memory.c
+++ b/Ext3Fsd/memory.c
@@ -2502,10 +2502,9 @@ Ext2InitializeVcb( IN PEXT2_IRP_CONTEXT IrpContext,
features = EXT3_HAS_RO_COMPAT_FEATURE(&Vcb->sb, ~EXT3_FEATURE_RO_COMPAT_SUPP);
if (features) {
- printk(KERN_ERR "EXT3-fs: %s: couldn't mount RDWR because of "
- "unsupported optional features (%x).\n",
+ printk(KERN_ERR "EXT3-fs: %s: unsupported optional features in this volume: (%x).\n",
Vcb->sb.s_id, le32_to_cpu(features));
- if (IsFlagOn(Ext2Global->Flags, EXT3_FORCE_WRITING)) {
+ if (CanIWrite(Vcb)) {
} else {
SetLongFlag(Vcb->Flags, VCB_READ_ONLY);
}
diff --git a/Ext3Fsd/read.c b/Ext3Fsd/read.c
index 230e422..d22a072 100644
--- a/Ext3Fsd/read.c
+++ b/Ext3Fsd/read.c
@@ -479,7 +479,7 @@ Ext2ReadFile(IN PEXT2_IRP_CONTEXT IrpContext)
PIO_STACK_LOCATION IoStackLocation;
ULONG Length;
- ULONG ReturnedLength;
+ ULONG ReturnedLength = 0;
LARGE_INTEGER ByteOffset;
BOOLEAN OpPostIrp = FALSE;
diff --git a/Ext3Fsd/shutdown.c b/Ext3Fsd/shutdown.c
index 28e5205..6b5ba46 100644
--- a/Ext3Fsd/shutdown.c
+++ b/Ext3Fsd/shutdown.c
@@ -27,7 +27,6 @@ Ext2ShutDown (IN PEXT2_IRP_CONTEXT IrpContext)
NTSTATUS Status;
PIRP Irp;
- PIO_STACK_LOCATION IrpSp;
PEXT2_VCB Vcb;
PLIST_ENTRY ListEntry;
@@ -43,7 +42,6 @@ Ext2ShutDown (IN PEXT2_IRP_CONTEXT IrpContext)
(IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
Irp = IrpContext->Irp;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
if (!ExAcquireResourceExclusiveLite(
&Ext2Global->Resource,