26 if (Vcn >= Runlist->NextVcn) {
28 if (EFI_ERROR (Status)) {
32 return Runlist->CurrentLcn;
35 Delta = Vcn - Runlist->CurrentVcn;
37 return Runlist->IsSparse ? 0 : (Runlist->CurrentLcn + Delta);
53 UINT64 OffsetInsideCluster;
60 ClusterSize = Runlist->Unit.FileSystem->ClusterSize;
61 OffsetInsideCluster = Offset & (ClusterSize - 1U);
65 for (Index = Runlist->TargetVcn; Index < ClustersTotal; ++Index) {
66 Cluster =
GetLcn (Runlist, Index);
67 if (Cluster == (UINT64)(-1)) {
68 return EFI_DEVICE_ERROR;
71 Cluster *= ClusterSize;
73 if (Index == (ClustersTotal - 1U)) {
74 Size = (UINTN)((
Length + Offset) & (ClusterSize - 1U));
80 if (Index != Runlist->TargetVcn) {
81 OffsetInsideCluster = 0;
85 if (Index == Runlist->TargetVcn) {
86 Size -= (UINTN)OffsetInsideCluster;
89 if ((Index != Runlist->TargetVcn) && (Index != (ClustersTotal - 1U))) {
91 OffsetInsideCluster = 0;
96 Runlist->Unit.FileSystem,
97 Cluster + OffsetInsideCluster,
101 if (EFI_ERROR (Status)) {
124 EFI_BLOCK_IO_MEDIA *Media;
126 ASSERT (FileSystem != NULL);
127 ASSERT (FileSystem->DiskIo != NULL);
128 ASSERT (FileSystem->BlockIo != NULL);
130 Media = FileSystem->BlockIo->Media;
132 Status = FileSystem->DiskIo->ReadDisk (
139 if (EFI_ERROR (Status)) {
140 DEBUG ((DEBUG_INFO,
"NTFS: Could not read disk at address %Lx\n", Offset));
151 IN UINT64 RecordNumber
155 UINTN FileRecordSize;
160 FileRecordSize = File->FileSystem->FileRecordSize;
165 RecordNumber * FileRecordSize,
168 if (EFI_ERROR (Status)) {
169 DEBUG ((DEBUG_INFO,
"NTFS: Could not read MFT Record 0x%Lx\n", RecordNumber));
177 SIGNATURE_32 (
'F',
'I',
'L',
'E'),
178 File->FileSystem->SectorSize
203 Current = Attr->Current;
204 Attr->Next = Attr->Current;
205 ClusterSize = Attr->BaseMftRecord->File->FileSystem->ClusterSize;
209 DEBUG ((DEBUG_INFO,
"NTFS: $ATTRIBUTE_LIST does not contain even a single record.\n"));
210 return EFI_VOLUME_CORRUPTED;
223 if (Record->
Type != Type) {
232 return EFI_VOLUME_CORRUPTED;
235 Attr->Next = (UINT8 *)Record;
244 if (AttrStart != NULL) {
247 DEBUG ((DEBUG_INFO,
"NTFS: Attribute not found\n"));
248 Status = EFI_VOLUME_CORRUPTED;
251 Attr->Current = Current;
272 UINT64 OffsetInsideCluster;
274 UINTN FileRecordSize;
282 FileRecordSize = Attr->BaseMftRecord->File->FileSystem->FileRecordSize;
283 SectorSize = Attr->BaseMftRecord->File->FileSystem->SectorSize;
284 ClusterSize = Attr->BaseMftRecord->File->FileSystem->ClusterSize;
285 BufferSize = FileRecordSize - (Attr->Current - Attr->BaseMftRecord->FileRecord);
290 DEBUG ((DEBUG_INFO,
"NTFS: (ReadData #1) Attribute is corrupted.\n"));
291 return EFI_VOLUME_CORRUPTED;
298 DEBUG ((DEBUG_INFO,
"NTFS: Read out of range\n"));
299 return EFI_VOLUME_CORRUPTED;
303 DEBUG ((DEBUG_INFO,
"NTFS: Read out of buffer.\n"));
304 return EFI_VOLUME_CORRUPTED;
316 DEBUG ((DEBUG_INFO,
"NTFS: (ReadData #2) Attribute is corrupted.\n"));
317 return EFI_VOLUME_CORRUPTED;
323 if (Runlist == NULL) {
324 return EFI_OUT_OF_RESOURCES;
327 Runlist->
Attr = Attr;
334 DEBUG ((DEBUG_INFO,
"NTFS: Non-Resident Attribute is corrupted.\n"));
336 return EFI_VOLUME_CORRUPTED;
345 DEBUG ((DEBUG_INFO,
"NTFS: Overflow: StartingVCN is too large.\n"));
347 return EFI_VOLUME_CORRUPTED;
351 DEBUG ((DEBUG_INFO,
"NTFS: Read out of range\n"));
353 return EFI_VOLUME_CORRUPTED;
361 DEBUG ((DEBUG_INFO,
"NTFS: Invalid copmression unit size.\n"));
363 return EFI_VOLUME_CORRUPTED;
376 if (EFI_ERROR (Status)) {
378 return EFI_VOLUME_CORRUPTED;
383 OffsetInsideCluster = Offset & (ClusterSize - 1U);
391 Sector1 = Sector0 + 1U;
399 if (EFI_ERROR (Status)) {
401 return EFI_VOLUME_CORRUPTED;
446 if (Signed && (FieldSize != 0) && ((Run[FieldSize - 1U] & 0x80U) != 0)) {
447 Value = (UINT64)(-1);
450 CopyMem (&Value, Run, FieldSize);
478 UINTN FileRecordSize;
482 Run = Runlist->NextDataRun;
483 FileRecordSize = Runlist->Attr->BaseMftRecord->File->FileSystem->FileRecordSize;
484 BufferSize = FileRecordSize - (Run - Runlist->Attr->BaseMftRecord->FileRecord);
487 if (BufferSize == 0) {
488 DEBUG ((DEBUG_INFO,
"NTFS: (ReadRunListElement #1) Runlist is corrupted.\n"));
489 return EFI_VOLUME_CORRUPTED;
492 LengthSize = *Run & 0xFU;
493 OffsetSize = (*Run >> 4U) & 0xFU;
497 if ( (LengthSize > 8U)
499 || ((LengthSize == 0) && (OffsetSize != 0)))
501 DEBUG ((DEBUG_INFO,
"NTFS: (ReadRunListElement #2) Runlist is corrupted.\n"));
502 return EFI_VOLUME_CORRUPTED;
508 if ((LengthSize == 0) && (OffsetSize == 0)) {
509 if ( (Runlist->Attr != NULL)
516 DEBUG ((DEBUG_INFO,
"NTFS: $DATA should be non-resident\n"));
517 return EFI_VOLUME_CORRUPTED;
521 Runlist->CurrentLcn = 0;
527 DEBUG ((DEBUG_INFO,
"NTFS: Run list overflown\n"));
528 return EFI_VOLUME_CORRUPTED;
531 Runlist->CurrentVcn = Runlist->NextVcn;
533 if (BufferSize < LengthSize) {
534 DEBUG ((DEBUG_INFO,
"NTFS: (ReadRunListElement #3) Runlist is corrupted.\n"));
535 return EFI_VOLUME_CORRUPTED;
538 Runlist->NextVcn +=
ReadField (Run, LengthSize, FALSE);
539 if (Runlist->NextVcn <= Runlist->CurrentVcn) {
540 DEBUG ((DEBUG_INFO,
"NTFS: (ReadRunListElement #3.1) Runlist is corrupted.\n"));
541 return EFI_VOLUME_CORRUPTED;
545 BufferSize -= LengthSize;
547 if (BufferSize < OffsetSize) {
548 DEBUG ((DEBUG_INFO,
"NTFS: (ReadRunListElement #4) Runlist is corrupted.\n"));
549 return EFI_VOLUME_CORRUPTED;
552 OffsetLcn =
ReadField (Run, OffsetSize, TRUE);
553 Runlist->CurrentLcn += OffsetLcn;
556 BufferSize -= OffsetSize;
557 Runlist->NextDataRun = Run;
559 Runlist->IsSparse = (OffsetLcn == 0);
577 File->FileRecord = AllocateZeroPool (File->File->FileSystem->FileRecordSize);
578 if (File->FileRecord == NULL) {
582 Status =
ReadMftRecord (File->File, File->FileRecord, File->Inode);
583 if (EFI_ERROR (Status)) {
588 DEBUG ((DEBUG_INFO,
"NTFS: no $SYMLINK in MFT 0x%Lx\n", File->Inode));
592 Status =
ReadAttr (&File->Attr, (UINT8 *)&Symlink, 0, sizeof (Symlink));
593 if (EFI_ERROR (Status)) {
598 switch (Symlink.
Type) {
606 DEBUG ((DEBUG_INFO,
"NTFS: Symlink type invalid (%x)\n", Symlink.
Type));
611 if (Substitute == NULL) {
616 if (EFI_ERROR (Status)) {
618 FreePool (Substitute);
622 for (Letter = Substitute; *Letter != L
'\0'; ++Letter) {
623 if (*Letter == L
'\\') {
EFI_STATUS Decompress(IN RUNLIST *Runlist, IN UINT64 Offset, IN UINTN Length, OUT UINT8 *Dest)
STATIC UINT64 GetLcn(IN OUT RUNLIST *Runlist, IN UINT64 Vcn)
EFI_STATUS EFIAPI ReadAttr(IN NTFS_ATTR *Attr, OUT UINT8 *Dest, IN UINT64 Offset, IN UINTN Length)
EFI_STATUS EFIAPI ReadData(IN NTFS_ATTR *Attr, IN UINT8 *AttrStart, OUT UINT8 *Dest, IN UINT64 Offset, IN UINTN Length)
EFI_STATUS EFIAPI DiskRead(IN EFI_FS *FileSystem, IN UINT64 Offset, IN UINTN Size, IN OUT VOID *Buffer)
EFI_STATUS EFIAPI ReadMftRecord(IN EFI_NTFS_FILE *File, OUT UINT8 *Buffer, IN UINT64 RecordNumber)
STATIC UINT64 ReadField(IN CONST UINT8 *Run, IN UINT8 FieldSize, IN BOOLEAN Signed)
CHAR16 * ReadSymlink(IN NTFS_FILE *File)
STATIC EFI_STATUS ReadClusters(IN RUNLIST *Runlist, IN UINT64 Offset, IN UINTN Length, OUT UINT8 *Dest)
EFI_STATUS EFIAPI ReadRunListElement(IN OUT RUNLIST *Runlist)
UINT8 * LocateAttr(IN NTFS_ATTR *Attr, IN NTFS_FILE *Mft, IN UINT32 Type)
VOID FreeAttr(IN NTFS_ATTR *Attr)
UINT8 * FindAttr(IN NTFS_ATTR *Attr, IN UINT32 Type)
EFI_STATUS EFIAPI Fixup(IN UINT8 *Buffer, IN UINT64 Length, IN UINT32 Magic, IN UINTN SectorSize)
#define COMPRESSION_BLOCK
DMG_SIZE_DEVICE_PATH Size
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
UINT32 EFIAPI WriteUnaligned32(OUT UINT32 *Buffer, IN UINT32 Value)
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT16 CompressionUnitSize