Fixed a bug in DoQuery with empty serach pattern strings after the first call to DoQuery.

svn path=/trunk/; revision=2605
This commit is contained in:
Hartmut Birr 2002-02-05 21:31:03 +00:00
parent 48fa361844
commit b95ed3ddf1
2 changed files with 110 additions and 87 deletions

View file

@ -1,5 +1,5 @@
/* /*
* $Id: dir.c,v 1.22 2002/02/02 14:04:55 hbirr Exp $ * $Id: dir.c,v 1.23 2002/02/05 21:31:03 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -234,8 +234,7 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
PVFATFCB pFcb; PVFATFCB pFcb;
VFATFCB tmpFcb; VFATFCB tmpFcb;
PVFATCCB pCcb; PVFATCCB pCcb;
WCHAR pCharPattern[MAX_PATH]; BOOLEAN First = FALSE;
unsigned long OldEntry, OldSector;
pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2; pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2;
pFcb = pCcb->pFcb; pFcb = pCcb->pFcb;
@ -251,100 +250,125 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
FileInformationClass = FileInformationClass =
IrpContext->Stack->Parameters.QueryDirectory.FileInformationClass; IrpContext->Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = IrpContext->Stack->Parameters.QueryDirectory.FileIndex; FileIndex = IrpContext->Stack->Parameters.QueryDirectory.FileIndex;
if (IrpContext->Stack->Flags & SL_RESTART_SCAN) if (pSearchPattern)
{ //FIXME : what is really use of RestartScan ? {
pCcb->StartEntry = pCcb->StartSector = 0; if (!pCcb->DirectorySearchPattern)
{
First = TRUE;
pCcb->DirectorySearchPattern =
ExAllocatePool(NonPagedPool, pSearchPattern->Length + sizeof(WCHAR));
if (!pCcb->DirectorySearchPattern)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
memcpy(pCcb->DirectorySearchPattern, pSearchPattern->Buffer,
pSearchPattern->Length);
pCcb->DirectorySearchPattern[pSearchPattern->Length / sizeof(WCHAR)] = 0;
}
}
else if (!pCcb->DirectorySearchPattern)
{
First = TRUE;
pCcb->DirectorySearchPattern = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
if (!pCcb->DirectorySearchPattern)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
pCcb->DirectorySearchPattern[0] = L'*';
pCcb->DirectorySearchPattern[1] = 0;
}
if (IrpContext->Stack->Flags & SL_INDEX_SPECIFIED)
{
pCcb->Entry = pCcb->CurrentByteOffset.u.LowPart;
}
else if (First || (IrpContext->Stack->Flags & SL_RESTART_SCAN))
{
pCcb->Entry = 0;
} }
// determine Buffer for result : // determine Buffer for result :
if (IrpContext->Irp->MdlAddress) if (IrpContext->Irp->MdlAddress)
{
Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress); Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress);
}
else else
{
Buffer = IrpContext->Irp->UserBuffer; Buffer = IrpContext->Irp->UserBuffer;
DPRINT ("Buffer=%x tofind=%S\n", Buffer, pSearchPattern->Buffer);
if (pSearchPattern == NULL)
{
pCharPattern[0] = L'*';
pCharPattern[1] = 0;
}
else
{
memcpy (pCharPattern, pSearchPattern->Buffer, pSearchPattern->Length);
pCharPattern[pSearchPattern->Length / sizeof(WCHAR)] = 0;
} }
DPRINT ("Buffer=%x tofind=%S\n", Buffer, pCcb->DirectorySearchPattern);
tmpFcb.ObjectName = tmpFcb.PathName; tmpFcb.ObjectName = tmpFcb.PathName;
while (RC == STATUS_SUCCESS && BufferLength > 0) while (RC == STATUS_SUCCESS && BufferLength > 0)
{ {
OldSector = pCcb->StartSector; RC = FindFile (IrpContext->DeviceExt, &tmpFcb, pFcb,
OldEntry = pCcb->StartEntry; pCcb->DirectorySearchPattern, &pCcb->Entry, NULL);
if (OldSector) DPRINT ("Found %S, RC=%x, entry %x\n", tmpFcb.ObjectName, RC, pCcb->Entry);
pCcb->StartEntry++;
RC =
FindFile (IrpContext->DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL);
pCcb->StartSector = 1;
DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC,
pCcb->StartSector, pCcb->StartEntry);
if (NT_SUCCESS (RC)) if (NT_SUCCESS (RC))
{ {
switch (FileInformationClass) switch (FileInformationClass)
{ {
case FileNameInformation: case FileNameInformation:
RC = RC = VfatGetFileNameInformation (&tmpFcb,
VfatGetFileNameInformation (&tmpFcb, (PFILE_NAMES_INFORMATION) Buffer, BufferLength);
(PFILE_NAMES_INFORMATION) Buffer,
BufferLength);
break; break;
case FileDirectoryInformation: case FileDirectoryInformation:
RC = RC = VfatGetFileDirectoryInformation (&tmpFcb, IrpContext->DeviceExt,
VfatGetFileDirectoryInformation (&tmpFcb, IrpContext->DeviceExt, (PFILE_DIRECTORY_INFORMATION) Buffer, BufferLength);
(PFILE_DIRECTORY_INFORMATION)
Buffer, BufferLength);
break; break;
case FileFullDirectoryInformation: case FileFullDirectoryInformation:
RC = RC = VfatGetFileFullDirectoryInformation (&tmpFcb, IrpContext->DeviceExt,
VfatGetFileFullDirectoryInformation (&tmpFcb, IrpContext->DeviceExt, (PFILE_FULL_DIRECTORY_INFORMATION) Buffer, BufferLength);
(PFILE_FULL_DIRECTORY_INFORMATION)
Buffer, BufferLength);
break; break;
case FileBothDirectoryInformation: case FileBothDirectoryInformation:
RC = RC = VfatGetFileBothInformation (&tmpFcb, IrpContext->DeviceExt,
VfatGetFileBothInformation (&tmpFcb, IrpContext->DeviceExt, (PFILE_BOTH_DIRECTORY_INFORMATION) Buffer, BufferLength);
(PFILE_BOTH_DIRECTORY_INFORMATION)
Buffer, BufferLength);
break; break;
default: default:
RC = STATUS_INVALID_INFO_CLASS; RC = STATUS_INVALID_INFO_CLASS;
} }
}
else
{
if (Buffer0)
Buffer0->NextEntryOffset = 0;
if (OldSector)
RC = STATUS_NO_MORE_FILES;
else
RC = STATUS_NO_SUCH_FILE;
break;
}
if (RC == STATUS_BUFFER_OVERFLOW) if (RC == STATUS_BUFFER_OVERFLOW)
{ {
if (Buffer0) if (Buffer0)
{
Buffer0->NextEntryOffset = 0; Buffer0->NextEntryOffset = 0;
pCcb->StartSector = OldSector; }
pCcb->StartEntry = OldEntry; break;
}
}
else
{
if (Buffer0)
{
Buffer0->NextEntryOffset = 0;
}
if (First)
{
RC = STATUS_NO_SUCH_FILE;
}
else
{
RC = STATUS_NO_MORE_FILES;
}
break; break;
} }
Buffer0 = (PFILE_NAMES_INFORMATION) Buffer; Buffer0 = (PFILE_NAMES_INFORMATION) Buffer;
Buffer0->FileIndex = FileIndex++; Buffer0->FileIndex = FileIndex++;
pCcb->Entry++;
if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY) if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY)
{
break; break;
}
BufferLength -= Buffer0->NextEntryOffset; BufferLength -= Buffer0->NextEntryOffset;
Buffer += Buffer0->NextEntryOffset; Buffer += Buffer0->NextEntryOffset;
} }
if (Buffer0) if (Buffer0)
{
Buffer0->NextEntryOffset = 0; Buffer0->NextEntryOffset = 0;
}
if (FileIndex > 0) if (FileIndex > 0)
{
RC = STATUS_SUCCESS; RC = STATUS_SUCCESS;
}
if (IrpContext->Flags & IRPCONTEXT_CANWAIT) if (IrpContext->Flags & IRPCONTEXT_CANWAIT)
{ {
ExReleaseResourceLite(&pFcb->MainResource); ExReleaseResourceLite(&pFcb->MainResource);

View file

@ -1,4 +1,4 @@
/* $Id: vfat.h,v 1.38 2002/01/08 00:49:01 dwelch Exp $ */ /* $Id: vfat.h,v 1.39 2002/02/05 21:31:03 hbirr Exp $ */
#include <ddk/ntifs.h> #include <ddk/ntifs.h>
@ -150,10 +150,9 @@ typedef struct _VFATCCB
PFILE_OBJECT PtrFileObject; PFILE_OBJECT PtrFileObject;
LARGE_INTEGER CurrentByteOffset; LARGE_INTEGER CurrentByteOffset;
/* for DirectoryControl */ /* for DirectoryControl */
ULONG StartSector; ULONG Entry;
/* for DirectoryControl */ /* for DirectoryControl */
ULONG StartEntry; PWCHAR DirectorySearchPattern;
// PSTRING DirectorySearchPattern;// for DirectoryControl ?
ULONG LastCluster; ULONG LastCluster;
ULONG LastOffset; ULONG LastOffset;