--- trunk/reactos/drivers/fs/vfat/create.c 2005-01-01 11:02:35 UTC (rev 12686)
+++ trunk/reactos/drivers/fs/vfat/create.c 2005-01-01 11:11:52 UTC (rev 12687)
@@ -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,46 +314,30 @@
}
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)
{
Status = VfatBlockDeviceIoControl (DeviceExt->StorageDevice,
@@ -382,40 +366,47 @@
if (!NT_SUCCESS(Status))
{
DPRINT ("Status %lx\n", Status);
+ *ParentFcb = NULL;
return Status;
}
}
+ if (*ParentFcb)
+ {
+ (*ParentFcb)->RefCount++;
+ }
- /* try first to find an existing FCB in memory */
- DPRINT ("Checking for existing FCB in memory\n");
- Fcb = vfatGrabFCBFromTable (DeviceExt, FileNameU);
- if (Fcb == NULL)
+ 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'\\')
{
- 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;
- }
+ PathNameU.Length -= sizeof(WCHAR);
}
- else
- {
- RtlCopyUnicodeString(FileNameU, &Fcb->PathNameU);
- }
+ PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
+
+ /* try first to find an existing FCB in memory */
+ DPRINT ("Checking for existing FCB in memory\n");
+
+ 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 @@
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 @@
}
}
- 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 @@
Status == STATUS_INVALID_PARAMETER ||
Status == STATUS_DELETE_PENDING)
{
+ if (ParentFcb)
+ {
+ vfatReleaseFCB (DeviceExt, ParentFcb);
+ }
return(Status);
}
@@ -593,12 +584,15 @@
{
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 @@
}
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)
{
--- trunk/reactos/drivers/fs/vfat/dirwr.c 2005-01-01 11:02:35 UTC (rev 12686)
+++ trunk/reactos/drivers/fs/vfat/dirwr.c 2005-01-01 11:11:52 UTC (rev 12687)
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
}
/* 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 @@
}
}
/* 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 @@
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 @@
{
/* 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 @@
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 @@
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 @@
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 @@
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
}
- ExReleaseResourceLite(&pDirFcb->MainResource);
- vfatReleaseFCB (DeviceExt, pDirFcb);
ExFreePool (Buffer);
DPRINT ("addentry ok\n");
return STATUS_SUCCESS;
@@ -529,8 +516,9 @@
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 @@
*/
{
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 @@
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 @@
/* 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
--- trunk/reactos/drivers/fs/vfat/fcb.c 2005-01-01 11:02:35 UTC (rev 12686)
+++ trunk/reactos/drivers/fs/vfat/fcb.c 2005-01-01 11:11:52 UTC (rev 12687)
@@ -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 @@
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'\\');
- 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;
+ 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;
+ }
}
VOID
@@ -637,63 +644,85 @@
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 @@
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 @@
return STATUS_SUCCESS;
}
+