[NTFS] - Fix POSIX rules. Fix accessing long filenames created in Windows when 8dot3...
authorTrevor Thompson <tmt256@email.vccs.edu>
Sat, 24 Jun 2017 04:36:28 +0000 (04:36 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sun, 10 Dec 2017 10:14:34 +0000 (11:14 +0100)
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

drivers/filesystems/ntfs/attrib.c
drivers/filesystems/ntfs/create.c
drivers/filesystems/ntfs/dirctl.c
drivers/filesystems/ntfs/fcb.c
drivers/filesystems/ntfs/finfo.c
drivers/filesystems/ntfs/mft.c
drivers/filesystems/ntfs/ntfs.h
drivers/filesystems/ntfs/rw.c

index 78be3ec..85f7f88 100644 (file)
@@ -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 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.
 * @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,
             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;
 {
     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);
 
         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;
 
         if (!NT_SUCCESS(Status))
             break;
 
index 96f563e..ddafb14 100644 (file)
@@ -246,6 +246,7 @@ NTSTATUS
 NtfsOpenFile(PDEVICE_EXTENSION DeviceExt,
              PFILE_OBJECT FileObject,
              PWSTR FileName,
 NtfsOpenFile(PDEVICE_EXTENSION DeviceExt,
              PFILE_OBJECT FileObject,
              PWSTR FileName,
+             BOOLEAN CaseSensitive,
              PNTFS_FCB * FoundFCB)
 {
     PNTFS_FCB ParentFcb;
              PNTFS_FCB * FoundFCB)
 {
     PNTFS_FCB ParentFcb;
@@ -253,7 +254,12 @@ NtfsOpenFile(PDEVICE_EXTENSION DeviceExt,
     NTSTATUS Status;
     PWSTR AbsFileName = NULL;
 
     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;
 
 
     *FoundFCB = NULL;
 
@@ -285,7 +291,8 @@ NtfsOpenFile(PDEVICE_EXTENSION DeviceExt,
         Status = NtfsGetFCBForFile(DeviceExt,
                                    &ParentFcb,
                                    &Fcb,
         Status = NtfsGetFCBForFile(DeviceExt,
                                    &ParentFcb,
                                    &Fcb,
-                                   FileName);
+                                   FileName,
+                                   CaseSensitive);
         if (ParentFcb != NULL)
         {
             NtfsReleaseFCB(DeviceExt,
         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),
         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)
                               &Fcb);
 
         if (RequestedOptions & FILE_OPEN_BY_FILE_ID)
index 91f0bc5..7c59e88 100644 (file)
@@ -627,7 +627,8 @@ NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
                                 &Ccb->Entry,
                                 &FileRecord,
                                 &MFTRecord,
                                 &Ccb->Entry,
                                 &FileRecord,
                                 &MFTRecord,
-                                Fcb->MFTIndex);
+                                Fcb->MFTIndex,
+                                (Stack->Flags & SL_CASE_SENSITIVE));
 
         if (NT_SUCCESS(Status))
         {
 
         if (NT_SUCCESS(Status))
         {
index 1116602..531749d 100644 (file)
@@ -506,6 +506,7 @@ static NTSTATUS
 NtfsDirFindFile(PNTFS_VCB Vcb,
                 PNTFS_FCB DirectoryFcb,
                 PWSTR FileToFind,
 NtfsDirFindFile(PNTFS_VCB Vcb,
                 PNTFS_FCB DirectoryFcb,
                 PWSTR FileToFind,
+                BOOLEAN CaseSensitive,
                 PNTFS_FCB *FoundFCB)
 {
     NTSTATUS Status;
                 PNTFS_FCB *FoundFCB)
 {
     NTSTATUS Status;
@@ -517,7 +518,12 @@ NtfsDirFindFile(PNTFS_VCB Vcb,
     PNTFS_ATTR_CONTEXT DataContext;
     USHORT Length = 0;
 
     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);
 
     *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);
     }
 
         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;
     if (!NT_SUCCESS(Status))
     {
         return Status;
@@ -587,7 +593,8 @@ NTSTATUS
 NtfsGetFCBForFile(PNTFS_VCB Vcb,
                   PNTFS_FCB *pParentFCB,
                   PNTFS_FCB *pFCB,
 NtfsGetFCBForFile(PNTFS_VCB Vcb,
                   PNTFS_FCB *pParentFCB,
                   PNTFS_FCB *pFCB,
-                  const PWSTR pFileName)
+                  const PWSTR pFileName,
+                  BOOLEAN CaseSensitive)
 {
     NTSTATUS Status;
     WCHAR pathName [MAX_PATH];
 {
     NTSTATUS Status;
     WCHAR pathName [MAX_PATH];
@@ -596,11 +603,12 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb,
     PNTFS_FCB FCB;
     PNTFS_FCB parentFCB;
 
     PNTFS_FCB FCB;
     PNTFS_FCB parentFCB;
 
-    DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S')\n",
+    DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S', %s)\n",
            Vcb,
            pParentFCB,
            pFCB,
            Vcb,
            pParentFCB,
            pFCB,
-           pFileName);
+           pFileName,
+           CaseSensitive ? "TRUE" : "FALSE");
 
     /* Dummy code */
 //  FCB = NtfsOpenRootFCB(Vcb);
 
     /* Dummy code */
 //  FCB = NtfsOpenRootFCB(Vcb);
@@ -677,7 +685,7 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb,
                            NtfsGetNextPathElement(currentElement) - currentElement);
             DPRINT("  elementName:%S\n", elementName);
 
                            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;
             if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
             {
                 *pParentFCB = parentFCB;
index 76cc78f..1cb7dbc 100644 (file)
@@ -415,6 +415,10 @@ NtfsQueryInformation(PNTFS_IRP_CONTEXT IrpContext)
 * @param IrpFlags
 * ULONG describing the flags of the original IRP request (Irp->Flags).
 *
 * @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).
 *
 * @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,
                  PFILE_OBJECT FileObject,
                  PDEVICE_EXTENSION DeviceExt,
                  ULONG IrpFlags,
+                 BOOLEAN CaseSensitive,
                  PLARGE_INTEGER NewFileSize)
 {
     LARGE_INTEGER CurrentFileSize;
                  PLARGE_INTEGER NewFileSize)
 {
     LARGE_INTEGER CurrentFileSize;
@@ -545,7 +550,13 @@ NtfsSetEndOfFile(PNTFS_FCB Fcb,
 
     AllocationSize = ROUND_UP(NewFileSize->QuadPart, Fcb->Vcb->NtfsInfo.BytesPerCluster);
 
 
     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);
 
     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;
             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
             break;
             
         // TODO: all other information classes
index 8df62ed..2c0dab6 100644 (file)
@@ -1359,7 +1359,8 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
                      PUNICODE_STRING FileName,
                      BOOLEAN DirSearch,
                      ULONGLONG NewDataSize,
                      PUNICODE_STRING FileName,
                      BOOLEAN DirSearch,
                      ULONGLONG NewDataSize,
-                     ULONGLONG NewAllocationSize)
+                     ULONGLONG NewAllocationSize,
+                     BOOLEAN CaseSensitive)
 {
     PFILE_RECORD_HEADER MftRecord;
     PNTFS_ATTR_CONTEXT IndexRootCtx;
 {
     PFILE_RECORD_HEADER MftRecord;
     PNTFS_ATTR_CONTEXT IndexRootCtx;
@@ -1369,7 +1370,14 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
     NTSTATUS Status;
     ULONG CurrentEntry = 0;
 
     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,
 
     MftRecord = ExAllocatePoolWithTag(NonPagedPool,
                                       Vcb->NtfsInfo.BytesPerFileRecord,
@@ -1421,7 +1429,8 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
                                           &CurrentEntry,
                                           DirSearch,
                                           NewDataSize,
                                           &CurrentEntry,
                                           DirSearch,
                                           NewDataSize,
-                                          NewAllocationSize);
+                                          NewAllocationSize,
+                                          CaseSensitive);
 
     ReleaseAttributeContext(IndexRootCtx);
     ExFreePoolWithTag(IndexRecord, TAG_NTFS);
 
     ReleaseAttributeContext(IndexRootCtx);
     ExFreePoolWithTag(IndexRecord, TAG_NTFS);
@@ -1447,7 +1456,8 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb,
                              PULONG CurrentEntry,
                              BOOLEAN DirSearch,
                              ULONGLONG NewDataSize,
                              PULONG CurrentEntry,
                              BOOLEAN DirSearch,
                              ULONGLONG NewDataSize,
-                             ULONGLONG NewAllocatedSize)
+                             ULONGLONG NewAllocatedSize,
+                             BOOLEAN CaseSensitive)
 {
     NTSTATUS Status;
     ULONG RecordOffset;
 {
     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 &&
         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;
         {
             *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));
 
         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
         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
 CompareFileName(PUNICODE_STRING FileName,
                 PINDEX_ENTRY_ATTRIBUTE IndexEntry,
-                BOOLEAN DirSearch)
+                BOOLEAN DirSearch,
+                BOOLEAN CaseSensitive)
 {
     BOOLEAN Ret, Alloc = FALSE;
     UNICODE_STRING EntryName;
 {
     BOOLEAN Ret, Alloc = FALSE;
     UNICODE_STRING EntryName;
@@ -1839,7 +1862,7 @@ CompareFileName(PUNICODE_STRING FileName,
     if (DirSearch)
     {
         UNICODE_STRING IntFileName;
     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;
         {
             NT_VERIFY(NT_SUCCESS(RtlUpcaseUnicodeString(&IntFileName, FileName, TRUE)));
             Alloc = TRUE;
@@ -1849,7 +1872,7 @@ CompareFileName(PUNICODE_STRING FileName,
             IntFileName = *FileName;
         }
 
             IntFileName = *FileName;
         }
 
-        Ret = FsRtlIsNameInExpression(&IntFileName, &EntryName, (IndexEntry->FileName.NameType != NTFS_FILE_NAME_POSIX), NULL);
+        Ret = FsRtlIsNameInExpression(&IntFileName, &EntryName, !CaseSensitive, NULL);
 
         if (Alloc)
         {
 
         if (Alloc)
         {
@@ -1860,7 +1883,7 @@ CompareFileName(PUNICODE_STRING FileName,
     }
     else
     {
     }
     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,
                    PULONG StartEntry,
                    PULONG CurrentEntry,
                    BOOLEAN DirSearch,
+                   BOOLEAN CaseSensitive,
                    ULONGLONG *OutMFTIndex)
 {
     NTSTATUS Status;
                    ULONGLONG *OutMFTIndex)
 {
     NTSTATUS Status;
@@ -1909,7 +1933,19 @@ BrowseIndexEntries(PDEVICE_EXTENSION Vcb,
     ULONGLONG IndexAllocationSize;
     PINDEX_BUFFER IndexBuffer;
 
     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 &&
 
     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 &&
         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);
         {
             *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));
 
         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;
         if (NT_SUCCESS(Status))
         {
             break;
@@ -1984,7 +2031,8 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
                   PUNICODE_STRING FileName,
                   PULONG FirstEntry,
                   BOOLEAN DirSearch,
                   PUNICODE_STRING FileName,
                   PULONG FirstEntry,
                   BOOLEAN DirSearch,
-                  ULONGLONG *OutMFTIndex)
+                  ULONGLONG *OutMFTIndex,
+                  BOOLEAN CaseSensitive)
 {
     PFILE_RECORD_HEADER MftRecord;
     PNTFS_ATTR_CONTEXT IndexRootCtx;
 {
     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);
 
 
     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);
 
     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,
                  PUNICODE_STRING PathName,
                  PFILE_RECORD_HEADER *FileRecord,
                  PULONGLONG MFTIndex,
-                 ULONGLONG CurrentMFTIndex)
+                 ULONGLONG CurrentMFTIndex,
+                 BOOLEAN CaseSensitive)
 {
     UNICODE_STRING Current, Remaining;
     NTSTATUS Status;
 {
     UNICODE_STRING Current, Remaining;
     NTSTATUS Status;
@@ -2063,7 +2123,7 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
     {
         DPRINT("Current: %wZ\n", &Current);
 
     {
         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;
         if (!NT_SUCCESS(Status))
         {
             return Status;
@@ -2099,9 +2159,10 @@ NTSTATUS
 NtfsLookupFile(PDEVICE_EXTENSION Vcb,
                PUNICODE_STRING PathName,
                PFILE_RECORD_HEADER *FileRecord,
 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,
                PULONG FirstEntry,
                PFILE_RECORD_HEADER *FileRecord,
                PULONGLONG MFTIndex,
-               ULONGLONG CurrentMFTIndex)
+               ULONGLONG CurrentMFTIndex,
+               BOOLEAN CaseSensitive)
 {
     NTSTATUS Status;
 
 {
     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);
     if (!NT_SUCCESS(Status))
     {
         DPRINT("NtfsFindFileAt: NtfsFindMftRecord() failed with status 0x%08lx\n", Status);
index 799f8e2..f54a14d 100644 (file)
@@ -781,7 +781,8 @@ NTSTATUS
 NtfsGetFCBForFile(PNTFS_VCB Vcb,
                   PNTFS_FCB *pParentFCB,
                   PNTFS_FCB *pFCB,
 NtfsGetFCBForFile(PNTFS_VCB Vcb,
                   PNTFS_FCB *pParentFCB,
                   PNTFS_FCB *pFCB,
-                  const PWSTR pFileName);
+                  const PWSTR pFileName,
+                  BOOLEAN CaseSensitive);
 
 NTSTATUS
 NtfsReadFCBAttribute(PNTFS_VCB Vcb,
 
 NTSTATUS
 NtfsReadFCBAttribute(PNTFS_VCB Vcb,
@@ -811,6 +812,7 @@ NtfsSetEndOfFile(PNTFS_FCB Fcb,
                  PFILE_OBJECT FileObject,
                  PDEVICE_EXTENSION DeviceExt,
                  ULONG IrpFlags,
                  PFILE_OBJECT FileObject,
                  PDEVICE_EXTENSION DeviceExt,
                  ULONG IrpFlags,
+                 BOOLEAN CaseSensitive,
                  PLARGE_INTEGER NewFileSize);
 
 NTSTATUS
                  PLARGE_INTEGER NewFileSize);
 
 NTSTATUS
@@ -892,7 +894,8 @@ AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord);
 BOOLEAN
 CompareFileName(PUNICODE_STRING FileName,
                 PINDEX_ENTRY_ATTRIBUTE IndexEntry,
 BOOLEAN
 CompareFileName(PUNICODE_STRING FileName,
                 PINDEX_ENTRY_ATTRIBUTE IndexEntry,
-                BOOLEAN DirSearch);
+                BOOLEAN DirSearch,
+                BOOLEAN CaseSensitive);
 
 NTSTATUS
 ReadFileRecord(PDEVICE_EXTENSION Vcb,
 
 NTSTATUS
 ReadFileRecord(PDEVICE_EXTENSION Vcb,
@@ -911,7 +914,8 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb,
                              PULONG CurrentEntry,
                              BOOLEAN DirSearch,
                              ULONGLONG NewDataSize,
                              PULONG CurrentEntry,
                              BOOLEAN DirSearch,
                              ULONGLONG NewDataSize,
-                             ULONGLONG NewAllocatedSize);
+                             ULONGLONG NewAllocatedSize,
+                             BOOLEAN CaseSensitive);
 
 NTSTATUS
 UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
 
 NTSTATUS
 UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
@@ -919,7 +923,8 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
                      PUNICODE_STRING FileName,
                      BOOLEAN DirSearch,
                      ULONGLONG NewDataSize,
                      PUNICODE_STRING FileName,
                      BOOLEAN DirSearch,
                      ULONGLONG NewDataSize,
-                     ULONGLONG NewAllocationSize);
+                     ULONGLONG NewAllocationSize,
+                     BOOLEAN CaseSensitive);
 
 NTSTATUS
 UpdateFileRecord(PDEVICE_EXTENSION Vcb,
 
 NTSTATUS
 UpdateFileRecord(PDEVICE_EXTENSION Vcb,
@@ -973,7 +978,8 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
                  PUNICODE_STRING PathName,
                  PFILE_RECORD_HEADER *FileRecord,
                  PULONGLONG MFTIndex,
                  PUNICODE_STRING PathName,
                  PFILE_RECORD_HEADER *FileRecord,
                  PULONGLONG MFTIndex,
-                 ULONGLONG CurrentMFTIndex);
+                 ULONGLONG CurrentMFTIndex,
+                 BOOLEAN CaseSensitive);
 
 VOID
 NtfsDumpFileRecord(PDEVICE_EXTENSION Vcb,
 
 VOID
 NtfsDumpFileRecord(PDEVICE_EXTENSION Vcb,
@@ -985,7 +991,8 @@ NtfsFindFileAt(PDEVICE_EXTENSION Vcb,
                PULONG FirstEntry,
                PFILE_RECORD_HEADER *FileRecord,
                PULONGLONG MFTIndex,
                PULONG FirstEntry,
                PFILE_RECORD_HEADER *FileRecord,
                PULONGLONG MFTIndex,
-               ULONGLONG CurrentMFTIndex);
+               ULONGLONG CurrentMFTIndex,
+               BOOLEAN CaseSensitive);
 
 NTSTATUS
 NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
 
 NTSTATUS
 NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
@@ -993,7 +1000,8 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
                   PUNICODE_STRING FileName,
                   PULONG FirstEntry,
                   BOOLEAN DirSearch,
                   PUNICODE_STRING FileName,
                   PULONG FirstEntry,
                   BOOLEAN DirSearch,
-                  ULONGLONG *OutMFTIndex);
+                  ULONGLONG *OutMFTIndex,
+                  BOOLEAN CaseSensitive);
 
 /* misc.c */
 
 
 /* misc.c */
 
index 7f119d7..1cfdd7f 100644 (file)
@@ -283,6 +283,10 @@ NtfsRead(PNTFS_IRP_CONTEXT IrpContext)
 * @param IrpFlags
 * TODO: flags are presently ignored in code.
 *
 * @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.
 *
 * @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,
                        ULONG Length,
                        ULONG WriteOffset,
                        ULONG IrpFlags,
+                       BOOLEAN CaseSensitive,
                        PULONG LengthWritten)
 {
     NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
                        PULONG LengthWritten)
 {
     NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
@@ -312,7 +317,15 @@ NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt,
     ULONG AttributeOffset;
     ULONGLONG StreamSize;
 
     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;
 
 
     *LengthWritten = 0;
 
@@ -444,7 +457,13 @@ NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt,
             filename.Length = fileNameAttribute->NameLength * sizeof(WCHAR);
             filename.MaximumLength = filename.Length;
 
             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
 
         }
         else
@@ -667,6 +686,7 @@ NtfsWrite(PNTFS_IRP_CONTEXT IrpContext)
                            Length,
                            ByteOffset.LowPart,
                            Irp->Flags,
                            Length,
                            ByteOffset.LowPart,
                            Irp->Flags,
+                           (IrpContext->Stack->Flags & SL_CASE_SENSITIVE),
                            &ReturnedWriteLength);
 
     IrpContext->Irp->IoStatus.Status = Status;
                            &ReturnedWriteLength);
 
     IrpContext->Irp->IoStatus.Status = Status;