/*
* ReactOS kernel
- * Copyright (C) 2002,2003 ReactOS Team
+ * Copyright (C) 2002, 2003, 2014 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* PROJECT: ReactOS kernel
* FILE: drivers/filesystem/ntfs/dirctl.c
* PURPOSE: NTFS filesystem driver
- * PROGRAMMER: Eric Kohl
+ * PROGRAMMERS: Eric Kohl
+ * Pierre Schweitzer (pierre@reactos.org)
+ * Hervé Poussineau (hpoussin@reactos.org)
*/
/* INCLUDES *****************************************************************/
DPRINT("NtfsGetNameInformation() called\n");
- FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_WIN32);
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_POSIX);
+ if (FileName == NULL)
+ {
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_WIN32);
+ if (FileName == NULL)
+ {
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_DOS);
+ }
+ }
ASSERT(FileName != NULL);
Length = FileName->NameLength * sizeof (WCHAR);
DPRINT("NtfsGetDirectoryInformation() called\n");
- FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_WIN32);
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_POSIX);
+ if (FileName == NULL)
+ {
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_WIN32);
+ if (FileName == NULL)
+ {
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_DOS);
+ }
+ }
ASSERT(FileName != NULL);
Length = FileName->NameLength * sizeof (WCHAR);
DPRINT("NtfsGetFullDirectoryInformation() called\n");
- FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_WIN32);
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_POSIX);
+ if (FileName == NULL)
+ {
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_WIN32);
+ if (FileName == NULL)
+ {
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_DOS);
+ }
+ }
ASSERT(FileName != NULL);
Length = FileName->NameLength * sizeof (WCHAR);
ULONG BufferLength)
{
ULONG Length;
- PFILENAME_ATTRIBUTE FileName;
+ PFILENAME_ATTRIBUTE FileName, ShortFileName;
DPRINT("NtfsGetBothDirectoryInformation() called\n");
- FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_WIN32);
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_POSIX);
+ if (FileName == NULL)
+ {
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_WIN32);
+ if (FileName == NULL)
+ {
+ FileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_DOS);
+ }
+ }
ASSERT(FileName != NULL);
+ ShortFileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_DOS);
Length = FileName->NameLength * sizeof (WCHAR);
if ((sizeof(FILE_BOTH_DIR_INFORMATION) + Length) > BufferLength)
ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, sizeof(ULONG));
RtlCopyMemory(Info->FileName, FileName->Name, Length);
+ if (ShortFileName)
+ {
+ /* Should we upcase the filename? */
+ ASSERT(ShortFileName->NameLength <= ARRAYSIZE(Info->ShortName));
+ Info->ShortNameLength = ShortFileName->NameLength * sizeof(WCHAR);
+ RtlCopyMemory(Info->ShortName, ShortFileName->Name, Info->ShortNameLength);
+ }
+ else
+ {
+ Info->ShortName[0] = 0;
+ Info->ShortNameLength = 0;
+ }
+
Info->CreationTime.QuadPart = FileName->CreationTime;
Info->LastAccessTime.QuadPart = FileName->LastAccessTime;
Info->LastWriteTime.QuadPart = FileName->LastWriteTime;
// Info->FileIndex=;
Info->EaSize = 0;
- Info->ShortName[0] = 0;
- Info->ShortNameLength = 0;
-
return STATUS_SUCCESS;
}
NTSTATUS Status = STATUS_SUCCESS;
PFILE_RECORD_HEADER FileRecord;
PNTFS_ATTR_CONTEXT DataContext;
- ULONGLONG MFTRecord;
+ ULONGLONG MFTRecord, OldMFTRecord = 0;
UNICODE_STRING Pattern;
DPRINT1("NtfsQueryDirectory() called\n");
if (!Ccb->DirectorySearchPattern)
{
First = TRUE;
- Ccb->DirectorySearchPattern =
- ExAllocatePoolWithTag(NonPagedPool, SearchPattern->Length + sizeof(WCHAR), TAG_NTFS);
+ Pattern.Length = 0;
+ Pattern.MaximumLength = SearchPattern->Length + sizeof(WCHAR);
+ Ccb->DirectorySearchPattern = Pattern.Buffer =
+ ExAllocatePoolWithTag(NonPagedPool, Pattern.MaximumLength, TAG_NTFS);
if (!Ccb->DirectorySearchPattern)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
- memcpy(Ccb->DirectorySearchPattern,
- SearchPattern->Buffer,
- SearchPattern->Length);
+ Status = RtlUpcaseUnicodeString(&Pattern, SearchPattern, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlUpcaseUnicodeString('%wZ') failed with status 0x%08lx\n", &Pattern, Status);
+ ExFreePoolWithTag(Ccb->DirectorySearchPattern, TAG_NTFS);
+ Ccb->DirectorySearchPattern = NULL;
+ return Status;
+ }
Ccb->DirectorySearchPattern[SearchPattern->Length / sizeof(WCHAR)] = 0;
}
}
}
RtlInitUnicodeString(&Pattern, Ccb->DirectorySearchPattern);
-
- DPRINT1("Search pattern '%S'\n", Ccb->DirectorySearchPattern);
- DPRINT1("In: '%S'\n", Fcb->PathName);
+ DPRINT("Search pattern '%S'\n", Ccb->DirectorySearchPattern);
+ DPRINT("In: '%S'\n", Fcb->PathName);
/* Determine directory index */
if (Stack->Flags & SL_INDEX_SPECIFIED)
&DataContext,
&MFTRecord,
Fcb->MFTIndex);
- //DPRINT("Found %S, Status=%x, entry %x\n", TempFcb.ObjectName, Status, Ccb->Entry);
if (NT_SUCCESS(Status))
{
+ /* HACK: files with both a short name and a long name are present twice in the index.
+ * Ignore the second entry, if it is immediately following the first one.
+ */
+ if (MFTRecord == OldMFTRecord)
+ {
+ DPRINT("Ignoring duplicate MFT entry 0x%x\n", MFTRecord);
+ Ccb->Entry++;
+ ExFreePoolWithTag(FileRecord, TAG_NTFS);
+ continue;
+ }
+ OldMFTRecord = MFTRecord;
+
switch (FileInformationClass)
{
case FileNameInformation: