64 CopyMem (&File->RootFile, File->FileSystem->RootIndex, sizeof (File->RootFile));
65 CopyMem (&File->MftFile, File->FileSystem->MftStart, sizeof (File->MftFile));
73 if (EFI_ERROR (Status)) {
77 if (BaseMftRecord != &File->RootFile) {
78 CopyMem (&File->RootFile, BaseMftRecord, sizeof (*BaseMftRecord));
80 if (!File->RootFile.InodeRead) {
81 Status =
InitFile (&File->RootFile, File->RootFile.Inode);
85 FreePool (BaseMftRecord);
103 ASSERT (FileSystem != NULL);
105 Status =
DiskRead (FileSystem, 0,
sizeof (Boot), &Boot);
106 if (EFI_ERROR (Status)) {
110 if ( (Boot.
SystemId[0] != SIGNATURE_32 (
'N',
'T',
'F',
'S'))
116 DEBUG ((DEBUG_INFO,
"NTFS: (NtfsMount #1) BIOS Parameter Block is corrupted.\n"));
117 return EFI_VOLUME_CORRUPTED;
121 FileSystem->ClusterSize = (UINTN)Boot.
SectorsPerCluster * FileSystem->SectorSize;
126 DEBUG ((DEBUG_INFO,
"NTFS: (NtfsMount #2) BIOS Parameter Block is corrupted.\n"));
127 return EFI_VOLUME_CORRUPTED;
132 FileSystem->FileRecordSize =
Size;
133 if (FileSystem->FileRecordSize < FileSystem->SectorSize) {
134 DEBUG ((DEBUG_INFO,
"NTFS: File Record is smaller than Sector.\n"));
135 return EFI_VOLUME_CORRUPTED;
141 DEBUG ((DEBUG_INFO,
"NTFS: (NtfsMount #3) BIOS Parameter Block is corrupted.\n"));
142 return EFI_VOLUME_CORRUPTED;
147 FileSystem->IndexRecordSize =
Size;
148 if (FileSystem->IndexRecordSize < FileSystem->SectorSize) {
149 DEBUG ((DEBUG_INFO,
"NTFS: Index Record is smaller than Sector.\n"));
150 return EFI_VOLUME_CORRUPTED;
153 FileSystem->FirstMftRecord = Boot.
MftLcn * FileSystem->ClusterSize;
160 DEBUG ((DEBUG_INFO,
"NTFS: (NtfsMount #4) BIOS Parameter Block is corrupted.\n"));
161 return EFI_VOLUME_CORRUPTED;
164 RootFile = AllocateZeroPool (
sizeof (*RootFile));
165 if (RootFile == NULL) {
166 return EFI_OUT_OF_RESOURCES;
169 CopyMem (RootFile, &FileSystem->
EfiFile, sizeof (FileSystem->EfiFile));
171 RootFile->
IsDir = TRUE;
172 RootFile->
Path = L
"/";
181 return EFI_OUT_OF_RESOURCES;
186 FileSystem->FirstMftRecord,
187 FileSystem->FileRecordSize,
190 if (EFI_ERROR (Status)) {
198 FileSystem->FileRecordSize,
199 SIGNATURE_32 (
'F',
'I',
'L',
'E'),
200 FileSystem->SectorSize
202 if (EFI_ERROR (Status)) {
211 return EFI_VOLUME_CORRUPTED;
215 if (EFI_ERROR (Status)) {
221 FileSystem->RootIndex = &RootFile->
RootFile;
222 FileSystem->MftStart = &RootFile->
MftFile;
412 UINTN FileRecordSize;
418 FileRecordSize = Attr->BaseMftRecord->File->FileSystem->FileRecordSize;
419 SectorSize = Attr->BaseMftRecord->File->FileSystem->SectorSize;
423 while ((Attr->Next + sizeof (*LRecord)) <= Attr->Last) {
424 Attr->Current = Attr->Next;
427 if (BufferSize < LRecord->RecordLength) {
428 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #0) $ATTRIBUTE_LIST is corrupted.\n"));
435 if (Attr->Next <= Attr->Current) {
436 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #1) $ATTRIBUTE_LIST is corrupted.\n"));
441 if ((LRecord->
Type == Type) || (Type == 0)) {
444 Attr->BaseMftRecord->File->FileSystem,
447 Attr->ExtensionMftRecord
449 if (EFI_ERROR (Status)) {
450 DEBUG ((DEBUG_INFO,
"NTFS: Could not read first part of extension record.\n"));
456 Attr->BaseMftRecord->File->FileSystem,
459 Attr->ExtensionMftRecord + FileRecordSize / 2U
461 if (EFI_ERROR (Status)) {
462 DEBUG ((DEBUG_INFO,
"NTFS: Could not read second part of extension record.\n"));
468 Attr->ExtensionMftRecord,
470 SIGNATURE_32 (
'F',
'I',
'L',
'E'),
471 Attr->BaseMftRecord->File->FileSystem->SectorSize
473 if (EFI_ERROR (Status)) {
474 DEBUG ((DEBUG_INFO,
"NTFS: Fixup failed.\n"));
480 Attr->BaseMftRecord->File,
481 Attr->ExtensionMftRecord,
484 if (EFI_ERROR (Status)) {
485 DEBUG ((DEBUG_INFO,
"NTFS: Could not read extension record.\n"));
492 BufferSize = FileRecordSize;
497 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #1) Extension record is corrupted.\n"));
503 if (BufferSize <
sizeof (*Res)) {
504 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #2) Extension record is corrupted.\n"));
515 if ((Res->
Length == 0) || (Res->
Length >= BufferSize)) {
516 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #3) Extension record is corrupted.\n"));
521 BufferSize -= Res->
Length;
525 DEBUG ((DEBUG_INFO,
"NTFS: Can\'t find 0x%X in attribute list\n", Attr->Current));
535 Attr->Current = Attr->Next;
537 BufferSize = FileRecordSize - (Attr->Current - Attr->BaseMftRecord->FileRecord);
540 if (BufferSize <
sizeof (*Res)) {
541 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #1) File record is corrupted.\n"));
546 if ((Res->
Length == 0) || (Res->
Length >= BufferSize)) {
547 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #2) File record is corrupted.\n"));
552 BufferSize -= Res->
Length;
553 Attr->Next += Res->
Length;
556 Attr->Last = Attr->Current;
559 if ((Res->
Type == Type) || (Type == 0)) {
560 return Attr->Current;
563 Attr->Current = Attr->Next;
570 if (Attr->Last != NULL) {
571 if (Attr->ExtensionMftRecord != NULL) {
572 FreePool (Attr->ExtensionMftRecord);
575 Attr->ExtensionMftRecord = AllocateZeroPool (FileRecordSize);
576 if (Attr->ExtensionMftRecord == NULL) {
581 AttrStart = Attr->Last;
583 BufferSize = FileRecordSize - (Attr->Last - Attr->BaseMftRecord->FileRecord);
585 if (BufferSize <
sizeof (*Res)) {
586 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #3) File record is corrupted.\n"));
593 Attr->Current = (UINT8 *)NonRes;
595 if (BufferSize <
sizeof (*NonRes)) {
596 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #4) File record is corrupted.\n"));
602 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr) File is too huge.\n"));
607 if (Attr->NonResAttrList != NULL) {
608 FreePool (Attr->NonResAttrList);
611 Attr->NonResAttrList = AllocateZeroPool ((UINTN)NonRes->
RealSize);
612 if (Attr->NonResAttrList == NULL) {
617 Status =
ReadData (Attr, AttrStart, Attr->NonResAttrList, 0, (UINTN)NonRes->
RealSize);
618 if (EFI_ERROR (Status)) {
619 DEBUG ((DEBUG_INFO,
"NTFS: Failed to read non-resident attribute list\n"));
624 Attr->Next = Attr->NonResAttrList;
625 Attr->Last = Attr->NonResAttrList + NonRes->
RealSize;
630 Attr->Last = (UINT8 *)Res + Res->
Length;
633 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #5) File record is corrupted.\n"));
641 while ((Attr->Next + sizeof (*LRecord)) < Attr->Last) {
642 if ((LRecord->
Type == Type) || (Type == 0)) {
646 if (BufferSize < LRecord->RecordLength) {
647 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #2) $ATTRIBUTE_LIST is corrupted.\n"));
653 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #3) $ATTRIBUTE_LIST is corrupted.\n"));
663 if ((Attr->Next + sizeof (*LRecord)) >= Attr->Last) {
670 Attr->Current = Attr->Next;
671 AttrStart = Attr->Current;
673 if (BufferSize >= 0x18U) {
675 (UINT32 *)(AttrStart + 0x10U),
676 (UINT32)
DivU64x64Remainder (Attr->BaseMftRecord->File->FileSystem->FirstMftRecord, SectorSize, NULL)
679 (UINT32 *)(AttrStart + 0x14U),
680 (UINT32)
DivU64x64Remainder (Attr->BaseMftRecord->File->FileSystem->FirstMftRecord, SectorSize, NULL) + 1U
683 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #7) File record is corrupted.\n"));
688 AttrStart = Attr->Next +
ReadUnaligned16 ((UINT16 *)(AttrStart + 0x04U));
689 while ((AttrStart +
sizeof (UINT32) +
sizeof (UINT16)) < Attr->Last) {
700 if (EFI_ERROR (Status)) {
706 DEBUG ((DEBUG_INFO,
"NTFS: (FindAttr #8) File record is corrupted.\n"));
714 Attr->Next = Attr->Current;
715 Attr->Flags &= ~NTFS_AF_GPOS;