mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Fixed some problems which occurs if a directory goes over the sector (2048 byte) boundary.
Save the current directory offset in the ccb for increasing the speed for countinous directory queries. svn path=/trunk/; revision=3493
This commit is contained in:
parent
eec75375c4
commit
5c88f1916c
2 changed files with 86 additions and 56 deletions
|
@ -196,6 +196,7 @@ typedef struct _CCB
|
||||||
LARGE_INTEGER CurrentByteOffset;
|
LARGE_INTEGER CurrentByteOffset;
|
||||||
/* for DirectoryControl */
|
/* for DirectoryControl */
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
|
ULONG Offset;
|
||||||
/* for DirectoryControl */
|
/* for DirectoryControl */
|
||||||
PWCHAR DirectorySearchPattern;
|
PWCHAR DirectorySearchPattern;
|
||||||
ULONG LastCluster;
|
ULONG LastCluster;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: dirctl.c,v 1.9 2002/09/08 10:22:08 chorns Exp $
|
/* $Id: dirctl.c,v 1.10 2002/09/13 18:51:01 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -36,6 +36,9 @@
|
||||||
|
|
||||||
#include "cdfs.h"
|
#include "cdfs.h"
|
||||||
|
|
||||||
|
/* DEFINES ******************************************************************/
|
||||||
|
|
||||||
|
#define ROUND_DOWN(N, S) (((N) / (S)) * (S))
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
@ -48,51 +51,73 @@ CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt,
|
||||||
PVOID *Ptr,
|
PVOID *Ptr,
|
||||||
PWSTR Name,
|
PWSTR Name,
|
||||||
PULONG pIndex,
|
PULONG pIndex,
|
||||||
PULONG pIndex2)
|
PULONG CurrentOffset)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieves the file name, be it in short or long file name format
|
* FUNCTION: Retrieves the file name, be it in short or long file name format
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PDIR_RECORD Record;
|
PDIR_RECORD Record;
|
||||||
NTSTATUS Status;
|
Record = *Ptr;
|
||||||
ULONG Index = 0;
|
ULONG Index;
|
||||||
ULONG Offset = 0;
|
|
||||||
ULONG BlockOffset = 0;
|
|
||||||
|
|
||||||
Record = (PDIR_RECORD)*Block;
|
if (*CurrentOffset >= DirLength)
|
||||||
while(Index < *pIndex)
|
return(STATUS_NO_MORE_ENTRIES);
|
||||||
{
|
|
||||||
BlockOffset += Record->RecordLength;
|
|
||||||
Offset += Record->RecordLength;
|
|
||||||
|
|
||||||
Record = (PDIR_RECORD)(*Block + BlockOffset);
|
if (*CurrentOffset == 0)
|
||||||
if (BlockOffset >= BLOCKSIZE || Record->RecordLength == 0)
|
{
|
||||||
{
|
Index = 0;
|
||||||
|
Record = (PDIR_RECORD)*Block;
|
||||||
|
while (Index < *pIndex)
|
||||||
|
{
|
||||||
|
(*Ptr) += Record->RecordLength;
|
||||||
|
(*CurrentOffset) += Record->RecordLength;
|
||||||
|
Record = *Ptr;
|
||||||
|
if (*Ptr - *Block >= BLOCKSIZE || Record->RecordLength == 0)
|
||||||
|
{
|
||||||
DPRINT("Map next sector\n");
|
DPRINT("Map next sector\n");
|
||||||
CcUnpinData(*Context);
|
CcUnpinData(*Context);
|
||||||
StreamOffset->QuadPart += BLOCKSIZE;
|
StreamOffset->QuadPart += BLOCKSIZE;
|
||||||
Offset = ROUND_UP(Offset, BLOCKSIZE);
|
*CurrentOffset = ROUND_UP(*CurrentOffset, BLOCKSIZE);
|
||||||
BlockOffset = 0;
|
|
||||||
|
|
||||||
if (!CcMapData(DeviceExt->StreamFileObject,
|
if (!CcMapData(DeviceExt->StreamFileObject,
|
||||||
StreamOffset,
|
StreamOffset,
|
||||||
BLOCKSIZE, TRUE,
|
BLOCKSIZE, TRUE,
|
||||||
Context, Block))
|
Context, Block))
|
||||||
{
|
{
|
||||||
DPRINT("CcMapData() failed\n");
|
DPRINT("CcMapData() failed\n");
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
Record = (PDIR_RECORD)(*Block + BlockOffset);
|
*Ptr = *Block;
|
||||||
}
|
Record = (PDIR_RECORD)*Ptr;
|
||||||
|
}
|
||||||
|
if (*CurrentOffset >= DirLength)
|
||||||
|
return(STATUS_NO_MORE_ENTRIES);
|
||||||
|
|
||||||
if (Offset >= DirLength)
|
Index++;
|
||||||
return(STATUS_NO_MORE_ENTRIES);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Index++;
|
if (*Ptr - *Block >= BLOCKSIZE || Record->RecordLength == 0)
|
||||||
}
|
{
|
||||||
|
DPRINT("Map next sector\n");
|
||||||
|
CcUnpinData(*Context);
|
||||||
|
StreamOffset->QuadPart += BLOCKSIZE;
|
||||||
|
*CurrentOffset = ROUND_UP(*CurrentOffset, BLOCKSIZE);
|
||||||
|
if (!CcMapData(DeviceExt->StreamFileObject,
|
||||||
|
StreamOffset,
|
||||||
|
BLOCKSIZE, TRUE,
|
||||||
|
Context, Block))
|
||||||
|
{
|
||||||
|
DPRINT("CcMapData() failed\n");
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
*Ptr = *Block;
|
||||||
|
Record = (PDIR_RECORD)*Ptr;
|
||||||
|
}
|
||||||
|
if (*CurrentOffset >= DirLength)
|
||||||
|
return(STATUS_NO_MORE_ENTRIES);
|
||||||
|
|
||||||
DPRINT("Index %lu RecordLength %lu Offset %lu\n",
|
DPRINT("Index %lu RecordLength %lu Offset %lu\n",
|
||||||
Index, Record->RecordLength, Offset);
|
*pIndex, Record->RecordLength, *CurrentOffset);
|
||||||
|
|
||||||
if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
|
if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
|
||||||
{
|
{
|
||||||
|
@ -122,19 +147,16 @@ CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
*Ptr = Record;
|
*Ptr = Record;
|
||||||
|
|
||||||
*pIndex = Index;
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
PFCB Fcb,
|
PFCB Fcb,
|
||||||
PFCB Parent,
|
PFCB Parent,
|
||||||
PWSTR FileToFind,
|
PWSTR FileToFind,
|
||||||
PULONG pDirIndex,
|
PULONG pDirIndex,
|
||||||
PULONG pDirIndex2)
|
PULONG pOffset)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Find a file
|
* FUNCTION: Find a file
|
||||||
*/
|
*/
|
||||||
|
@ -148,12 +170,11 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG len;
|
ULONG len;
|
||||||
ULONG DirIndex;
|
ULONG DirIndex;
|
||||||
ULONG Offset;
|
ULONG Offset = 0;
|
||||||
ULONG Read;
|
ULONG Read;
|
||||||
BOOLEAN IsRoot;
|
BOOLEAN IsRoot;
|
||||||
PVOID Context = NULL;
|
PVOID Context = NULL;
|
||||||
ULONG DirSize;
|
ULONG DirSize;
|
||||||
PUCHAR Ptr;
|
|
||||||
PDIR_RECORD Record;
|
PDIR_RECORD Record;
|
||||||
LARGE_INTEGER StreamOffset;
|
LARGE_INTEGER StreamOffset;
|
||||||
BOOLEAN HasSpaces;
|
BOOLEAN HasSpaces;
|
||||||
|
@ -206,8 +227,8 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
if (pDirIndex)
|
if (pDirIndex)
|
||||||
*pDirIndex = 0;
|
*pDirIndex = 0;
|
||||||
if (pDirIndex2)
|
if (pOffset)
|
||||||
*pDirIndex2 = 0;
|
*pOffset = 0;
|
||||||
DPRINT("CdfsFindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
|
DPRINT("CdfsFindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
|
||||||
return (STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -223,6 +244,12 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
if (pDirIndex && (*pDirIndex))
|
if (pDirIndex && (*pDirIndex))
|
||||||
DirIndex = *pDirIndex;
|
DirIndex = *pDirIndex;
|
||||||
|
|
||||||
|
if (pOffset && (*pOffset))
|
||||||
|
{
|
||||||
|
Offset = *pOffset;
|
||||||
|
StreamOffset.QuadPart += ROUND_DOWN(Offset, BLOCKSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
if(!CcMapData(DeviceExt->StreamFileObject, &StreamOffset,
|
if(!CcMapData(DeviceExt->StreamFileObject, &StreamOffset,
|
||||||
BLOCKSIZE, TRUE, &Context, &Block))
|
BLOCKSIZE, TRUE, &Context, &Block))
|
||||||
{
|
{
|
||||||
|
@ -230,21 +257,20 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr = (PUCHAR)Block;
|
Record = (PDIR_RECORD) (Block + Offset % BLOCKSIZE);
|
||||||
|
if (Offset)
|
||||||
|
{
|
||||||
|
Offset += Record->RecordLength;
|
||||||
|
Record = (PVOID)Record + Record->RecordLength;
|
||||||
|
}
|
||||||
while(TRUE)
|
while(TRUE)
|
||||||
{
|
{
|
||||||
Record = (PDIR_RECORD)Ptr;
|
|
||||||
if (Record->RecordLength == 0)
|
|
||||||
{
|
|
||||||
DPRINT1("Stopped!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("RecordLength %u ExtAttrRecordLength %u NameLength %u\n",
|
DPRINT("RecordLength %u ExtAttrRecordLength %u NameLength %u\n",
|
||||||
Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);
|
Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);
|
||||||
|
|
||||||
Status = CdfsGetEntryName(DeviceExt, &Context, &Block, &StreamOffset,
|
Status = CdfsGetEntryName(DeviceExt, &Context, &Block, &StreamOffset,
|
||||||
DirSize, (PVOID*)&Ptr, name, &DirIndex, pDirIndex2);
|
DirSize, (PVOID*)&Record, name, &DirIndex, &Offset);
|
||||||
|
|
||||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -304,7 +330,7 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
DPRINT("PathName '%S' ObjectName '%S'\n", Fcb->PathName, Fcb->ObjectName);
|
DPRINT("PathName '%S' ObjectName '%S'\n", Fcb->PathName, Fcb->ObjectName);
|
||||||
|
|
||||||
memcpy(&Fcb->Entry, Ptr, sizeof(DIR_RECORD));
|
memcpy(&Fcb->Entry, Record, sizeof(DIR_RECORD));
|
||||||
wcsncpy(Fcb->ObjectName, name, MAX_PATH);
|
wcsncpy(Fcb->ObjectName, name, MAX_PATH);
|
||||||
|
|
||||||
/* Copy short name */
|
/* Copy short name */
|
||||||
|
@ -313,6 +339,8 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
if (pDirIndex)
|
if (pDirIndex)
|
||||||
*pDirIndex = DirIndex;
|
*pDirIndex = DirIndex;
|
||||||
|
if (pOffset)
|
||||||
|
*pOffset = Offset;
|
||||||
|
|
||||||
DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",
|
DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",
|
||||||
Fcb->PathName, Fcb->ObjectName, DirIndex);
|
Fcb->PathName, Fcb->ObjectName, DirIndex);
|
||||||
|
@ -323,14 +351,10 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ptr = Ptr + Record->RecordLength;
|
Offset += Record->RecordLength;
|
||||||
|
Record = (PVOID)Record + Record->RecordLength;
|
||||||
DirIndex++;
|
DirIndex++;
|
||||||
|
|
||||||
if (((ULONG)Ptr - (ULONG)Block) >= DirSize)
|
|
||||||
{
|
|
||||||
DPRINT("Stopped!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CcUnpinData(Context);
|
CcUnpinData(Context);
|
||||||
|
@ -338,6 +362,9 @@ CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||||
if (pDirIndex)
|
if (pDirIndex)
|
||||||
*pDirIndex = DirIndex;
|
*pDirIndex = DirIndex;
|
||||||
|
|
||||||
|
if (pOffset)
|
||||||
|
*pOffset = Offset;
|
||||||
|
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,10 +601,12 @@ CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject,
|
||||||
if (Stack->Flags & SL_INDEX_SPECIFIED)
|
if (Stack->Flags & SL_INDEX_SPECIFIED)
|
||||||
{
|
{
|
||||||
Ccb->Entry = Ccb->CurrentByteOffset.u.LowPart;
|
Ccb->Entry = Ccb->CurrentByteOffset.u.LowPart;
|
||||||
|
Ccb->Offset = 0;
|
||||||
}
|
}
|
||||||
else if (First || (Stack->Flags & SL_RESTART_SCAN))
|
else if (First || (Stack->Flags & SL_RESTART_SCAN))
|
||||||
{
|
{
|
||||||
Ccb->Entry = 0;
|
Ccb->Entry = 0;
|
||||||
|
Ccb->Offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine Buffer for result */
|
/* Determine Buffer for result */
|
||||||
|
@ -599,7 +628,7 @@ CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject,
|
||||||
Fcb,
|
Fcb,
|
||||||
Ccb->DirectorySearchPattern,
|
Ccb->DirectorySearchPattern,
|
||||||
&Ccb->Entry,
|
&Ccb->Entry,
|
||||||
NULL);
|
&Ccb->Offset);
|
||||||
DPRINT("Found %S, Status=%x, entry %x\n", TempFcb.ObjectName, Status, Ccb->Entry);
|
DPRINT("Found %S, Status=%x, entry %x\n", TempFcb.ObjectName, Status, Ccb->Entry);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
|
|
Loading…
Reference in a new issue