Author: pschweitzer
Date: Wed Oct 15 21:02:05 2014
New Revision: 64754
URL:
http://svn.reactos.org/svn/reactos?rev=64754&view=rev
Log:
[NTFS]
- Implement NtfsGetNameInformation()
- Implement NtfsGetDirectoryInformation()
- Implement NtfsGetFullDirectoryInformation()
- Implement NtfsGetBothDirectoryInformation()
- Implement NtfsQueryDirectory() which makes use of all the functions upper + all the
previous fixes to make it able to look for a file using WC and file entry index
This is supposed to bring directory enumeration in line on NTFS volumes. BUT, there's
a bug at some point which makes it fail (or my test volume is corrupted :-P (which is
unlikely (Scheme, get out of this commit message!))). Will look into it later on.
Committing so far because it's quite major work anyway.
More to follow~
Modified:
trunk/reactos/drivers/filesystems/ntfs/dirctl.c
Modified: trunk/reactos/drivers/filesystems/ntfs/dirctl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/ntfs/d…
==============================================================================
--- trunk/reactos/drivers/filesystems/ntfs/dirctl.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/ntfs/dirctl.c [iso-8859-1] Wed Oct 15 21:02:05 2014
@@ -120,400 +120,209 @@
return(STATUS_SUCCESS);
}
+#endif
static NTSTATUS
-CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
- PFCB Fcb,
- PFCB Parent,
- PWSTR FileToFind,
- PULONG pDirIndex,
- PULONG pDirIndex2)
-/*
- * FUNCTION: Find a file
- */
-{
- WCHAR name[256];
- WCHAR TempStr[2];
- PVOID Block;
- NTSTATUS Status;
- ULONG len;
- ULONG DirIndex;
- ULONG Offset;
- ULONG Read;
- BOOLEAN IsRoot;
- PVOID Context = NULL;
- ULONG DirSize;
- PUCHAR Ptr;
- PDIR_RECORD Record;
- LARGE_INTEGER StreamOffset;
-
- DPRINT("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n",
- Parent, FileToFind, pDirIndex ? *pDirIndex : 0);
- DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",
- Fcb->PathName, Fcb->ObjectName);
-
- IsRoot = FALSE;
- DirIndex = 0;
- if (wcslen (FileToFind) == 0)
- {
- CHECKPOINT;
- TempStr[0] = (WCHAR) '.';
- TempStr[1] = 0;
- FileToFind = (PWSTR)&TempStr;
- }
-
- if (Parent)
- {
- if (Parent->Entry.ExtentLocationL == DeviceExt->CdInfo.RootStart)
- {
- IsRoot = TRUE;
- }
- }
- else
- {
- IsRoot = TRUE;
- }
-
- if (IsRoot == TRUE)
- {
- StreamOffset.QuadPart = (LONGLONG)DeviceExt->CdInfo.RootStart *
(LONGLONG)BLOCKSIZE;
- DirSize = DeviceExt->CdInfo.RootSize;
-
-
- if (FileToFind[0] == 0 || (FileToFind[0] == '\\' && FileToFind[1]
== 0)
- || (FileToFind[0] == '.' && FileToFind[1] == 0))
- {
- /* it's root : complete essentials fields then return ok */
- RtlZeroMemory(Fcb, sizeof(FCB));
-
- Fcb->PathName[0]='\\';
- Fcb->ObjectName = &Fcb->PathName[1];
- Fcb->Entry.ExtentLocationL = DeviceExt->CdInfo.RootStart;
- Fcb->Entry.DataLengthL = DeviceExt->CdInfo.RootSize;
- Fcb->Entry.FileFlags = 0x02; //FILE_ATTRIBUTE_DIRECTORY;
-
- if (pDirIndex)
- *pDirIndex = 0;
- if (pDirIndex2)
- *pDirIndex2 = 0;
- DPRINT("CdfsFindFile: new Pathname %S, new Objectname
%S)\n",Fcb->PathName, Fcb->ObjectName);
- return (STATUS_SUCCESS);
- }
- }
- else
- {
- StreamOffset.QuadPart = (LONGLONG)Parent->Entry.ExtentLocationL *
(LONGLONG)BLOCKSIZE;
- DirSize = Parent->Entry.DataLengthL;
- }
-
- DPRINT("StreamOffset %I64u DirSize %lu\n", StreamOffset.QuadPart, DirSize);
-
- if (pDirIndex && (*pDirIndex))
- DirIndex = *pDirIndex;
-
- if(!CcMapData(DeviceExt->StreamFileObject, &StreamOffset,
- BLOCKSIZE, TRUE, &Context, &Block))
- {
- DPRINT("CcMapData() failed\n");
- return(STATUS_UNSUCCESSFUL);
- }
-
- Ptr = (PUCHAR)Block;
- while(TRUE)
- {
- Record = (PDIR_RECORD)Ptr;
- if (Record->RecordLength == 0)
- {
- DPRINT1("Stopped!\n");
- break;
- }
-
- DPRINT("RecordLength %u ExtAttrRecordLength %u NameLength %u\n",
- Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);
-
- Status = CdfsGetEntryName(DeviceExt, &Context, &Block, &StreamOffset,
- DirSize, (PVOID*)&Ptr, name, &DirIndex, pDirIndex2);
- if (Status == STATUS_NO_MORE_ENTRIES)
- {
- break;
- }
- else if (Status == STATUS_UNSUCCESSFUL)
- {
- /* Note: the directory cache has already been unpinned */
- return(Status);
- }
-
- DPRINT("Name '%S'\n", name);
-
- if (wstrcmpjoki(name, FileToFind)) /* || wstrcmpjoki (name2, FileToFind)) */
- {
- if (Parent && Parent->PathName)
- {
- len = wcslen(Parent->PathName);
- memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR));
- Fcb->ObjectName=&Fcb->PathName[len];
- if (len != 1 || Fcb->PathName[0] != '\\')
- {
- Fcb->ObjectName[0] = '\\';
- Fcb->ObjectName = &Fcb->ObjectName[1];
- }
- }
- else
- {
- Fcb->ObjectName=Fcb->PathName;
- Fcb->ObjectName[0]='\\';
- Fcb->ObjectName=&Fcb->ObjectName[1];
- }
-
- DPRINT("PathName '%S' ObjectName '%S'\n", Fcb->PathName,
Fcb->ObjectName);
-
- memcpy(&Fcb->Entry, Ptr, sizeof(DIR_RECORD));
- wcsncpy(Fcb->ObjectName, name, MAX_PATH);
- if (pDirIndex)
- *pDirIndex = DirIndex;
-
- DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",
- Fcb->PathName, Fcb->ObjectName, DirIndex);
-
- CcUnpinData(Context);
-
- return(STATUS_SUCCESS);
- }
-
-
- Ptr = Ptr + Record->RecordLength;
- DirIndex++;
-
- if (((ULONG)Ptr - (ULONG)Block) >= DirSize)
- {
- DPRINT("Stopped!\n");
- break;
- }
- }
-
- CcUnpinData(Context);
-
- if (pDirIndex)
- *pDirIndex = DirIndex;
-
- return(STATUS_UNSUCCESSFUL);
+NtfsGetNameInformation(PDEVICE_EXTENSION DeviceExt,
+ PFILE_RECORD_HEADER FileRecord,
+ PNTFS_ATTR_CONTEXT DataContext,
+ PFILE_NAMES_INFORMATION Info,
+ ULONG BufferLength)
+{
+ ULONG Length;
+ PFILENAME_ATTRIBUTE FileName;
+
+ DPRINT("NtfsGetNameInformation() called\n");
+
+ FileName = GetFileNameFromRecord(FileRecord);
+ ASSERT(FileName != NULL);
+
+ Length = FileName->NameLength;
+ if ((sizeof(FILE_NAMES_INFORMATION) + Length) > BufferLength)
+ return(STATUS_BUFFER_OVERFLOW);
+
+ Info->FileNameLength = Length;
+ Info->NextEntryOffset =
+ ROUND_UP(sizeof(FILE_NAMES_INFORMATION) + Length, sizeof(ULONG));
+ RtlCopyMemory(Info->FileName, FileName->Name, Length);
+
+ return(STATUS_SUCCESS);
}
static NTSTATUS
-CdfsGetNameInformation(PFCB Fcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_NAMES_INFORMATION Info,
- ULONG BufferLength)
-{
- ULONG Length;
-
- DPRINT("CdfsGetNameInformation() called\n");
-
- Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
- if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
- return(STATUS_BUFFER_OVERFLOW);
-
- Info->FileNameLength = Length;
- Info->NextEntryOffset =
- ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
- memcpy(Info->FileName, Fcb->ObjectName, Length);
-
- return(STATUS_SUCCESS);
+NtfsGetDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
+ PFILE_RECORD_HEADER FileRecord,
+ PNTFS_ATTR_CONTEXT DataContext,
+ PFILE_DIRECTORY_INFORMATION Info,
+ ULONG BufferLength)
+{
+ ULONG Length;
+ PFILENAME_ATTRIBUTE FileName;
+
+ DPRINT("NtfsGetDirectoryInformation() called\n");
+
+ FileName = GetFileNameFromRecord(FileRecord);
+ ASSERT(FileName != NULL);
+
+ Length = FileName->NameLength;
+ if ((sizeof(FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
+ return(STATUS_BUFFER_OVERFLOW);
+
+ Info->FileNameLength = Length;
+ Info->NextEntryOffset =
+ ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION) + Length, sizeof(ULONG));
+ RtlCopyMemory(Info->FileName, FileName->Name, Length);
+
+ /* Convert file times */
+ NtfsDateTimeToFileTime(FileName->CreationTime, &Info->CreationTime);
+ NtfsDateTimeToFileTime(FileName->LastAccessTime, &Info->LastAccessTime);
+ NtfsDateTimeToFileTime(FileName->LastWriteTime, &Info->LastWriteTime);
+ NtfsDateTimeToFileTime(FileName->ChangeTime, &Info->ChangeTime);
+
+ /* Convert file flags */
+ NtfsFileFlagsToAttributes(FileName->FileAttributes,
&Info->FileAttributes);
+
+ Info->EndOfFile.QuadPart = FileName->DataSize;
+ Info->AllocationSize.QuadPart = FileName->AllocatedSize;
+
+// Info->FileIndex=;
+
+ return STATUS_SUCCESS;
}
static NTSTATUS
-CdfsGetDirectoryInformation(PFCB Fcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_DIRECTORY_INFORMATION Info,
- ULONG BufferLength)
-{
- ULONG Length;
-
- DPRINT("CdfsGetDirectoryInformation() called\n");
-
- Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
- if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
- return(STATUS_BUFFER_OVERFLOW);
-
- Info->FileNameLength = Length;
- Info->NextEntryOffset =
- ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
- memcpy(Info->FileName, Fcb->ObjectName, Length);
-
- /* Convert file times */
- CdfsDateTimeToFileTime(Fcb,
- &Info->CreationTime);
- CdfsDateTimeToFileTime(Fcb,
- &Info->LastAccessTime);
- CdfsDateTimeToFileTime(Fcb,
- &Info->LastWriteTime);
- CdfsDateTimeToFileTime(Fcb,
- &Info->ChangeTime);
-
- /* Convert file flags */
- CdfsFileFlagsToAttributes(Fcb,
- &Info->FileAttributes);
-
- Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
-
- /* Make AllocSize a rounded up multiple of the sector size */
- Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
+NtfsGetFullDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
+ PFILE_RECORD_HEADER FileRecord,
+ PNTFS_ATTR_CONTEXT DataContext,
+ PFILE_FULL_DIRECTORY_INFORMATION Info,
+ ULONG BufferLength)
+{
+ ULONG Length;
+ PFILENAME_ATTRIBUTE FileName;
+
+ DPRINT("NtfsGetFullDirectoryInformation() called\n");
+
+ FileName = GetFileNameFromRecord(FileRecord);
+ ASSERT(FileName != NULL);
+
+ Length = FileName->NameLength;
+ if ((sizeof(FILE_FULL_DIRECTORY_INFORMATION) + Length) > BufferLength)
+ return(STATUS_BUFFER_OVERFLOW);
+
+ Info->FileNameLength = Length;
+ Info->NextEntryOffset =
+ ROUND_UP(sizeof(FILE_FULL_DIRECTORY_INFORMATION) + Length, sizeof(ULONG));
+ RtlCopyMemory(Info->FileName, FileName->Name, Length);
+
+ /* Convert file times */
+ NtfsDateTimeToFileTime(FileName->CreationTime, &Info->CreationTime);
+ NtfsDateTimeToFileTime(FileName->LastAccessTime, &Info->LastAccessTime);
+ NtfsDateTimeToFileTime(FileName->LastWriteTime, &Info->LastWriteTime);
+ NtfsDateTimeToFileTime(FileName->ChangeTime, &Info->ChangeTime);
+
+ /* Convert file flags */
+ NtfsFileFlagsToAttributes(FileName->FileAttributes,
&Info->FileAttributes);
+
+ Info->EndOfFile.QuadPart = FileName->DataSize;
+ Info->AllocationSize.QuadPart = FileName->AllocatedSize;
// Info->FileIndex=;
-
- return(STATUS_SUCCESS);
+ Info->EaSize = 0;
+
+ return STATUS_SUCCESS;
}
static NTSTATUS
-CdfsGetFullDirectoryInformation(PFCB Fcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_FULL_DIRECTORY_INFORMATION Info,
- ULONG BufferLength)
-{
- ULONG Length;
-
- DPRINT("CdfsGetFullDirectoryInformation() called\n");
-
- Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
- if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
- return(STATUS_BUFFER_OVERFLOW);
-
- Info->FileNameLength = Length;
- Info->NextEntryOffset =
- ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
- memcpy(Info->FileName, Fcb->ObjectName, Length);
-
- /* Convert file times */
- CdfsDateTimeToFileTime(Fcb,
- &Info->CreationTime);
- CdfsDateTimeToFileTime(Fcb,
- &Info->LastAccessTime);
- CdfsDateTimeToFileTime(Fcb,
- &Info->LastWriteTime);
- CdfsDateTimeToFileTime(Fcb,
- &Info->ChangeTime);
-
- /* Convert file flags */
- CdfsFileFlagsToAttributes(Fcb,
- &Info->FileAttributes);
-
- Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
-
- /* Make AllocSize a rounded up multiple of the sector size */
- Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
+NtfsGetBothDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
+ PFILE_RECORD_HEADER FileRecord,
+ PNTFS_ATTR_CONTEXT DataContext,
+ PFILE_BOTH_DIR_INFORMATION Info,
+ ULONG BufferLength)
+{
+ ULONG Length;
+ PFILENAME_ATTRIBUTE FileName;
+
+ DPRINT("NtfsGetBothDirectoryInformation() called\n");
+
+ FileName = GetFileNameFromRecord(FileRecord);
+ ASSERT(FileName != NULL);
+
+ Length = FileName->NameLength;
+ if ((sizeof(FILE_BOTH_DIR_INFORMATION) + Length) > BufferLength)
+ return(STATUS_BUFFER_OVERFLOW);
+
+ Info->FileNameLength = Length;
+ Info->NextEntryOffset =
+ ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, sizeof(ULONG));
+ RtlCopyMemory(Info->FileName, FileName->Name, Length);
+
+ /* Convert file times */
+ NtfsDateTimeToFileTime(FileName->CreationTime, &Info->CreationTime);
+ NtfsDateTimeToFileTime(FileName->LastAccessTime, &Info->LastAccessTime);
+ NtfsDateTimeToFileTime(FileName->LastWriteTime, &Info->LastWriteTime);
+ NtfsDateTimeToFileTime(FileName->ChangeTime, &Info->ChangeTime);
+
+ /* Convert file flags */
+ NtfsFileFlagsToAttributes(FileName->FileAttributes,
&Info->FileAttributes);
+
+ Info->EndOfFile.QuadPart = FileName->DataSize;
+ Info->AllocationSize.QuadPart = FileName->AllocatedSize;
// Info->FileIndex=;
- Info->EaSize = 0;
-
- return(STATUS_SUCCESS);
-}
-
-
-static NTSTATUS
-CdfsGetBothDirectoryInformation(PFCB Fcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_BOTH_DIRECTORY_INFORMATION Info,
- ULONG BufferLength)
-{
- ULONG Length;
-
- DPRINT("CdfsGetBothDirectoryInformation() called\n");
-
- Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
- if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
- return(STATUS_BUFFER_OVERFLOW);
-
- Info->FileNameLength = Length;
- Info->NextEntryOffset =
- ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
- memcpy(Info->FileName, Fcb->ObjectName, Length);
-
- /* Convert file times */
- CdfsDateTimeToFileTime(Fcb,
- &Info->CreationTime);
- CdfsDateTimeToFileTime(Fcb,
- &Info->LastAccessTime);
- CdfsDateTimeToFileTime(Fcb,
- &Info->LastWriteTime);
- CdfsDateTimeToFileTime(Fcb,
- &Info->ChangeTime);
-
- /* Convert file flags */
- CdfsFileFlagsToAttributes(Fcb,
- &Info->FileAttributes);
-
- Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
-
- /* Make AllocSize a rounded up multiple of the sector size */
- Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
-
-// Info->FileIndex=;
- Info->EaSize = 0;
-
- if (DeviceExt->CdInfo.JolietLevel == 0)
- {
- /* Standard ISO-9660 format */
- Info->ShortNameLength = Length;
- memcpy(Info->ShortName, Fcb->ObjectName, Length);
- }
- else
- {
- /* Joliet extension */
-
- /* FIXME: Copy or create a short file name */
-
- Info->ShortName[0] = 0;
- Info->ShortNameLength = 0;
- }
-
- return(STATUS_SUCCESS);
-}
-#endif
+ Info->EaSize = 0;
+
+ Info->ShortName[0] = 0;
+ Info->ShortNameLength = 0;
+
+ return STATUS_SUCCESS;
+}
NTSTATUS
NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
{
PIRP Irp;
- //PDEVICE_OBJECT DeviceObject;
- //PDEVICE_EXTENSION DeviceExtension;
- //LONG BufferLength = 0;
+ PDEVICE_OBJECT DeviceObject;
+ PDEVICE_EXTENSION DeviceExtension;
+ LONG BufferLength = 0;
PUNICODE_STRING SearchPattern = NULL;
- //FILE_INFORMATION_CLASS FileInformationClass;
+ FILE_INFORMATION_CLASS FileInformationClass;
ULONG FileIndex = 0;
PUCHAR Buffer = NULL;
PFILE_NAMES_INFORMATION Buffer0 = NULL;
- //PNTFS_FCB Fcb;
+ PNTFS_FCB Fcb;
PNTFS_CCB Ccb;
-// FCB TempFcb;
BOOLEAN First = FALSE;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
- //NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PFILE_RECORD_HEADER FileRecord;
+ PNTFS_ATTR_CONTEXT DataContext;
+ ULONGLONG MFTRecord;
+ UNICODE_STRING Pattern;
DPRINT1("NtfsQueryDirectory() called\n");
ASSERT(IrpContext);
Irp = IrpContext->Irp;
-// DeviceObject = IrpContext->DeviceObject;
-
-// DeviceExtension = DeviceObject->DeviceExtension;
+ DeviceObject = IrpContext->DeviceObject;
+
+ DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
Ccb = (PNTFS_CCB)FileObject->FsContext2;
-// Fcb = (PNTFS_FCB)FileObject->FsContext;
+ Fcb = (PNTFS_FCB)FileObject->FsContext;
/* Obtain the callers parameters */
- //BufferLength = Stack->Parameters.QueryDirectory.Length;
+ BufferLength = Stack->Parameters.QueryDirectory.Length;
SearchPattern = Stack->Parameters.QueryDirectory.FileName;
- //FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
+ FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
-
if (SearchPattern != NULL)
{
@@ -546,7 +355,10 @@
Ccb->DirectorySearchPattern[1] = 0;
}
- DPRINT("Search pattern '%S'\n", Ccb->DirectorySearchPattern);
+ RtlInitUnicodeString(&Pattern, Ccb->DirectorySearchPattern);
+
+ DPRINT1("Search pattern '%S'\n", Ccb->DirectorySearchPattern);
+ DPRINT1("In: '%S'\n", Fcb->PathName);
/* Determine directory index */
if (Stack->Flags & SL_INDEX_SPECIFIED)
@@ -570,93 +382,96 @@
DPRINT("Buffer=%p tofind=%S\n", Buffer, Ccb->DirectorySearchPattern);
-#if 0
- TempFcb.ObjectName = TempFcb.PathName;
- while (Status == STATUS_SUCCESS && BufferLength > 0)
- {
- Status = CdfsFindFile(DeviceExtension,
- &TempFcb,
- Fcb,
- Ccb->DirectorySearchPattern,
- &Ccb->Entry,
- NULL);
- DPRINT("Found %S, Status=%x, entry %x\n", TempFcb.ObjectName, Status,
Ccb->Entry);
-
- if (NT_SUCCESS(Status))
- {
- switch (FileInformationClass)
- {
- case FileNameInformation:
- Status = CdfsGetNameInformation(&TempFcb,
- DeviceExtension,
- (PFILE_NAMES_INFORMATION)Buffer,
- BufferLength);
- break;
-
- case FileDirectoryInformation:
- Status = CdfsGetDirectoryInformation(&TempFcb,
- DeviceExtension,
- (PFILE_DIRECTORY_INFORMATION)Buffer,
- BufferLength);
- break;
-
- case FileFullDirectoryInformation:
- Status = CdfsGetFullDirectoryInformation(&TempFcb,
- DeviceExtension,
- (PFILE_FULL_DIRECTORY_INFORMATION)Buffer,
- BufferLength);
- break;
-
- case FileBothDirectoryInformation:
- Status = NtfsGetBothDirectoryInformation(&TempFcb,
- DeviceExtension,
- (PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,
- BufferLength);
- break;
-
- default:
- Status = STATUS_INVALID_INFO_CLASS;
- }
-
- if (Status == STATUS_BUFFER_OVERFLOW)
- {
- if (Buffer0)
- {
- Buffer0->NextEntryOffset = 0;
- }
- break;
- }
- }
- else
- {
- if (Buffer0)
- {
- Buffer0->NextEntryOffset = 0;
- }
-
- if (First)
- {
- Status = STATUS_NO_SUCH_FILE;
- }
- else
- {
- Status = STATUS_NO_MORE_FILES;
- }
- break;
- }
-
- Buffer0 = (PFILE_NAMES_INFORMATION)Buffer;
- Buffer0->FileIndex = FileIndex++;
- Ccb->Entry++;
-
- if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
- {
- break;
- }
- BufferLength -= Buffer0->NextEntryOffset;
- Buffer += Buffer0->NextEntryOffset;
- }
-#endif
+ while (Status == STATUS_SUCCESS && BufferLength > 0)
+ {
+ Status = NtfsFindFileAt(DeviceExtension,
+ &Pattern,
+ &Ccb->Entry,
+ &FileRecord,
+ &DataContext,
+ &MFTRecord,
+ Fcb->MFTIndex);
+ //DPRINT("Found %S, Status=%x, entry %x\n", TempFcb.ObjectName, Status,
Ccb->Entry);
+
+ if (NT_SUCCESS(Status))
+ {
+ switch (FileInformationClass)
+ {
+ case FileNameInformation:
+ Status = NtfsGetNameInformation(DeviceExtension,
+ FileRecord,
+ DataContext,
+ (PFILE_NAMES_INFORMATION)Buffer,
+ BufferLength);
+ break;
+
+ case FileDirectoryInformation:
+ Status = NtfsGetDirectoryInformation(DeviceExtension,
+ FileRecord,
+ DataContext,
+
(PFILE_DIRECTORY_INFORMATION)Buffer,
+ BufferLength);
+ break;
+
+ case FileFullDirectoryInformation:
+ Status = NtfsGetFullDirectoryInformation(DeviceExtension,
+ FileRecord,
+ DataContext,
+
(PFILE_FULL_DIRECTORY_INFORMATION)Buffer,
+ BufferLength);
+ break;
+
+ case FileBothDirectoryInformation:
+ Status = NtfsGetBothDirectoryInformation(DeviceExtension,
+ FileRecord,
+ DataContext,
+
(PFILE_BOTH_DIR_INFORMATION)Buffer,
+ BufferLength);
+ break;
+
+ default:
+ Status = STATUS_INVALID_INFO_CLASS;
+ }
+
+ if (Status == STATUS_BUFFER_OVERFLOW)
+ {
+ if (Buffer0)
+ {
+ Buffer0->NextEntryOffset = 0;
+ }
+ break;
+ }
+ }
+ else
+ {
+ if (Buffer0)
+ {
+ Buffer0->NextEntryOffset = 0;
+ }
+
+ if (First)
+ {
+ Status = STATUS_NO_SUCH_FILE;
+ }
+ else
+ {
+ Status = STATUS_NO_MORE_FILES;
+ }
+ break;
+ }
+
+ Buffer0 = (PFILE_NAMES_INFORMATION)Buffer;
+ Buffer0->FileIndex = FileIndex++;
+ Ccb->Entry++;
+
+ if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
+ {
+ break;
+ }
+ BufferLength -= Buffer0->NextEntryOffset;
+ Buffer += Buffer0->NextEntryOffset;
+ ExFreePoolWithTag(FileRecord, TAG_NTFS);
+ }
if (Buffer0)
{
@@ -665,11 +480,10 @@
if (FileIndex > 0)
{
- //Status = STATUS_SUCCESS;
- }
-
-// return Status;
- return STATUS_NO_MORE_FILES;
+ Status = STATUS_SUCCESS;
+ }
+
+ return Status;
}