mirror of
https://github.com/reactos/reactos.git
synced 2024-08-05 11:00:55 +00:00
- Used the parent fcb instead to determine it from parent fileobject.
svn path=/trunk/; revision=12687
This commit is contained in:
parent
635e37f654
commit
37d9e18817
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue