Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP_64(Size, Vcb->FatInfo.BytesPerCluster);
}
+NTSTATUS
+vfatSetFCBNewDirName(
+ PDEVICE_EXTENSION pVCB,
+ PVFATFCB Fcb,
+ PVFATFCB ParentFcb)
+{
+ NTSTATUS Status;
+ UNICODE_STRING NewNameU;
+
+ /* Get full path name */
+ Status = vfatMakeFullName(ParentFcb, &Fcb->LongNameU, &Fcb->ShortNameU, &NewNameU);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Delete old name */
+ if (Fcb->PathNameBuffer)
+ {
+ ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB);
+ }
+ Fcb->PathNameU = NewNameU;
+
+ /* Delete from table */
+ vfatDelFCBFromTable(pVCB, Fcb);
+
+ /* Split it properly */
+ Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
+ Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
+ vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
+
+ if (pVCB->Flags & VCB_IS_FATX)
+ {
+ Fcb->ShortHash.Hash = Fcb->Hash.Hash;
+ }
+ else
+ {
+ Fcb->ShortHash.Hash = vfatNameHash(0, &Fcb->DirNameU);
+ Fcb->ShortHash.Hash = vfatNameHash(Fcb->ShortHash.Hash, &Fcb->ShortNameU);
+ }
+
+ vfatAddFCBToTable(pVCB, Fcb);
+ vfatReleaseFCB(pVCB, ParentFcb);
+
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
vfatUpdateFCB(
PDEVICE_EXTENSION pVCB,
return FALSE;
}
+static
+VOID
+VfatRenameChildFCB(
+ PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB FCB)
+{
+ PLIST_ENTRY Entry;
+ PVFATFCB Child;
+
+ if (IsListEmpty(&FCB->ParentListHead))
+ return;
+
+ for (Entry = FCB->ParentListHead.Flink; Entry != &FCB->ParentListHead; Entry = Entry->Flink)
+ {
+ NTSTATUS Status;
+
+ Child = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
+ DPRINT("Found %wZ with still %lu references (parent: %lu)!\n", &Child->PathNameU, Child->RefCount, FCB->RefCount);
+
+ Status = vfatSetFCBNewDirName(DeviceExt, Child, FCB);
+ if (!NT_SUCCESS(Status))
+ continue;
+
+ if (vfatFCBIsDirectory(Child))
+ {
+ VfatRenameChildFCB(DeviceExt, Child);
+ }
+ }
+}
+
/*
* FUNCTION: Set the file name information
*/
}
}
+ if (NT_SUCCESS(Status) && vfatFCBIsDirectory(FCB))
+ {
+ VfatRenameChildFCB(DeviceExt, FCB);
+ }
+
ASSERT(OldReferences == OldParent->RefCount + 1); // removed file
ASSERT(NewReferences == ParentFCB->RefCount - 1); // new file
Cleanup: