From: Trevor Thompson Date: Sat, 24 Jun 2017 04:36:28 +0000 (+0000) Subject: [NTFS] - Fix POSIX rules. Fix accessing long filenames created in Windows when 8dot3... X-Git-Tag: 0.4.9-dev~693^2~33 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=032be0295481aeed18a5ced204f4b83d247b0232 [NTFS] - Fix POSIX rules. Fix accessing long filenames created in Windows when 8dot3 name creation is disabled. Whether or not a filename should be interpreted as case-sensitive is dependent on a flag passed to the driver when a file is created (opened); it's separate from the namespace associated with the file being accessed. svn path=/branches/GSoC_2016/NTFS/; revision=75178 --- diff --git a/drivers/filesystems/ntfs/attrib.c b/drivers/filesystems/ntfs/attrib.c index 78be3ecf3ce..85f7f880476 100644 --- a/drivers/filesystems/ntfs/attrib.c +++ b/drivers/filesystems/ntfs/attrib.c @@ -115,6 +115,10 @@ AddData(PFILE_RECORD_HEADER FileRecord, * @param ParentMftIndex * Pointer to a ULONGLONG which will receive the index of the parent directory. * +* @param CaseSensitive +* Boolean indicating if the function should operate in case-sensitive mode. This will be TRUE +* if an application opened the file with the FILE_FLAG_POSIX_SEMANTICS flag. +* * @return * STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end * of the given file record. @@ -132,7 +136,8 @@ AddFileName(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, - PULONGLONG ParentMftIndex) + PULONGLONG ParentMftIndex, + BOOLEAN CaseSensitive) { ULONG ResidentHeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR); PFILENAME_ATTRIBUTE FileNameAttribute; @@ -178,7 +183,13 @@ AddFileName(PFILE_RECORD_HEADER FileRecord, if(Remaining.Length != 0) RtlCopyUnicodeString(&FilenameNoPath, &Remaining); - Status = NtfsFindMftRecord(DeviceExt, CurrentMFTIndex, &Current, &FirstEntry, FALSE, &CurrentMFTIndex); + Status = NtfsFindMftRecord(DeviceExt, + CurrentMFTIndex, + &Current, + &FirstEntry, + FALSE, + &CurrentMFTIndex, + CaseSensitive); if (!NT_SUCCESS(Status)) break; diff --git a/drivers/filesystems/ntfs/create.c b/drivers/filesystems/ntfs/create.c index 96f563e75dd..ddafb14d678 100644 --- a/drivers/filesystems/ntfs/create.c +++ b/drivers/filesystems/ntfs/create.c @@ -246,6 +246,7 @@ NTSTATUS NtfsOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PWSTR FileName, + BOOLEAN CaseSensitive, PNTFS_FCB * FoundFCB) { PNTFS_FCB ParentFcb; @@ -253,7 +254,12 @@ NtfsOpenFile(PDEVICE_EXTENSION DeviceExt, NTSTATUS Status; PWSTR AbsFileName = NULL; - DPRINT1("NtfsOpenFile(%p, %p, %S, %p)\n", DeviceExt, FileObject, FileName, FoundFCB); + DPRINT1("NtfsOpenFile(%p, %p, %S, %s, %p)\n", + DeviceExt, + FileObject, + FileName, + CaseSensitive ? "TRUE" : "FALSE", + FoundFCB); *FoundFCB = NULL; @@ -285,7 +291,8 @@ NtfsOpenFile(PDEVICE_EXTENSION DeviceExt, Status = NtfsGetFCBForFile(DeviceExt, &ParentFcb, &Fcb, - FileName); + FileName, + CaseSensitive); if (ParentFcb != NULL) { NtfsReleaseFCB(DeviceExt, @@ -412,6 +419,7 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject, Status = NtfsOpenFile(DeviceExt, FileObject, ((RequestedOptions & FILE_OPEN_BY_FILE_ID) ? FullPath.Buffer : FileObject->FileName.Buffer), + (Stack->Flags & SL_CASE_SENSITIVE), &Fcb); if (RequestedOptions & FILE_OPEN_BY_FILE_ID) diff --git a/drivers/filesystems/ntfs/dirctl.c b/drivers/filesystems/ntfs/dirctl.c index 91f0bc5db70..7c59e88204d 100644 --- a/drivers/filesystems/ntfs/dirctl.c +++ b/drivers/filesystems/ntfs/dirctl.c @@ -627,7 +627,8 @@ NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext) &Ccb->Entry, &FileRecord, &MFTRecord, - Fcb->MFTIndex); + Fcb->MFTIndex, + (Stack->Flags & SL_CASE_SENSITIVE)); if (NT_SUCCESS(Status)) { diff --git a/drivers/filesystems/ntfs/fcb.c b/drivers/filesystems/ntfs/fcb.c index 111660288ab..531749d4d28 100644 --- a/drivers/filesystems/ntfs/fcb.c +++ b/drivers/filesystems/ntfs/fcb.c @@ -506,6 +506,7 @@ static NTSTATUS NtfsDirFindFile(PNTFS_VCB Vcb, PNTFS_FCB DirectoryFcb, PWSTR FileToFind, + BOOLEAN CaseSensitive, PNTFS_FCB *FoundFCB) { NTSTATUS Status; @@ -517,7 +518,12 @@ NtfsDirFindFile(PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT DataContext; USHORT Length = 0; - DPRINT1("NtfsDirFindFile(%p, %p, %S, %p)\n", Vcb, DirectoryFcb, FileToFind, FoundFCB); + DPRINT1("NtfsDirFindFile(%p, %p, %S, %s, %p)\n", + Vcb, + DirectoryFcb, + FileToFind, + CaseSensitive ? "TRUE" : "FALSE", + FoundFCB); *FoundFCB = NULL; RtlInitUnicodeString(&File, FileToFind); @@ -551,7 +557,7 @@ NtfsDirFindFile(PNTFS_VCB Vcb, DPRINT1("Will now look for file '%wZ' with stream '%S'\n", &File, Colon); } - Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &MFTIndex, CurrentDir); + Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &MFTIndex, CurrentDir, CaseSensitive); if (!NT_SUCCESS(Status)) { return Status; @@ -587,7 +593,8 @@ NTSTATUS NtfsGetFCBForFile(PNTFS_VCB Vcb, PNTFS_FCB *pParentFCB, PNTFS_FCB *pFCB, - const PWSTR pFileName) + const PWSTR pFileName, + BOOLEAN CaseSensitive) { NTSTATUS Status; WCHAR pathName [MAX_PATH]; @@ -596,11 +603,12 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb, PNTFS_FCB FCB; PNTFS_FCB parentFCB; - DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S')\n", + DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S', %s)\n", Vcb, pParentFCB, pFCB, - pFileName); + pFileName, + CaseSensitive ? "TRUE" : "FALSE"); /* Dummy code */ // FCB = NtfsOpenRootFCB(Vcb); @@ -677,7 +685,7 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb, NtfsGetNextPathElement(currentElement) - currentElement); DPRINT(" elementName:%S\n", elementName); - Status = NtfsDirFindFile(Vcb, parentFCB, elementName, &FCB); + Status = NtfsDirFindFile(Vcb, parentFCB, elementName, CaseSensitive, &FCB); if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { *pParentFCB = parentFCB; diff --git a/drivers/filesystems/ntfs/finfo.c b/drivers/filesystems/ntfs/finfo.c index 76cc78f4d9a..1cb7dbc0fe9 100644 --- a/drivers/filesystems/ntfs/finfo.c +++ b/drivers/filesystems/ntfs/finfo.c @@ -415,6 +415,10 @@ NtfsQueryInformation(PNTFS_IRP_CONTEXT IrpContext) * @param IrpFlags * ULONG describing the flags of the original IRP request (Irp->Flags). * +* @param CaseSensitive +* Boolean indicating if the function should operate in case-sensitive mode. This will be TRUE +* if an application opened the file with the FILE_FLAG_POSIX_SEMANTICS flag. +* * @param NewFileSize * Pointer to a LARGE_INTEGER which indicates the new end of file (file size). * @@ -436,6 +440,7 @@ NtfsSetEndOfFile(PNTFS_FCB Fcb, PFILE_OBJECT FileObject, PDEVICE_EXTENSION DeviceExt, ULONG IrpFlags, + BOOLEAN CaseSensitive, PLARGE_INTEGER NewFileSize) { LARGE_INTEGER CurrentFileSize; @@ -545,7 +550,13 @@ NtfsSetEndOfFile(PNTFS_FCB Fcb, AllocationSize = ROUND_UP(NewFileSize->QuadPart, Fcb->Vcb->NtfsInfo.BytesPerCluster); - Status = UpdateFileNameRecord(Fcb->Vcb, ParentMFTId, &filename, FALSE, NewFileSize->QuadPart, AllocationSize); + Status = UpdateFileNameRecord(Fcb->Vcb, + ParentMFTId, + &filename, + FALSE, + NewFileSize->QuadPart, + AllocationSize, + CaseSensitive); ReleaseAttributeContext(DataContext); ExFreePoolWithTag(FileRecord, TAG_NTFS); @@ -620,7 +631,12 @@ NtfsSetInformation(PNTFS_IRP_CONTEXT IrpContext) DPRINT1("FIXME: Using hacky method of setting FileAllocationInformation.\n"); case FileEndOfFileInformation: EndOfFileInfo = (PFILE_END_OF_FILE_INFORMATION)SystemBuffer; - Status = NtfsSetEndOfFile(Fcb, FileObject, DeviceExt, Irp->Flags, &EndOfFileInfo->EndOfFile); + Status = NtfsSetEndOfFile(Fcb, + FileObject, + DeviceExt, + Irp->Flags, + (Stack->Flags & SL_CASE_SENSITIVE), + &EndOfFileInfo->EndOfFile); break; // TODO: all other information classes diff --git a/drivers/filesystems/ntfs/mft.c b/drivers/filesystems/ntfs/mft.c index 8df62ed5420..2c0dab65864 100644 --- a/drivers/filesystems/ntfs/mft.c +++ b/drivers/filesystems/ntfs/mft.c @@ -1359,7 +1359,8 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb, PUNICODE_STRING FileName, BOOLEAN DirSearch, ULONGLONG NewDataSize, - ULONGLONG NewAllocationSize) + ULONGLONG NewAllocationSize, + BOOLEAN CaseSensitive) { PFILE_RECORD_HEADER MftRecord; PNTFS_ATTR_CONTEXT IndexRootCtx; @@ -1369,7 +1370,14 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb, NTSTATUS Status; ULONG CurrentEntry = 0; - DPRINT("UpdateFileNameRecord(%p, %I64d, %wZ, %u, %I64u, %I64u)\n", Vcb, ParentMFTIndex, FileName, DirSearch, NewDataSize, NewAllocationSize); + DPRINT("UpdateFileNameRecord(%p, %I64d, %wZ, %u, %I64u, %I64u, %s)\n", + Vcb, + ParentMFTIndex, + FileName, + DirSearch, + NewDataSize, + NewAllocationSize, + CaseSensitive ? "TRUE" : "FALSE"); MftRecord = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerFileRecord, @@ -1421,7 +1429,8 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb, &CurrentEntry, DirSearch, NewDataSize, - NewAllocationSize); + NewAllocationSize, + CaseSensitive); ReleaseAttributeContext(IndexRootCtx); ExFreePoolWithTag(IndexRecord, TAG_NTFS); @@ -1447,7 +1456,8 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb, PULONG CurrentEntry, BOOLEAN DirSearch, ULONGLONG NewDataSize, - ULONGLONG NewAllocatedSize) + ULONGLONG NewAllocatedSize, + BOOLEAN CaseSensitive) { NTSTATUS Status; ULONG RecordOffset; @@ -1466,7 +1476,7 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb, if ((IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK) > 0x10 && *CurrentEntry >= *StartEntry && IndexEntry->FileName.NameType != NTFS_FILE_NAME_DOS && - CompareFileName(FileName, IndexEntry, DirSearch)) + CompareFileName(FileName, IndexEntry, DirSearch, CaseSensitive)) { *StartEntry = *CurrentEntry; IndexEntry->FileName.DataSize = NewDataSize; @@ -1517,7 +1527,19 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb, LastEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)&IndexBuffer->Header + IndexBuffer->Header.TotalSizeOfEntries); ASSERT(LastEntry <= (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexBuffer + IndexBlockSize)); - Status = UpdateIndexEntryFileNameSize(NULL, NULL, NULL, 0, FirstEntry, LastEntry, FileName, StartEntry, CurrentEntry, DirSearch, NewDataSize, NewAllocatedSize); + Status = UpdateIndexEntryFileNameSize(NULL, + NULL, + NULL, + 0, + FirstEntry, + LastEntry, + FileName, + StartEntry, + CurrentEntry, + DirSearch, + NewDataSize, + NewAllocatedSize, + CaseSensitive); if (Status == STATUS_PENDING) { // write the index record back to disk @@ -1827,7 +1849,8 @@ ReadLCN(PDEVICE_EXTENSION Vcb, BOOLEAN CompareFileName(PUNICODE_STRING FileName, PINDEX_ENTRY_ATTRIBUTE IndexEntry, - BOOLEAN DirSearch) + BOOLEAN DirSearch, + BOOLEAN CaseSensitive) { BOOLEAN Ret, Alloc = FALSE; UNICODE_STRING EntryName; @@ -1839,7 +1862,7 @@ CompareFileName(PUNICODE_STRING FileName, if (DirSearch) { UNICODE_STRING IntFileName; - if (IndexEntry->FileName.NameType != NTFS_FILE_NAME_POSIX) + if (!CaseSensitive) { NT_VERIFY(NT_SUCCESS(RtlUpcaseUnicodeString(&IntFileName, FileName, TRUE))); Alloc = TRUE; @@ -1849,7 +1872,7 @@ CompareFileName(PUNICODE_STRING FileName, IntFileName = *FileName; } - Ret = FsRtlIsNameInExpression(&IntFileName, &EntryName, (IndexEntry->FileName.NameType != NTFS_FILE_NAME_POSIX), NULL); + Ret = FsRtlIsNameInExpression(&IntFileName, &EntryName, !CaseSensitive, NULL); if (Alloc) { @@ -1860,7 +1883,7 @@ CompareFileName(PUNICODE_STRING FileName, } else { - return (RtlCompareUnicodeString(FileName, &EntryName, (IndexEntry->FileName.NameType != NTFS_FILE_NAME_POSIX)) == 0); + return (RtlCompareUnicodeString(FileName, &EntryName, !CaseSensitive) == 0); } } @@ -1900,6 +1923,7 @@ BrowseIndexEntries(PDEVICE_EXTENSION Vcb, PULONG StartEntry, PULONG CurrentEntry, BOOLEAN DirSearch, + BOOLEAN CaseSensitive, ULONGLONG *OutMFTIndex) { NTSTATUS Status; @@ -1909,7 +1933,19 @@ BrowseIndexEntries(PDEVICE_EXTENSION Vcb, ULONGLONG IndexAllocationSize; PINDEX_BUFFER IndexBuffer; - DPRINT("BrowseIndexEntries(%p, %p, %p, %u, %p, %p, %wZ, %u, %u, %u, %p)\n", Vcb, MftRecord, IndexRecord, IndexBlockSize, FirstEntry, LastEntry, FileName, *StartEntry, *CurrentEntry, DirSearch, OutMFTIndex); + DPRINT("BrowseIndexEntries(%p, %p, %p, %u, %p, %p, %wZ, %u, %u, %s, %s, %p)\n", + Vcb, + MftRecord, + IndexRecord, + IndexBlockSize, + FirstEntry, + LastEntry, + FileName, + *StartEntry, + *CurrentEntry, + DirSearch ? "TRUE" : "FALSE", + CaseSensitive ? "TRUE" : "FALSE", + OutMFTIndex); IndexEntry = FirstEntry; while (IndexEntry < LastEntry && @@ -1918,7 +1954,7 @@ BrowseIndexEntries(PDEVICE_EXTENSION Vcb, if ((IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK) >= 0x10 && *CurrentEntry >= *StartEntry && IndexEntry->FileName.NameType != NTFS_FILE_NAME_DOS && - CompareFileName(FileName, IndexEntry, DirSearch)) + CompareFileName(FileName, IndexEntry, DirSearch, CaseSensitive)) { *StartEntry = *CurrentEntry; *OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK); @@ -1967,7 +2003,18 @@ BrowseIndexEntries(PDEVICE_EXTENSION Vcb, LastEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)&IndexBuffer->Header + IndexBuffer->Header.TotalSizeOfEntries); ASSERT(LastEntry <= (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexBuffer + IndexBlockSize)); - Status = BrowseIndexEntries(NULL, NULL, NULL, 0, FirstEntry, LastEntry, FileName, StartEntry, CurrentEntry, DirSearch, OutMFTIndex); + Status = BrowseIndexEntries(NULL, + NULL, + NULL, + 0, + FirstEntry, + LastEntry, + FileName, + StartEntry, + CurrentEntry, + DirSearch, + CaseSensitive, + OutMFTIndex); if (NT_SUCCESS(Status)) { break; @@ -1984,7 +2031,8 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb, PUNICODE_STRING FileName, PULONG FirstEntry, BOOLEAN DirSearch, - ULONGLONG *OutMFTIndex) + ULONGLONG *OutMFTIndex, + BOOLEAN CaseSensitive) { PFILE_RECORD_HEADER MftRecord; PNTFS_ATTR_CONTEXT IndexRootCtx; @@ -2036,7 +2084,18 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb, DPRINT("IndexRecordSize: %x IndexBlockSize: %x\n", Vcb->NtfsInfo.BytesPerIndexRecord, IndexRoot->SizeOfEntry); - Status = BrowseIndexEntries(Vcb, MftRecord, IndexRecord, IndexRoot->SizeOfEntry, IndexEntry, IndexEntryEnd, FileName, FirstEntry, &CurrentEntry, DirSearch, OutMFTIndex); + Status = BrowseIndexEntries(Vcb, + MftRecord, + IndexRecord, + IndexRoot->SizeOfEntry, + IndexEntry, + IndexEntryEnd, + FileName, + FirstEntry, + &CurrentEntry, + DirSearch, + CaseSensitive, + OutMFTIndex); ExFreePoolWithTag(IndexRecord, TAG_NTFS); ExFreePoolWithTag(MftRecord, TAG_NTFS); @@ -2049,7 +2108,8 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex, - ULONGLONG CurrentMFTIndex) + ULONGLONG CurrentMFTIndex, + BOOLEAN CaseSensitive) { UNICODE_STRING Current, Remaining; NTSTATUS Status; @@ -2063,7 +2123,7 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb, { DPRINT("Current: %wZ\n", &Current); - Status = NtfsFindMftRecord(Vcb, CurrentMFTIndex, &Current, &FirstEntry, FALSE, &CurrentMFTIndex); + Status = NtfsFindMftRecord(Vcb, CurrentMFTIndex, &Current, &FirstEntry, FALSE, &CurrentMFTIndex, CaseSensitive); if (!NT_SUCCESS(Status)) { return Status; @@ -2099,9 +2159,10 @@ NTSTATUS NtfsLookupFile(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, PFILE_RECORD_HEADER *FileRecord, - PULONGLONG MFTIndex) + PULONGLONG MFTIndex, + BOOLEAN CaseSensitive) { - return NtfsLookupFileAt(Vcb, PathName, FileRecord, MFTIndex, NTFS_FILE_ROOT); + return NtfsLookupFileAt(Vcb, PathName, FileRecord, MFTIndex, NTFS_FILE_ROOT, CaseSensitive); } /** @@ -2150,13 +2211,21 @@ NtfsFindFileAt(PDEVICE_EXTENSION Vcb, PULONG FirstEntry, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex, - ULONGLONG CurrentMFTIndex) + ULONGLONG CurrentMFTIndex, + BOOLEAN CaseSensitive) { NTSTATUS Status; - DPRINT("NtfsFindFileAt(%p, %wZ, %u, %p, %p, %I64x)\n", Vcb, SearchPattern, *FirstEntry, FileRecord, MFTIndex, CurrentMFTIndex); + DPRINT("NtfsFindFileAt(%p, %wZ, %u, %p, %p, %I64x, %s)\n", + Vcb, + SearchPattern, + *FirstEntry, + FileRecord, + MFTIndex, + CurrentMFTIndex, + (CaseSensitive ? "TRUE" : "FALSE")); - Status = NtfsFindMftRecord(Vcb, CurrentMFTIndex, SearchPattern, FirstEntry, TRUE, &CurrentMFTIndex); + Status = NtfsFindMftRecord(Vcb, CurrentMFTIndex, SearchPattern, FirstEntry, TRUE, &CurrentMFTIndex, CaseSensitive); if (!NT_SUCCESS(Status)) { DPRINT("NtfsFindFileAt: NtfsFindMftRecord() failed with status 0x%08lx\n", Status); diff --git a/drivers/filesystems/ntfs/ntfs.h b/drivers/filesystems/ntfs/ntfs.h index 799f8e2a4f0..f54a14d2545 100644 --- a/drivers/filesystems/ntfs/ntfs.h +++ b/drivers/filesystems/ntfs/ntfs.h @@ -781,7 +781,8 @@ NTSTATUS NtfsGetFCBForFile(PNTFS_VCB Vcb, PNTFS_FCB *pParentFCB, PNTFS_FCB *pFCB, - const PWSTR pFileName); + const PWSTR pFileName, + BOOLEAN CaseSensitive); NTSTATUS NtfsReadFCBAttribute(PNTFS_VCB Vcb, @@ -811,6 +812,7 @@ NtfsSetEndOfFile(PNTFS_FCB Fcb, PFILE_OBJECT FileObject, PDEVICE_EXTENSION DeviceExt, ULONG IrpFlags, + BOOLEAN CaseSensitive, PLARGE_INTEGER NewFileSize); NTSTATUS @@ -892,7 +894,8 @@ AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord); BOOLEAN CompareFileName(PUNICODE_STRING FileName, PINDEX_ENTRY_ATTRIBUTE IndexEntry, - BOOLEAN DirSearch); + BOOLEAN DirSearch, + BOOLEAN CaseSensitive); NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, @@ -911,7 +914,8 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb, PULONG CurrentEntry, BOOLEAN DirSearch, ULONGLONG NewDataSize, - ULONGLONG NewAllocatedSize); + ULONGLONG NewAllocatedSize, + BOOLEAN CaseSensitive); NTSTATUS UpdateFileNameRecord(PDEVICE_EXTENSION Vcb, @@ -919,7 +923,8 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb, PUNICODE_STRING FileName, BOOLEAN DirSearch, ULONGLONG NewDataSize, - ULONGLONG NewAllocationSize); + ULONGLONG NewAllocationSize, + BOOLEAN CaseSensitive); NTSTATUS UpdateFileRecord(PDEVICE_EXTENSION Vcb, @@ -973,7 +978,8 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex, - ULONGLONG CurrentMFTIndex); + ULONGLONG CurrentMFTIndex, + BOOLEAN CaseSensitive); VOID NtfsDumpFileRecord(PDEVICE_EXTENSION Vcb, @@ -985,7 +991,8 @@ NtfsFindFileAt(PDEVICE_EXTENSION Vcb, PULONG FirstEntry, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex, - ULONGLONG CurrentMFTIndex); + ULONGLONG CurrentMFTIndex, + BOOLEAN CaseSensitive); NTSTATUS NtfsFindMftRecord(PDEVICE_EXTENSION Vcb, @@ -993,7 +1000,8 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb, PUNICODE_STRING FileName, PULONG FirstEntry, BOOLEAN DirSearch, - ULONGLONG *OutMFTIndex); + ULONGLONG *OutMFTIndex, + BOOLEAN CaseSensitive); /* misc.c */ diff --git a/drivers/filesystems/ntfs/rw.c b/drivers/filesystems/ntfs/rw.c index 7f119d706b1..1cfdd7fde20 100644 --- a/drivers/filesystems/ntfs/rw.c +++ b/drivers/filesystems/ntfs/rw.c @@ -283,6 +283,10 @@ NtfsRead(PNTFS_IRP_CONTEXT IrpContext) * @param IrpFlags * TODO: flags are presently ignored in code. * +* @param CaseSensitive +* Boolean indicating if the function should operate in case-sensitive mode. This will be TRUE +* if an application opened the file with the FILE_FLAG_POSIX_SEMANTICS flag. +* * @param LengthWritten * Pointer to a ULONG. This ULONG will be set to the number of bytes successfully written. * @@ -303,6 +307,7 @@ NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt, ULONG Length, ULONG WriteOffset, ULONG IrpFlags, + BOOLEAN CaseSensitive, PULONG LengthWritten) { NTSTATUS Status = STATUS_NOT_IMPLEMENTED; @@ -312,7 +317,15 @@ NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt, ULONG AttributeOffset; ULONGLONG StreamSize; - DPRINT("NtfsWriteFile(%p, %p, %p, %u, %u, %x, %p)\n", DeviceExt, FileObject, Buffer, Length, WriteOffset, IrpFlags, LengthWritten); + DPRINT("NtfsWriteFile(%p, %p, %p, %u, %u, %x, %s, %p)\n", + DeviceExt, + FileObject, + Buffer, + Length, + WriteOffset, + IrpFlags, + (CaseSensitive ? "TRUE" : "FALSE"), + LengthWritten); *LengthWritten = 0; @@ -444,7 +457,13 @@ NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt, filename.Length = fileNameAttribute->NameLength * sizeof(WCHAR); filename.MaximumLength = filename.Length; - Status = UpdateFileNameRecord(Fcb->Vcb, ParentMFTId, &filename, FALSE, DataSize.QuadPart, AllocationSize); + Status = UpdateFileNameRecord(Fcb->Vcb, + ParentMFTId, + &filename, + FALSE, + DataSize.QuadPart, + AllocationSize, + CaseSensitive); } else @@ -667,6 +686,7 @@ NtfsWrite(PNTFS_IRP_CONTEXT IrpContext) Length, ByteOffset.LowPart, Irp->Flags, + (IrpContext->Stack->Flags & SL_CASE_SENSITIVE), &ReturnedWriteLength); IrpContext->Irp->IoStatus.Status = Status;