diff options
author | Matt Wu <matt@ext2fsd.com> | 2014-05-25 13:48:55 +0400 |
---|---|---|
committer | Matt Wu <matt@ext2fsd.com> | 2014-05-25 13:48:55 +0400 |
commit | 982843f889ebcac93c802ba329e9f8e61aabc82a (patch) | |
tree | f92029e3099456482a601a03577f19a0db6b3037 | |
parent | 3efc213a7cbc000fa759c881d29d58663779d0c2 (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
-rw-r--r-- | Ext3Fsd/Ext3fsd.rc | 8 | ||||
-rw-r--r-- | Ext3Fsd/create.c | 8 | ||||
-rw-r--r-- | Ext3Fsd/devctl.c | 8 | ||||
-rw-r--r-- | Ext3Fsd/dirctl.c | 2 | ||||
-rw-r--r-- | Ext3Fsd/ext3/htree.c | 222 | ||||
-rw-r--r-- | Ext3Fsd/fsctl.c | 4 | ||||
-rw-r--r-- | Ext3Fsd/include/ext2fs.h | 15 | ||||
-rw-r--r-- | Ext3Fsd/include/linux/ext3_fs.h | 14 | ||||
-rw-r--r-- | Ext3Fsd/memory.c | 5 | ||||
-rw-r--r-- | Ext3Fsd/read.c | 2 | ||||
-rw-r--r-- | Ext3Fsd/shutdown.c | 2 |
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, |