+static
+VOID
+vfatDelFCBFromTable(
+ PDEVICE_EXTENSION pVCB,
+ PVFATFCB pFCB)
+{
+ ULONG Index;
+ ULONG ShortIndex;
+ HASHENTRY* entry;
+
+ Index = pFCB->Hash.Hash % pVCB->HashTableSize;
+ ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
+
+ 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;
+ }
+
+ RemoveEntryList(&pFCB->FcbListEntry);
+}
+
+static
+NTSTATUS
+vfatMakeFullName(
+ PVFATFCB directoryFCB,
+ PUNICODE_STRING LongNameU,
+ PUNICODE_STRING ShortNameU,
+ PUNICODE_STRING NameU)
+{
+ PWCHAR PathNameBuffer;
+ USHORT PathNameLength;
+
+ PathNameLength = directoryFCB->PathNameU.Length + max(LongNameU->Length, 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"\\");
+ }
+ if (LongNameU->Length > 0)
+ {
+ RtlAppendUnicodeStringToString(NameU, LongNameU);
+ }
+ else
+ {
+ RtlAppendUnicodeStringToString(NameU, ShortNameU);
+ }
+ NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
+
+ return STATUS_SUCCESS;
+}
+