/*
* FUNCTION: Cleans up after a file has been closed.
*/
-static NTSTATUS
-VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
+static
+NTSTATUS
+VfatCleanupFile(
+ PVFAT_IRP_CONTEXT IrpContext)
{
PVFATFCB pFcb;
PFILE_OBJECT FileObject = IrpContext->FileObject;
IrpContext->DeviceExt, FileObject);
/* FIXME: handle file/directory deletion here */
- pFcb = (PVFATFCB) FileObject->FsContext;
+ pFcb = (PVFATFCB)FileObject->FsContext;
if (!pFcb)
return STATUS_SUCCESS;
}
else
{
- if(!ExAcquireResourceExclusiveLite (&pFcb->MainResource,
- (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
+ if(!ExAcquireResourceExclusiveLite(&pFcb->MainResource,
+ (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{
return STATUS_PENDING;
}
- if(!ExAcquireResourceExclusiveLite (&pFcb->PagingIoResource,
- (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
+ if(!ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource,
+ (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{
- ExReleaseResourceLite (&pFcb->MainResource);
+ ExReleaseResourceLite(&pFcb->MainResource);
return STATUS_PENDING;
}
pFcb->FileObject = NULL;
CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
ObDereferenceObject(tmpFileObject);
- }
+ }
- CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
+ CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
}
/* Uninitialize the cache (should be done even if caching was never initialized) */
FileObject->Flags |= FO_CLEANUP_COMPLETE;
- ExReleaseResourceLite (&pFcb->PagingIoResource);
- ExReleaseResourceLite (&pFcb->MainResource);
+ ExReleaseResourceLite(&pFcb->PagingIoResource);
+ ExReleaseResourceLite(&pFcb->MainResource);
}
return STATUS_SUCCESS;
/*
* FUNCTION: Cleans up after a file has been closed.
*/
-NTSTATUS VfatCleanup(PVFAT_IRP_CONTEXT IrpContext)
+NTSTATUS
+VfatCleanup(
+ PVFAT_IRP_CONTEXT IrpContext)
{
NTSTATUS Status;
goto ByeBye;
}
- if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource,
- (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
+ if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
+ (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{
- return VfatQueueRequest (IrpContext);
+ return VfatQueueRequest(IrpContext);
}
Status = VfatCleanupFile(IrpContext);
- ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
+ ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
if (Status == STATUS_PENDING)
{
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
- IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
- return (Status);
+ return Status;
}
/* EOF */
{
if (pFcb->Flags & FCB_DELETE_PENDING)
{
- VfatDelEntry (DeviceExt, pFcb);
+ VfatDelEntry(DeviceExt, pFcb);
}
else
{
}
}
- vfatReleaseFCB (DeviceExt, pFcb);
+ vfatReleaseFCB(DeviceExt, pFcb);
}
FileObject->FsContext2 = NULL;
ByeBye:
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
- IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return Status;
if (cString[8] != ' ')
{
- Length = NameU->Length;
- NameU->Buffer += Length / sizeof(WCHAR);
- if (!FAT_ENTRY_VOLUME(pEntry))
- {
- Length += sizeof(WCHAR);
- NameU->Buffer[0] = L'.';
- NameU->Buffer++;
- }
- NameU->Length = 0;
- NameU->MaximumLength -= Length;
-
- StringA.Buffer = &cString[8];
- for (StringA.Length = 0;
- StringA.Length < 3 && StringA.Buffer[StringA.Length] != ' ';
- StringA.Length++);
- StringA.MaximumLength = StringA.Length;
- RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
- if (pEntry->lCase & VFAT_CASE_LOWER_EXT)
- {
- RtlDowncaseUnicodeString(NameU, NameU, FALSE);
- }
- NameU->Buffer -= Length / sizeof(WCHAR);
- NameU->Length += Length;
- NameU->MaximumLength += Length;
- }
+ Length = NameU->Length;
+ NameU->Buffer += Length / sizeof(WCHAR);
+ if (!FAT_ENTRY_VOLUME(pEntry))
+ {
+ Length += sizeof(WCHAR);
+ NameU->Buffer[0] = L'.';
+ NameU->Buffer++;
+ }
+ NameU->Length = 0;
+ NameU->MaximumLength -= Length;
+
+ StringA.Buffer = &cString[8];
+ for (StringA.Length = 0;
+ StringA.Length < 3 && StringA.Buffer[StringA.Length] != ' ';
+ StringA.Length++);
+ StringA.MaximumLength = StringA.Length;
+ RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
+ if (pEntry->lCase & VFAT_CASE_LOWER_EXT)
+ {
+ RtlDowncaseUnicodeString(NameU, NameU, FALSE);
+ }
+ NameU->Buffer -= Length / sizeof(WCHAR);
+ NameU->Length += Length;
+ NameU->MaximumLength += Length;
+ }
NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
DPRINT("'%wZ'\n", NameU);
}
-NTSTATUS
-ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
/*
* FUNCTION: Read the volume label
*/
+NTSTATUS
+ReadVolumeLabel(
+ PDEVICE_EXTENSION DeviceExt,
+ PVPB Vpb)
{
- PVOID Context = NULL;
- ULONG DirIndex = 0;
- PDIR_ENTRY Entry;
- PVFATFCB pFcb;
- LARGE_INTEGER FileOffset;
- UNICODE_STRING NameU;
- ULONG SizeDirEntry;
- ULONG EntriesPerPage;
- OEM_STRING StringO;
-
- NameU.Buffer = Vpb->VolumeLabel;
- NameU.Length = 0;
- NameU.MaximumLength = sizeof(Vpb->VolumeLabel);
- *(Vpb->VolumeLabel) = 0;
- Vpb->VolumeLabelLength = 0;
-
- if (DeviceExt->Flags & VCB_IS_FATX)
- {
- SizeDirEntry = sizeof(FATX_DIR_ENTRY);
- EntriesPerPage = FATX_ENTRIES_PER_PAGE;
- }
- else
- {
- SizeDirEntry = sizeof(FAT_DIR_ENTRY);
- EntriesPerPage = FAT_ENTRIES_PER_PAGE;
- }
-
- ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE);
- pFcb = vfatOpenRootFCB (DeviceExt);
- ExReleaseResourceLite (&DeviceExt->DirResource);
-
- FileOffset.QuadPart = 0;
- if (CcMapData(pFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry))
- {
- while (TRUE)
- {
- if (ENTRY_VOLUME(DeviceExt, Entry))
- {
- /* copy volume label */
- if (DeviceExt->Flags & VCB_IS_FATX)
- {
- StringO.Buffer = (PCHAR)Entry->FatX.Filename;
- StringO.MaximumLength = StringO.Length = Entry->FatX.FilenameLength;
- RtlOemStringToUnicodeString(&NameU, &StringO, FALSE);
- }
- else
- {
- vfat8Dot3ToString (&Entry->Fat, &NameU);
- }
- Vpb->VolumeLabelLength = NameU.Length;
- break;
- }
- if (ENTRY_END(DeviceExt, Entry))
- {
- break;
- }
- DirIndex++;
- Entry = (PDIR_ENTRY)((ULONG_PTR)Entry + SizeDirEntry);
- if ((DirIndex % EntriesPerPage) == 0)
- {
- CcUnpinData(Context);
- FileOffset.u.LowPart += PAGE_SIZE;
- if (!CcMapData(pFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry))
- {
- Context = NULL;
- break;
- }
- }
- }
- if (Context)
- {
- CcUnpinData(Context);
- }
- }
- ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE);
- vfatReleaseFCB (DeviceExt, pFcb);
- ExReleaseResourceLite (&DeviceExt->DirResource);
-
- return STATUS_SUCCESS;
+ PVOID Context = NULL;
+ ULONG DirIndex = 0;
+ PDIR_ENTRY Entry;
+ PVFATFCB pFcb;
+ LARGE_INTEGER FileOffset;
+ UNICODE_STRING NameU;
+ ULONG SizeDirEntry;
+ ULONG EntriesPerPage;
+ OEM_STRING StringO;
+
+ NameU.Buffer = Vpb->VolumeLabel;
+ NameU.Length = 0;
+ NameU.MaximumLength = sizeof(Vpb->VolumeLabel);
+ *(Vpb->VolumeLabel) = 0;
+ Vpb->VolumeLabelLength = 0;
+
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ SizeDirEntry = sizeof(FATX_DIR_ENTRY);
+ EntriesPerPage = FATX_ENTRIES_PER_PAGE;
+ }
+ else
+ {
+ SizeDirEntry = sizeof(FAT_DIR_ENTRY);
+ EntriesPerPage = FAT_ENTRIES_PER_PAGE;
+ }
+
+ ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
+ pFcb = vfatOpenRootFCB(DeviceExt);
+ ExReleaseResourceLite(&DeviceExt->DirResource);
+
+ FileOffset.QuadPart = 0;
+ if (CcMapData(pFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry))
+ {
+ while (TRUE)
+ {
+ if (ENTRY_VOLUME(DeviceExt, Entry))
+ {
+ /* copy volume label */
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ StringO.Buffer = (PCHAR)Entry->FatX.Filename;
+ StringO.MaximumLength = StringO.Length = Entry->FatX.FilenameLength;
+ RtlOemStringToUnicodeString(&NameU, &StringO, FALSE);
+ }
+ else
+ {
+ vfat8Dot3ToString(&Entry->Fat, &NameU);
+ }
+ Vpb->VolumeLabelLength = NameU.Length;
+ break;
+ }
+ if (ENTRY_END(DeviceExt, Entry))
+ {
+ break;
+ }
+ DirIndex++;
+ Entry = (PDIR_ENTRY)((ULONG_PTR)Entry + SizeDirEntry);
+ if ((DirIndex % EntriesPerPage) == 0)
+ {
+ CcUnpinData(Context);
+ FileOffset.u.LowPart += PAGE_SIZE;
+ if (!CcMapData(pFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry))
+ {
+ Context = NULL;
+ break;
+ }
+ }
+ }
+ if (Context)
+ {
+ CcUnpinData(Context);
+ }
+ }
+ ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
+ vfatReleaseFCB(DeviceExt, pFcb);
+ ExReleaseResourceLite(&DeviceExt->DirResource);
+
+ return STATUS_SUCCESS;
}
-NTSTATUS
-FindFile (
- PDEVICE_EXTENSION DeviceExt,
- PVFATFCB Parent,
- PUNICODE_STRING FileToFindU,
- PVFAT_DIRENTRY_CONTEXT DirContext,
- BOOLEAN First)
/*
* FUNCTION: Find a file
*/
+NTSTATUS
+FindFile(
+ PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB Parent,
+ PUNICODE_STRING FileToFindU,
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ BOOLEAN First)
{
- PWCHAR PathNameBuffer;
- USHORT PathNameBufferLength;
- NTSTATUS Status;
- PVOID Context = NULL;
- PVOID Page;
- PVFATFCB rcFcb;
- BOOLEAN Found;
- UNICODE_STRING PathNameU;
- UNICODE_STRING FileToFindUpcase;
- BOOLEAN WildCard;
-
- DPRINT ("FindFile(Parent %p, FileToFind '%wZ', DirIndex: %u)\n",
- Parent, FileToFindU, DirContext->DirIndex);
- DPRINT ("FindFile: Path %wZ\n",&Parent->PathNameU);
-
- PathNameBufferLength = LONGNAME_MAX_LENGTH * sizeof(WCHAR);
- PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameBufferLength + sizeof(WCHAR), TAG_VFAT);
- if (!PathNameBuffer)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- PathNameU.Buffer = PathNameBuffer;
- PathNameU.Length = 0;
- PathNameU.MaximumLength = PathNameBufferLength;
-
- DirContext->LongNameU.Length = 0;
- DirContext->ShortNameU.Length = 0;
-
- WildCard = FsRtlDoesNameContainWildCards(FileToFindU);
-
- if (WildCard == FALSE)
- {
- /* if there is no '*?' in the search name, than look first for an existing fcb */
- RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
- if (!vfatFCBIsRoot(Parent))
- {
- PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
- PathNameU.Length += sizeof(WCHAR);
- }
- RtlAppendUnicodeStringToString(&PathNameU, FileToFindU);
- PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
- rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
- if (rcFcb)
- {
- ULONG startIndex = rcFcb->startIndex;
- if ((rcFcb->Flags & FCB_IS_FATX_ENTRY) && !vfatFCBIsRoot(Parent))
- {
- startIndex += 2;
- }
- if(startIndex >= DirContext->DirIndex)
- {
- RtlCopyUnicodeString(&DirContext->LongNameU, &rcFcb->LongNameU);
- RtlCopyUnicodeString(&DirContext->ShortNameU, &rcFcb->ShortNameU);
- RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
- DirContext->StartIndex = rcFcb->startIndex;
- DirContext->DirIndex = rcFcb->dirIndex;
- DPRINT("FindFile: new Name %wZ, DirIndex %u (%u)\n",
- &DirContext->LongNameU, DirContext->DirIndex, DirContext->StartIndex);
- Status = STATUS_SUCCESS;
- }
- else
- {
- DPRINT("FCB not found for %wZ\n", &PathNameU);
- Status = STATUS_UNSUCCESSFUL;
- }
- vfatReleaseFCB(DeviceExt, rcFcb);
- ExFreePool(PathNameBuffer);
- return Status;
- }
- }
-
- /* FsRtlIsNameInExpression need the searched string to be upcase,
- * even if IgnoreCase is specified */
- Status = RtlUpcaseUnicodeString(&FileToFindUpcase, FileToFindU, TRUE);
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(PathNameBuffer);
- return Status;
- }
-
- while(TRUE)
- {
- Status = DeviceExt->GetNextDirEntry(&Context, &Page, Parent, DirContext, First);
- First = FALSE;
- if (Status == STATUS_NO_MORE_ENTRIES)
- {
- break;
- }
- if (ENTRY_VOLUME(DeviceExt, &DirContext->DirEntry))
- {
- DirContext->DirIndex++;
- continue;
- }
- if (WildCard)
- {
- Found = FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->LongNameU, TRUE, NULL) ||
- FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->ShortNameU, TRUE, NULL);
- }
- else
- {
- Found = FsRtlAreNamesEqual(&DirContext->LongNameU, FileToFindU, TRUE, NULL) ||
- FsRtlAreNamesEqual(&DirContext->ShortNameU, FileToFindU, TRUE, NULL);
- }
-
- if (Found)
- {
- if (WildCard)
- {
- RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
- if (!vfatFCBIsRoot(Parent))
- {
- PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
- PathNameU.Length += sizeof(WCHAR);
- }
- RtlAppendUnicodeStringToString(&PathNameU, &DirContext->LongNameU);
- PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
- rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
- if (rcFcb != NULL)
- {
- RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
- vfatReleaseFCB(DeviceExt, rcFcb);
- }
- }
- DPRINT("%u\n", DirContext->LongNameU.Length);
- DPRINT("FindFile: new Name %wZ, DirIndex %u\n",
- &DirContext->LongNameU, DirContext->DirIndex);
-
- if (Context)
- {
- CcUnpinData(Context);
- }
- RtlFreeUnicodeString(&FileToFindUpcase);
- ExFreePool(PathNameBuffer);
- return STATUS_SUCCESS;
- }
- DirContext->DirIndex++;
- }
-
- if (Context)
- {
- CcUnpinData(Context);
- }
-
- RtlFreeUnicodeString(&FileToFindUpcase);
- ExFreePool(PathNameBuffer);
- return Status;
+ PWCHAR PathNameBuffer;
+ USHORT PathNameBufferLength;
+ NTSTATUS Status;
+ PVOID Context = NULL;
+ PVOID Page;
+ PVFATFCB rcFcb;
+ BOOLEAN Found;
+ UNICODE_STRING PathNameU;
+ UNICODE_STRING FileToFindUpcase;
+ BOOLEAN WildCard;
+
+ DPRINT("FindFile(Parent %p, FileToFind '%wZ', DirIndex: %u)\n",
+ Parent, FileToFindU, DirContext->DirIndex);
+ DPRINT("FindFile: Path %wZ\n",&Parent->PathNameU);
+
+ PathNameBufferLength = LONGNAME_MAX_LENGTH * sizeof(WCHAR);
+ PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameBufferLength + sizeof(WCHAR), TAG_VFAT);
+ if (!PathNameBuffer)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ PathNameU.Buffer = PathNameBuffer;
+ PathNameU.Length = 0;
+ PathNameU.MaximumLength = PathNameBufferLength;
+
+ DirContext->LongNameU.Length = 0;
+ DirContext->ShortNameU.Length = 0;
+
+ WildCard = FsRtlDoesNameContainWildCards(FileToFindU);
+
+ if (WildCard == FALSE)
+ {
+ /* if there is no '*?' in the search name, than look first for an existing fcb */
+ RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
+ if (!vfatFCBIsRoot(Parent))
+ {
+ PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
+ PathNameU.Length += sizeof(WCHAR);
+ }
+ RtlAppendUnicodeStringToString(&PathNameU, FileToFindU);
+ PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
+ rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
+ if (rcFcb)
+ {
+ ULONG startIndex = rcFcb->startIndex;
+ if ((rcFcb->Flags & FCB_IS_FATX_ENTRY) && !vfatFCBIsRoot(Parent))
+ {
+ startIndex += 2;
+ }
+ if(startIndex >= DirContext->DirIndex)
+ {
+ RtlCopyUnicodeString(&DirContext->LongNameU, &rcFcb->LongNameU);
+ RtlCopyUnicodeString(&DirContext->ShortNameU, &rcFcb->ShortNameU);
+ RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
+ DirContext->StartIndex = rcFcb->startIndex;
+ DirContext->DirIndex = rcFcb->dirIndex;
+ DPRINT("FindFile: new Name %wZ, DirIndex %u (%u)\n",
+ &DirContext->LongNameU, DirContext->DirIndex, DirContext->StartIndex);
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ DPRINT("FCB not found for %wZ\n", &PathNameU);
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ vfatReleaseFCB(DeviceExt, rcFcb);
+ ExFreePool(PathNameBuffer);
+ return Status;
+ }
+ }
+
+ /* FsRtlIsNameInExpression need the searched string to be upcase,
+ * even if IgnoreCase is specified */
+ Status = RtlUpcaseUnicodeString(&FileToFindUpcase, FileToFindU, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(PathNameBuffer);
+ return Status;
+ }
+
+ while(TRUE)
+ {
+ Status = DeviceExt->GetNextDirEntry(&Context, &Page, Parent, DirContext, First);
+ First = FALSE;
+ if (Status == STATUS_NO_MORE_ENTRIES)
+ {
+ break;
+ }
+ if (ENTRY_VOLUME(DeviceExt, &DirContext->DirEntry))
+ {
+ DirContext->DirIndex++;
+ continue;
+ }
+ if (WildCard)
+ {
+ Found = FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->LongNameU, TRUE, NULL) ||
+ FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->ShortNameU, TRUE, NULL);
+ }
+ else
+ {
+ Found = FsRtlAreNamesEqual(&DirContext->LongNameU, FileToFindU, TRUE, NULL) ||
+ FsRtlAreNamesEqual(&DirContext->ShortNameU, FileToFindU, TRUE, NULL);
+ }
+
+ if (Found)
+ {
+ if (WildCard)
+ {
+ RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
+ if (!vfatFCBIsRoot(Parent))
+ {
+ PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
+ PathNameU.Length += sizeof(WCHAR);
+ }
+ RtlAppendUnicodeStringToString(&PathNameU, &DirContext->LongNameU);
+ PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
+ rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
+ if (rcFcb != NULL)
+ {
+ RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
+ vfatReleaseFCB(DeviceExt, rcFcb);
+ }
+ }
+ DPRINT("%u\n", DirContext->LongNameU.Length);
+ DPRINT("FindFile: new Name %wZ, DirIndex %u\n",
+ &DirContext->LongNameU, DirContext->DirIndex);
+
+ if (Context)
+ {
+ CcUnpinData(Context);
+ }
+ RtlFreeUnicodeString(&FileToFindUpcase);
+ ExFreePool(PathNameBuffer);
+ return STATUS_SUCCESS;
+ }
+ DirContext->DirIndex++;
+ }
+
+ if (Context)
+ {
+ CcUnpinData(Context);
+ }
+
+ RtlFreeUnicodeString(&FileToFindUpcase);
+ ExFreePool(PathNameBuffer);
+ return Status;
}
-static
-NTSTATUS
-VfatOpenFile (
- PDEVICE_EXTENSION DeviceExt,
- PUNICODE_STRING PathNameU,
- PFILE_OBJECT FileObject,
- PVFATFCB* ParentFcb )
/*
* FUNCTION: Opens a file
*/
+static
+NTSTATUS
+VfatOpenFile(
+ PDEVICE_EXTENSION DeviceExt,
+ PUNICODE_STRING PathNameU,
+ PFILE_OBJECT FileObject,
+ PVFATFCB *ParentFcb)
{
- PVFATFCB Fcb;
- NTSTATUS Status;
-
- DPRINT ("VfatOpenFile(%p, '%wZ', %p, %p)\n", DeviceExt, PathNameU, FileObject, ParentFcb);
-
- if (FileObject->RelatedFileObject)
- {
- DPRINT ("'%wZ'\n", &FileObject->RelatedFileObject->FileName);
-
- *ParentFcb = FileObject->RelatedFileObject->FsContext;
- (*ParentFcb)->RefCount++;
- }
- else
- {
- *ParentFcb = NULL;
- }
-
- if (!DeviceExt->FatInfo.FixedMedia)
- {
- Status = VfatBlockDeviceIoControl (DeviceExt->StorageDevice,
- IOCTL_DISK_CHECK_VERIFY,
- NULL,
- 0,
- NULL,
- 0,
- FALSE);
-
- 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");
-
- 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;
- }
- DPRINT ("Attaching FCB to fileObject\n");
- Status = vfatAttachFCBToFileObject (DeviceExt, Fcb, FileObject);
- if (!NT_SUCCESS(Status))
- {
- vfatReleaseFCB (DeviceExt, Fcb);
- }
- return Status;
+ PVFATFCB Fcb;
+ NTSTATUS Status;
+
+ DPRINT("VfatOpenFile(%p, '%wZ', %p, %p)\n", DeviceExt, PathNameU, FileObject, ParentFcb);
+
+ if (FileObject->RelatedFileObject)
+ {
+ DPRINT("'%wZ'\n", &FileObject->RelatedFileObject->FileName);
+
+ *ParentFcb = FileObject->RelatedFileObject->FsContext;
+ (*ParentFcb)->RefCount++;
+ }
+ else
+ {
+ *ParentFcb = NULL;
+ }
+
+ if (!DeviceExt->FatInfo.FixedMedia)
+ {
+ Status = VfatBlockDeviceIoControl(DeviceExt->StorageDevice,
+ IOCTL_DISK_CHECK_VERIFY,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ FALSE);
+ 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");
+
+ 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;
+ }
+ DPRINT("Attaching FCB to fileObject\n");
+ Status = vfatAttachFCBToFileObject(DeviceExt, Fcb, FileObject);
+ if (!NT_SUCCESS(Status))
+ {
+ vfatReleaseFCB (DeviceExt, Fcb);
+ }
+ return Status;
}
-static NTSTATUS
-VfatCreateFile ( PDEVICE_OBJECT DeviceObject, PIRP Irp )
/*
* FUNCTION: Create or open a file
*/
+static NTSTATUS
+VfatCreateFile(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
{
- PIO_STACK_LOCATION Stack;
- PFILE_OBJECT FileObject;
- NTSTATUS Status = STATUS_SUCCESS;
- PDEVICE_EXTENSION DeviceExt;
- ULONG RequestedDisposition, RequestedOptions;
- PVFATFCB pFcb = NULL;
- PVFATFCB ParentFcb = NULL;
- PWCHAR c, last;
- BOOLEAN PagingFileCreate = FALSE;
- BOOLEAN Dots;
- UNICODE_STRING FileNameU;
- UNICODE_STRING PathNameU;
-
- /* Unpack the various parameters. */
- Stack = IoGetCurrentIrpStackLocation (Irp);
- RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
- RequestedOptions =
- Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
- PagingFileCreate = (Stack->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE;
- FileObject = Stack->FileObject;
- DeviceExt = DeviceObject->DeviceExtension;
-
- /* Check their validity. */
- if (RequestedOptions & FILE_DIRECTORY_FILE &&
- RequestedDisposition == FILE_SUPERSEDE)
- {
- return(STATUS_INVALID_PARAMETER);
- }
+ PIO_STACK_LOCATION Stack;
+ PFILE_OBJECT FileObject;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PDEVICE_EXTENSION DeviceExt;
+ ULONG RequestedDisposition, RequestedOptions;
+ PVFATFCB pFcb = NULL;
+ PVFATFCB ParentFcb = NULL;
+ PWCHAR c, last;
+ BOOLEAN PagingFileCreate = FALSE;
+ BOOLEAN Dots;
+ UNICODE_STRING FileNameU;
+ UNICODE_STRING PathNameU;
+ ULONG Attributes;
+
+ /* Unpack the various parameters. */
+ Stack = IoGetCurrentIrpStackLocation (Irp);
+ RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
+ RequestedOptions = Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
+ PagingFileCreate = (Stack->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE;
+ FileObject = Stack->FileObject;
+ DeviceExt = DeviceObject->DeviceExtension;
+
+ /* Check their validity. */
+ if (RequestedOptions & FILE_DIRECTORY_FILE &&
+ RequestedDisposition == FILE_SUPERSEDE)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
- if (RequestedOptions & FILE_DIRECTORY_FILE &&
- RequestedOptions & FILE_NON_DIRECTORY_FILE)
+ if (RequestedOptions & FILE_DIRECTORY_FILE &&
+ RequestedOptions & FILE_NON_DIRECTORY_FILE)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* This a open operation for the volume itself */
+ if (FileObject->FileName.Length == 0 &&
+ (FileObject->RelatedFileObject == NULL || FileObject->RelatedFileObject->FsContext2 != NULL))
+ {
+ if (RequestedDisposition != FILE_OPEN &&
+ RequestedDisposition != FILE_OPEN_IF)
{
- return(STATUS_INVALID_PARAMETER);
+ return STATUS_ACCESS_DENIED;
}
-
- /* This a open operation for the volume itself */
- if (FileObject->FileName.Length == 0 &&
- (FileObject->RelatedFileObject == NULL || FileObject->RelatedFileObject->FsContext2 != NULL))
- {
- if (RequestedDisposition != FILE_OPEN &&
- RequestedDisposition != FILE_OPEN_IF)
- {
- return(STATUS_ACCESS_DENIED);
- }
#if 0
/* In spite of what is shown in WDK, it seems that Windows FAT driver doesn't perform that test */
- if (RequestedOptions & FILE_DIRECTORY_FILE)
- {
- return(STATUS_NOT_A_DIRECTORY);
- }
+ if (RequestedOptions & FILE_DIRECTORY_FILE)
+ {
+ return STATUS_NOT_A_DIRECTORY;
+ }
#endif
- pFcb = DeviceExt->VolumeFcb;
- vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
- pFcb->RefCount++;
-
- Irp->IoStatus.Information = FILE_OPENED;
- return(STATUS_SUCCESS);
- }
-
- /*
- * Check for illegal characters and illegale dot sequences in the file name
- */
- PathNameU = FileObject->FileName;
- c = PathNameU.Buffer + PathNameU.Length / sizeof(WCHAR);
- last = c - 1;
- Dots = TRUE;
- while (c-- > PathNameU.Buffer)
- {
- if (*c == L'\\' || c == PathNameU.Buffer)
- {
- if (Dots && last > c)
- {
- return(STATUS_OBJECT_NAME_INVALID);
- }
- last = c - 1;
- Dots = TRUE;
- }
- else if (*c != L'.')
- {
- Dots = FALSE;
- }
-
- if (*c != '\\' && vfatIsLongIllegal(*c))
- {
- return(STATUS_OBJECT_NAME_INVALID);
- }
- }
- if (FileObject->RelatedFileObject && PathNameU.Length >= sizeof(WCHAR) && PathNameU.Buffer[0] == L'\\')
- {
- return(STATUS_OBJECT_NAME_INVALID);
- }
- if (PathNameU.Length > sizeof(WCHAR) && PathNameU.Buffer[PathNameU.Length/sizeof(WCHAR)-1] == L'\\')
- {
- PathNameU.Length -= sizeof(WCHAR);
- }
-
- /* Try opening the file. */
- Status = VfatOpenFile (DeviceExt, &PathNameU, FileObject, &ParentFcb);
-
- /*
- * If the directory containing the file to open doesn't exist then
- * fail immediately
- */
- if (Status == STATUS_OBJECT_PATH_NOT_FOUND ||
- Status == STATUS_INVALID_PARAMETER ||
- Status == STATUS_DELETE_PENDING)
- {
- if (ParentFcb)
- {
- vfatReleaseFCB (DeviceExt, ParentFcb);
- }
- return(Status);
- }
- if (!NT_SUCCESS(Status) && ParentFcb == NULL)
- {
- DPRINT1("VfatOpenFile faild for '%wZ', status %x\n", &PathNameU, Status);
+ pFcb = DeviceExt->VolumeFcb;
+ vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
+ pFcb->RefCount++;
+
+ Irp->IoStatus.Information = FILE_OPENED;
+ return STATUS_SUCCESS;
+ }
+
+ /* Check for illegal characters and illegale dot sequences in the file name */
+ PathNameU = FileObject->FileName;
+ c = PathNameU.Buffer + PathNameU.Length / sizeof(WCHAR);
+ last = c - 1;
+ Dots = TRUE;
+ while (c-- > PathNameU.Buffer)
+ {
+ if (*c == L'\\' || c == PathNameU.Buffer)
+ {
+ if (Dots && last > c)
+ {
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+ last = c - 1;
+ Dots = TRUE;
+ }
+ else if (*c != L'.')
+ {
+ Dots = FALSE;
+ }
+
+ if (*c != '\\' && vfatIsLongIllegal(*c))
+ {
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+ }
+
+ if (FileObject->RelatedFileObject && PathNameU.Length >= sizeof(WCHAR) && PathNameU.Buffer[0] == L'\\')
+ {
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+
+ if (PathNameU.Length > sizeof(WCHAR) && PathNameU.Buffer[PathNameU.Length/sizeof(WCHAR)-1] == L'\\')
+ {
+ PathNameU.Length -= sizeof(WCHAR);
+ }
+
+ /* Try opening the file. */
+ Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, &ParentFcb);
+
+ /*
+ * If the directory containing the file to open doesn't exist then
+ * fail immediately
+ */
+ if (Status == STATUS_OBJECT_PATH_NOT_FOUND ||
+ Status == STATUS_INVALID_PARAMETER ||
+ Status == STATUS_DELETE_PENDING)
+ {
+ if (ParentFcb)
+ {
+ vfatReleaseFCB(DeviceExt, ParentFcb);
+ }
+ return Status;
+ }
+
+ if (!NT_SUCCESS(Status) && ParentFcb == NULL)
+ {
+ DPRINT1("VfatOpenFile faild for '%wZ', status %x\n", &PathNameU, Status);
+ return Status;
+ }
+
+ /* If the file open failed then create the required file */
+ if (!NT_SUCCESS (Status))
+ {
+ if (RequestedDisposition == FILE_CREATE ||
+ RequestedDisposition == FILE_OPEN_IF ||
+ RequestedDisposition == FILE_OVERWRITE_IF ||
+ RequestedDisposition == FILE_SUPERSEDE)
+ {
+ Attributes = Stack->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL;
+ vfatSplitPathName(&PathNameU, NULL, &FileNameU);
+ Status = VfatAddEntry(DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions,
+ (UCHAR)(Attributes & FILE_ATTRIBUTE_VALID_FLAGS));
+ vfatReleaseFCB(DeviceExt, ParentFcb);
+ if (NT_SUCCESS(Status))
+ {
+ Status = vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
+ if (!NT_SUCCESS(Status))
+ {
+ vfatReleaseFCB(DeviceExt, pFcb);
+ return Status;
+ }
+
+ Irp->IoStatus.Information = FILE_CREATED;
+ VfatSetAllocationSizeInformation(FileObject,
+ pFcb,
+ DeviceExt,
+ &Irp->Overlay.AllocationSize);
+ VfatSetExtendedAttributes(FileObject,
+ Irp->AssociatedIrp.SystemBuffer,
+ Stack->Parameters.Create.EaLength);
+
+ if (PagingFileCreate)
+ {
+ pFcb->Flags |= FCB_IS_PAGE_FILE;
+ }
+ }
+ else
+ {
+ return Status;
+ }
+ }
+ else
+ {
+ if (ParentFcb)
+ {
+ 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)
+ {
+ Irp->IoStatus.Information = FILE_EXISTS;
+ VfatCloseFile(DeviceExt, FileObject);
+ return STATUS_OBJECT_NAME_COLLISION;
+ }
+
+ pFcb = FileObject->FsContext;
+
+ if (pFcb->OpenHandleCount != 0)
+ {
+ Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
+ Stack->Parameters.Create.ShareAccess,
+ FileObject,
+ &pFcb->FCBShareAccess,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ VfatCloseFile(DeviceExt, FileObject);
return Status;
+ }
}
- /*
- * If the file open failed then create the required file
- */
- if (!NT_SUCCESS (Status))
- {
- if (RequestedDisposition == FILE_CREATE ||
- RequestedDisposition == FILE_OPEN_IF ||
- RequestedDisposition == FILE_OVERWRITE_IF ||
- RequestedDisposition == FILE_SUPERSEDE)
- {
- ULONG Attributes;
- Attributes = Stack->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL;
- vfatSplitPathName(&PathNameU, NULL, &FileNameU);
- Status = VfatAddEntry (DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions,
- (UCHAR)(Attributes & FILE_ATTRIBUTE_VALID_FLAGS));
- vfatReleaseFCB (DeviceExt, ParentFcb);
- if (NT_SUCCESS (Status))
- {
- Status = vfatAttachFCBToFileObject (DeviceExt, pFcb, FileObject);
- if ( !NT_SUCCESS(Status) )
- {
- vfatReleaseFCB (DeviceExt, pFcb);
- return Status;
- }
-
- Irp->IoStatus.Information = FILE_CREATED;
- VfatSetAllocationSizeInformation(FileObject,
- pFcb,
- DeviceExt,
- &Irp->Overlay.AllocationSize);
- VfatSetExtendedAttributes(FileObject,
- Irp->AssociatedIrp.SystemBuffer,
- Stack->Parameters.Create.EaLength);
-
- if (PagingFileCreate)
- {
- pFcb->Flags |= FCB_IS_PAGE_FILE;
- }
- }
- else
- {
- return(Status);
- }
- }
- else
- {
- if (ParentFcb)
- {
- 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)
- {
- Irp->IoStatus.Information = FILE_EXISTS;
- VfatCloseFile (DeviceExt, FileObject);
- return(STATUS_OBJECT_NAME_COLLISION);
- }
-
- pFcb = FileObject->FsContext;
-
- if (pFcb->OpenHandleCount != 0)
- {
- Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
- Stack->Parameters.Create.ShareAccess,
- FileObject,
- &pFcb->FCBShareAccess,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- VfatCloseFile (DeviceExt, FileObject);
- return(Status);
- }
- }
-
- /*
- * Check the file has the requested attributes
- */
- if (RequestedOptions & FILE_NON_DIRECTORY_FILE &&
- *pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- VfatCloseFile (DeviceExt, FileObject);
- return(STATUS_FILE_IS_A_DIRECTORY);
- }
- if (RequestedOptions & FILE_DIRECTORY_FILE &&
- !(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- VfatCloseFile (DeviceExt, FileObject);
- return(STATUS_NOT_A_DIRECTORY);
- }
+ /*
+ * Check the file has the requested attributes
+ */
+ if (RequestedOptions & FILE_NON_DIRECTORY_FILE &&
+ *pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ VfatCloseFile (DeviceExt, FileObject);
+ return STATUS_FILE_IS_A_DIRECTORY;
+ }
+ if (RequestedOptions & FILE_DIRECTORY_FILE &&
+ !(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ VfatCloseFile (DeviceExt, FileObject);
+ return STATUS_NOT_A_DIRECTORY;
+ }
#ifndef USE_ROS_CC_AND_FS
- if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- if (Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA ||
- RequestedDisposition == FILE_OVERWRITE ||
- RequestedDisposition == FILE_OVERWRITE_IF)
- {
- if (!MmFlushImageSection(&pFcb->SectionObjectPointers, MmFlushForWrite))
- {
- DPRINT1("%wZ\n", &pFcb->PathNameU);
- DPRINT1("%d %d %d\n", Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA,
- RequestedDisposition == FILE_OVERWRITE, RequestedDisposition == FILE_OVERWRITE_IF);
- VfatCloseFile (DeviceExt, FileObject);
- return STATUS_SHARING_VIOLATION;
- }
- }
- }
+ if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ if (Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA ||
+ RequestedDisposition == FILE_OVERWRITE ||
+ RequestedDisposition == FILE_OVERWRITE_IF)
+ {
+ if (!MmFlushImageSection(&pFcb->SectionObjectPointers, MmFlushForWrite))
+ {
+ DPRINT1("%wZ\n", &pFcb->PathNameU);
+ DPRINT1("%d %d %d\n", Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA,
+ RequestedDisposition == FILE_OVERWRITE, RequestedDisposition == FILE_OVERWRITE_IF);
+ VfatCloseFile (DeviceExt, FileObject);
+ return STATUS_SHARING_VIOLATION;
+ }
+ }
+ }
#endif
- if (PagingFileCreate)
- {
- /* FIXME:
- * Do more checking for page files. It is possible,
- * that the file was opened and closed previously
- * as a normal cached file. In this case, the cache
- * manager has referenced the fileobject and the fcb
- * is held in memory. Try to remove the fileobject
- * from cache manager and use the fcb.
- */
- if (pFcb->RefCount > 1)
- {
- if(!(pFcb->Flags & FCB_IS_PAGE_FILE))
- {
- VfatCloseFile(DeviceExt, FileObject);
- return(STATUS_INVALID_PARAMETER);
- }
- }
- else
- {
- pFcb->Flags |= FCB_IS_PAGE_FILE;
- }
- }
- else
- {
- if (pFcb->Flags & FCB_IS_PAGE_FILE)
- {
- VfatCloseFile(DeviceExt, FileObject);
- return(STATUS_INVALID_PARAMETER);
- }
- }
-
-
- if (RequestedDisposition == FILE_OVERWRITE ||
- RequestedDisposition == FILE_OVERWRITE_IF ||
- RequestedDisposition == FILE_SUPERSEDE)
- {
- ExAcquireResourceExclusiveLite(&(pFcb->MainResource), TRUE);
- Status = VfatSetAllocationSizeInformation (FileObject,
- pFcb,
- DeviceExt,
- &Irp->Overlay.AllocationSize);
- ExReleaseResourceLite(&(pFcb->MainResource));
- if (!NT_SUCCESS (Status))
- {
- VfatCloseFile (DeviceExt, FileObject);
- return(Status);
- }
- }
-
- if (RequestedDisposition == FILE_SUPERSEDE)
- {
- Irp->IoStatus.Information = FILE_SUPERSEDED;
- }
- else if (RequestedDisposition == FILE_OVERWRITE ||
- RequestedDisposition == FILE_OVERWRITE_IF)
- {
- Irp->IoStatus.Information = FILE_OVERWRITTEN;
- }
- else
- {
- Irp->IoStatus.Information = FILE_OPENED;
- }
- }
-
- if (pFcb->OpenHandleCount == 0)
- {
- IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
- Stack->Parameters.Create.ShareAccess,
- FileObject,
- &pFcb->FCBShareAccess);
- }
- else
- {
- IoUpdateShareAccess(
- FileObject,
- &pFcb->FCBShareAccess
- );
-
- }
-
- pFcb->OpenHandleCount++;
-
- /* FIXME : test write access if requested */
-
- return(Status);
-}
+ if (PagingFileCreate)
+ {
+ /* FIXME:
+ * Do more checking for page files. It is possible,
+ * that the file was opened and closed previously
+ * as a normal cached file. In this case, the cache
+ * manager has referenced the fileobject and the fcb
+ * is held in memory. Try to remove the fileobject
+ * from cache manager and use the fcb.
+ */
+ if (pFcb->RefCount > 1)
+ {
+ if(!(pFcb->Flags & FCB_IS_PAGE_FILE))
+ {
+ VfatCloseFile(DeviceExt, FileObject);
+ return STATUS_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ pFcb->Flags |= FCB_IS_PAGE_FILE;
+ }
+ }
+ else
+ {
+ if (pFcb->Flags & FCB_IS_PAGE_FILE)
+ {
+ VfatCloseFile(DeviceExt, FileObject);
+ return STATUS_INVALID_PARAMETER;
+ }
+ }
+ if (RequestedDisposition == FILE_OVERWRITE ||
+ RequestedDisposition == FILE_OVERWRITE_IF ||
+ RequestedDisposition == FILE_SUPERSEDE)
+ {
+ ExAcquireResourceExclusiveLite(&(pFcb->MainResource), TRUE);
+ Status = VfatSetAllocationSizeInformation(FileObject,
+ pFcb,
+ DeviceExt,
+ &Irp->Overlay.AllocationSize);
+ ExReleaseResourceLite(&(pFcb->MainResource));
+ if (!NT_SUCCESS (Status))
+ {
+ VfatCloseFile(DeviceExt, FileObject);
+ return Status;
+ }
+ }
+
+ if (RequestedDisposition == FILE_SUPERSEDE)
+ {
+ Irp->IoStatus.Information = FILE_SUPERSEDED;
+ }
+ else if (RequestedDisposition == FILE_OVERWRITE ||
+ RequestedDisposition == FILE_OVERWRITE_IF)
+ {
+ Irp->IoStatus.Information = FILE_OVERWRITTEN;
+ }
+ else
+ {
+ Irp->IoStatus.Information = FILE_OPENED;
+ }
+ }
+
+ if (pFcb->OpenHandleCount == 0)
+ {
+ IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
+ Stack->Parameters.Create.ShareAccess,
+ FileObject,
+ &pFcb->FCBShareAccess);
+ }
+ else
+ {
+ IoUpdateShareAccess(FileObject,
+ &pFcb->FCBShareAccess);
+ }
+
+ pFcb->OpenHandleCount++;
+
+ /* FIXME : test write access if requested */
+
+ return Status;
+}
-NTSTATUS
-VfatCreate (PVFAT_IRP_CONTEXT IrpContext)
/*
* FUNCTION: Create or open a file
*/
+NTSTATUS
+VfatCreate(
+ PVFAT_IRP_CONTEXT IrpContext)
{
- NTSTATUS Status;
-
- ASSERT(IrpContext);
-
- if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
- {
- /* DeviceObject represents FileSystem instead of logical volume */
- DPRINT ("FsdCreate called with file system\n");
- IrpContext->Irp->IoStatus.Information = FILE_OPENED;
- IrpContext->Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest (IrpContext->Irp, IO_DISK_INCREMENT);
- VfatFreeIrpContext(IrpContext);
- return(STATUS_SUCCESS);
- }
-
- if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT))
- {
- return(VfatQueueRequest (IrpContext));
- }
-
- IrpContext->Irp->IoStatus.Information = 0;
- ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, TRUE);
- Status = VfatCreateFile (IrpContext->DeviceObject, IrpContext->Irp);
- ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
-
- IrpContext->Irp->IoStatus.Status = Status;
- IoCompleteRequest (IrpContext->Irp,
- (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
- VfatFreeIrpContext(IrpContext);
- return(Status);
+ NTSTATUS Status;
+
+ ASSERT(IrpContext);
+
+ if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
+ {
+ /* DeviceObject represents FileSystem instead of logical volume */
+ DPRINT ("FsdCreate called with file system\n");
+ IrpContext->Irp->IoStatus.Information = FILE_OPENED;
+ IrpContext->Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(IrpContext->Irp, IO_DISK_INCREMENT);
+ VfatFreeIrpContext(IrpContext);
+ return STATUS_SUCCESS;
+ }
+
+ if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT))
+ {
+ return(VfatQueueRequest(IrpContext));
+ }
+
+ IrpContext->Irp->IoStatus.Information = 0;
+ ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
+ Status = VfatCreateFile(IrpContext->DeviceObject, IrpContext->Irp);
+ ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
+
+ IrpContext->Irp->IoStatus.Status = Status;
+ IoCompleteRequest(IrpContext->Irp,
+ (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
+ VfatFreeIrpContext(IrpContext);
+ return Status;
}
/* EOF */
/* Function like DosDateTimeToFileTime */
BOOLEAN
-FsdDosDateTimeToSystemTime(PDEVICE_EXTENSION DeviceExt,
- USHORT DosDate,
- USHORT DosTime,
- PLARGE_INTEGER SystemTime)
+FsdDosDateTimeToSystemTime(
+ PDEVICE_EXTENSION DeviceExt,
+ USHORT DosDate,
+ USHORT DosTime,
+ PLARGE_INTEGER SystemTime)
{
PDOSTIME pdtime = (PDOSTIME)&DosTime;
PDOSDATE pddate = (PDOSDATE)&DosDate;
/* Function like FileTimeToDosDateTime */
BOOLEAN
-FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt,
- PLARGE_INTEGER SystemTime,
- PUSHORT pDosDate,
- PUSHORT pDosTime)
+FsdSystemTimeToDosDateTime(
+ PDEVICE_EXTENSION DeviceExt,
+ PLARGE_INTEGER SystemTime,
+ PUSHORT pDosDate,
+ PUSHORT pDosTime)
{
PDOSTIME pdtime = (PDOSTIME)pDosTime;
PDOSDATE pddate = (PDOSDATE)pDosDate;
#define ULONG_ROUND_UP(x) ROUND_UP((x), (sizeof(ULONG)))
-static NTSTATUS
-VfatGetFileNameInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
- PFILE_NAMES_INFORMATION pInfo,
- ULONG BufferLength)
+static
+NTSTATUS
+VfatGetFileNameInformation(
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ PFILE_NAMES_INFORMATION pInfo,
+ ULONG BufferLength)
{
if ((sizeof(FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
return STATUS_BUFFER_OVERFLOW;
return STATUS_SUCCESS;
}
-static NTSTATUS
-VfatGetFileDirectoryInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_DIRECTORY_INFORMATION pInfo,
- ULONG BufferLength)
+static
+NTSTATUS
+VfatGetFileDirectoryInformation(
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_DIRECTORY_INFORMATION pInfo,
+ ULONG BufferLength)
{
if ((sizeof(FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
return STATUS_BUFFER_OVERFLOW;
return STATUS_SUCCESS;
}
-static NTSTATUS
-VfatGetFileFullDirectoryInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_FULL_DIR_INFORMATION pInfo,
- ULONG BufferLength)
+static
+NTSTATUS
+VfatGetFileFullDirectoryInformation(
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_FULL_DIR_INFORMATION pInfo,
+ ULONG BufferLength)
{
if ((sizeof(FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
return STATUS_BUFFER_OVERFLOW;
return STATUS_SUCCESS;
}
-static NTSTATUS
-VfatGetFileBothInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_BOTH_DIR_INFORMATION pInfo,
- ULONG BufferLength)
+static
+NTSTATUS
+VfatGetFileBothInformation(
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_BOTH_DIR_INFORMATION pInfo,
+ ULONG BufferLength)
{
if ((sizeof(FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
return STATUS_BUFFER_OVERFLOW;
return STATUS_SUCCESS;
}
-static NTSTATUS
-DoQuery(PVFAT_IRP_CONTEXT IrpContext)
+static
+NTSTATUS
+DoQuery(
+ PVFAT_IRP_CONTEXT IrpContext)
{
NTSTATUS Status = STATUS_SUCCESS;
LONG BufferLength = 0;
* FUNCTION: directory control : read/write directory informations
*/
NTSTATUS
-VfatDirectoryControl(PVFAT_IRP_CONTEXT IrpContext)
+VfatDirectoryControl(
+ PVFAT_IRP_CONTEXT IrpContext)
{
NTSTATUS Status = STATUS_SUCCESS;
#include "vfat.h"
ULONG
-vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
- PDIR_ENTRY pFatDirEntry)
+vfatDirEntryGetFirstCluster(
+ PDEVICE_EXTENSION pDeviceExt,
+ PDIR_ENTRY pFatDirEntry)
{
ULONG cluster;
static
BOOLEAN
-FATIsDirectoryEmpty(PVFATFCB Fcb)
+FATIsDirectoryEmpty(
+ PVFATFCB Fcb)
{
LARGE_INTEGER FileOffset;
PVOID Context = NULL;
static
BOOLEAN
-FATXIsDirectoryEmpty(PVFATFCB Fcb)
+FATXIsDirectoryEmpty(
+ PVFATFCB Fcb)
{
LARGE_INTEGER FileOffset;
PVOID Context = NULL;
}
BOOLEAN
-VfatIsDirectoryEmpty(PVFATFCB Fcb)
+VfatIsDirectoryEmpty(
+ PVFATFCB Fcb)
{
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
return FATXIsDirectoryEmpty(Fcb);
}
NTSTATUS
-FATGetNextDirEntry(PVOID *pContext,
- PVOID *pPage,
- IN PVFATFCB pDirFcb,
- PVFAT_DIRENTRY_CONTEXT DirContext,
- BOOLEAN First)
+FATGetNextDirEntry(
+ PVOID *pContext,
+ PVOID *pPage,
+ IN PVFATFCB pDirFcb,
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ BOOLEAN First)
{
ULONG dirMap;
PWCHAR pName;
return STATUS_SUCCESS;
}
-NTSTATUS FATXGetNextDirEntry(PVOID * pContext,
- PVOID * pPage,
- IN PVFATFCB pDirFcb,
- PVFAT_DIRENTRY_CONTEXT DirContext,
- BOOLEAN First)
+NTSTATUS
+FATXGetNextDirEntry(
+ PVOID *pContext,
+ PVOID *pPage,
+ IN PVFATFCB pDirFcb,
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ BOOLEAN First)
{
- LARGE_INTEGER FileOffset;
- PFATX_DIR_ENTRY fatxDirEntry;
- OEM_STRING StringO;
- ULONG DirIndex = DirContext->DirIndex;
-
- FileOffset.u.HighPart = 0;
-
- UNREFERENCED_PARAMETER(First);
-
- if (!vfatFCBIsRoot(pDirFcb))
- {
- /* need to add . and .. entries */
- switch (DirContext->DirIndex)
- {
- case 0: /* entry . */
- {
- DirContext->ShortNameU.Buffer[0] = 0;
- DirContext->ShortNameU.Length = 0;
- wcscpy(DirContext->LongNameU.Buffer, L".");
- DirContext->LongNameU.Length = sizeof(WCHAR);
- RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
- DirContext->DirEntry.FatX.Filename[0] = '.';
- DirContext->DirEntry.FatX.FilenameLength = 1;
- DirContext->StartIndex = 0;
- return STATUS_SUCCESS;
- }
- case 1: /* entry .. */
- {
- DirContext->ShortNameU.Buffer[0] = 0;
- DirContext->ShortNameU.Length = 0;
- wcscpy(DirContext->LongNameU.Buffer, L"..");
- DirContext->LongNameU.Length = 2 * sizeof(WCHAR);
- RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
- DirContext->DirEntry.FatX.Filename[0] = DirContext->DirEntry.FatX.Filename[1] = '.';
- DirContext->DirEntry.FatX.FilenameLength = 2;
- DirContext->StartIndex = 1;
- return STATUS_SUCCESS;
- }
- default:
- DirIndex -= 2;
- }
- }
-
- if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
- {
- if (*pContext != NULL)
- {
- CcUnpinData(*pContext);
- }
- FileOffset.u.LowPart = ROUND_DOWN(DirIndex * sizeof(FATX_DIR_ENTRY), PAGE_SIZE);
- if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart ||
- !CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
- {
- *pContext = NULL;
- return STATUS_NO_MORE_ENTRIES;
- }
- }
-
- fatxDirEntry = (PFATX_DIR_ENTRY)(*pPage) + DirIndex % FATX_ENTRIES_PER_PAGE;
-
- DirContext->StartIndex = DirContext->DirIndex;
-
- while (TRUE)
- {
- if (FATX_ENTRY_END(fatxDirEntry))
- {
- CcUnpinData(*pContext);
- *pContext = NULL;
- return STATUS_NO_MORE_ENTRIES;
- }
-
- if (!FATX_ENTRY_DELETED(fatxDirEntry))
- {
- RtlCopyMemory(&DirContext->DirEntry.FatX, fatxDirEntry, sizeof(FATX_DIR_ENTRY));
- break;
- }
- DirContext->DirIndex++;
- DirContext->StartIndex++;
- DirIndex++;
- if ((DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
- {
- CcUnpinData(*pContext);
- FileOffset.u.LowPart += PAGE_SIZE;
- if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart ||
- !CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
- {
+ LARGE_INTEGER FileOffset;
+ PFATX_DIR_ENTRY fatxDirEntry;
+ OEM_STRING StringO;
+ ULONG DirIndex = DirContext->DirIndex;
+
+ FileOffset.u.HighPart = 0;
+
+ UNREFERENCED_PARAMETER(First);
+
+ if (!vfatFCBIsRoot(pDirFcb))
+ {
+ /* need to add . and .. entries */
+ switch (DirContext->DirIndex)
+ {
+ case 0: /* entry . */
+ DirContext->ShortNameU.Buffer[0] = 0;
+ DirContext->ShortNameU.Length = 0;
+ wcscpy(DirContext->LongNameU.Buffer, L".");
+ DirContext->LongNameU.Length = sizeof(WCHAR);
+ RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
+ DirContext->DirEntry.FatX.Filename[0] = '.';
+ DirContext->DirEntry.FatX.FilenameLength = 1;
+ DirContext->StartIndex = 0;
+ return STATUS_SUCCESS;
+
+ case 1: /* entry .. */
+ DirContext->ShortNameU.Buffer[0] = 0;
+ DirContext->ShortNameU.Length = 0;
+ wcscpy(DirContext->LongNameU.Buffer, L"..");
+ DirContext->LongNameU.Length = 2 * sizeof(WCHAR);
+ RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
+ DirContext->DirEntry.FatX.Filename[0] = DirContext->DirEntry.FatX.Filename[1] = '.';
+ DirContext->DirEntry.FatX.FilenameLength = 2;
+ DirContext->StartIndex = 1;
+ return STATUS_SUCCESS;
+
+ default:
+ DirIndex -= 2;
+ }
+ }
+
+ if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
+ {
+ if (*pContext != NULL)
+ {
+ CcUnpinData(*pContext);
+ }
+ FileOffset.u.LowPart = ROUND_DOWN(DirIndex * sizeof(FATX_DIR_ENTRY), PAGE_SIZE);
+ if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart ||
+ !CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
+ {
*pContext = NULL;
- return STATUS_NO_MORE_ENTRIES;
- }
- fatxDirEntry = (PFATX_DIR_ENTRY)*pPage;
- }
- else
- {
- fatxDirEntry++;
- }
- }
- DirContext->ShortNameU.Buffer[0] = 0;
- DirContext->ShortNameU.Length = 0;
- StringO.Buffer = (PCHAR)fatxDirEntry->Filename;
- StringO.Length = StringO.MaximumLength = fatxDirEntry->FilenameLength;
- RtlOemStringToUnicodeString(&DirContext->LongNameU, &StringO, FALSE);
- return STATUS_SUCCESS;
+ return STATUS_NO_MORE_ENTRIES;
+ }
+ }
+
+ fatxDirEntry = (PFATX_DIR_ENTRY)(*pPage) + DirIndex % FATX_ENTRIES_PER_PAGE;
+
+ DirContext->StartIndex = DirContext->DirIndex;
+
+ while (TRUE)
+ {
+ if (FATX_ENTRY_END(fatxDirEntry))
+ {
+ CcUnpinData(*pContext);
+ *pContext = NULL;
+ return STATUS_NO_MORE_ENTRIES;
+ }
+
+ if (!FATX_ENTRY_DELETED(fatxDirEntry))
+ {
+ RtlCopyMemory(&DirContext->DirEntry.FatX, fatxDirEntry, sizeof(FATX_DIR_ENTRY));
+ break;
+ }
+ DirContext->DirIndex++;
+ DirContext->StartIndex++;
+ DirIndex++;
+ if ((DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
+ {
+ CcUnpinData(*pContext);
+ FileOffset.u.LowPart += PAGE_SIZE;
+ if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart ||
+ !CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
+ {
+ *pContext = NULL;
+ return STATUS_NO_MORE_ENTRIES;
+ }
+ fatxDirEntry = (PFATX_DIR_ENTRY)*pPage;
+ }
+ else
+ {
+ fatxDirEntry++;
+ }
+ }
+ DirContext->ShortNameU.Buffer[0] = 0;
+ DirContext->ShortNameU.Length = 0;
+ StringO.Buffer = (PCHAR)fatxDirEntry->Filename;
+ StringO.Length = StringO.MaximumLength = fatxDirEntry->FilenameLength;
+ RtlOemStringToUnicodeString(&DirContext->LongNameU, &StringO, FALSE);
+ return STATUS_SUCCESS;
}
static FAST_IO_CHECK_IF_POSSIBLE VfatFastIoCheckIfPossible;
-static BOOLEAN NTAPI
-VfatFastIoCheckIfPossible(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN BOOLEAN Wait,
- IN ULONG LockKey,
- IN BOOLEAN CheckForReadOperation,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoCheckIfPossible(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ IN ULONG LockKey,
+ IN BOOLEAN CheckForReadOperation,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
/* Prevent all Fast I/O requests */
DPRINT("VfatFastIoCheckIfPossible(): returning FALSE.\n");
static FAST_IO_READ VfatFastIoRead;
-static BOOLEAN NTAPI
-VfatFastIoRead(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN BOOLEAN Wait,
- IN ULONG LockKey,
- OUT PVOID Buffer,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoRead(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ IN ULONG LockKey,
+ OUT PVOID Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoRead()\n");
static FAST_IO_WRITE VfatFastIoWrite;
-static BOOLEAN NTAPI
-VfatFastIoWrite(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN BOOLEAN Wait,
- IN ULONG LockKey,
- OUT PVOID Buffer,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoWrite(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ IN ULONG LockKey,
+ OUT PVOID Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoWrite()\n");
static FAST_IO_QUERY_BASIC_INFO VfatFastIoQueryBasicInfo;
-static BOOLEAN NTAPI
-VfatFastIoQueryBasicInfo(IN PFILE_OBJECT FileObject,
- IN BOOLEAN Wait,
- OUT PFILE_BASIC_INFORMATION Buffer,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoQueryBasicInfo(
+ IN PFILE_OBJECT FileObject,
+ IN BOOLEAN Wait,
+ OUT PFILE_BASIC_INFORMATION Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoQueryBasicInfo()\n");
static FAST_IO_QUERY_STANDARD_INFO VfatFastIoQueryStandardInfo;
-static BOOLEAN NTAPI
-VfatFastIoQueryStandardInfo(IN PFILE_OBJECT FileObject,
- IN BOOLEAN Wait,
- OUT PFILE_STANDARD_INFORMATION Buffer,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoQueryStandardInfo(
+ IN PFILE_OBJECT FileObject,
+ IN BOOLEAN Wait,
+ OUT PFILE_STANDARD_INFORMATION Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoQueryStandardInfo\n");
static FAST_IO_LOCK VfatFastIoLock;
-static BOOLEAN NTAPI
-VfatFastIoLock(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN PLARGE_INTEGER Length,
- PEPROCESS ProcessId,
- ULONG Key,
- BOOLEAN FailImmediately,
- BOOLEAN ExclusiveLock,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoLock(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PLARGE_INTEGER Length,
+ PEPROCESS ProcessId,
+ ULONG Key,
+ BOOLEAN FailImmediately,
+ BOOLEAN ExclusiveLock,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoLock\n");
static FAST_IO_UNLOCK_SINGLE VfatFastIoUnlockSingle;
-static BOOLEAN NTAPI
-VfatFastIoUnlockSingle(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN PLARGE_INTEGER Length,
- PEPROCESS ProcessId,
- ULONG Key,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoUnlockSingle(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PLARGE_INTEGER Length,
+ PEPROCESS ProcessId,
+ ULONG Key,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoUnlockSingle\n");
static FAST_IO_UNLOCK_ALL VfatFastIoUnlockAll;
-static BOOLEAN NTAPI
-VfatFastIoUnlockAll(IN PFILE_OBJECT FileObject,
- PEPROCESS ProcessId,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoUnlockAll(
+ IN PFILE_OBJECT FileObject,
+ PEPROCESS ProcessId,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoUnlockAll\n");
static FAST_IO_UNLOCK_ALL_BY_KEY VfatFastIoUnlockAllByKey;
-static BOOLEAN NTAPI
-VfatFastIoUnlockAllByKey(IN PFILE_OBJECT FileObject,
- PVOID ProcessId,
- ULONG Key,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoUnlockAllByKey(
+ IN PFILE_OBJECT FileObject,
+ PVOID ProcessId,
+ ULONG Key,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoUnlockAllByKey\n");
static FAST_IO_DEVICE_CONTROL VfatFastIoDeviceControl;
-static BOOLEAN NTAPI
-VfatFastIoDeviceControl(IN PFILE_OBJECT FileObject,
- IN BOOLEAN Wait,
- IN PVOID InputBuffer OPTIONAL,
- IN ULONG InputBufferLength,
- OUT PVOID OutputBuffer OPTIONAL,
- IN ULONG OutputBufferLength,
- IN ULONG IoControlCode,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoDeviceControl(
+ IN PFILE_OBJECT FileObject,
+ IN BOOLEAN Wait,
+ IN PVOID InputBuffer OPTIONAL,
+ IN ULONG InputBufferLength,
+ OUT PVOID OutputBuffer OPTIONAL,
+ IN ULONG OutputBufferLength,
+ IN ULONG IoControlCode,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoDeviceControl\n");
static FAST_IO_ACQUIRE_FILE VfatAcquireFileForNtCreateSection;
-static VOID NTAPI
-VfatAcquireFileForNtCreateSection(IN PFILE_OBJECT FileObject)
+static
+VOID
+NTAPI
+VfatAcquireFileForNtCreateSection(
+ IN PFILE_OBJECT FileObject)
{
DPRINT("VfatAcquireFileForNtCreateSection\n");
UNREFERENCED_PARAMETER(FileObject);
static FAST_IO_RELEASE_FILE VfatReleaseFileForNtCreateSection;
-static VOID NTAPI
-VfatReleaseFileForNtCreateSection(IN PFILE_OBJECT FileObject)
+static
+VOID
+NTAPI
+VfatReleaseFileForNtCreateSection(
+ IN PFILE_OBJECT FileObject)
{
DPRINT("VfatReleaseFileForNtCreateSection\n");
UNREFERENCED_PARAMETER(FileObject);
static FAST_IO_DETACH_DEVICE VfatFastIoDetachDevice;
-static VOID NTAPI
-VfatFastIoDetachDevice(IN PDEVICE_OBJECT SourceDevice,
- IN PDEVICE_OBJECT TargetDevice)
+static
+VOID
+NTAPI
+VfatFastIoDetachDevice(
+ IN PDEVICE_OBJECT SourceDevice,
+ IN PDEVICE_OBJECT TargetDevice)
{
DPRINT("VfatFastIoDetachDevice\n");
UNREFERENCED_PARAMETER(SourceDevice);
static FAST_IO_QUERY_NETWORK_OPEN_INFO VfatFastIoQueryNetworkOpenInfo;
-static BOOLEAN NTAPI
-VfatFastIoQueryNetworkOpenInfo(IN PFILE_OBJECT FileObject,
- IN BOOLEAN Wait,
- OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoQueryNetworkOpenInfo(
+ IN PFILE_OBJECT FileObject,
+ IN BOOLEAN Wait,
+ OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoQueryNetworkOpenInfo\n");
static FAST_IO_ACQUIRE_FOR_MOD_WRITE VfatAcquireForModWrite;
-static NTSTATUS NTAPI
-VfatAcquireForModWrite(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER EndingOffset,
- OUT PERESOURCE* ResourceToRelease,
- IN PDEVICE_OBJECT DeviceObject)
+static
+NTSTATUS
+NTAPI
+VfatAcquireForModWrite(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER EndingOffset,
+ OUT PERESOURCE* ResourceToRelease,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatAcquireForModWrite\n");
static FAST_IO_MDL_READ VfatMdlRead;
-static BOOLEAN NTAPI
-VfatMdlRead(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN ULONG LockKey,
- OUT PMDL* MdlChain,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatMdlRead(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG LockKey,
+ OUT PMDL* MdlChain,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatMdlRead\n");
static FAST_IO_MDL_READ_COMPLETE VfatMdlReadComplete;
-static BOOLEAN NTAPI
-VfatMdlReadComplete(IN PFILE_OBJECT FileObject,
- IN PMDL MdlChain,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatMdlReadComplete(
+ IN PFILE_OBJECT FileObject,
+ IN PMDL MdlChain,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatMdlReadComplete\n");
static FAST_IO_PREPARE_MDL_WRITE VfatPrepareMdlWrite;
-static BOOLEAN NTAPI
-VfatPrepareMdlWrite(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN ULONG LockKey,
- OUT PMDL* MdlChain,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatPrepareMdlWrite(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG LockKey,
+ OUT PMDL* MdlChain,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatPrepareMdlWrite\n");
static FAST_IO_MDL_WRITE_COMPLETE VfatMdlWriteComplete;
-static BOOLEAN NTAPI
-VfatMdlWriteComplete(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN PMDL MdlChain,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatMdlWriteComplete(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PMDL MdlChain,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatMdlWriteComplete\n");
static FAST_IO_READ_COMPRESSED VfatFastIoReadCompressed;
-static BOOLEAN NTAPI
-VfatFastIoReadCompressed(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN ULONG LockKey,
- OUT PVOID Buffer,
- OUT PMDL* MdlChain,
- OUT PIO_STATUS_BLOCK IoStatus,
- OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
- IN ULONG CompressedDataInfoLength,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoReadCompressed(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG LockKey,
+ OUT PVOID Buffer,
+ OUT PMDL* MdlChain,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
+ IN ULONG CompressedDataInfoLength,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoReadCompressed\n");
static FAST_IO_WRITE_COMPRESSED VfatFastIoWriteCompressed;
-static BOOLEAN NTAPI
-VfatFastIoWriteCompressed(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN ULONG LockKey,
- IN PVOID Buffer,
- OUT PMDL* MdlChain,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
- IN ULONG CompressedDataInfoLength,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoWriteCompressed(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG LockKey,
+ IN PVOID Buffer,
+ OUT PMDL* MdlChain,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
+ IN ULONG CompressedDataInfoLength,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatFastIoWriteCompressed\n");
static FAST_IO_MDL_READ_COMPLETE_COMPRESSED VfatMdlReadCompleteCompressed;
-static BOOLEAN NTAPI
-VfatMdlReadCompleteCompressed(IN PFILE_OBJECT FileObject,
- IN PMDL MdlChain,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatMdlReadCompleteCompressed(
+ IN PFILE_OBJECT FileObject,
+ IN PMDL MdlChain,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatMdlReadCompleteCompressed\n");
static FAST_IO_MDL_WRITE_COMPLETE_COMPRESSED VfatMdlWriteCompleteCompressed;
-static BOOLEAN NTAPI
-VfatMdlWriteCompleteCompressed(IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN PMDL MdlChain,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatMdlWriteCompleteCompressed(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PMDL MdlChain,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatMdlWriteCompleteCompressed\n");
static FAST_IO_QUERY_OPEN VfatFastIoQueryOpen;
-static BOOLEAN NTAPI
-VfatFastIoQueryOpen(IN PIRP Irp,
- OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
- IN PDEVICE_OBJECT DeviceObject)
+static
+BOOLEAN
+NTAPI
+VfatFastIoQueryOpen(
+ IN PIRP Irp,
+ OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
+ IN PDEVICE_OBJECT DeviceObject)
{
- DPRINT("VfatFastIoQueryOpen\n");
+ DPRINT("VfatFastIoQueryOpen\n");
UNREFERENCED_PARAMETER(Irp);
UNREFERENCED_PARAMETER(NetworkInformation);
static FAST_IO_RELEASE_FOR_MOD_WRITE VfatReleaseForModWrite;
-static NTSTATUS NTAPI
-VfatReleaseForModWrite(IN PFILE_OBJECT FileObject,
- IN PERESOURCE ResourceToRelease,
- IN PDEVICE_OBJECT DeviceObject)
+static
+NTSTATUS
+NTAPI
+VfatReleaseForModWrite(
+ IN PFILE_OBJECT FileObject,
+ IN PERESOURCE ResourceToRelease,
+ IN PDEVICE_OBJECT DeviceObject)
{
DPRINT("VfatReleaseForModWrite\n");
static FAST_IO_ACQUIRE_FOR_CCFLUSH VfatAcquireForCcFlush;
-static NTSTATUS NTAPI
-VfatAcquireForCcFlush(IN PFILE_OBJECT FileObject,
- IN PDEVICE_OBJECT DeviceObject)
+static
+NTSTATUS
+NTAPI
+VfatAcquireForCcFlush(
+ IN PFILE_OBJECT FileObject,
+ IN PDEVICE_OBJECT DeviceObject)
{
- PVFATFCB Fcb = (PVFATFCB)FileObject->FsContext;
+ PVFATFCB Fcb = (PVFATFCB)FileObject->FsContext;
- DPRINT("VfatAcquireForCcFlush\n");
+ DPRINT("VfatAcquireForCcFlush\n");
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(DeviceObject);
- /* Make sure it is not a volume lock */
- ASSERT(!(Fcb->Flags & FCB_IS_VOLUME));
+ /* Make sure it is not a volume lock */
+ ASSERT(!(Fcb->Flags & FCB_IS_VOLUME));
- /* Acquire the resource */
- ExAcquireResourceExclusiveLite(&(Fcb->MainResource), TRUE);
+ /* Acquire the resource */
+ ExAcquireResourceExclusiveLite(&(Fcb->MainResource), TRUE);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
static FAST_IO_RELEASE_FOR_CCFLUSH VfatReleaseForCcFlush;
-static NTSTATUS NTAPI
-VfatReleaseForCcFlush(IN PFILE_OBJECT FileObject,
- IN PDEVICE_OBJECT DeviceObject)
+static
+NTSTATUS
+NTAPI
+VfatReleaseForCcFlush(
+ IN PFILE_OBJECT FileObject,
+ IN PDEVICE_OBJECT DeviceObject)
{
- PVFATFCB Fcb = (PVFATFCB)FileObject->FsContext;
+ PVFATFCB Fcb = (PVFATFCB)FileObject->FsContext;
- DPRINT("VfatReleaseForCcFlush\n");
+ DPRINT("VfatReleaseForCcFlush\n");
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(DeviceObject);
- /* Make sure it is not a volume lock */
- ASSERT(!(Fcb->Flags & FCB_IS_VOLUME));
+ /* Make sure it is not a volume lock */
+ ASSERT(!(Fcb->Flags & FCB_IS_VOLUME));
- /* Release the resource */
- ExReleaseResourceLite(&(Fcb->MainResource));
+ /* Release the resource */
+ ExReleaseResourceLite(&(Fcb->MainResource));
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-BOOLEAN NTAPI
-VfatAcquireForLazyWrite(IN PVOID Context,
- IN BOOLEAN Wait)
+BOOLEAN
+NTAPI
+VfatAcquireForLazyWrite(
+ IN PVOID Context,
+ IN BOOLEAN Wait)
{
- PVFATFCB Fcb = (PVFATFCB)Context;
- ASSERT(Fcb);
- DPRINT("VfatAcquireForLazyWrite(): Fcb %p\n", Fcb);
+ PVFATFCB Fcb = (PVFATFCB)Context;
+ ASSERT(Fcb);
+ DPRINT("VfatAcquireForLazyWrite(): Fcb %p\n", Fcb);
- if (!ExAcquireResourceExclusiveLite(&(Fcb->MainResource), Wait))
- {
- DPRINT("VfatAcquireForLazyWrite(): ExReleaseResourceLite failed.\n");
- return FALSE;
- }
- return TRUE;
+ if (!ExAcquireResourceExclusiveLite(&(Fcb->MainResource), Wait))
+ {
+ DPRINT("VfatAcquireForLazyWrite(): ExReleaseResourceLite failed.\n");
+ return FALSE;
+ }
+ return TRUE;
}
-VOID NTAPI
-VfatReleaseFromLazyWrite(IN PVOID Context)
+VOID
+NTAPI
+VfatReleaseFromLazyWrite(
+ IN PVOID Context)
{
- PVFATFCB Fcb = (PVFATFCB)Context;
- ASSERT(Fcb);
- DPRINT("VfatReleaseFromLazyWrite(): Fcb %p\n", Fcb);
+ PVFATFCB Fcb = (PVFATFCB)Context;
+ ASSERT(Fcb);
+ DPRINT("VfatReleaseFromLazyWrite(): Fcb %p\n", Fcb);
- ExReleaseResourceLite(&(Fcb->MainResource));
+ ExReleaseResourceLite(&(Fcb->MainResource));
}
-BOOLEAN NTAPI
-VfatAcquireForReadAhead(IN PVOID Context,
- IN BOOLEAN Wait)
+BOOLEAN
+NTAPI
+VfatAcquireForReadAhead(
+ IN PVOID Context,
+ IN BOOLEAN Wait)
{
- PVFATFCB Fcb = (PVFATFCB)Context;
- ASSERT(Fcb);
- DPRINT("VfatAcquireForReadAhead(): Fcb %p\n", Fcb);
+ PVFATFCB Fcb = (PVFATFCB)Context;
+ ASSERT(Fcb);
+ DPRINT("VfatAcquireForReadAhead(): Fcb %p\n", Fcb);
- if (!ExAcquireResourceExclusiveLite(&(Fcb->MainResource), Wait))
- {
- DPRINT("VfatAcquireForReadAhead(): ExReleaseResourceLite failed.\n");
- return FALSE;
- }
- return TRUE;
+ if (!ExAcquireResourceExclusiveLite(&(Fcb->MainResource), Wait))
+ {
+ DPRINT("VfatAcquireForReadAhead(): ExReleaseResourceLite failed.\n");
+ return FALSE;
+ }
+ return TRUE;
}
-VOID NTAPI
-VfatReleaseFromReadAhead(IN PVOID Context)
+VOID
+NTAPI
+VfatReleaseFromReadAhead(
+ IN PVOID Context)
{
- PVFATFCB Fcb = (PVFATFCB)Context;
- ASSERT(Fcb);
- DPRINT("VfatReleaseFromReadAhead(): Fcb %p\n", Fcb);
+ PVFATFCB Fcb = (PVFATFCB)Context;
+ ASSERT(Fcb);
+ DPRINT("VfatReleaseFromReadAhead(): Fcb %p\n", Fcb);
- ExReleaseResourceLite(&(Fcb->MainResource));
+ ExReleaseResourceLite(&(Fcb->MainResource));
}
VOID
-VfatInitFastIoRoutines(PFAST_IO_DISPATCH FastIoDispatch)
-{
- FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
- FastIoDispatch->FastIoCheckIfPossible = VfatFastIoCheckIfPossible;
- FastIoDispatch->FastIoRead = VfatFastIoRead;
- FastIoDispatch->FastIoWrite = VfatFastIoWrite;
- FastIoDispatch->FastIoQueryBasicInfo = VfatFastIoQueryBasicInfo;
- FastIoDispatch->FastIoQueryStandardInfo = VfatFastIoQueryStandardInfo;
- FastIoDispatch->FastIoLock = VfatFastIoLock;
- FastIoDispatch->FastIoUnlockSingle = VfatFastIoUnlockSingle;
- FastIoDispatch->FastIoUnlockAll = VfatFastIoUnlockAll;
- FastIoDispatch->FastIoUnlockAllByKey = VfatFastIoUnlockAllByKey;
- FastIoDispatch->FastIoDeviceControl = VfatFastIoDeviceControl;
- FastIoDispatch->AcquireFileForNtCreateSection = VfatAcquireFileForNtCreateSection;
- FastIoDispatch->ReleaseFileForNtCreateSection = VfatReleaseFileForNtCreateSection;
- FastIoDispatch->FastIoDetachDevice = VfatFastIoDetachDevice;
- FastIoDispatch->FastIoQueryNetworkOpenInfo = VfatFastIoQueryNetworkOpenInfo;
- FastIoDispatch->MdlRead = VfatMdlRead;
- FastIoDispatch->MdlReadComplete = VfatMdlReadComplete;
- FastIoDispatch->PrepareMdlWrite = VfatPrepareMdlWrite;
- FastIoDispatch->MdlWriteComplete = VfatMdlWriteComplete;
- FastIoDispatch->FastIoReadCompressed = VfatFastIoReadCompressed;
- FastIoDispatch->FastIoWriteCompressed = VfatFastIoWriteCompressed;
- FastIoDispatch->MdlReadCompleteCompressed = VfatMdlReadCompleteCompressed;
- FastIoDispatch->MdlWriteCompleteCompressed = VfatMdlWriteCompleteCompressed;
- FastIoDispatch->FastIoQueryOpen = VfatFastIoQueryOpen;
- FastIoDispatch->AcquireForModWrite = VfatAcquireForModWrite;
- FastIoDispatch->ReleaseForModWrite = VfatReleaseForModWrite;
- FastIoDispatch->AcquireForCcFlush = VfatAcquireForCcFlush;
- FastIoDispatch->ReleaseForCcFlush = VfatReleaseForCcFlush;
+VfatInitFastIoRoutines(
+ PFAST_IO_DISPATCH FastIoDispatch)
+{
+ FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
+ FastIoDispatch->FastIoCheckIfPossible = VfatFastIoCheckIfPossible;
+ FastIoDispatch->FastIoRead = VfatFastIoRead;
+ FastIoDispatch->FastIoWrite = VfatFastIoWrite;
+ FastIoDispatch->FastIoQueryBasicInfo = VfatFastIoQueryBasicInfo;
+ FastIoDispatch->FastIoQueryStandardInfo = VfatFastIoQueryStandardInfo;
+ FastIoDispatch->FastIoLock = VfatFastIoLock;
+ FastIoDispatch->FastIoUnlockSingle = VfatFastIoUnlockSingle;
+ FastIoDispatch->FastIoUnlockAll = VfatFastIoUnlockAll;
+ FastIoDispatch->FastIoUnlockAllByKey = VfatFastIoUnlockAllByKey;
+ FastIoDispatch->FastIoDeviceControl = VfatFastIoDeviceControl;
+ FastIoDispatch->AcquireFileForNtCreateSection = VfatAcquireFileForNtCreateSection;
+ FastIoDispatch->ReleaseFileForNtCreateSection = VfatReleaseFileForNtCreateSection;
+ FastIoDispatch->FastIoDetachDevice = VfatFastIoDetachDevice;
+ FastIoDispatch->FastIoQueryNetworkOpenInfo = VfatFastIoQueryNetworkOpenInfo;
+ FastIoDispatch->MdlRead = VfatMdlRead;
+ FastIoDispatch->MdlReadComplete = VfatMdlReadComplete;
+ FastIoDispatch->PrepareMdlWrite = VfatPrepareMdlWrite;
+ FastIoDispatch->MdlWriteComplete = VfatMdlWriteComplete;
+ FastIoDispatch->FastIoReadCompressed = VfatFastIoReadCompressed;
+ FastIoDispatch->FastIoWriteCompressed = VfatFastIoWriteCompressed;
+ FastIoDispatch->MdlReadCompleteCompressed = VfatMdlReadCompleteCompressed;
+ FastIoDispatch->MdlWriteCompleteCompressed = VfatMdlWriteCompleteCompressed;
+ FastIoDispatch->FastIoQueryOpen = VfatFastIoQueryOpen;
+ FastIoDispatch->AcquireForModWrite = VfatAcquireForModWrite;
+ FastIoDispatch->ReleaseForModWrite = VfatReleaseForModWrite;
+ FastIoDispatch->AcquireForCcFlush = VfatAcquireForCcFlush;
+ FastIoDispatch->ReleaseForCcFlush = VfatReleaseForCcFlush;
}
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = CurrentCluster * 2;
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
+ if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
return STATUS_DISK_FULL;
}
-NTSTATUS
-FAT12FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
/*
* FUNCTION: Finds the first available cluster in a FAT12 table
*/
+NTSTATUS
+FAT12FindAndMarkAvailableCluster(
+ PDEVICE_EXTENSION DeviceExt,
+ PULONG Cluster)
{
- ULONG FatLength;
- ULONG StartCluster;
- ULONG Entry;
- PUSHORT CBlock;
- ULONG i, j;
- PVOID BaseAddress;
- PVOID Context;
- LARGE_INTEGER Offset;
-
- FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
- *Cluster = 0;
- StartCluster = DeviceExt->LastAvailableCluster;
- Offset.QuadPart = 0;
- if(!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
- {
- DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
- return STATUS_UNSUCCESSFUL;
- }
-
- for (j = 0; j < 2; j++)
- {
- for (i = StartCluster; i < FatLength; i++)
+ ULONG FatLength;
+ ULONG StartCluster;
+ ULONG Entry;
+ PUSHORT CBlock;
+ ULONG i, j;
+ PVOID BaseAddress;
+ PVOID Context;
+ LARGE_INTEGER Offset;
+
+ FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
+ *Cluster = 0;
+ StartCluster = DeviceExt->LastAvailableCluster;
+ Offset.QuadPart = 0;
+ if (!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{
- CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
- if ((i % 2) == 0)
- {
- Entry = *CBlock & 0xfff;
- }
- else
- {
- Entry = *CBlock >> 4;
- }
- if (Entry == 0)
- {
- DPRINT("Found available cluster 0x%x\n", i);
- DeviceExt->LastAvailableCluster = *Cluster = i;
- if ((i % 2) == 0)
- *CBlock = (*CBlock & 0xf000) | 0xfff;
- else
- *CBlock = (*CBlock & 0xf) | 0xfff0;
- CcSetDirtyPinnedData(Context, NULL);
- CcUnpinData(Context);
- if (DeviceExt->AvailableClustersValid)
- InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
- return(STATUS_SUCCESS);
- }
+ DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
+ return STATUS_UNSUCCESSFUL;
}
- FatLength = StartCluster;
- StartCluster = 2;
- }
- CcUnpinData(Context);
- return (STATUS_DISK_FULL);
+
+ for (j = 0; j < 2; j++)
+ {
+ for (i = StartCluster; i < FatLength; i++)
+ {
+ CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
+ if ((i % 2) == 0)
+ {
+ Entry = *CBlock & 0xfff;
+ }
+ else
+ {
+ Entry = *CBlock >> 4;
+ }
+
+ if (Entry == 0)
+ {
+ DPRINT("Found available cluster 0x%x\n", i);
+ DeviceExt->LastAvailableCluster = *Cluster = i;
+ if ((i % 2) == 0)
+ *CBlock = (*CBlock & 0xf000) | 0xfff;
+ else
+ *CBlock = (*CBlock & 0xf) | 0xfff0;
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ if (DeviceExt->AvailableClustersValid)
+ InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
+ return STATUS_SUCCESS;
+ }
+ }
+ FatLength = StartCluster;
+ StartCluster = 2;
+ }
+ CcUnpinData(Context);
+ return STATUS_DISK_FULL;
}
-NTSTATUS
-FAT32FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
/*
* FUNCTION: Finds the first available cluster in a FAT32 table
*/
+NTSTATUS
+FAT32FindAndMarkAvailableCluster(
+ PDEVICE_EXTENSION DeviceExt,
+ PULONG Cluster)
{
- ULONG FatLength;
- ULONG StartCluster;
- ULONG i, j;
- PVOID BaseAddress;
- ULONG ChunkSize;
- PVOID Context;
- LARGE_INTEGER Offset;
- PULONG Block;
- PULONG BlockEnd;
-
- ChunkSize = CACHEPAGESIZE(DeviceExt);
- FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
- *Cluster = 0;
- StartCluster = DeviceExt->LastAvailableCluster;
-
- for (j = 0; j < 2; j++)
- {
- for (i = StartCluster; i < FatLength;)
+ ULONG FatLength;
+ ULONG StartCluster;
+ ULONG i, j;
+ PVOID BaseAddress;
+ ULONG ChunkSize;
+ PVOID Context;
+ LARGE_INTEGER Offset;
+ PULONG Block;
+ PULONG BlockEnd;
+
+ ChunkSize = CACHEPAGESIZE(DeviceExt);
+ FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
+ *Cluster = 0;
+ StartCluster = DeviceExt->LastAvailableCluster;
+
+ for (j = 0; j < 2; j++)
{
- Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
- if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
- {
- DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
- return STATUS_UNSUCCESSFUL;
- }
- Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
- BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
-
- /* Now process the whole block */
- while (Block < BlockEnd && i < FatLength)
- {
- if ((*Block & 0x0fffffff) == 0)
+ for (i = StartCluster; i < FatLength;)
{
- DPRINT("Found available cluster 0x%x\n", i);
- DeviceExt->LastAvailableCluster = *Cluster = i;
- *Block = 0x0fffffff;
- CcSetDirtyPinnedData(Context, NULL);
- CcUnpinData(Context);
- if (DeviceExt->AvailableClustersValid)
- InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
- return(STATUS_SUCCESS);
- }
+ Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
+ if (!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
+ {
+ DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
+ return STATUS_UNSUCCESSFUL;
+ }
+ Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
+ BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
+
+ /* Now process the whole block */
+ while (Block < BlockEnd && i < FatLength)
+ {
+ if ((*Block & 0x0fffffff) == 0)
+ {
+ DPRINT("Found available cluster 0x%x\n", i);
+ DeviceExt->LastAvailableCluster = *Cluster = i;
+ *Block = 0x0fffffff;
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ if (DeviceExt->AvailableClustersValid)
+ InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
+ return STATUS_SUCCESS;
+ }
- Block++;
- i++;
- }
+ Block++;
+ i++;
+ }
- CcUnpinData(Context);
+ CcUnpinData(Context);
+ }
+ FatLength = StartCluster;
+ StartCluster = 2;
}
- FatLength = StartCluster;
- StartCluster = 2;
- }
- return (STATUS_DISK_FULL);
+ return STATUS_DISK_FULL;
}
-static NTSTATUS
-FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free cluster in a FAT12 table
*/
+static
+NTSTATUS
+FAT12CountAvailableClusters(
+ PDEVICE_EXTENSION DeviceExt)
{
- ULONG Entry;
- PVOID BaseAddress;
- ULONG ulCount = 0;
- ULONG i;
- ULONG numberofclusters;
- LARGE_INTEGER Offset;
- PVOID Context;
- PUSHORT CBlock;
-
- Offset.QuadPart = 0;
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
-
- for (i = 2; i < numberofclusters; i++)
+ ULONG Entry;
+ PVOID BaseAddress;
+ ULONG ulCount = 0;
+ ULONG i;
+ ULONG numberofclusters;
+ LARGE_INTEGER Offset;
+ PVOID Context;
+ PUSHORT CBlock;
+
+ Offset.QuadPart = 0;
+ if (!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{
- CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
- if ((i % 2) == 0)
- {
- Entry = *CBlock & 0x0fff;
- }
- else
- {
- Entry = *CBlock >> 4;
- }
- if (Entry == 0)
- ulCount++;
+ return STATUS_UNSUCCESSFUL;
}
- CcUnpinData(Context);
- DeviceExt->AvailableClusters = ulCount;
- DeviceExt->AvailableClustersValid = TRUE;
+ numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
- return(STATUS_SUCCESS);
+ for (i = 2; i < numberofclusters; i++)
+ {
+ CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
+ if ((i % 2) == 0)
+ {
+ Entry = *CBlock & 0x0fff;
+ }
+ else
+ {
+ Entry = *CBlock >> 4;
+ }
+
+ if (Entry == 0)
+ ulCount++;
+ }
+
+ CcUnpinData(Context);
+ DeviceExt->AvailableClusters = ulCount;
+ DeviceExt->AvailableClustersValid = TRUE;
+
+ return STATUS_SUCCESS;
}
-static NTSTATUS
-FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free clusters in a FAT16 table
*/
+static
+NTSTATUS
+FAT16CountAvailableClusters(
+ PDEVICE_EXTENSION DeviceExt)
{
- PUSHORT Block;
- PUSHORT BlockEnd;
- PVOID BaseAddress = NULL;
- ULONG ulCount = 0;
- ULONG i;
- ULONG ChunkSize;
- PVOID Context = NULL;
- LARGE_INTEGER Offset;
- ULONG FatLength;
-
- ChunkSize = CACHEPAGESIZE(DeviceExt);
- FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
-
- for (i = 2; i < FatLength; )
- {
- Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
- {
- return STATUS_UNSUCCESSFUL;
- }
- Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
- BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
+ PUSHORT Block;
+ PUSHORT BlockEnd;
+ PVOID BaseAddress = NULL;
+ ULONG ulCount = 0;
+ ULONG i;
+ ULONG ChunkSize;
+ PVOID Context = NULL;
+ LARGE_INTEGER Offset;
+ ULONG FatLength;
- /* Now process the whole block */
- while (Block < BlockEnd && i < FatLength)
+ ChunkSize = CACHEPAGESIZE(DeviceExt);
+ FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
+
+ for (i = 2; i < FatLength; )
{
- if (*Block == 0)
- ulCount++;
- Block++;
- i++;
- }
+ Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
+ if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+ Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
+ BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
- CcUnpinData(Context);
- }
+ /* Now process the whole block */
+ while (Block < BlockEnd && i < FatLength)
+ {
+ if (*Block == 0)
+ ulCount++;
+ Block++;
+ i++;
+ }
+
+ CcUnpinData(Context);
+ }
- DeviceExt->AvailableClusters = ulCount;
- DeviceExt->AvailableClustersValid = TRUE;
+ DeviceExt->AvailableClusters = ulCount;
+ DeviceExt->AvailableClustersValid = TRUE;
- return(STATUS_SUCCESS);
+ return STATUS_SUCCESS;
}
-static NTSTATUS
-FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free clusters in a FAT32 table
*/
+static
+NTSTATUS
+FAT32CountAvailableClusters(
+ PDEVICE_EXTENSION DeviceExt)
{
- PULONG Block;
- PULONG BlockEnd;
- PVOID BaseAddress = NULL;
- ULONG ulCount = 0;
- ULONG i;
- ULONG ChunkSize;
- PVOID Context = NULL;
- LARGE_INTEGER Offset;
- ULONG FatLength;
-
- ChunkSize = CACHEPAGESIZE(DeviceExt);
- FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
-
- for (i = 2; i < FatLength; )
- {
- Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
- {
- DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
- return STATUS_UNSUCCESSFUL;
- }
- Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
- BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
+ PULONG Block;
+ PULONG BlockEnd;
+ PVOID BaseAddress = NULL;
+ ULONG ulCount = 0;
+ ULONG i;
+ ULONG ChunkSize;
+ PVOID Context = NULL;
+ LARGE_INTEGER Offset;
+ ULONG FatLength;
- /* Now process the whole block */
- while (Block < BlockEnd && i < FatLength)
+ ChunkSize = CACHEPAGESIZE(DeviceExt);
+ FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
+
+ for (i = 2; i < FatLength; )
{
- if ((*Block & 0x0fffffff) == 0)
- ulCount++;
- Block++;
- i++;
- }
+ Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
+ if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
+ {
+ DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
+ return STATUS_UNSUCCESSFUL;
+ }
+ Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
+ BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
- CcUnpinData(Context);
- }
+ /* Now process the whole block */
+ while (Block < BlockEnd && i < FatLength)
+ {
+ if ((*Block & 0x0fffffff) == 0)
+ ulCount++;
+ Block++;
+ i++;
+ }
+
+ CcUnpinData(Context);
+ }
- DeviceExt->AvailableClusters = ulCount;
- DeviceExt->AvailableClustersValid = TRUE;
+ DeviceExt->AvailableClusters = ulCount;
+ DeviceExt->AvailableClustersValid = TRUE;
- return(STATUS_SUCCESS);
+ return STATUS_SUCCESS;
}
NTSTATUS
-CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
- PLARGE_INTEGER Clusters)
+CountAvailableClusters(
+ PDEVICE_EXTENSION DeviceExt,
+ PLARGE_INTEGER Clusters)
{
- NTSTATUS Status = STATUS_SUCCESS;
- ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
- if (!DeviceExt->AvailableClustersValid)
- {
- if (DeviceExt->FatInfo.FatType == FAT12)
- Status = FAT12CountAvailableClusters(DeviceExt);
- else if (DeviceExt->FatInfo.FatType == FAT16 || DeviceExt->FatInfo.FatType == FATX16)
- Status = FAT16CountAvailableClusters(DeviceExt);
- else
- Status = FAT32CountAvailableClusters(DeviceExt);
+ NTSTATUS Status = STATUS_SUCCESS;
+ ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
+ if (!DeviceExt->AvailableClustersValid)
+ {
+ if (DeviceExt->FatInfo.FatType == FAT12)
+ Status = FAT12CountAvailableClusters(DeviceExt);
+ else if (DeviceExt->FatInfo.FatType == FAT16 || DeviceExt->FatInfo.FatType == FATX16)
+ Status = FAT16CountAvailableClusters(DeviceExt);
+ else
+ Status = FAT32CountAvailableClusters(DeviceExt);
}
- Clusters->QuadPart = DeviceExt->AvailableClusters;
- ExReleaseResourceLite (&DeviceExt->FatResource);
+ Clusters->QuadPart = DeviceExt->AvailableClusters;
+ ExReleaseResourceLite (&DeviceExt->FatResource);
- return Status;
+ return Status;
}
-
-
-
-NTSTATUS
-FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG ClusterToWrite,
- ULONG NewValue,
- PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
*/
+NTSTATUS
+FAT12WriteCluster(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG ClusterToWrite,
+ ULONG NewValue,
+ PULONG OldValue)
{
- ULONG FATOffset;
- PUCHAR CBlock;
- PVOID BaseAddress;
- PVOID Context;
- LARGE_INTEGER Offset;
-
- Offset.QuadPart = 0;
- if(!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
- {
- return STATUS_UNSUCCESSFUL;
- }
- CBlock = (PUCHAR)BaseAddress;
-
- FATOffset = (ClusterToWrite * 12) / 8;
- DPRINT("Writing 0x%x for 0x%x at 0x%x\n",
- NewValue, ClusterToWrite, FATOffset);
- if ((ClusterToWrite % 2) == 0)
+ ULONG FATOffset;
+ PUCHAR CBlock;
+ PVOID BaseAddress;
+ PVOID Context;
+ LARGE_INTEGER Offset;
+
+ Offset.QuadPart = 0;
+ if (!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{
- *OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
- CBlock[FATOffset] = (UCHAR)NewValue;
- CBlock[FATOffset + 1] &= 0xf0;
- CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
+ return STATUS_UNSUCCESSFUL;
}
- else
+ CBlock = (PUCHAR)BaseAddress;
+
+ FATOffset = (ClusterToWrite * 12) / 8;
+ DPRINT("Writing 0x%x for 0x%x at 0x%x\n",
+ NewValue, ClusterToWrite, FATOffset);
+ if ((ClusterToWrite % 2) == 0)
+ {
+ *OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
+ CBlock[FATOffset] = (UCHAR)NewValue;
+ CBlock[FATOffset + 1] &= 0xf0;
+ CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
+ }
+ else
{
- *OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
- CBlock[FATOffset] &= 0x0f;
- CBlock[FATOffset] |= (NewValue & 0xf) << 4;
- CBlock[FATOffset + 1] = (UCHAR)(NewValue >> 4);
+ *OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
+ CBlock[FATOffset] &= 0x0f;
+ CBlock[FATOffset] |= (NewValue & 0xf) << 4;
+ CBlock[FATOffset + 1] = (UCHAR)(NewValue >> 4);
}
- /* Write the changed FAT sector(s) to disk */
- CcSetDirtyPinnedData(Context, NULL);
- CcUnpinData(Context);
- return(STATUS_SUCCESS);
+ /* Write the changed FAT sector(s) to disk */
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ return STATUS_SUCCESS;
}
-NTSTATUS
-FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG ClusterToWrite,
- ULONG NewValue,
- PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
*/
+NTSTATUS
+FAT16WriteCluster(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG ClusterToWrite,
+ ULONG NewValue,
+ PULONG OldValue)
{
- PVOID BaseAddress;
- ULONG FATOffset;
- ULONG ChunkSize;
- PVOID Context;
- LARGE_INTEGER Offset;
- PUSHORT Cluster;
-
- ChunkSize = CACHEPAGESIZE(DeviceExt);
- FATOffset = ClusterToWrite * 2;
- Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
- if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
- {
- return STATUS_UNSUCCESSFUL;
- }
- DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
- ClusterToWrite);
- Cluster = ((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
- *OldValue = *Cluster;
- *Cluster = (USHORT)NewValue;
- CcSetDirtyPinnedData(Context, NULL);
- CcUnpinData(Context);
- return(STATUS_SUCCESS);
+ PVOID BaseAddress;
+ ULONG FATOffset;
+ ULONG ChunkSize;
+ PVOID Context;
+ LARGE_INTEGER Offset;
+ PUSHORT Cluster;
+
+ ChunkSize = CACHEPAGESIZE(DeviceExt);
+ FATOffset = ClusterToWrite * 2;
+ Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
+ if (!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
+ ClusterToWrite);
+ Cluster = ((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
+ *OldValue = *Cluster;
+ *Cluster = (USHORT)NewValue;
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ return STATUS_SUCCESS;
}
-NTSTATUS
-FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG ClusterToWrite,
- ULONG NewValue,
- PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT32 physical tables
*/
+NTSTATUS
+FAT32WriteCluster(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG ClusterToWrite,
+ ULONG NewValue,
+ PULONG OldValue)
{
- PVOID BaseAddress;
- ULONG FATOffset;
- ULONG ChunkSize;
- PVOID Context;
- LARGE_INTEGER Offset;
- PULONG Cluster;
-
- ChunkSize = CACHEPAGESIZE(DeviceExt);
-
- FATOffset = (ClusterToWrite * 4);
- Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
- if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
- {
- return STATUS_UNSUCCESSFUL;
- }
- DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
- ClusterToWrite);
- Cluster = ((PULONG)((char*)BaseAddress + (FATOffset % ChunkSize)));
- *OldValue = *Cluster & 0x0fffffff;
- *Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
-
- CcSetDirtyPinnedData(Context, NULL);
- CcUnpinData(Context);
-
- return(STATUS_SUCCESS);
+ PVOID BaseAddress;
+ ULONG FATOffset;
+ ULONG ChunkSize;
+ PVOID Context;
+ LARGE_INTEGER Offset;
+ PULONG Cluster;
+
+ ChunkSize = CACHEPAGESIZE(DeviceExt);
+
+ FATOffset = (ClusterToWrite * 4);
+ Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
+ if (!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
+ ClusterToWrite);
+ Cluster = ((PULONG)((char*)BaseAddress + (FATOffset % ChunkSize)));
+ *OldValue = *Cluster & 0x0fffffff;
+ *Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
+
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+
+ return STATUS_SUCCESS;
}
-NTSTATUS
-WriteCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG ClusterToWrite,
- ULONG NewValue)
/*
* FUNCTION: Write a changed FAT entry
*/
+NTSTATUS
+WriteCluster(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG ClusterToWrite,
+ ULONG NewValue)
{
- NTSTATUS Status;
- ULONG OldValue;
- ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
- Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
- if (DeviceExt->AvailableClustersValid)
- {
- if (OldValue && NewValue == 0)
- InterlockedIncrement((PLONG)&DeviceExt->AvailableClusters);
- else if (OldValue == 0 && NewValue)
- InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
- }
- ExReleaseResourceLite(&DeviceExt->FatResource);
- return(Status);
+ NTSTATUS Status;
+ ULONG OldValue;
+
+ ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
+ Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
+ if (DeviceExt->AvailableClustersValid)
+ {
+ if (OldValue && NewValue == 0)
+ InterlockedIncrement((PLONG)&DeviceExt->AvailableClusters);
+ else if (OldValue == 0 && NewValue)
+ InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
+ }
+ ExReleaseResourceLite(&DeviceExt->FatResource);
+ return Status;
}
-ULONGLONG
-ClusterToSector(PDEVICE_EXTENSION DeviceExt,
- ULONG Cluster)
/*
* FUNCTION: Converts the cluster number to a sector number for this physical
* device
*/
+ULONGLONG
+ClusterToSector(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG Cluster)
{
- return DeviceExt->FatInfo.dataStart +
- ((ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
+ return DeviceExt->FatInfo.dataStart +
+ ((ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
}
-NTSTATUS
-GetNextCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG CurrentCluster,
- PULONG NextCluster)
/*
* FUNCTION: Retrieve the next cluster depending on the FAT type
*/
+NTSTATUS
+GetNextCluster(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG CurrentCluster,
+ PULONG NextCluster)
{
- NTSTATUS Status;
+ NTSTATUS Status;
- DPRINT ("GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
- DeviceExt, CurrentCluster);
+ DPRINT("GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
+ DeviceExt, CurrentCluster);
- if (CurrentCluster == 0)
- return(STATUS_INVALID_PARAMETER);
+ if (CurrentCluster == 0)
+ return STATUS_INVALID_PARAMETER;
- ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
- Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
- ExReleaseResourceLite(&DeviceExt->FatResource);
+ ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
+ Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
+ ExReleaseResourceLite(&DeviceExt->FatResource);
- return(Status);
+ return Status;
}
-NTSTATUS
-GetNextClusterExtend(PDEVICE_EXTENSION DeviceExt,
- ULONG CurrentCluster,
- PULONG NextCluster)
/*
* FUNCTION: Retrieve the next cluster depending on the FAT type
*/
+NTSTATUS
+GetNextClusterExtend(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG CurrentCluster,
+ PULONG NextCluster)
{
- NTSTATUS Status;
-
- DPRINT ("GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
- DeviceExt, CurrentCluster);
-
- ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
- /*
- * If the file hasn't any clusters allocated then we need special
- * handling
- */
- if (CurrentCluster == 0)
- {
ULONG NewCluster;
+ NTSTATUS Status;
- Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
- if (!NT_SUCCESS(Status))
- {
- ExReleaseResourceLite(&DeviceExt->FatResource);
- return Status;
- }
-
- *NextCluster = NewCluster;
- ExReleaseResourceLite(&DeviceExt->FatResource);
- return(STATUS_SUCCESS);
- }
-
- Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
+ DPRINT("GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
+ DeviceExt, CurrentCluster);
- if ((*NextCluster) == 0xFFFFFFFF)
- {
- ULONG NewCluster;
+ ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
+ /*
+ * If the file hasn't any clusters allocated then we need special
+ * handling
+ */
+ if (CurrentCluster == 0)
+ {
+ Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
+ if (!NT_SUCCESS(Status))
+ {
+ ExReleaseResourceLite(&DeviceExt->FatResource);
+ return Status;
+ }
- /* We are after last existing cluster, we must add one to file */
- /* Firstly, find the next available open allocation unit and
- mark it as end of file */
- Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
- if (!NT_SUCCESS(Status))
- {
+ *NextCluster = NewCluster;
ExReleaseResourceLite(&DeviceExt->FatResource);
- return Status;
- }
+ return STATUS_SUCCESS;
+ }
- /* Now, write the AU of the LastCluster with the value of the newly
- found AU */
- WriteCluster(DeviceExt, CurrentCluster, NewCluster);
- *NextCluster = NewCluster;
- }
+ Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
- ExReleaseResourceLite(&DeviceExt->FatResource);
+ if ((*NextCluster) == 0xFFFFFFFF)
+ {
+ /* We are after last existing cluster, we must add one to file */
+ /* Firstly, find the next available open allocation unit and
+ mark it as end of file */
+ Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
+ if (!NT_SUCCESS(Status))
+ {
+ ExReleaseResourceLite(&DeviceExt->FatResource);
+ return Status;
+ }
- return(Status);
+ /* Now, write the AU of the LastCluster with the value of the newly
+ found AU */
+ WriteCluster(DeviceExt, CurrentCluster, NewCluster);
+ *NextCluster = NewCluster;
+ }
+
+ ExReleaseResourceLite(&DeviceExt->FatResource);
+ return Status;
}
/* EOF */
/* -------------------------------------------------------- PUBLICS */
-static ULONG vfatNameHash(ULONG hash, PUNICODE_STRING NameU)
+static
+ULONG
+vfatNameHash(
+ ULONG hash,
+ PUNICODE_STRING NameU)
{
- PWCHAR last;
- PWCHAR curr;
- register WCHAR c;
-
- // LFN could start from "."
- //ASSERT(NameU->Buffer[0] != L'.');
- curr = NameU->Buffer;
- last = NameU->Buffer + NameU->Length / sizeof(WCHAR);
-
- while(curr < last)
- {
- c = towlower(*curr++);
- hash = (hash + (c << 4) + (c >> 4)) * 11;
- }
- return hash;
+ PWCHAR last;
+ PWCHAR curr;
+ register WCHAR c;
+
+ // LFN could start from "."
+ //ASSERT(NameU->Buffer[0] != L'.');
+ curr = NameU->Buffer;
+ last = NameU->Buffer + NameU->Length / sizeof(WCHAR);
+
+ while(curr < last)
+ {
+ c = towlower(*curr++);
+ hash = (hash + (c << 4) + (c >> 4)) * 11;
+ }
+ return hash;
}
VOID
-vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
+vfatSplitPathName(
+ PUNICODE_STRING PathNameU,
+ PUNICODE_STRING DirNameU,
+ PUNICODE_STRING FileNameU)
{
- PWCHAR pName;
- USHORT Length = 0;
- pName = PathNameU->Buffer + PathNameU->Length / sizeof(WCHAR) - 1;
- 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;
- }
+ PWCHAR pName;
+ USHORT Length = 0;
+ pName = PathNameU->Buffer + PathNameU->Length / sizeof(WCHAR) - 1;
+ 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;
+ }
}
-static VOID
-vfatInitFcb(PVFATFCB Fcb, PUNICODE_STRING NameU)
+static
+VOID
+vfatInitFcb(
+ PVFATFCB Fcb,
+ PUNICODE_STRING NameU)
{
- USHORT PathNameBufferLength;
-
- if (NameU)
- PathNameBufferLength = NameU->Length + sizeof(WCHAR);
- else
- PathNameBufferLength = 0;
-
- Fcb->PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameBufferLength, TAG_FCB);
- if (!Fcb->PathNameBuffer)
- {
- /* FIXME: what to do if no more memory? */
- DPRINT1("Unable to initialize FCB for filename '%wZ'\n", NameU);
- KeBugCheckEx(FAT_FILE_SYSTEM, (ULONG_PTR)Fcb, (ULONG_PTR)NameU, 0, 0);
- }
-
- Fcb->PathNameU.Length = 0;
- Fcb->PathNameU.Buffer = Fcb->PathNameBuffer;
- Fcb->PathNameU.MaximumLength = PathNameBufferLength;
- Fcb->ShortNameU.Length = 0;
- Fcb->ShortNameU.Buffer = Fcb->ShortNameBuffer;
- Fcb->ShortNameU.MaximumLength = sizeof(Fcb->ShortNameBuffer);
- Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
- if (NameU && NameU->Length)
- {
- RtlCopyUnicodeString(&Fcb->PathNameU, NameU);
- vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
- }
- else
- {
- Fcb->DirNameU.Buffer = Fcb->LongNameU.Buffer = NULL;
- Fcb->DirNameU.MaximumLength = Fcb->DirNameU.Length = 0;
- Fcb->LongNameU.MaximumLength = Fcb->LongNameU.Length = 0;
- }
- RtlZeroMemory(&Fcb->FCBShareAccess, sizeof(SHARE_ACCESS));
- Fcb->OpenHandleCount = 0;
+ USHORT PathNameBufferLength;
+
+ if (NameU)
+ PathNameBufferLength = NameU->Length + sizeof(WCHAR);
+ else
+ PathNameBufferLength = 0;
+
+ Fcb->PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameBufferLength, TAG_FCB);
+ if (!Fcb->PathNameBuffer)
+ {
+ /* FIXME: what to do if no more memory? */
+ DPRINT1("Unable to initialize FCB for filename '%wZ'\n", NameU);
+ KeBugCheckEx(FAT_FILE_SYSTEM, (ULONG_PTR)Fcb, (ULONG_PTR)NameU, 0, 0);
+ }
+
+ Fcb->PathNameU.Length = 0;
+ Fcb->PathNameU.Buffer = Fcb->PathNameBuffer;
+ Fcb->PathNameU.MaximumLength = PathNameBufferLength;
+ Fcb->ShortNameU.Length = 0;
+ Fcb->ShortNameU.Buffer = Fcb->ShortNameBuffer;
+ Fcb->ShortNameU.MaximumLength = sizeof(Fcb->ShortNameBuffer);
+ Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
+ if (NameU && NameU->Length)
+ {
+ RtlCopyUnicodeString(&Fcb->PathNameU, NameU);
+ vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
+ }
+ else
+ {
+ Fcb->DirNameU.Buffer = Fcb->LongNameU.Buffer = NULL;
+ Fcb->DirNameU.MaximumLength = Fcb->DirNameU.Length = 0;
+ Fcb->LongNameU.MaximumLength = Fcb->LongNameU.Length = 0;
+ }
+ RtlZeroMemory(&Fcb->FCBShareAccess, sizeof(SHARE_ACCESS));
+ Fcb->OpenHandleCount = 0;
}
PVFATFCB
-vfatNewFCB(PDEVICE_EXTENSION pVCB, PUNICODE_STRING pFileNameU)
+vfatNewFCB(
+ PDEVICE_EXTENSION pVCB,
+ PUNICODE_STRING pFileNameU)
{
- PVFATFCB rcFCB;
-
- DPRINT("'%wZ'\n", pFileNameU);
-
- rcFCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->FcbLookasideList);
- if (rcFCB == NULL)
- {
- return NULL;
- }
- RtlZeroMemory(rcFCB, sizeof(VFATFCB));
- vfatInitFcb(rcFCB, pFileNameU);
- if (pVCB->Flags & VCB_IS_FATX)
- {
- rcFCB->Flags |= FCB_IS_FATX_ENTRY;
- rcFCB->Attributes = &rcFCB->entry.FatX.Attrib;
- }
- else
- rcFCB->Attributes = &rcFCB->entry.Fat.Attrib;
- rcFCB->Hash.Hash = vfatNameHash(0, &rcFCB->PathNameU);
- rcFCB->Hash.self = rcFCB;
- rcFCB->ShortHash.self = rcFCB;
- ExInitializeResourceLite(&rcFCB->PagingIoResource);
- ExInitializeResourceLite(&rcFCB->MainResource);
- FsRtlInitializeFileLock(&rcFCB->FileLock, NULL, NULL);
- ExInitializeFastMutex(&rcFCB->LastMutex);
- rcFCB->RFCB.PagingIoResource = &rcFCB->PagingIoResource;
- rcFCB->RFCB.Resource = &rcFCB->MainResource;
- rcFCB->RFCB.IsFastIoPossible = FastIoIsNotPossible;
-
- return rcFCB;
+ PVFATFCB rcFCB;
+
+ DPRINT("'%wZ'\n", pFileNameU);
+
+ rcFCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->FcbLookasideList);
+ if (rcFCB == NULL)
+ {
+ return NULL;
+ }
+ RtlZeroMemory(rcFCB, sizeof(VFATFCB));
+ vfatInitFcb(rcFCB, pFileNameU);
+ if (pVCB->Flags & VCB_IS_FATX)
+ {
+ rcFCB->Flags |= FCB_IS_FATX_ENTRY;
+ rcFCB->Attributes = &rcFCB->entry.FatX.Attrib;
+ }
+ else
+ rcFCB->Attributes = &rcFCB->entry.Fat.Attrib;
+ rcFCB->Hash.Hash = vfatNameHash(0, &rcFCB->PathNameU);
+ rcFCB->Hash.self = rcFCB;
+ rcFCB->ShortHash.self = rcFCB;
+ ExInitializeResourceLite(&rcFCB->PagingIoResource);
+ ExInitializeResourceLite(&rcFCB->MainResource);
+ FsRtlInitializeFileLock(&rcFCB->FileLock, NULL, NULL);
+ ExInitializeFastMutex(&rcFCB->LastMutex);
+ rcFCB->RFCB.PagingIoResource = &rcFCB->PagingIoResource;
+ rcFCB->RFCB.Resource = &rcFCB->MainResource;
+ rcFCB->RFCB.IsFastIoPossible = FastIoIsNotPossible;
+
+ return rcFCB;
}
VOID
-vfatDestroyCCB(PVFATCCB pCcb)
+vfatDestroyCCB(
+ PVFATCCB pCcb)
{
- if (pCcb->SearchPattern.Buffer)
- {
- ExFreePoolWithTag(pCcb->SearchPattern.Buffer, TAG_VFAT);
- }
- ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb);
+ if (pCcb->SearchPattern.Buffer)
+ {
+ ExFreePoolWithTag(pCcb->SearchPattern.Buffer, TAG_VFAT);
+ }
+ ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb);
}
VOID
-vfatDestroyFCB(PVFATFCB pFCB)
+vfatDestroyFCB(
+ PVFATFCB pFCB)
{
- FsRtlUninitializeFileLock(&pFCB->FileLock);
- ExFreePool(pFCB->PathNameBuffer);
- ExDeleteResourceLite(&pFCB->PagingIoResource);
- ExDeleteResourceLite(&pFCB->MainResource);
- ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
+ FsRtlUninitializeFileLock(&pFCB->FileLock);
+ ExFreePool(pFCB->PathNameBuffer);
+ ExDeleteResourceLite(&pFCB->PagingIoResource);
+ ExDeleteResourceLite(&pFCB->MainResource);
+ ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
}
BOOLEAN
-vfatFCBIsDirectory(PVFATFCB FCB)
+vfatFCBIsDirectory(
+ PVFATFCB FCB)
{
- return *FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY;
+ return *FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY;
}
BOOLEAN
-vfatFCBIsRoot(PVFATFCB FCB)
+vfatFCBIsRoot(
+ PVFATFCB FCB)
{
- return FCB->PathNameU.Length == sizeof(WCHAR) && FCB->PathNameU.Buffer[0] == L'\\' ? TRUE : FALSE;
+ return FCB->PathNameU.Length == sizeof(WCHAR) && FCB->PathNameU.Buffer[0] == L'\\' ? TRUE : FALSE;
}
VOID
-vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
+vfatReleaseFCB(
+ PDEVICE_EXTENSION pVCB,
+ PVFATFCB pFCB)
{
- HASHENTRY* entry;
- ULONG Index;
- ULONG ShortIndex;
- PVFATFCB tmpFcb;
-
- DPRINT ("releasing FCB at %p: %wZ, refCount:%d\n",
- pFCB,
- &pFCB->PathNameU,
- pFCB->RefCount);
-
- while (pFCB)
- {
- Index = pFCB->Hash.Hash % pVCB->HashTableSize;
- ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
- pFCB->RefCount--;
- if (pFCB->RefCount == 0)
- {
- tmpFcb = pFCB->parentFcb;
- RemoveEntryList (&pFCB->FcbListEntry);
- if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
- {
- entry = pVCB->FcbHashTable[ShortIndex];
- if (entry->self == pFCB)
- {
- pVCB->FcbHashTable[ShortIndex] = entry->next;
- }
- else
- {
- while (entry->next->self != pFCB)
- {
- entry = entry->next;
- }
- entry->next = pFCB->ShortHash.next;
- }
- }
- entry = pVCB->FcbHashTable[Index];
- if (entry->self == pFCB)
- {
- pVCB->FcbHashTable[Index] = entry->next;
- }
- else
- {
- while (entry->next->self != pFCB)
- {
- entry = entry->next;
- }
- entry->next = pFCB->Hash.next;
- }
- vfatDestroyFCB (pFCB);
- }
- else
- {
- tmpFcb = NULL;
- }
- pFCB = tmpFcb;
- }
+ HASHENTRY* entry;
+ ULONG Index;
+ ULONG ShortIndex;
+ PVFATFCB tmpFcb;
+
+ DPRINT("releasing FCB at %p: %wZ, refCount:%d\n",
+ pFCB, &pFCB->PathNameU, pFCB->RefCount);
+
+ while (pFCB)
+ {
+ Index = pFCB->Hash.Hash % pVCB->HashTableSize;
+ ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
+ pFCB->RefCount--;
+ if (pFCB->RefCount == 0)
+ {
+ tmpFcb = pFCB->parentFcb;
+ RemoveEntryList (&pFCB->FcbListEntry);
+ if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
+ {
+ entry = pVCB->FcbHashTable[ShortIndex];
+ if (entry->self == pFCB)
+ {
+ pVCB->FcbHashTable[ShortIndex] = entry->next;
+ }
+ else
+ {
+ while (entry->next->self != pFCB)
+ {
+ entry = entry->next;
+ }
+ entry->next = pFCB->ShortHash.next;
+ }
+ }
+ entry = pVCB->FcbHashTable[Index];
+ if (entry->self == pFCB)
+ {
+ pVCB->FcbHashTable[Index] = entry->next;
+ }
+ else
+ {
+ while (entry->next->self != pFCB)
+ {
+ entry = entry->next;
+ }
+ entry->next = pFCB->Hash.next;
+ }
+ vfatDestroyFCB(pFCB);
+ }
+ else
+ {
+ tmpFcb = NULL;
+ }
+ pFCB = tmpFcb;
+ }
}
VOID
-vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
+vfatAddFCBToTable(
+ PDEVICE_EXTENSION pVCB,
+ PVFATFCB pFCB)
{
- ULONG Index;
- ULONG ShortIndex;
-
- Index = pFCB->Hash.Hash % pVCB->HashTableSize;
- ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
-
- InsertTailList (&pVCB->FcbListHead, &pFCB->FcbListEntry);
-
- pFCB->Hash.next = pVCB->FcbHashTable[Index];
- pVCB->FcbHashTable[Index] = &pFCB->Hash;
- if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
- {
- pFCB->ShortHash.next = pVCB->FcbHashTable[ShortIndex];
- pVCB->FcbHashTable[ShortIndex] = &pFCB->ShortHash;
- }
- if (pFCB->parentFcb)
- {
- pFCB->parentFcb->RefCount++;
- }
+ ULONG Index;
+ ULONG ShortIndex;
+
+ Index = pFCB->Hash.Hash % pVCB->HashTableSize;
+ ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
+
+ InsertTailList(&pVCB->FcbListHead, &pFCB->FcbListEntry);
+
+ pFCB->Hash.next = pVCB->FcbHashTable[Index];
+ pVCB->FcbHashTable[Index] = &pFCB->Hash;
+ if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
+ {
+ pFCB->ShortHash.next = pVCB->FcbHashTable[ShortIndex];
+ pVCB->FcbHashTable[ShortIndex] = &pFCB->ShortHash;
+ }
+ if (pFCB->parentFcb)
+ {
+ pFCB->parentFcb->RefCount++;
+ }
}
PVFATFCB
-vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PUNICODE_STRING PathNameU)
+vfatGrabFCBFromTable(
+ PDEVICE_EXTENSION pVCB,
+ PUNICODE_STRING PathNameU)
{
- PVFATFCB rcFCB;
- ULONG Hash;
- UNICODE_STRING DirNameU;
- UNICODE_STRING FileNameU;
- PUNICODE_STRING FcbNameU;
-
- HASHENTRY* entry;
-
- DPRINT("'%wZ'\n", PathNameU);
-
- Hash = vfatNameHash(0, PathNameU);
-
- entry = pVCB->FcbHashTable[Hash % pVCB->HashTableSize];
- if (entry)
- {
- vfatSplitPathName(PathNameU, &DirNameU, &FileNameU);
- }
-
- while (entry)
- {
- if (entry->Hash == Hash)
- {
- rcFCB = entry->self;
- DPRINT("'%wZ' '%wZ'\n", &DirNameU, &rcFCB->DirNameU);
- if (RtlEqualUnicodeString(&DirNameU, &rcFCB->DirNameU, TRUE))
- {
- if (rcFCB->Hash.Hash == Hash)
- {
- FcbNameU = &rcFCB->LongNameU;
- }
- else
- {
- FcbNameU = &rcFCB->ShortNameU;
- }
- /* compare the file name */
- DPRINT("'%wZ' '%wZ'\n", &FileNameU, FcbNameU);
- if (RtlEqualUnicodeString(&FileNameU, FcbNameU, TRUE))
- {
- rcFCB->RefCount++;
- return rcFCB;
- }
- }
- }
- entry = entry->next;
- }
- return NULL;
+ PVFATFCB rcFCB;
+ ULONG Hash;
+ UNICODE_STRING DirNameU;
+ UNICODE_STRING FileNameU;
+ PUNICODE_STRING FcbNameU;
+
+ HASHENTRY* entry;
+
+ DPRINT("'%wZ'\n", PathNameU);
+
+ Hash = vfatNameHash(0, PathNameU);
+
+ entry = pVCB->FcbHashTable[Hash % pVCB->HashTableSize];
+ if (entry)
+ {
+ vfatSplitPathName(PathNameU, &DirNameU, &FileNameU);
+ }
+
+ while (entry)
+ {
+ if (entry->Hash == Hash)
+ {
+ rcFCB = entry->self;
+ DPRINT("'%wZ' '%wZ'\n", &DirNameU, &rcFCB->DirNameU);
+ if (RtlEqualUnicodeString(&DirNameU, &rcFCB->DirNameU, TRUE))
+ {
+ if (rcFCB->Hash.Hash == Hash)
+ {
+ FcbNameU = &rcFCB->LongNameU;
+ }
+ else
+ {
+ FcbNameU = &rcFCB->ShortNameU;
+ }
+ /* compare the file name */
+ DPRINT("'%wZ' '%wZ'\n", &FileNameU, FcbNameU);
+ if (RtlEqualUnicodeString(&FileNameU, FcbNameU, TRUE))
+ {
+ rcFCB->RefCount++;
+ return rcFCB;
+ }
+ }
+ }
+ entry = entry->next;
+ }
+ return NULL;
}
-static NTSTATUS
-vfatFCBInitializeCacheFromVolume (PVCB vcb, PVFATFCB fcb)
+static
+NTSTATUS
+vfatFCBInitializeCacheFromVolume(
+ PVCB vcb,
+ PVFATFCB fcb)
{
- PFILE_OBJECT fileObject;
- PVFATCCB newCCB;
-
- fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
-
- newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
- if (newCCB == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- RtlZeroMemory(newCCB, sizeof (VFATCCB));
-
- fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
- fileObject->FsContext = fcb;
- fileObject->FsContext2 = newCCB;
- fcb->FileObject = fileObject;
- fcb->RefCount++;
-
- CcInitializeCacheMap(fileObject,
- (PCC_FILE_SIZES)(&fcb->RFCB.AllocationSize),
- TRUE,
- &VfatGlobalData->CacheMgrCallbacks,
- fcb);
-
- fcb->Flags |= FCB_CACHE_INITIALIZED;
- return STATUS_SUCCESS;
+ PFILE_OBJECT fileObject;
+ PVFATCCB newCCB;
+
+ fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
+
+ newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
+ if (newCCB == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlZeroMemory(newCCB, sizeof (VFATCCB));
+
+ fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
+ fileObject->FsContext = fcb;
+ fileObject->FsContext2 = newCCB;
+ fcb->FileObject = fileObject;
+ fcb->RefCount++;
+
+ CcInitializeCacheMap(fileObject,
+ (PCC_FILE_SIZES)(&fcb->RFCB.AllocationSize),
+ TRUE,
+ &VfatGlobalData->CacheMgrCallbacks,
+ fcb);
+
+ fcb->Flags |= FCB_CACHE_INITIALIZED;
+ return STATUS_SUCCESS;
}
PVFATFCB
-vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
+vfatMakeRootFCB(
+ PDEVICE_EXTENSION pVCB)
{
- PVFATFCB FCB;
- ULONG FirstCluster, CurrentCluster, Size = 0;
- NTSTATUS Status = STATUS_SUCCESS;
- UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\");
-
- FCB = vfatNewFCB(pVCB, &NameU);
- if (FCB->Flags & FCB_IS_FATX_ENTRY)
- {
- memset(FCB->entry.FatX.Filename, ' ', 42);
- FCB->entry.FatX.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
- FCB->entry.FatX.Attrib = FILE_ATTRIBUTE_DIRECTORY;
- FCB->entry.FatX.FirstCluster = 1;
- Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
- }
- else
- {
- memset(FCB->entry.Fat.ShortName, ' ', 11);
- FCB->entry.Fat.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
- FCB->entry.Fat.Attrib = FILE_ATTRIBUTE_DIRECTORY;
- if (pVCB->FatInfo.FatType == FAT32)
- {
- CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
- FCB->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0xffff);
- FCB->entry.Fat.FirstClusterHigh = (unsigned short)(FirstCluster >> 16);
-
- while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
- {
- Size += pVCB->FatInfo.BytesPerCluster;
- Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE);
- }
- }
- else
- {
- FCB->entry.Fat.FirstCluster = 1;
- Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
- }
- }
- FCB->ShortHash.Hash = FCB->Hash.Hash;
- FCB->RefCount = 2;
- FCB->dirIndex = 0;
- FCB->RFCB.FileSize.QuadPart = Size;
- FCB->RFCB.ValidDataLength.QuadPart = Size;
- FCB->RFCB.AllocationSize.QuadPart = Size;
- FCB->RFCB.IsFastIoPossible = FastIoIsNotPossible;
-
- vfatFCBInitializeCacheFromVolume(pVCB, FCB);
- vfatAddFCBToTable(pVCB, FCB);
-
- return(FCB);
+ PVFATFCB FCB;
+ ULONG FirstCluster, CurrentCluster, Size = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+ UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\");
+
+ FCB = vfatNewFCB(pVCB, &NameU);
+ if (FCB->Flags & FCB_IS_FATX_ENTRY)
+ {
+ memset(FCB->entry.FatX.Filename, ' ', 42);
+ FCB->entry.FatX.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
+ FCB->entry.FatX.Attrib = FILE_ATTRIBUTE_DIRECTORY;
+ FCB->entry.FatX.FirstCluster = 1;
+ Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
+ }
+ else
+ {
+ memset(FCB->entry.Fat.ShortName, ' ', 11);
+ FCB->entry.Fat.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
+ FCB->entry.Fat.Attrib = FILE_ATTRIBUTE_DIRECTORY;
+ if (pVCB->FatInfo.FatType == FAT32)
+ {
+ CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
+ FCB->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0xffff);
+ FCB->entry.Fat.FirstClusterHigh = (unsigned short)(FirstCluster >> 16);
+
+ while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
+ {
+ Size += pVCB->FatInfo.BytesPerCluster;
+ Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE);
+ }
+ }
+ else
+ {
+ FCB->entry.Fat.FirstCluster = 1;
+ Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
+ }
+ }
+ FCB->ShortHash.Hash = FCB->Hash.Hash;
+ FCB->RefCount = 2;
+ FCB->dirIndex = 0;
+ FCB->RFCB.FileSize.QuadPart = Size;
+ FCB->RFCB.ValidDataLength.QuadPart = Size;
+ FCB->RFCB.AllocationSize.QuadPart = Size;
+ FCB->RFCB.IsFastIoPossible = FastIoIsNotPossible;
+
+ vfatFCBInitializeCacheFromVolume(pVCB, FCB);
+ vfatAddFCBToTable(pVCB, FCB);
+
+ return FCB;
}
PVFATFCB
-vfatOpenRootFCB(PDEVICE_EXTENSION pVCB)
+vfatOpenRootFCB(
+ PDEVICE_EXTENSION pVCB)
{
- PVFATFCB FCB;
- UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\");
+ PVFATFCB FCB;
+ UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\");
- FCB = vfatGrabFCBFromTable (pVCB, &NameU);
- if (FCB == NULL)
- {
- FCB = vfatMakeRootFCB (pVCB);
- }
+ FCB = vfatGrabFCBFromTable(pVCB, &NameU);
+ if (FCB == NULL)
+ {
+ FCB = vfatMakeRootFCB(pVCB);
+ }
- return FCB;
+ return FCB;
}
NTSTATUS
vfatMakeFCBFromDirEntry(
- PVCB vcb,
- PVFATFCB directoryFCB,
- PVFAT_DIRENTRY_CONTEXT DirContext,
- PVFATFCB* fileFCB)
+ PVCB vcb,
+ PVFATFCB directoryFCB,
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ PVFATFCB *fileFCB)
{
- PVFATFCB rcFCB;
- PWCHAR PathNameBuffer;
- USHORT PathNameLength;
- ULONG Size;
- ULONG hash;
-
- UNICODE_STRING NameU;
-
- PathNameLength = directoryFCB->PathNameU.Length + max(DirContext->LongNameU.Length, DirContext->ShortNameU.Length);
- if (!vfatFCBIsRoot (directoryFCB))
- {
- PathNameLength += sizeof(WCHAR);
- }
-
- if (PathNameLength > LONGNAME_MAX_LENGTH * sizeof(WCHAR))
- {
- return STATUS_OBJECT_NAME_INVALID;
- }
- PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameLength + sizeof(WCHAR), TAG_FCB);
- if (!PathNameBuffer)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- NameU.Buffer = PathNameBuffer;
- NameU.Length = 0;
- NameU.MaximumLength = PathNameLength;
-
- RtlCopyUnicodeString(&NameU, &directoryFCB->PathNameU);
- if (!vfatFCBIsRoot (directoryFCB))
- {
- RtlAppendUnicodeToString(&NameU, L"\\");
- }
- hash = vfatNameHash(0, &NameU);
- if (DirContext->LongNameU.Length > 0)
- {
- RtlAppendUnicodeStringToString(&NameU, &DirContext->LongNameU);
- }
- else
- {
- RtlAppendUnicodeStringToString(&NameU, &DirContext->ShortNameU);
- }
- NameU.Buffer[NameU.Length / sizeof(WCHAR)] = 0;
-
- rcFCB = vfatNewFCB (vcb, &NameU);
- RtlCopyMemory (&rcFCB->entry, &DirContext->DirEntry, sizeof (DIR_ENTRY));
- RtlCopyUnicodeString(&rcFCB->ShortNameU, &DirContext->ShortNameU);
- if (vcb->Flags & VCB_IS_FATX)
- {
- rcFCB->ShortHash.Hash = rcFCB->Hash.Hash;
- }
- else
- {
- rcFCB->ShortHash.Hash = vfatNameHash(hash, &rcFCB->ShortNameU);
- }
-
- if (vfatFCBIsDirectory(rcFCB))
- {
- ULONG FirstCluster, CurrentCluster;
- NTSTATUS Status = STATUS_SUCCESS;
- Size = 0;
- FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry);
- if (FirstCluster == 1)
- {
- Size = vcb->FatInfo.rootDirectorySectors * vcb->FatInfo.BytesPerSector;
- }
- else if (FirstCluster != 0)
- {
- CurrentCluster = FirstCluster;
- while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
- {
- Size += vcb->FatInfo.BytesPerCluster;
- Status = NextCluster (vcb, FirstCluster, &CurrentCluster, FALSE);
- }
- }
- }
- else if (rcFCB->Flags & FCB_IS_FATX_ENTRY)
- {
- Size = rcFCB->entry.FatX.FileSize;
- }
- else
- {
- Size = rcFCB->entry.Fat.FileSize;
- }
- rcFCB->dirIndex = DirContext->DirIndex;
- rcFCB->startIndex = DirContext->StartIndex;
- if ((rcFCB->Flags & FCB_IS_FATX_ENTRY) && !vfatFCBIsRoot (directoryFCB))
- {
- ASSERT(DirContext->DirIndex >= 2 && DirContext->StartIndex >= 2);
- rcFCB->dirIndex = DirContext->DirIndex-2;
- rcFCB->startIndex = DirContext->StartIndex-2;
- }
- rcFCB->RFCB.FileSize.QuadPart = Size;
- rcFCB->RFCB.ValidDataLength.QuadPart = Size;
- rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster);
- rcFCB->RefCount++;
- if (vfatFCBIsDirectory(rcFCB))
- {
- vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
- }
- rcFCB->parentFcb = directoryFCB;
- vfatAddFCBToTable (vcb, rcFCB);
- *fileFCB = rcFCB;
-
- ExFreePool(PathNameBuffer);
- return STATUS_SUCCESS;
+ PVFATFCB rcFCB;
+ PWCHAR PathNameBuffer;
+ USHORT PathNameLength;
+ ULONG Size;
+ ULONG hash;
+
+ UNICODE_STRING NameU;
+
+ PathNameLength = directoryFCB->PathNameU.Length + max(DirContext->LongNameU.Length, DirContext->ShortNameU.Length);
+ if (!vfatFCBIsRoot (directoryFCB))
+ {
+ PathNameLength += sizeof(WCHAR);
+ }
+
+ if (PathNameLength > LONGNAME_MAX_LENGTH * sizeof(WCHAR))
+ {
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+ PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameLength + sizeof(WCHAR), TAG_FCB);
+ if (!PathNameBuffer)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ NameU.Buffer = PathNameBuffer;
+ NameU.Length = 0;
+ NameU.MaximumLength = PathNameLength;
+
+ RtlCopyUnicodeString(&NameU, &directoryFCB->PathNameU);
+ if (!vfatFCBIsRoot(directoryFCB))
+ {
+ RtlAppendUnicodeToString(&NameU, L"\\");
+ }
+ hash = vfatNameHash(0, &NameU);
+ if (DirContext->LongNameU.Length > 0)
+ {
+ RtlAppendUnicodeStringToString(&NameU, &DirContext->LongNameU);
+ }
+ else
+ {
+ RtlAppendUnicodeStringToString(&NameU, &DirContext->ShortNameU);
+ }
+ NameU.Buffer[NameU.Length / sizeof(WCHAR)] = 0;
+
+ rcFCB = vfatNewFCB(vcb, &NameU);
+ RtlCopyMemory(&rcFCB->entry, &DirContext->DirEntry, sizeof (DIR_ENTRY));
+ RtlCopyUnicodeString(&rcFCB->ShortNameU, &DirContext->ShortNameU);
+ if (vcb->Flags & VCB_IS_FATX)
+ {
+ rcFCB->ShortHash.Hash = rcFCB->Hash.Hash;
+ }
+ else
+ {
+ rcFCB->ShortHash.Hash = vfatNameHash(hash, &rcFCB->ShortNameU);
+ }
+
+ if (vfatFCBIsDirectory(rcFCB))
+ {
+ ULONG FirstCluster, CurrentCluster;
+ NTSTATUS Status = STATUS_SUCCESS;
+ Size = 0;
+ FirstCluster = vfatDirEntryGetFirstCluster(vcb, &rcFCB->entry);
+ if (FirstCluster == 1)
+ {
+ Size = vcb->FatInfo.rootDirectorySectors * vcb->FatInfo.BytesPerSector;
+ }
+ else if (FirstCluster != 0)
+ {
+ CurrentCluster = FirstCluster;
+ while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
+ {
+ Size += vcb->FatInfo.BytesPerCluster;
+ Status = NextCluster(vcb, FirstCluster, &CurrentCluster, FALSE);
+ }
+ }
+ }
+ else if (rcFCB->Flags & FCB_IS_FATX_ENTRY)
+ {
+ Size = rcFCB->entry.FatX.FileSize;
+ }
+ else
+ {
+ Size = rcFCB->entry.Fat.FileSize;
+ }
+ rcFCB->dirIndex = DirContext->DirIndex;
+ rcFCB->startIndex = DirContext->StartIndex;
+ if ((rcFCB->Flags & FCB_IS_FATX_ENTRY) && !vfatFCBIsRoot(directoryFCB))
+ {
+ ASSERT(DirContext->DirIndex >= 2 && DirContext->StartIndex >= 2);
+ rcFCB->dirIndex = DirContext->DirIndex-2;
+ rcFCB->startIndex = DirContext->StartIndex-2;
+ }
+ rcFCB->RFCB.FileSize.QuadPart = Size;
+ rcFCB->RFCB.ValidDataLength.QuadPart = Size;
+ rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster);
+ rcFCB->RefCount++;
+ if (vfatFCBIsDirectory(rcFCB))
+ {
+ vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
+ }
+ rcFCB->parentFcb = directoryFCB;
+ vfatAddFCBToTable(vcb, rcFCB);
+ *fileFCB = rcFCB;
+
+ ExFreePool(PathNameBuffer);
+ return STATUS_SUCCESS;
}
NTSTATUS
-vfatAttachFCBToFileObject (
- PDEVICE_EXTENSION vcb,
- PVFATFCB fcb,
- PFILE_OBJECT fileObject)
+vfatAttachFCBToFileObject(
+ PDEVICE_EXTENSION vcb,
+ PVFATFCB fcb,
+ PFILE_OBJECT fileObject)
{
- PVFATCCB newCCB;
+ PVFATCCB newCCB;
- UNREFERENCED_PARAMETER(vcb);
+ UNREFERENCED_PARAMETER(vcb);
- newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
- if (newCCB == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- RtlZeroMemory (newCCB, sizeof (VFATCCB));
+ newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
+ if (newCCB == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlZeroMemory(newCCB, sizeof (VFATCCB));
- fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
- fileObject->FsContext = fcb;
- fileObject->FsContext2 = newCCB;
- DPRINT ("file open: fcb:%p PathName:%wZ\n", fcb, &fcb->PathNameU);
+ fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
+ fileObject->FsContext = fcb;
+ fileObject->FsContext2 = newCCB;
+ DPRINT("file open: fcb:%p PathName:%wZ\n", fcb, &fcb->PathNameU);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
NTSTATUS
-vfatDirFindFile (
- PDEVICE_EXTENSION pDeviceExt,
- PVFATFCB pDirectoryFCB,
- PUNICODE_STRING FileToFindU,
- PVFATFCB * pFoundFCB)
+vfatDirFindFile(
+ PDEVICE_EXTENSION pDeviceExt,
+ PVFATFCB pDirectoryFCB,
+ PUNICODE_STRING FileToFindU,
+ PVFATFCB *pFoundFCB)
{
- NTSTATUS status;
- PVOID Context = NULL;
- PVOID Page = NULL;
- BOOLEAN First = TRUE;
- VFAT_DIRENTRY_CONTEXT DirContext;
- /* This buffer must have a size of 260 characters, because
- vfatMakeFCBFromDirEntry can copy 20 name entries with 13 characters. */
- WCHAR LongNameBuffer[260];
- WCHAR ShortNameBuffer[13];
- BOOLEAN FoundLong = FALSE;
- BOOLEAN FoundShort = FALSE;
-
- ASSERT(pDeviceExt);
- ASSERT(pDirectoryFCB);
- ASSERT(FileToFindU);
-
- DPRINT ("vfatDirFindFile(VCB:%p, dirFCB:%p, File:%wZ)\n",
- pDeviceExt,
- pDirectoryFCB,
- FileToFindU);
- DPRINT ("Dir Path:%wZ\n", &pDirectoryFCB->PathNameU);
-
- DirContext.DirIndex = 0;
- DirContext.LongNameU.Buffer = LongNameBuffer;
- DirContext.LongNameU.Length = 0;
- DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
- DirContext.ShortNameU.Buffer = ShortNameBuffer;
- DirContext.ShortNameU.Length = 0;
- DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
-
- while (TRUE)
- {
- status = pDeviceExt->GetNextDirEntry(&Context,
- &Page,
- pDirectoryFCB,
- &DirContext,
- First);
- First = FALSE;
- if (status == STATUS_NO_MORE_ENTRIES)
- {
- return STATUS_OBJECT_NAME_NOT_FOUND;
- }
- if (!NT_SUCCESS(status))
- {
- return status;
- }
-
- DPRINT (" Index:%u longName:%wZ\n",
- DirContext.DirIndex,
- &DirContext.LongNameU);
-
- if (!ENTRY_VOLUME(pDeviceExt, &DirContext.DirEntry))
- {
- FoundLong = RtlEqualUnicodeString(FileToFindU, &DirContext.LongNameU, TRUE);
- if (FoundLong == FALSE)
- {
- FoundShort = RtlEqualUnicodeString(FileToFindU, &DirContext.ShortNameU, TRUE);
- }
- if (FoundLong || FoundShort)
- {
- status = vfatMakeFCBFromDirEntry (pDeviceExt,
- pDirectoryFCB,
- &DirContext,
- pFoundFCB);
- CcUnpinData(Context);
- return status;
- }
- }
- DirContext.DirIndex++;
- }
-
- return STATUS_OBJECT_NAME_NOT_FOUND;
+ NTSTATUS status;
+ PVOID Context = NULL;
+ PVOID Page = NULL;
+ BOOLEAN First = TRUE;
+ VFAT_DIRENTRY_CONTEXT DirContext;
+ /* This buffer must have a size of 260 characters, because
+ vfatMakeFCBFromDirEntry can copy 20 name entries with 13 characters. */
+ WCHAR LongNameBuffer[260];
+ WCHAR ShortNameBuffer[13];
+ BOOLEAN FoundLong = FALSE;
+ BOOLEAN FoundShort = FALSE;
+
+ ASSERT(pDeviceExt);
+ ASSERT(pDirectoryFCB);
+ ASSERT(FileToFindU);
+
+ DPRINT("vfatDirFindFile(VCB:%p, dirFCB:%p, File:%wZ)\n",
+ pDeviceExt, pDirectoryFCB, FileToFindU);
+ DPRINT("Dir Path:%wZ\n", &pDirectoryFCB->PathNameU);
+
+ DirContext.DirIndex = 0;
+ DirContext.LongNameU.Buffer = LongNameBuffer;
+ DirContext.LongNameU.Length = 0;
+ DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
+ DirContext.ShortNameU.Buffer = ShortNameBuffer;
+ DirContext.ShortNameU.Length = 0;
+ DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
+
+ while (TRUE)
+ {
+ status = pDeviceExt->GetNextDirEntry(&Context,
+ &Page,
+ pDirectoryFCB,
+ &DirContext,
+ First);
+ First = FALSE;
+ if (status == STATUS_NO_MORE_ENTRIES)
+ {
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+ DPRINT(" Index:%u longName:%wZ\n",
+ DirContext.DirIndex, &DirContext.LongNameU);
+
+ if (!ENTRY_VOLUME(pDeviceExt, &DirContext.DirEntry))
+ {
+ FoundLong = RtlEqualUnicodeString(FileToFindU, &DirContext.LongNameU, TRUE);
+ if (FoundLong == FALSE)
+ {
+ FoundShort = RtlEqualUnicodeString(FileToFindU, &DirContext.ShortNameU, TRUE);
+ }
+ if (FoundLong || FoundShort)
+ {
+ status = vfatMakeFCBFromDirEntry(pDeviceExt,
+ pDirectoryFCB,
+ &DirContext,
+ pFoundFCB);
+ CcUnpinData(Context);
+ return status;
+ }
+ }
+ DirContext.DirIndex++;
+ }
+
+ return STATUS_OBJECT_NAME_NOT_FOUND;
}
NTSTATUS
-vfatGetFCBForFile (
- PDEVICE_EXTENSION pVCB,
- PVFATFCB *pParentFCB,
- PVFATFCB *pFCB,
- PUNICODE_STRING pFileNameU)
+vfatGetFCBForFile(
+ PDEVICE_EXTENSION pVCB,
+ PVFATFCB *pParentFCB,
+ PVFATFCB *pFCB,
+ PUNICODE_STRING pFileNameU)
{
- NTSTATUS status;
- PVFATFCB FCB = NULL;
- PVFATFCB parentFCB;
- UNICODE_STRING NameU;
- UNICODE_STRING RootNameU = RTL_CONSTANT_STRING(L"\\");
- UNICODE_STRING FileNameU;
- WCHAR NameBuffer[260];
- PWCHAR curr, prev, last;
- ULONG Length;
-
- DPRINT ("vfatGetFCBForFile (%p,%p,%p,%wZ)\n",
- pVCB,
- pParentFCB,
- pFCB,
- pFileNameU);
-
- FileNameU.Buffer = NameBuffer;
- FileNameU.MaximumLength = sizeof(NameBuffer);
- RtlCopyUnicodeString(&FileNameU, pFileNameU);
-
- parentFCB = *pParentFCB;
-
- if (parentFCB == NULL)
- {
- // Trivial case, open of the root directory on volume
- if (RtlEqualUnicodeString(&FileNameU, &RootNameU, FALSE))
- {
- DPRINT ("returning root FCB\n");
-
- FCB = vfatOpenRootFCB (pVCB);
- *pFCB = FCB;
- *pParentFCB = NULL;
-
- return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND;
- }
-
- /* Check for an existing FCB */
- FCB = vfatGrabFCBFromTable (pVCB, &FileNameU);
- if (FCB)
- {
- *pFCB = FCB;
- *pParentFCB = FCB->parentFcb;
- (*pParentFCB)->RefCount++;
- return STATUS_SUCCESS;
- }
-
- last = curr = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
- while (*curr != L'\\' && curr > FileNameU.Buffer)
- {
- curr--;
- }
-
- if (curr > FileNameU.Buffer)
- {
- NameU.Buffer = FileNameU.Buffer;
- NameU.MaximumLength = NameU.Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
- FCB = vfatGrabFCBFromTable(pVCB, &NameU);
- if (FCB)
- {
- Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
- if (Length != FCB->PathNameU.Length)
- {
- if (FileNameU.Length + FCB->PathNameU.Length - Length > FileNameU.MaximumLength)
- {
- vfatReleaseFCB (pVCB, FCB);
- return STATUS_OBJECT_NAME_INVALID;
- }
- RtlMoveMemory(FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR),
- curr, FileNameU.Length - Length);
- FileNameU.Length += (USHORT)(FCB->PathNameU.Length - Length);
- curr = FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR);
- last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
- }
- RtlCopyMemory(FileNameU.Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
- }
- }
- else
- {
- FCB = NULL;
- }
-
- if (FCB == NULL)
- {
- FCB = vfatOpenRootFCB(pVCB);
- curr = FileNameU.Buffer;
- }
-
- parentFCB = NULL;
- prev = curr;
- }
- else
- {
- FCB = parentFCB;
- parentFCB = NULL;
- prev = curr = FileNameU.Buffer - 1;
- last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
- }
-
- while (curr <= last)
- {
- if (parentFCB)
- {
- vfatReleaseFCB (pVCB, parentFCB);
- parentFCB = 0;
- }
- // fail if element in FCB is not a directory
- if (!vfatFCBIsDirectory (FCB))
- {
- DPRINT ("Element in requested path is not a directory\n");
-
- vfatReleaseFCB (pVCB, FCB);
- FCB = NULL;
- *pParentFCB = NULL;
- *pFCB = NULL;
-
- return STATUS_OBJECT_PATH_NOT_FOUND;
- }
- parentFCB = FCB;
- if (prev < curr)
- {
- Length = (curr - prev) * sizeof(WCHAR);
- if (Length != parentFCB->LongNameU.Length)
- {
- if (FileNameU.Length + parentFCB->LongNameU.Length - Length > FileNameU.MaximumLength)
- {
- vfatReleaseFCB (pVCB, parentFCB);
- return STATUS_OBJECT_NAME_INVALID;
- }
- RtlMoveMemory(prev + parentFCB->LongNameU.Length / sizeof(WCHAR), curr,
- FileNameU.Length - (curr - FileNameU.Buffer) * sizeof(WCHAR));
- FileNameU.Length += (USHORT)(parentFCB->LongNameU.Length - Length);
- curr = prev + parentFCB->LongNameU.Length / sizeof(WCHAR);
- last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
- }
- RtlCopyMemory(prev, parentFCB->LongNameU.Buffer, parentFCB->LongNameU.Length);
- }
- curr++;
- prev = curr;
- while (*curr != L'\\' && curr <= last)
- {
- curr++;
- }
- NameU.Buffer = FileNameU.Buffer;
- NameU.Length = (curr - NameU.Buffer) * sizeof(WCHAR);
- NameU.MaximumLength = FileNameU.MaximumLength;
- DPRINT("%wZ\n", &NameU);
- FCB = vfatGrabFCBFromTable(pVCB, &NameU);
- if (FCB == NULL)
- {
- NameU.Buffer = prev;
- NameU.MaximumLength = NameU.Length = (curr - prev) * sizeof(WCHAR);
- status = vfatDirFindFile(pVCB, parentFCB, &NameU, &FCB);
- if (status == STATUS_OBJECT_NAME_NOT_FOUND)
- {
- *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;
- }
- }
- else if (!NT_SUCCESS (status))
- {
- vfatReleaseFCB (pVCB, parentFCB);
- *pParentFCB = NULL;
- *pFCB = NULL;
-
- return status;
- }
- }
- }
-
- *pParentFCB = parentFCB;
- *pFCB = FCB;
-
- return STATUS_SUCCESS;
+ NTSTATUS status;
+ PVFATFCB FCB = NULL;
+ PVFATFCB parentFCB;
+ UNICODE_STRING NameU;
+ UNICODE_STRING RootNameU = RTL_CONSTANT_STRING(L"\\");
+ UNICODE_STRING FileNameU;
+ WCHAR NameBuffer[260];
+ PWCHAR curr, prev, last;
+ ULONG Length;
+
+ DPRINT("vfatGetFCBForFile (%p,%p,%p,%wZ)\n",
+ pVCB, pParentFCB, pFCB, pFileNameU);
+
+ FileNameU.Buffer = NameBuffer;
+ FileNameU.MaximumLength = sizeof(NameBuffer);
+ RtlCopyUnicodeString(&FileNameU, pFileNameU);
+
+ parentFCB = *pParentFCB;
+
+ if (parentFCB == NULL)
+ {
+ // Trivial case, open of the root directory on volume
+ if (RtlEqualUnicodeString(&FileNameU, &RootNameU, FALSE))
+ {
+ DPRINT("returning root FCB\n");
+
+ FCB = vfatOpenRootFCB(pVCB);
+ *pFCB = FCB;
+ *pParentFCB = NULL;
+
+ return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+
+ /* Check for an existing FCB */
+ FCB = vfatGrabFCBFromTable(pVCB, &FileNameU);
+ if (FCB)
+ {
+ *pFCB = FCB;
+ *pParentFCB = FCB->parentFcb;
+ (*pParentFCB)->RefCount++;
+ return STATUS_SUCCESS;
+ }
+
+ last = curr = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
+ while (*curr != L'\\' && curr > FileNameU.Buffer)
+ {
+ curr--;
+ }
+
+ if (curr > FileNameU.Buffer)
+ {
+ NameU.Buffer = FileNameU.Buffer;
+ NameU.MaximumLength = NameU.Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
+ FCB = vfatGrabFCBFromTable(pVCB, &NameU);
+ if (FCB)
+ {
+ Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
+ if (Length != FCB->PathNameU.Length)
+ {
+ if (FileNameU.Length + FCB->PathNameU.Length - Length > FileNameU.MaximumLength)
+ {
+ vfatReleaseFCB(pVCB, FCB);
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+ RtlMoveMemory(FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR),
+ curr, FileNameU.Length - Length);
+ FileNameU.Length += (USHORT)(FCB->PathNameU.Length - Length);
+ curr = FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR);
+ last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
+ }
+ RtlCopyMemory(FileNameU.Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
+ }
+ }
+ else
+ {
+ FCB = NULL;
+ }
+
+ if (FCB == NULL)
+ {
+ FCB = vfatOpenRootFCB(pVCB);
+ curr = FileNameU.Buffer;
+ }
+
+ parentFCB = NULL;
+ prev = curr;
+ }
+ else
+ {
+ FCB = parentFCB;
+ parentFCB = NULL;
+ prev = curr = FileNameU.Buffer - 1;
+ last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
+ }
+
+ while (curr <= last)
+ {
+ if (parentFCB)
+ {
+ vfatReleaseFCB(pVCB, parentFCB);
+ parentFCB = 0;
+ }
+ // fail if element in FCB is not a directory
+ if (!vfatFCBIsDirectory(FCB))
+ {
+ DPRINT ("Element in requested path is not a directory\n");
+
+ vfatReleaseFCB(pVCB, FCB);
+ FCB = NULL;
+ *pParentFCB = NULL;
+ *pFCB = NULL;
+
+ return STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+ parentFCB = FCB;
+ if (prev < curr)
+ {
+ Length = (curr - prev) * sizeof(WCHAR);
+ if (Length != parentFCB->LongNameU.Length)
+ {
+ if (FileNameU.Length + parentFCB->LongNameU.Length - Length > FileNameU.MaximumLength)
+ {
+ vfatReleaseFCB(pVCB, parentFCB);
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+ RtlMoveMemory(prev + parentFCB->LongNameU.Length / sizeof(WCHAR), curr,
+ FileNameU.Length - (curr - FileNameU.Buffer) * sizeof(WCHAR));
+ FileNameU.Length += (USHORT)(parentFCB->LongNameU.Length - Length);
+ curr = prev + parentFCB->LongNameU.Length / sizeof(WCHAR);
+ last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
+ }
+ RtlCopyMemory(prev, parentFCB->LongNameU.Buffer, parentFCB->LongNameU.Length);
+ }
+ curr++;
+ prev = curr;
+ while (*curr != L'\\' && curr <= last)
+ {
+ curr++;
+ }
+ NameU.Buffer = FileNameU.Buffer;
+ NameU.Length = (curr - NameU.Buffer) * sizeof(WCHAR);
+ NameU.MaximumLength = FileNameU.MaximumLength;
+ DPRINT("%wZ\n", &NameU);
+ FCB = vfatGrabFCBFromTable(pVCB, &NameU);
+ if (FCB == NULL)
+ {
+ NameU.Buffer = prev;
+ NameU.MaximumLength = NameU.Length = (curr - prev) * sizeof(WCHAR);
+ status = vfatDirFindFile(pVCB, parentFCB, &NameU, &FCB);
+ if (status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ *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;
+ }
+ }
+ else if (!NT_SUCCESS(status))
+ {
+ vfatReleaseFCB(pVCB, parentFCB);
+ *pParentFCB = NULL;
+ *pFCB = NULL;
+
+ return status;
+ }
+ }
+ }
+
+ *pParentFCB = parentFCB;
+ *pFCB = FCB;
+
+ return STATUS_SUCCESS;
}