mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[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
This commit is contained in:
parent
98ddf610bc
commit
032be02954
8 changed files with 185 additions and 44 deletions
|
@ -115,6 +115,10 @@ AddData(PFILE_RECORD_HEADER FileRecord,
|
||||||
* @param ParentMftIndex
|
* @param ParentMftIndex
|
||||||
* Pointer to a ULONGLONG which will receive the index of the parent directory.
|
* 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
|
* @return
|
||||||
* STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end
|
* STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end
|
||||||
* of the given file record.
|
* of the given file record.
|
||||||
|
@ -132,7 +136,8 @@ AddFileName(PFILE_RECORD_HEADER FileRecord,
|
||||||
PNTFS_ATTR_RECORD AttributeAddress,
|
PNTFS_ATTR_RECORD AttributeAddress,
|
||||||
PDEVICE_EXTENSION DeviceExt,
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
PFILE_OBJECT FileObject,
|
PFILE_OBJECT FileObject,
|
||||||
PULONGLONG ParentMftIndex)
|
PULONGLONG ParentMftIndex,
|
||||||
|
BOOLEAN CaseSensitive)
|
||||||
{
|
{
|
||||||
ULONG ResidentHeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
|
ULONG ResidentHeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
|
||||||
PFILENAME_ATTRIBUTE FileNameAttribute;
|
PFILENAME_ATTRIBUTE FileNameAttribute;
|
||||||
|
@ -178,7 +183,13 @@ AddFileName(PFILE_RECORD_HEADER FileRecord,
|
||||||
if(Remaining.Length != 0)
|
if(Remaining.Length != 0)
|
||||||
RtlCopyUnicodeString(&FilenameNoPath, &Remaining);
|
RtlCopyUnicodeString(&FilenameNoPath, &Remaining);
|
||||||
|
|
||||||
Status = NtfsFindMftRecord(DeviceExt, CurrentMFTIndex, &Current, &FirstEntry, FALSE, &CurrentMFTIndex);
|
Status = NtfsFindMftRecord(DeviceExt,
|
||||||
|
CurrentMFTIndex,
|
||||||
|
&Current,
|
||||||
|
&FirstEntry,
|
||||||
|
FALSE,
|
||||||
|
&CurrentMFTIndex,
|
||||||
|
CaseSensitive);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,7 @@ NTSTATUS
|
||||||
NtfsOpenFile(PDEVICE_EXTENSION DeviceExt,
|
NtfsOpenFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
PFILE_OBJECT FileObject,
|
PFILE_OBJECT FileObject,
|
||||||
PWSTR FileName,
|
PWSTR FileName,
|
||||||
|
BOOLEAN CaseSensitive,
|
||||||
PNTFS_FCB * FoundFCB)
|
PNTFS_FCB * FoundFCB)
|
||||||
{
|
{
|
||||||
PNTFS_FCB ParentFcb;
|
PNTFS_FCB ParentFcb;
|
||||||
|
@ -253,7 +254,12 @@ NtfsOpenFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PWSTR AbsFileName = NULL;
|
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,
|
Status = NtfsGetFCBForFile(DeviceExt,
|
||||||
&ParentFcb,
|
&ParentFcb,
|
||||||
&Fcb,
|
&Fcb,
|
||||||
FileName);
|
FileName,
|
||||||
|
CaseSensitive);
|
||||||
if (ParentFcb != NULL)
|
if (ParentFcb != NULL)
|
||||||
{
|
{
|
||||||
NtfsReleaseFCB(DeviceExt,
|
NtfsReleaseFCB(DeviceExt,
|
||||||
|
@ -412,6 +419,7 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject,
|
||||||
Status = NtfsOpenFile(DeviceExt,
|
Status = NtfsOpenFile(DeviceExt,
|
||||||
FileObject,
|
FileObject,
|
||||||
((RequestedOptions & FILE_OPEN_BY_FILE_ID) ? FullPath.Buffer : FileObject->FileName.Buffer),
|
((RequestedOptions & FILE_OPEN_BY_FILE_ID) ? FullPath.Buffer : FileObject->FileName.Buffer),
|
||||||
|
(Stack->Flags & SL_CASE_SENSITIVE),
|
||||||
&Fcb);
|
&Fcb);
|
||||||
|
|
||||||
if (RequestedOptions & FILE_OPEN_BY_FILE_ID)
|
if (RequestedOptions & FILE_OPEN_BY_FILE_ID)
|
||||||
|
|
|
@ -627,7 +627,8 @@ NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
|
||||||
&Ccb->Entry,
|
&Ccb->Entry,
|
||||||
&FileRecord,
|
&FileRecord,
|
||||||
&MFTRecord,
|
&MFTRecord,
|
||||||
Fcb->MFTIndex);
|
Fcb->MFTIndex,
|
||||||
|
(Stack->Flags & SL_CASE_SENSITIVE));
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
|
@ -506,6 +506,7 @@ static NTSTATUS
|
||||||
NtfsDirFindFile(PNTFS_VCB Vcb,
|
NtfsDirFindFile(PNTFS_VCB Vcb,
|
||||||
PNTFS_FCB DirectoryFcb,
|
PNTFS_FCB DirectoryFcb,
|
||||||
PWSTR FileToFind,
|
PWSTR FileToFind,
|
||||||
|
BOOLEAN CaseSensitive,
|
||||||
PNTFS_FCB *FoundFCB)
|
PNTFS_FCB *FoundFCB)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -517,7 +518,12 @@ NtfsDirFindFile(PNTFS_VCB Vcb,
|
||||||
PNTFS_ATTR_CONTEXT DataContext;
|
PNTFS_ATTR_CONTEXT DataContext;
|
||||||
USHORT Length = 0;
|
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;
|
*FoundFCB = NULL;
|
||||||
RtlInitUnicodeString(&File, FileToFind);
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -587,7 +593,8 @@ NTSTATUS
|
||||||
NtfsGetFCBForFile(PNTFS_VCB Vcb,
|
NtfsGetFCBForFile(PNTFS_VCB Vcb,
|
||||||
PNTFS_FCB *pParentFCB,
|
PNTFS_FCB *pParentFCB,
|
||||||
PNTFS_FCB *pFCB,
|
PNTFS_FCB *pFCB,
|
||||||
const PWSTR pFileName)
|
const PWSTR pFileName,
|
||||||
|
BOOLEAN CaseSensitive)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
WCHAR pathName [MAX_PATH];
|
WCHAR pathName [MAX_PATH];
|
||||||
|
@ -596,11 +603,12 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb,
|
||||||
PNTFS_FCB FCB;
|
PNTFS_FCB FCB;
|
||||||
PNTFS_FCB parentFCB;
|
PNTFS_FCB parentFCB;
|
||||||
|
|
||||||
DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S')\n",
|
DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S', %s)\n",
|
||||||
Vcb,
|
Vcb,
|
||||||
pParentFCB,
|
pParentFCB,
|
||||||
pFCB,
|
pFCB,
|
||||||
pFileName);
|
pFileName,
|
||||||
|
CaseSensitive ? "TRUE" : "FALSE");
|
||||||
|
|
||||||
/* Dummy code */
|
/* Dummy code */
|
||||||
// FCB = NtfsOpenRootFCB(Vcb);
|
// FCB = NtfsOpenRootFCB(Vcb);
|
||||||
|
@ -677,7 +685,7 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb,
|
||||||
NtfsGetNextPathElement(currentElement) - currentElement);
|
NtfsGetNextPathElement(currentElement) - currentElement);
|
||||||
DPRINT(" elementName:%S\n", elementName);
|
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)
|
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
{
|
{
|
||||||
*pParentFCB = parentFCB;
|
*pParentFCB = parentFCB;
|
||||||
|
|
|
@ -415,6 +415,10 @@ NtfsQueryInformation(PNTFS_IRP_CONTEXT IrpContext)
|
||||||
* @param IrpFlags
|
* @param IrpFlags
|
||||||
* ULONG describing the flags of the original IRP request (Irp->Flags).
|
* 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
|
* @param NewFileSize
|
||||||
* Pointer to a LARGE_INTEGER which indicates the new end of file (file size).
|
* 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,
|
PFILE_OBJECT FileObject,
|
||||||
PDEVICE_EXTENSION DeviceExt,
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG IrpFlags,
|
ULONG IrpFlags,
|
||||||
|
BOOLEAN CaseSensitive,
|
||||||
PLARGE_INTEGER NewFileSize)
|
PLARGE_INTEGER NewFileSize)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER CurrentFileSize;
|
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);
|
ReleaseAttributeContext(DataContext);
|
||||||
ExFreePoolWithTag(FileRecord, TAG_NTFS);
|
ExFreePoolWithTag(FileRecord, TAG_NTFS);
|
||||||
|
@ -620,7 +631,12 @@ NtfsSetInformation(PNTFS_IRP_CONTEXT IrpContext)
|
||||||
DPRINT1("FIXME: Using hacky method of setting FileAllocationInformation.\n");
|
DPRINT1("FIXME: Using hacky method of setting FileAllocationInformation.\n");
|
||||||
case FileEndOfFileInformation:
|
case FileEndOfFileInformation:
|
||||||
EndOfFileInfo = (PFILE_END_OF_FILE_INFORMATION)SystemBuffer;
|
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;
|
break;
|
||||||
|
|
||||||
// TODO: all other information classes
|
// TODO: all other information classes
|
||||||
|
|
|
@ -1359,7 +1359,8 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
|
||||||
PUNICODE_STRING FileName,
|
PUNICODE_STRING FileName,
|
||||||
BOOLEAN DirSearch,
|
BOOLEAN DirSearch,
|
||||||
ULONGLONG NewDataSize,
|
ULONGLONG NewDataSize,
|
||||||
ULONGLONG NewAllocationSize)
|
ULONGLONG NewAllocationSize,
|
||||||
|
BOOLEAN CaseSensitive)
|
||||||
{
|
{
|
||||||
PFILE_RECORD_HEADER MftRecord;
|
PFILE_RECORD_HEADER MftRecord;
|
||||||
PNTFS_ATTR_CONTEXT IndexRootCtx;
|
PNTFS_ATTR_CONTEXT IndexRootCtx;
|
||||||
|
@ -1369,7 +1370,14 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG CurrentEntry = 0;
|
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,
|
MftRecord = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
Vcb->NtfsInfo.BytesPerFileRecord,
|
Vcb->NtfsInfo.BytesPerFileRecord,
|
||||||
|
@ -1421,7 +1429,8 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
|
||||||
&CurrentEntry,
|
&CurrentEntry,
|
||||||
DirSearch,
|
DirSearch,
|
||||||
NewDataSize,
|
NewDataSize,
|
||||||
NewAllocationSize);
|
NewAllocationSize,
|
||||||
|
CaseSensitive);
|
||||||
|
|
||||||
ReleaseAttributeContext(IndexRootCtx);
|
ReleaseAttributeContext(IndexRootCtx);
|
||||||
ExFreePoolWithTag(IndexRecord, TAG_NTFS);
|
ExFreePoolWithTag(IndexRecord, TAG_NTFS);
|
||||||
|
@ -1447,7 +1456,8 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb,
|
||||||
PULONG CurrentEntry,
|
PULONG CurrentEntry,
|
||||||
BOOLEAN DirSearch,
|
BOOLEAN DirSearch,
|
||||||
ULONGLONG NewDataSize,
|
ULONGLONG NewDataSize,
|
||||||
ULONGLONG NewAllocatedSize)
|
ULONGLONG NewAllocatedSize,
|
||||||
|
BOOLEAN CaseSensitive)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG RecordOffset;
|
ULONG RecordOffset;
|
||||||
|
@ -1466,7 +1476,7 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb,
|
||||||
if ((IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK) > 0x10 &&
|
if ((IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK) > 0x10 &&
|
||||||
*CurrentEntry >= *StartEntry &&
|
*CurrentEntry >= *StartEntry &&
|
||||||
IndexEntry->FileName.NameType != NTFS_FILE_NAME_DOS &&
|
IndexEntry->FileName.NameType != NTFS_FILE_NAME_DOS &&
|
||||||
CompareFileName(FileName, IndexEntry, DirSearch))
|
CompareFileName(FileName, IndexEntry, DirSearch, CaseSensitive))
|
||||||
{
|
{
|
||||||
*StartEntry = *CurrentEntry;
|
*StartEntry = *CurrentEntry;
|
||||||
IndexEntry->FileName.DataSize = NewDataSize;
|
IndexEntry->FileName.DataSize = NewDataSize;
|
||||||
|
@ -1517,7 +1527,19 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb,
|
||||||
LastEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)&IndexBuffer->Header + IndexBuffer->Header.TotalSizeOfEntries);
|
LastEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)&IndexBuffer->Header + IndexBuffer->Header.TotalSizeOfEntries);
|
||||||
ASSERT(LastEntry <= (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexBuffer + IndexBlockSize));
|
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)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
// write the index record back to disk
|
// write the index record back to disk
|
||||||
|
@ -1827,7 +1849,8 @@ ReadLCN(PDEVICE_EXTENSION Vcb,
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
CompareFileName(PUNICODE_STRING FileName,
|
CompareFileName(PUNICODE_STRING FileName,
|
||||||
PINDEX_ENTRY_ATTRIBUTE IndexEntry,
|
PINDEX_ENTRY_ATTRIBUTE IndexEntry,
|
||||||
BOOLEAN DirSearch)
|
BOOLEAN DirSearch,
|
||||||
|
BOOLEAN CaseSensitive)
|
||||||
{
|
{
|
||||||
BOOLEAN Ret, Alloc = FALSE;
|
BOOLEAN Ret, Alloc = FALSE;
|
||||||
UNICODE_STRING EntryName;
|
UNICODE_STRING EntryName;
|
||||||
|
@ -1839,7 +1862,7 @@ CompareFileName(PUNICODE_STRING FileName,
|
||||||
if (DirSearch)
|
if (DirSearch)
|
||||||
{
|
{
|
||||||
UNICODE_STRING IntFileName;
|
UNICODE_STRING IntFileName;
|
||||||
if (IndexEntry->FileName.NameType != NTFS_FILE_NAME_POSIX)
|
if (!CaseSensitive)
|
||||||
{
|
{
|
||||||
NT_VERIFY(NT_SUCCESS(RtlUpcaseUnicodeString(&IntFileName, FileName, TRUE)));
|
NT_VERIFY(NT_SUCCESS(RtlUpcaseUnicodeString(&IntFileName, FileName, TRUE)));
|
||||||
Alloc = 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 StartEntry,
|
||||||
PULONG CurrentEntry,
|
PULONG CurrentEntry,
|
||||||
BOOLEAN DirSearch,
|
BOOLEAN DirSearch,
|
||||||
|
BOOLEAN CaseSensitive,
|
||||||
ULONGLONG *OutMFTIndex)
|
ULONGLONG *OutMFTIndex)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -1909,7 +1933,19 @@ BrowseIndexEntries(PDEVICE_EXTENSION Vcb,
|
||||||
ULONGLONG IndexAllocationSize;
|
ULONGLONG IndexAllocationSize;
|
||||||
PINDEX_BUFFER IndexBuffer;
|
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;
|
IndexEntry = FirstEntry;
|
||||||
while (IndexEntry < LastEntry &&
|
while (IndexEntry < LastEntry &&
|
||||||
|
@ -1918,7 +1954,7 @@ BrowseIndexEntries(PDEVICE_EXTENSION Vcb,
|
||||||
if ((IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK) >= 0x10 &&
|
if ((IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK) >= 0x10 &&
|
||||||
*CurrentEntry >= *StartEntry &&
|
*CurrentEntry >= *StartEntry &&
|
||||||
IndexEntry->FileName.NameType != NTFS_FILE_NAME_DOS &&
|
IndexEntry->FileName.NameType != NTFS_FILE_NAME_DOS &&
|
||||||
CompareFileName(FileName, IndexEntry, DirSearch))
|
CompareFileName(FileName, IndexEntry, DirSearch, CaseSensitive))
|
||||||
{
|
{
|
||||||
*StartEntry = *CurrentEntry;
|
*StartEntry = *CurrentEntry;
|
||||||
*OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK);
|
*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);
|
LastEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)&IndexBuffer->Header + IndexBuffer->Header.TotalSizeOfEntries);
|
||||||
ASSERT(LastEntry <= (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexBuffer + IndexBlockSize));
|
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))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -1984,7 +2031,8 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
|
||||||
PUNICODE_STRING FileName,
|
PUNICODE_STRING FileName,
|
||||||
PULONG FirstEntry,
|
PULONG FirstEntry,
|
||||||
BOOLEAN DirSearch,
|
BOOLEAN DirSearch,
|
||||||
ULONGLONG *OutMFTIndex)
|
ULONGLONG *OutMFTIndex,
|
||||||
|
BOOLEAN CaseSensitive)
|
||||||
{
|
{
|
||||||
PFILE_RECORD_HEADER MftRecord;
|
PFILE_RECORD_HEADER MftRecord;
|
||||||
PNTFS_ATTR_CONTEXT IndexRootCtx;
|
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(IndexRecord, TAG_NTFS);
|
||||||
ExFreePoolWithTag(MftRecord, TAG_NTFS);
|
ExFreePoolWithTag(MftRecord, TAG_NTFS);
|
||||||
|
@ -2049,7 +2108,8 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
|
||||||
PUNICODE_STRING PathName,
|
PUNICODE_STRING PathName,
|
||||||
PFILE_RECORD_HEADER *FileRecord,
|
PFILE_RECORD_HEADER *FileRecord,
|
||||||
PULONGLONG MFTIndex,
|
PULONGLONG MFTIndex,
|
||||||
ULONGLONG CurrentMFTIndex)
|
ULONGLONG CurrentMFTIndex,
|
||||||
|
BOOLEAN CaseSensitive)
|
||||||
{
|
{
|
||||||
UNICODE_STRING Current, Remaining;
|
UNICODE_STRING Current, Remaining;
|
||||||
NTSTATUS Status;
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -2099,9 +2159,10 @@ NTSTATUS
|
||||||
NtfsLookupFile(PDEVICE_EXTENSION Vcb,
|
NtfsLookupFile(PDEVICE_EXTENSION Vcb,
|
||||||
PUNICODE_STRING PathName,
|
PUNICODE_STRING PathName,
|
||||||
PFILE_RECORD_HEADER *FileRecord,
|
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,
|
PULONG FirstEntry,
|
||||||
PFILE_RECORD_HEADER *FileRecord,
|
PFILE_RECORD_HEADER *FileRecord,
|
||||||
PULONGLONG MFTIndex,
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("NtfsFindFileAt: NtfsFindMftRecord() failed with status 0x%08lx\n", Status);
|
DPRINT("NtfsFindFileAt: NtfsFindMftRecord() failed with status 0x%08lx\n", Status);
|
||||||
|
|
|
@ -781,7 +781,8 @@ NTSTATUS
|
||||||
NtfsGetFCBForFile(PNTFS_VCB Vcb,
|
NtfsGetFCBForFile(PNTFS_VCB Vcb,
|
||||||
PNTFS_FCB *pParentFCB,
|
PNTFS_FCB *pParentFCB,
|
||||||
PNTFS_FCB *pFCB,
|
PNTFS_FCB *pFCB,
|
||||||
const PWSTR pFileName);
|
const PWSTR pFileName,
|
||||||
|
BOOLEAN CaseSensitive);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NtfsReadFCBAttribute(PNTFS_VCB Vcb,
|
NtfsReadFCBAttribute(PNTFS_VCB Vcb,
|
||||||
|
@ -811,6 +812,7 @@ NtfsSetEndOfFile(PNTFS_FCB Fcb,
|
||||||
PFILE_OBJECT FileObject,
|
PFILE_OBJECT FileObject,
|
||||||
PDEVICE_EXTENSION DeviceExt,
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG IrpFlags,
|
ULONG IrpFlags,
|
||||||
|
BOOLEAN CaseSensitive,
|
||||||
PLARGE_INTEGER NewFileSize);
|
PLARGE_INTEGER NewFileSize);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -892,7 +894,8 @@ AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord);
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
CompareFileName(PUNICODE_STRING FileName,
|
CompareFileName(PUNICODE_STRING FileName,
|
||||||
PINDEX_ENTRY_ATTRIBUTE IndexEntry,
|
PINDEX_ENTRY_ATTRIBUTE IndexEntry,
|
||||||
BOOLEAN DirSearch);
|
BOOLEAN DirSearch,
|
||||||
|
BOOLEAN CaseSensitive);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ReadFileRecord(PDEVICE_EXTENSION Vcb,
|
ReadFileRecord(PDEVICE_EXTENSION Vcb,
|
||||||
|
@ -911,7 +914,8 @@ UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb,
|
||||||
PULONG CurrentEntry,
|
PULONG CurrentEntry,
|
||||||
BOOLEAN DirSearch,
|
BOOLEAN DirSearch,
|
||||||
ULONGLONG NewDataSize,
|
ULONGLONG NewDataSize,
|
||||||
ULONGLONG NewAllocatedSize);
|
ULONGLONG NewAllocatedSize,
|
||||||
|
BOOLEAN CaseSensitive);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
|
UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
|
||||||
|
@ -919,7 +923,8 @@ UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
|
||||||
PUNICODE_STRING FileName,
|
PUNICODE_STRING FileName,
|
||||||
BOOLEAN DirSearch,
|
BOOLEAN DirSearch,
|
||||||
ULONGLONG NewDataSize,
|
ULONGLONG NewDataSize,
|
||||||
ULONGLONG NewAllocationSize);
|
ULONGLONG NewAllocationSize,
|
||||||
|
BOOLEAN CaseSensitive);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
UpdateFileRecord(PDEVICE_EXTENSION Vcb,
|
UpdateFileRecord(PDEVICE_EXTENSION Vcb,
|
||||||
|
@ -973,7 +978,8 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
|
||||||
PUNICODE_STRING PathName,
|
PUNICODE_STRING PathName,
|
||||||
PFILE_RECORD_HEADER *FileRecord,
|
PFILE_RECORD_HEADER *FileRecord,
|
||||||
PULONGLONG MFTIndex,
|
PULONGLONG MFTIndex,
|
||||||
ULONGLONG CurrentMFTIndex);
|
ULONGLONG CurrentMFTIndex,
|
||||||
|
BOOLEAN CaseSensitive);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NtfsDumpFileRecord(PDEVICE_EXTENSION Vcb,
|
NtfsDumpFileRecord(PDEVICE_EXTENSION Vcb,
|
||||||
|
@ -985,7 +991,8 @@ NtfsFindFileAt(PDEVICE_EXTENSION Vcb,
|
||||||
PULONG FirstEntry,
|
PULONG FirstEntry,
|
||||||
PFILE_RECORD_HEADER *FileRecord,
|
PFILE_RECORD_HEADER *FileRecord,
|
||||||
PULONGLONG MFTIndex,
|
PULONGLONG MFTIndex,
|
||||||
ULONGLONG CurrentMFTIndex);
|
ULONGLONG CurrentMFTIndex,
|
||||||
|
BOOLEAN CaseSensitive);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
|
NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
|
||||||
|
@ -993,7 +1000,8 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
|
||||||
PUNICODE_STRING FileName,
|
PUNICODE_STRING FileName,
|
||||||
PULONG FirstEntry,
|
PULONG FirstEntry,
|
||||||
BOOLEAN DirSearch,
|
BOOLEAN DirSearch,
|
||||||
ULONGLONG *OutMFTIndex);
|
ULONGLONG *OutMFTIndex,
|
||||||
|
BOOLEAN CaseSensitive);
|
||||||
|
|
||||||
/* misc.c */
|
/* misc.c */
|
||||||
|
|
||||||
|
|
|
@ -283,6 +283,10 @@ NtfsRead(PNTFS_IRP_CONTEXT IrpContext)
|
||||||
* @param IrpFlags
|
* @param IrpFlags
|
||||||
* TODO: flags are presently ignored in code.
|
* 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
|
* @param LengthWritten
|
||||||
* Pointer to a ULONG. This ULONG will be set to the number of bytes successfully written.
|
* 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 Length,
|
||||||
ULONG WriteOffset,
|
ULONG WriteOffset,
|
||||||
ULONG IrpFlags,
|
ULONG IrpFlags,
|
||||||
|
BOOLEAN CaseSensitive,
|
||||||
PULONG LengthWritten)
|
PULONG LengthWritten)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
@ -312,7 +317,15 @@ NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG AttributeOffset;
|
ULONG AttributeOffset;
|
||||||
ULONGLONG StreamSize;
|
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.Length = fileNameAttribute->NameLength * sizeof(WCHAR);
|
||||||
filename.MaximumLength = filename.Length;
|
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,
|
Length,
|
||||||
ByteOffset.LowPart,
|
ByteOffset.LowPart,
|
||||||
Irp->Flags,
|
Irp->Flags,
|
||||||
|
(IrpContext->Stack->Flags & SL_CASE_SENSITIVE),
|
||||||
&ReturnedWriteLength);
|
&ReturnedWriteLength);
|
||||||
|
|
||||||
IrpContext->Irp->IoStatus.Status = Status;
|
IrpContext->Irp->IoStatus.Status = Status;
|
||||||
|
|
Loading…
Reference in a new issue