- 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 = ExAllocatePool(NonPagedPool, PathNameLength + sizeof(WCHAR));
- 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;
- 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)
- {
- 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 = ExAllocatePool(NonPagedPool, PathNameLength + sizeof(WCHAR));
+ 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;
+ 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)
+ {
+ 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;