- Used the parent fcb instead to determine it from parent fileobject.

svn path=/trunk/; revision=12687
This commit is contained in:
Hartmut Birr 2005-01-01 11:11:52 +00:00
parent 635e37f654
commit 37d9e18817
5 changed files with 196 additions and 199 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: create.c,v 1.78 2004/12/25 11:18:38 navaraf Exp $
/* $Id$
*
* PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/create.c
@ -314,45 +314,29 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
}
NTSTATUS
VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PUNICODE_STRING FileNameU)
VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PVFATFCB* ParentFcb)
/*
* FUNCTION: Opens a file
*/
{
PVFATFCB ParentFcb;
PVFATFCB Fcb;
NTSTATUS Status;
UNICODE_STRING PathNameU;
WCHAR Buffer[260];
// PDEVICE_OBJECT DeviceObject = DeviceExt->StorageDevice->Vpb->DeviceObject;
DPRINT ("VfatOpenFile(%08lx, %08lx, '%wZ')\n", DeviceExt, FileObject, &FileObject->FileName);
if (FileObject->RelatedFileObject)
{
DPRINT ("Converting relative filename to absolute filename\n");
DPRINT ("'%wZ'\n", &FileObject->RelatedFileObject->FileName);
Fcb = FileObject->RelatedFileObject->FsContext;
RtlCopyUnicodeString(FileNameU, &Fcb->PathNameU);
if (!vfatFCBIsRoot(Fcb))
{
RtlAppendUnicodeToString(FileNameU, L"\\");
}
RtlAppendUnicodeStringToString(FileNameU, &FileObject->FileName);
*ParentFcb = FileObject->RelatedFileObject->FsContext;
(*ParentFcb)->RefCount++;
}
else
{
RtlCopyUnicodeString(FileNameU, &FileObject->FileName);
*ParentFcb = NULL;
}
if (FileNameU->Length > sizeof(WCHAR) &&
FileNameU->Buffer[FileNameU->Length / sizeof(WCHAR) - 1] == L'\\')
{
FileNameU->Length -= sizeof(WCHAR);
}
FileNameU->Buffer[FileNameU->Length / sizeof(WCHAR)] = 0;
DPRINT ("PathName to open: '%wZ'\n", FileNameU);
if (!DeviceExt->FatInfo.FixedMedia)
{
@ -382,40 +366,47 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
if (!NT_SUCCESS(Status))
{
DPRINT ("Status %lx\n", Status);
*ParentFcb = NULL;
return Status;
}
}
if (*ParentFcb)
{
(*ParentFcb)->RefCount++;
}
PathNameU.Buffer = Buffer;
PathNameU.Length = 0;
PathNameU.MaximumLength = sizeof(Buffer);
RtlCopyUnicodeString(&PathNameU, &FileObject->FileName);
if (PathNameU.Length > sizeof(WCHAR) &&
PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR) - 1] == L'\\')
{
PathNameU.Length -= sizeof(WCHAR);
}
PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
/* try first to find an existing FCB in memory */
DPRINT ("Checking for existing FCB in memory\n");
Fcb = vfatGrabFCBFromTable (DeviceExt, FileNameU);
if (Fcb == NULL)
{
DPRINT ("No existing FCB found, making a new one if file exists.\n");
Status = vfatGetFCBForFile (DeviceExt, &ParentFcb, &Fcb, FileNameU);
if (ParentFcb != NULL)
{
vfatReleaseFCB (DeviceExt, ParentFcb);
}
if (!NT_SUCCESS (Status))
{
DPRINT ("Could not make a new FCB, status: %x\n", Status);
return Status;
}
}
else
{
RtlCopyUnicodeString(FileNameU, &Fcb->PathNameU);
}
Status = vfatGetFCBForFile (DeviceExt, ParentFcb, &Fcb, &PathNameU);
if (!NT_SUCCESS (Status))
{
DPRINT ("Could not make a new FCB, status: %x\n", Status);
return Status;
}
if (Fcb->Flags & FCB_DELETE_PENDING)
{
vfatReleaseFCB (DeviceExt, Fcb);
return STATUS_DELETE_PENDING;
}
{
vfatReleaseFCB (DeviceExt, Fcb);
return STATUS_DELETE_PENDING;
}
DPRINT ("Attaching FCB to fileObject\n");
Status = vfatAttachFCBToFileObject (DeviceExt, Fcb, FileObject);
if (!NT_SUCCESS(Status))
{
vfatReleaseFCB (DeviceExt, Fcb);
}
return Status;
}
@ -481,12 +472,12 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
ULONG RequestedDisposition, RequestedOptions;
PVFATCCB pCcb;
PVFATFCB pFcb;
PVFATFCB ParentFcb;
PWCHAR c, last;
BOOLEAN PagingFileCreate = FALSE;
LARGE_INTEGER AllocationSize;
BOOLEAN Dots;
UNICODE_STRING NameU;
WCHAR NameW[MAX_PATH];
UNICODE_STRING FileNameU;
/* Unpack the various parameters. */
Stack = IoGetCurrentIrpStackLocation (Irp);
@ -563,12 +554,8 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
}
NameU.Buffer = NameW;
NameU.Length = 0;
NameU.MaximumLength = sizeof(NameW);
/* Try opening the file. */
Status = VfatOpenFile (DeviceExt, FileObject, &NameU);
Status = VfatOpenFile (DeviceExt, FileObject, &ParentFcb);
/*
* If the directory containing the file to open doesn't exist then
@ -578,6 +565,10 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
Status == STATUS_INVALID_PARAMETER ||
Status == STATUS_DELETE_PENDING)
{
if (ParentFcb)
{
vfatReleaseFCB (DeviceExt, ParentFcb);
}
return(Status);
}
@ -593,12 +584,15 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
ULONG Attributes;
Attributes = Stack->Parameters.Create.FileAttributes;
Status = VfatAddEntry (DeviceExt, &NameU, FileObject, RequestedOptions,
vfatSplitPathName(&FileObject->FileName, NULL, &FileNameU);
Status = VfatAddEntry (DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions,
(UCHAR)(Attributes & FILE_ATTRIBUTE_VALID_FLAGS));
vfatReleaseFCB (DeviceExt, ParentFcb);
if (NT_SUCCESS (Status))
{
pFcb = FileObject->FsContext;
vfatAttachFCBToFileObject (DeviceExt, pFcb, FileObject);
Irp->IoStatus.Information = FILE_CREATED;
VfatSetAllocationSizeInformation(FileObject,
@ -621,11 +615,16 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
else
{
vfatReleaseFCB (DeviceExt, ParentFcb);
return(Status);
}
}
else
{
if (ParentFcb)
{
vfatReleaseFCB (DeviceExt, ParentFcb);
}
/* Otherwise fail if the caller wanted to create a new file */
if (RequestedDisposition == FILE_CREATE)
{

View file

@ -1,4 +1,4 @@
/* $Id: dirwr.c,v 1.44 2004/12/25 11:18:38 navaraf Exp $
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -183,10 +183,11 @@ vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt,
NTSTATUS
FATAddEntry (PDEVICE_EXTENSION DeviceExt,
PUNICODE_STRING PathNameU,
PFILE_OBJECT pFileObject,
ULONG RequestedOptions,
UCHAR ReqAttr)
PUNICODE_STRING NameU,
PVFATFCB* Fcb,
PVFATFCB ParentFcb,
ULONG RequestedOptions,
UCHAR ReqAttr)
/*
create a new FAT entry
*/
@ -198,11 +199,9 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
PUCHAR Buffer;
BOOLEAN needTilde = FALSE, needLong = FALSE;
BOOLEAN lCaseBase = FALSE, uCaseBase, lCaseExt = FALSE, uCaseExt;
PVFATFCB newFCB;
ULONG CurrentCluster;
LARGE_INTEGER SystemTime, FileOffset;
NTSTATUS Status = STATUS_SUCCESS;
PVFATFCB pDirFcb;
ULONG size;
long i;
@ -212,33 +211,20 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
BOOLEAN SpacesFound;
VFAT_DIRENTRY_CONTEXT DirContext;
UNICODE_STRING DirNameU;
WCHAR LongNameBuffer[MAX_PATH];
WCHAR ShortNameBuffer[13];
DPRINT ("addEntry: Pathname='%wZ'\n", PathNameU);
DPRINT ("addEntry: Name='%wZ', Dir='%wZ'\n", NameU, &ParentFcb->PathNameU);
vfatSplitPathName(PathNameU, &DirNameU, &DirContext.LongNameU);
if (DirNameU.Length > sizeof(WCHAR))
{
DirNameU.Length -= sizeof(WCHAR);
}
pDirFcb = vfatGrabFCBFromTable(DeviceExt, &DirNameU);
if (pDirFcb == NULL)
{
return STATUS_UNSUCCESSFUL;
}
if (!ExAcquireResourceExclusiveLite(&pDirFcb->MainResource, TRUE))
{
DPRINT("Failed acquiring lock\n");
return STATUS_UNSUCCESSFUL;
}
DirContext.LongNameU = *NameU;
nbSlots = (DirContext.LongNameU.Length / sizeof(WCHAR) + 12) / 13 + 1; //nb of entry needed for long name+normal entry
DPRINT ("NameLen= %d, nbSlots =%d\n", DirContext.LongNameU.Length / sizeof(WCHAR), nbSlots);
Buffer = ExAllocatePool (NonPagedPool, (nbSlots - 1) * sizeof (FAT_DIR_ENTRY));
if (Buffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory (Buffer, (nbSlots - 1) * sizeof (FAT_DIR_ENTRY));
pSlots = (slot *) Buffer;
@ -254,7 +240,7 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.LongNameU, &NameA, &SpacesFound);
if (IsNameLegal == FALSE || SpacesFound != FALSE)
if (!IsNameLegal || SpacesFound)
{
GENERATE_NAME_CONTEXT NameContext;
VFAT_DIRENTRY_CONTEXT SearchContext;
@ -272,7 +258,7 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
RtlGenerate8dot3Name(&DirContext.LongNameU, FALSE, &NameContext, &DirContext.ShortNameU);
DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0;
SearchContext.DirIndex = 0;
Status = FindFile (DeviceExt, pDirFcb, &DirContext.ShortNameU, &SearchContext, TRUE);
Status = FindFile (DeviceExt, ParentFcb, &DirContext.ShortNameU, &SearchContext, TRUE);
if (!NT_SUCCESS(Status))
{
break;
@ -280,8 +266,6 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
}
if (i == 100) /* FIXME : what to do after this ? */
{
ExReleaseResourceLite(&pDirFcb->MainResource);
vfatReleaseFCB(DeviceExt, pDirFcb);
ExFreePool (Buffer);
CHECKPOINT;
return STATUS_UNSUCCESSFUL;
@ -386,6 +370,16 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
}
/* set dates and times */
KeQuerySystemTime (&SystemTime);
#if 0
{
TIME_FIELDS tf;
RtlTimeToTimeFields (&SystemTime, &tf);
DPRINT1("%d.%d.%d %02d:%02d:%02d.%03d '%wZ'\n",
tf.Day, tf.Month, tf.Year, tf.Hour,
tf.Minute, tf.Second, tf.Milliseconds,
NameU);
}
#endif
FsdSystemTimeToDosDateTime (DeviceExt, &SystemTime, &DirContext.DirEntry.Fat.CreationDate,
&DirContext.DirEntry.Fat.CreationTime);
DirContext.DirEntry.Fat.UpdateDate = DirContext.DirEntry.Fat.CreationDate;
@ -421,10 +415,8 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
}
}
/* try to find nbSlots contiguous entries frees in directory */
if (!vfatFindDirSpace(DeviceExt, pDirFcb, nbSlots, &DirContext.StartIndex))
if (!vfatFindDirSpace(DeviceExt, ParentFcb, nbSlots, &DirContext.StartIndex))
{
ExReleaseResourceLite(&pDirFcb->MainResource);
vfatReleaseFCB(DeviceExt, pDirFcb);
ExFreePool (Buffer);
return STATUS_DISK_FULL;
}
@ -435,8 +427,6 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
Status = NextCluster (DeviceExt, 0, &CurrentCluster, TRUE);
if (CurrentCluster == 0xffffffff || !NT_SUCCESS(Status))
{
ExReleaseResourceLite(&pDirFcb->MainResource);
vfatReleaseFCB(DeviceExt, pDirFcb);
ExFreePool (Buffer);
if (!NT_SUCCESS(Status))
{
@ -458,7 +448,7 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
{
/* one cluster */
CHECKPOINT;
CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FAT_DIR_ENTRY),
CcMapData (ParentFcb->FileObject, &FileOffset, nbSlots * sizeof(FAT_DIR_ENTRY),
TRUE, &Context, (PVOID*)&pFatEntry);
if (nbSlots > 1)
{
@ -473,13 +463,13 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
size = DeviceExt->FatInfo.BytesPerCluster -
(DirContext.StartIndex * sizeof(FAT_DIR_ENTRY)) % DeviceExt->FatInfo.BytesPerCluster;
i = size / sizeof(FAT_DIR_ENTRY);
CcMapData (pDirFcb->FileObject, &FileOffset, size, TRUE,
CcMapData (ParentFcb->FileObject, &FileOffset, size, TRUE,
&Context, (PVOID*)&pFatEntry);
RtlCopyMemory(pFatEntry, Buffer, size);
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
FileOffset.u.LowPart += size;
CcMapData (pDirFcb->FileObject, &FileOffset,
CcMapData (ParentFcb->FileObject, &FileOffset,
nbSlots * sizeof(FAT_DIR_ENTRY) - size,
TRUE, &Context, (PVOID*)&pFatEntry);
if (nbSlots - 1 > i)
@ -492,16 +482,15 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
CcUnpinData(Context);
/* FIXME: check status */
vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, &DirContext, &newFCB);
vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
vfatMakeFCBFromDirEntry (DeviceExt, ParentFcb, &DirContext, Fcb);
DPRINT ("new : entry=%11.11s\n", newFCB->entry.Fat.Filename);
DPRINT ("new : entry=%11.11s\n", (*Fcb)->entry.Fat.Filename);
DPRINT ("new : entry=%11.11s\n", DirContext.DirEntry.Fat.Filename);
if (RequestedOptions & FILE_DIRECTORY_FILE)
{
FileOffset.QuadPart = 0;
CcMapData (pFileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster, TRUE,
CcMapData ((*Fcb)->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster, TRUE,
&Context, (PVOID*)&pFatEntry);
/* clear the new directory cluster */
RtlZeroMemory (pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
@ -510,9 +499,9 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
RtlCopyMemory (pFatEntry[0].Filename, ". ", 11);
RtlCopyMemory (&pFatEntry[1].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
RtlCopyMemory (pFatEntry[1].Filename, ".. ", 11);
pFatEntry[1].FirstCluster = pDirFcb->entry.Fat.FirstCluster;
pFatEntry[1].FirstClusterHigh = pDirFcb->entry.Fat.FirstClusterHigh;
if (vfatFCBIsRoot(pDirFcb))
pFatEntry[1].FirstCluster = ParentFcb->entry.Fat.FirstCluster;
pFatEntry[1].FirstClusterHigh = ParentFcb->entry.Fat.FirstClusterHigh;
if (vfatFCBIsRoot(ParentFcb))
{
pFatEntry[1].FirstCluster = 0;
pFatEntry[1].FirstClusterHigh = 0;
@ -520,8 +509,6 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
}
ExReleaseResourceLite(&pDirFcb->MainResource);
vfatReleaseFCB (DeviceExt, pDirFcb);
ExFreePool (Buffer);
DPRINT ("addentry ok\n");
return STATUS_SUCCESS;
@ -529,8 +516,9 @@ FATAddEntry (PDEVICE_EXTENSION DeviceExt,
NTSTATUS
FATXAddEntry (PDEVICE_EXTENSION DeviceExt,
PUNICODE_STRING PathNameU,
PFILE_OBJECT pFileObject,
PUNICODE_STRING NameU,
PVFATFCB* Fcb,
PVFATFCB ParentFcb,
ULONG RequestedOptions,
UCHAR ReqAttr)
/*
@ -538,21 +526,14 @@ FATXAddEntry (PDEVICE_EXTENSION DeviceExt,
*/
{
PVOID Context = NULL;
PVFATFCB newFCB;
LARGE_INTEGER SystemTime, FileOffset;
PVFATFCB pDirFcb;
OEM_STRING NameA;
VFAT_DIRENTRY_CONTEXT DirContext;
PFATX_DIR_ENTRY pFatXDirEntry;
UNICODE_STRING DirNameU;
DPRINT ("addEntry: Pathname='%wZ'\n", PathNameU);
DPRINT ("addEntry: Name='%wZ', Dir='%wZ'\n", NameU, &ParentFcb->PathNameU);
vfatSplitPathName(PathNameU, &DirNameU, &DirContext.LongNameU);
if (DirNameU.Length > sizeof(WCHAR))
{
DirNameU.Length -= sizeof(WCHAR);
}
DirContext.LongNameU = *NameU;
if (DirContext.LongNameU.Length / sizeof(WCHAR) > 42)
{
@ -561,27 +542,13 @@ FATXAddEntry (PDEVICE_EXTENSION DeviceExt,
return STATUS_NAME_TOO_LONG;
}
pDirFcb = vfatGrabFCBFromTable(DeviceExt, &DirNameU);
if (pDirFcb == NULL)
{
return STATUS_UNSUCCESSFUL;
}
if (!ExAcquireResourceExclusiveLite(&pDirFcb->MainResource, TRUE))
{
DPRINT("Failed acquiring lock\n");
return STATUS_UNSUCCESSFUL;
}
/* try to find 1 entry free in directory */
if (!vfatFindDirSpace(DeviceExt, pDirFcb, 1, &DirContext.StartIndex))
if (!vfatFindDirSpace(DeviceExt, ParentFcb, 1, &DirContext.StartIndex))
{
ExReleaseResourceLite(&pDirFcb->MainResource);
vfatReleaseFCB(DeviceExt, pDirFcb);
return STATUS_DISK_FULL;
}
DirContext.DirIndex = DirContext.StartIndex;
if (!vfatFCBIsRoot(pDirFcb))
if (!vfatFCBIsRoot(ParentFcb))
{
DirContext.DirIndex += 2;
}
@ -620,33 +587,31 @@ FATXAddEntry (PDEVICE_EXTENSION DeviceExt,
/* add entry into parent directory */
FileOffset.u.HighPart = 0;
FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FATX_DIR_ENTRY);
CcMapData(pDirFcb->FileObject, &FileOffset, sizeof(FATX_DIR_ENTRY),
TRUE, &Context, (PVOID*)&pFatXDirEntry);
CcMapData(ParentFcb->FileObject, &FileOffset, sizeof(FATX_DIR_ENTRY),
TRUE, &Context, (PVOID*)&pFatXDirEntry);
RtlCopyMemory(pFatXDirEntry, &DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
/* FIXME: check status */
vfatMakeFCBFromDirEntry(DeviceExt, pDirFcb, &DirContext, &newFCB);
vfatAttachFCBToFileObject(DeviceExt, newFCB, pFileObject);
vfatMakeFCBFromDirEntry(DeviceExt, ParentFcb, &DirContext, Fcb);
ExReleaseResourceLite(&pDirFcb->MainResource);
vfatReleaseFCB(DeviceExt, pDirFcb);
DPRINT("addentry ok\n");
return STATUS_SUCCESS;
}
NTSTATUS
VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
PUNICODE_STRING PathNameU,
PFILE_OBJECT pFileObject,
PUNICODE_STRING NameU,
PVFATFCB *Fcb,
PVFATFCB ParentFcb,
ULONG RequestedOptions,
UCHAR ReqAttr)
{
if (DeviceExt->Flags & VCB_IS_FATX)
return FATXAddEntry(DeviceExt, PathNameU, pFileObject, RequestedOptions, ReqAttr);
return FATXAddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr);
else
return FATAddEntry(DeviceExt, PathNameU, pFileObject, RequestedOptions, ReqAttr);
return FATAddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr);
}
NTSTATUS

View file

@ -1,4 +1,4 @@
/* $Id: fcb.c,v 1.43 2004/12/05 16:31:51 gvg Exp $
/* $Id$
*
*
* FILE: drivers/fs/vfat/fcb.c
@ -55,18 +55,25 @@ VOID
vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
{
PWCHAR pName;
DirNameU->Buffer = PathNameU->Buffer;
ULONG Length = 0;
pName = PathNameU->Buffer + PathNameU->Length / sizeof(WCHAR) - 1;
while (*pName != L'\\' && pName > PathNameU->Buffer)
while (*pName != L'\\' && pName >= PathNameU->Buffer)
{
pName--;
Length++;
}
ASSERT(*pName == L'\\' || pName < PathNameU->Buffer);
if (FileNameU)
{
FileNameU->Buffer = pName + 1;
FileNameU->Length = FileNameU->MaximumLength = Length * sizeof(WCHAR);
}
if (DirNameU)
{
DirNameU->Buffer = PathNameU->Buffer;
DirNameU->Length = (pName + 1 - PathNameU->Buffer) * sizeof(WCHAR);
DirNameU->MaximumLength = DirNameU->Length;
}
ASSERT(*pName == L'\\');
FileNameU->Buffer = pName + 1;
DirNameU->Length = (FileNameU->Buffer - PathNameU->Buffer) * sizeof(WCHAR);
DirNameU->MaximumLength = DirNameU->Length;
FileNameU->Length = PathNameU->Length - DirNameU->Length;
FileNameU->MaximumLength = FileNameU->Length;
}
VOID
@ -637,63 +644,85 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
pFCB,
pFileNameU);
RtlRosInitUnicodeStringFromLiteral(&RootNameU, L"\\");
parentFCB = *pParentFCB;
// Trivial case, open of the root directory on volume
if (RtlEqualUnicodeString(pFileNameU, &RootNameU, FALSE))
{
DPRINT ("returning root FCB\n");
if (parentFCB == NULL)
{
RtlRosInitUnicodeStringFromLiteral(&RootNameU, L"\\");
FCB = vfatOpenRootFCB (pVCB);
*pFCB = FCB;
*pParentFCB = NULL;
// Trivial case, open of the root directory on volume
if (RtlEqualUnicodeString(pFileNameU, &RootNameU, FALSE))
{
DPRINT ("returning root FCB\n");
return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND;
}
FCB = vfatOpenRootFCB (pVCB);
*pFCB = FCB;
*pParentFCB = NULL;
last = curr = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
while (*curr != L'\\' && curr > pFileNameU->Buffer)
{
curr--;
}
return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND;
}
/* Check for an existing FCB */
FCB = vfatGrabFCBFromTable (pVCB, pFileNameU);
if (FCB)
{
*pFCB = FCB;
*pParentFCB = FCB->parentFcb;
(*pParentFCB)->RefCount++;
return STATUS_SUCCESS;
}
last = curr = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
while (*curr != L'\\' && curr > pFileNameU->Buffer)
{
curr--;
}
if (curr > pFileNameU->Buffer)
{
NameU.Buffer = pFileNameU->Buffer;
NameU.MaximumLength = NameU.Length = (curr - pFileNameU->Buffer) * sizeof(WCHAR);
FCB = vfatGrabFCBFromTable(pVCB, &NameU);
if (FCB)
if (curr > pFileNameU->Buffer)
{
NameU.Buffer = pFileNameU->Buffer;
NameU.MaximumLength = NameU.Length = (curr - pFileNameU->Buffer) * sizeof(WCHAR);
FCB = vfatGrabFCBFromTable(pVCB, &NameU);
if (FCB)
{
Length = (curr - pFileNameU->Buffer) * sizeof(WCHAR);
if (Length != FCB->PathNameU.Length)
{
Length = (curr - pFileNameU->Buffer) * sizeof(WCHAR);
if (Length != FCB->PathNameU.Length)
{
if (pFileNameU->Length + FCB->PathNameU.Length - Length > pFileNameU->MaximumLength)
{
vfatReleaseFCB (pVCB, FCB);
return STATUS_OBJECT_NAME_INVALID;
}
{
vfatReleaseFCB (pVCB, FCB);
return STATUS_OBJECT_NAME_INVALID;
}
memmove(pFileNameU->Buffer + FCB->PathNameU.Length / sizeof(WCHAR),
curr, pFileNameU->Length - Length);
pFileNameU->Length += FCB->PathNameU.Length - Length;
curr = pFileNameU->Buffer + FCB->PathNameU.Length / sizeof(WCHAR);
last = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
}
}
RtlCopyMemory(pFileNameU->Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
}
}
else
{
FCB = NULL;
}
}
}
else
{
FCB = NULL;
}
if (FCB == NULL)
{
FCB = vfatOpenRootFCB(pVCB);
curr = pFileNameU->Buffer;
}
if (FCB == NULL)
{
FCB = vfatOpenRootFCB(pVCB);
curr = pFileNameU->Buffer;
}
parentFCB = NULL;
prev = curr;
parentFCB = NULL;
prev = curr;
}
else
{
FCB = parentFCB;
parentFCB = NULL;
prev = curr = pFileNameU->Buffer - 1;
last = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
}
while (curr <= last)
{
@ -751,14 +780,16 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
status = vfatDirFindFile(pVCB, parentFCB, &NameU, &FCB);
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
{
*pParentFCB = parentFCB;
*pFCB = NULL;
if (curr > last)
{
*pParentFCB = parentFCB;
return STATUS_OBJECT_NAME_NOT_FOUND;
}
else
{
vfatReleaseFCB (pVCB, parentFCB);
*pParentFCB = NULL;
return STATUS_OBJECT_PATH_NOT_FOUND;
}
}
@ -778,3 +809,4 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
return STATUS_SUCCESS;
}

View file

@ -1,5 +1,5 @@
/* $Id: rw.c,v 1.72 2004/12/05 16:31:51 gvg Exp $
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -642,7 +642,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
Resource = &Fcb->MainResource;
}
if (!ExAcquireResourceSharedLite(Resource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
IrpContext->Flags & IRPCONTEXT_CANWAIT ? TRUE : FALSE))
{
Resource = NULL;
Status = STATUS_PENDING;

View file

@ -1,4 +1,4 @@
/* $Id: vfat.h,v 1.70 2004/12/05 16:31:51 gvg Exp $ */
/* $Id$ */
#include <ddk/ntifs.h>
@ -457,7 +457,7 @@ NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PUNICODE_STRING FileNameU);
PVFATFCB* parentFcb);
NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
PVFATFCB Parent,
@ -507,7 +507,8 @@ NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
PUNICODE_STRING PathNameU,
PFILE_OBJECT pFileObject,
PVFATFCB* Fcb,
PVFATFCB ParentFcb,
ULONG RequestedOptions,
UCHAR ReqAttr);