mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[BOOTLIB]:
- Fix multiple bugs in ETFS code (confusion between file offset vs. disk offset) - Implement EtfsGetInformation, EtfsSetInformation, and fix ETFS_FILE definition to make this easy. - Implement EtfsRead. - Fix multiple bugs in file I/O code (swapped/reversed validation checks) - Make BlStatusPrint call EfiPrintf on debug builds, even without BD. - Add some additional error logging. svn path=/trunk/; revision=69452
This commit is contained in:
parent
10dbbf573b
commit
0cc3cfadf3
6 changed files with 170 additions and 29 deletions
|
@ -49,7 +49,7 @@ typedef struct _BL_PACKED_BOOT_ERROR
|
|||
ULONG Size;
|
||||
} BL_PACKED_BOOT_ERROR, *PBL_PACKED_BOOT_ERROR;
|
||||
|
||||
#define BL_FATAL_ERROR_BCD_READ 0x02
|
||||
#define BL_FATAL_ERROR_BCD_READ 0x01
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ NTSTATUS
|
|||
_In_ struct _BL_FILE_ENTRY* FileEntry,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ ULONG Size,
|
||||
_Out_ PULONG BytesRead
|
||||
_Out_opt_ PULONG BytesRead
|
||||
);
|
||||
|
||||
typedef
|
||||
|
@ -786,8 +786,10 @@ typedef struct _BL_ADDRESS_RANGE
|
|||
|
||||
typedef struct _BL_FILE_INFORMATION
|
||||
{
|
||||
ULONGLONG FileSize;
|
||||
ULONGLONG CurrentOffset;
|
||||
ULONGLONG Size;
|
||||
ULONGLONG Offset;
|
||||
PWCHAR FsName;
|
||||
ULONG Flags;
|
||||
} BL_FILE_INFORMATION, *PBL_FILE_INFORMATION;
|
||||
|
||||
typedef struct _BL_FILE_CALLBACKS
|
||||
|
@ -809,7 +811,7 @@ typedef struct _BL_FILE_ENTRY
|
|||
ULONG Flags;
|
||||
ULONG ReferenceCount;
|
||||
ULONG Unknown;
|
||||
ULONGLONG Unknown1;
|
||||
ULONGLONG TotalBytesRead;
|
||||
ULONGLONG Unknown2;
|
||||
BL_FILE_CALLBACKS Callbacks;
|
||||
PVOID FsSpecificData;
|
||||
|
|
|
@ -36,12 +36,12 @@ typedef struct _BL_ETFS_DEVICE
|
|||
|
||||
typedef struct _BL_ETFS_FILE
|
||||
{
|
||||
ULONG DiskOffset;
|
||||
ULONG DirOffset;
|
||||
ULONG DirEntOffset;
|
||||
ULONGLONG Size;
|
||||
ULONGLONG Offset;
|
||||
PWCHAR FsName;
|
||||
ULONG Flags;
|
||||
|
||||
BL_FILE_INFORMATION;
|
||||
|
||||
ULONG DeviceId;
|
||||
} BL_ETFS_FILE, *PBL_ETFS_FILE;
|
||||
|
||||
|
@ -56,9 +56,35 @@ EtfsOpen (
|
|||
_Out_ PBL_FILE_ENTRY *FileEntry
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
EtfsGetInformation (
|
||||
_In_ PBL_FILE_ENTRY FileEntry,
|
||||
_Out_ PBL_FILE_INFORMATION FileInfo
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
EtfsSetInformation (
|
||||
_In_ PBL_FILE_ENTRY FileEntry,
|
||||
_In_ PBL_FILE_INFORMATION FileInfo
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
EtfsRead (
|
||||
_In_ PBL_FILE_ENTRY FileEntry,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ ULONG Size,
|
||||
_Out_opt_ PULONG BytesReturned
|
||||
);
|
||||
|
||||
BL_FILE_CALLBACKS EtfsFunctionTable =
|
||||
{
|
||||
EtfsOpen,
|
||||
NULL,
|
||||
EtfsRead,
|
||||
NULL,
|
||||
NULL,
|
||||
EtfsGetInformation,
|
||||
EtfsSetInformation
|
||||
};
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
@ -205,7 +231,7 @@ EtfspGetDirent (
|
|||
|
||||
EtfsFile = DirectoryEntry->FsSpecificData;
|
||||
DeviceId = EtfsFile->DeviceId;
|
||||
FileOffset = EtfsFile->Offset;
|
||||
FileOffset = EtfsFile->DiskOffset;
|
||||
EtfsDevice = EtfsDeviceTable[DeviceId];
|
||||
|
||||
DirectoryOffset = *DirentOffset;
|
||||
|
@ -362,7 +388,7 @@ EtfspCachedSearchForDirent (
|
|||
DirentOffset = EtfsFile->DirEntOffset;
|
||||
|
||||
if ((KeepOffset) ||
|
||||
(ALIGN_DOWN_BY((DirentOffset + EtfsFile->Offset), CD_SECTOR_SIZE) ==
|
||||
(ALIGN_DOWN_BY((DirentOffset + EtfsFile->DiskOffset), CD_SECTOR_SIZE) ==
|
||||
EtfsDevice->Offset))
|
||||
{
|
||||
Status = EtfspGetDirent(DirectoryEntry, &Dirent, &DirentOffset);
|
||||
|
@ -406,6 +432,108 @@ EtfspCachedSearchForDirent (
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EtfsRead (
|
||||
_In_ PBL_FILE_ENTRY FileEntry,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ ULONG Size,
|
||||
_Out_opt_ PULONG BytesReturned
|
||||
)
|
||||
{
|
||||
ULONG BytesRead;
|
||||
PBL_ETFS_FILE EtfsFile;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Assume failure for now */
|
||||
BytesRead = 0;
|
||||
|
||||
/* Make sure that the read is within the file's boundaries */
|
||||
EtfsFile = FileEntry->FsSpecificData;
|
||||
if ((Size + EtfsFile->Offset) > EtfsFile->Size)
|
||||
{
|
||||
/* Bail out otherwise */
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read the offset that matches this file's offset, on the disk */
|
||||
Status = BlDeviceReadAtOffset(FileEntry->DeviceId,
|
||||
Size,
|
||||
EtfsFile->Offset + EtfsFile->DiskOffset,
|
||||
Buffer,
|
||||
&BytesRead);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Update the file offset and return the size as having been read */
|
||||
EtfsFile->Offset += Size;
|
||||
BytesRead = Size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if caller wanted to know how many bytes were read */
|
||||
if (BytesReturned)
|
||||
{
|
||||
/* Return the value */
|
||||
*BytesReturned = BytesRead;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EtfsSetInformation (
|
||||
_In_ PBL_FILE_ENTRY FileEntry,
|
||||
_In_ PBL_FILE_INFORMATION FileInfo
|
||||
)
|
||||
{
|
||||
PBL_ETFS_FILE EtfsFile;
|
||||
BL_FILE_INFORMATION LocalFileInfo;
|
||||
|
||||
/* Get the underlying ETFS file data structure */
|
||||
EtfsFile = (PBL_ETFS_FILE)FileEntry->FsSpecificData;
|
||||
|
||||
/* Make a copy of the incoming attributes, but ignore the new offset */
|
||||
LocalFileInfo = *FileInfo;
|
||||
LocalFileInfo.Offset = EtfsFile->Offset;
|
||||
|
||||
/* Check if these match exactly the current file */
|
||||
if (!RtlEqualMemory(&LocalFileInfo, &EtfsFile->Size, sizeof(*FileInfo)))
|
||||
{
|
||||
/* Nope -- which means caller is trying to change an immutable */
|
||||
EfiPrintf(L"Incorrect information change\r\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Is the offset past the end of the file? */
|
||||
if (FileInfo->Offset >= EtfsFile->Size)
|
||||
{
|
||||
/* Don't allow EOF */
|
||||
EfiPrintf(L"Offset too large: %lx vs %lx \r\n", FileInfo->Offset, EtfsFile->Size);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Update the offset */
|
||||
EtfsFile->Offset = FileInfo->Offset;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EtfsGetInformation (
|
||||
_In_ PBL_FILE_ENTRY FileEntry,
|
||||
_Out_ PBL_FILE_INFORMATION FileInfo
|
||||
)
|
||||
{
|
||||
PBL_ETFS_FILE EtfsFile;
|
||||
|
||||
/* Get the underlying ETFS file data structure */
|
||||
EtfsFile = (PBL_ETFS_FILE)FileEntry->FsSpecificData;
|
||||
|
||||
/* Copy the cached information structure within it */
|
||||
RtlCopyMemory(FileInfo, &EtfsFile->Size, sizeof(*FileInfo));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EtfsOpen (
|
||||
_In_ PBL_FILE_ENTRY Directory,
|
||||
|
@ -486,7 +614,7 @@ EtfsOpen (
|
|||
RtlCopyMemory(&NewFile->Callbacks,
|
||||
&EtfsFunctionTable,
|
||||
sizeof(NewFile->Callbacks));
|
||||
EtfsFile->Offset = FileOffset;
|
||||
EtfsFile->DiskOffset = FileOffset;
|
||||
EtfsFile->DirOffset = DirOffset;
|
||||
EtfsFile->Size = FileSize;
|
||||
EtfsFile->DeviceId = DeviceId;
|
||||
|
@ -794,7 +922,7 @@ EtfsMount (
|
|||
RootEntry->FsSpecificData = EtfsFile;
|
||||
EtfsFile->DeviceId = DeviceId;
|
||||
EtfsFile->Flags |= 1;
|
||||
EtfsFile->Offset = EtfsDevice->RootDirOffset;
|
||||
EtfsFile->DiskOffset = EtfsDevice->RootDirOffset;
|
||||
EtfsFile->DirOffset = 0;
|
||||
EtfsFile->Size = EtfsDevice->RootDirSize;
|
||||
EtfsFile->FsName = L"cdfs";
|
||||
|
|
|
@ -434,7 +434,7 @@ FileOpened:
|
|||
if (++FileEntry->ReferenceCount == 1)
|
||||
{
|
||||
/* Reset unknowns */
|
||||
FileEntry->Unknown1 = 0;
|
||||
FileEntry->TotalBytesRead = 0;
|
||||
FileEntry->Unknown2 = 0;
|
||||
}
|
||||
|
||||
|
@ -548,7 +548,7 @@ BlFileSetInformation (
|
|||
}
|
||||
|
||||
/* Validate file ID */
|
||||
if (FileEntries > FileId)
|
||||
if (FileId > FileEntries)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -579,7 +579,7 @@ BlFileGetInformation (
|
|||
}
|
||||
|
||||
/* Validate file ID */
|
||||
if (FileEntries > FileId)
|
||||
if (FileId > FileEntries)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -612,7 +612,7 @@ FileInformationCheck (
|
|||
Size = 0;
|
||||
|
||||
/* Make sure we didn't overshoot */
|
||||
if (FileInformation->CurrentOffset > FileInformation->FileSize)
|
||||
if (FileInformation->Offset > FileInformation->Size)
|
||||
{
|
||||
/* Bail out */
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
@ -621,9 +621,9 @@ FileInformationCheck (
|
|||
|
||||
/* Compute the appropriate 32-bit size of this read, based on file size */
|
||||
Size = ULONG_MAX;
|
||||
if ((FileInformation->FileSize - FileInformation->CurrentOffset) <= ULONG_MAX)
|
||||
if ((FileInformation->Size - FileInformation->Offset) <= ULONG_MAX)
|
||||
{
|
||||
Size = (ULONG)(FileInformation->FileSize) - (ULONG)(FileInformation->CurrentOffset);
|
||||
Size = (ULONG)(FileInformation->Size) - (ULONG)(FileInformation->Offset);
|
||||
}
|
||||
|
||||
/* Check if the caller has an input buffer */
|
||||
|
@ -683,7 +683,7 @@ BlFileReadEx (
|
|||
}
|
||||
|
||||
/* Bail out of the file ID is invalid */
|
||||
if (FileEntries > FileId)
|
||||
if (FileId > FileEntries)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -774,7 +774,7 @@ BlFileReadEx (
|
|||
}
|
||||
|
||||
/* Increment the number of bytes read */
|
||||
FileEntry->Unknown1 += RequiredSize;
|
||||
FileEntry->TotalBytesRead += RequiredSize;
|
||||
|
||||
/* Check if the unknown flag on the device was changed during this routine */
|
||||
if (ChangedUnknown)
|
||||
|
@ -811,8 +811,8 @@ BlFileReadAtOffsetEx (
|
|||
}
|
||||
|
||||
/* Save the current offset, and overwrite it with the one we want */
|
||||
FileOffset = FileInfo.CurrentOffset;
|
||||
FileInfo.CurrentOffset = ByteOffset;
|
||||
FileOffset = FileInfo.Offset;
|
||||
FileInfo.Offset = ByteOffset;
|
||||
|
||||
/* Check the validity of the read and the actual size to read */
|
||||
RequiredSize = Size;
|
||||
|
@ -824,11 +824,12 @@ BlFileReadAtOffsetEx (
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Bail out if the read is invalid */
|
||||
EfiPrintf(L"File info check failure: %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check if the offset we're requesting is not the current offset */
|
||||
if (FileInfo.CurrentOffset != FileOffset)
|
||||
if (FileInfo.Offset != FileOffset)
|
||||
{
|
||||
/* Set the new offset to use */
|
||||
Status = BlFileSetInformation(FileId, &FileInfo);
|
||||
|
@ -848,10 +849,10 @@ BlFileReadAtOffsetEx (
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* The read failed -- had we modified the offset? */
|
||||
if (FileInfo.CurrentOffset != FileOffset)
|
||||
if (FileInfo.Offset != FileOffset)
|
||||
{
|
||||
/* Restore the offset back to its original value */
|
||||
FileInfo.CurrentOffset = FileOffset;
|
||||
FileInfo.Offset = FileOffset;
|
||||
BlFileSetInformation(FileId, &FileInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,11 +83,19 @@ BlStatusPrint (
|
|||
va_start(va, Format);
|
||||
|
||||
/* Check if the boot debugger is enabled */
|
||||
if (BlBdDebuggerEnabled())
|
||||
if (BlBdDebuggerEnabled()
|
||||
#if (defined(DBG))
|
||||
|| TRUE
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* Print the string out into a buffer */
|
||||
if (vswprintf(BlScratchBuffer, Format, va) > 0)
|
||||
{
|
||||
#if defined(DBG)
|
||||
EfiPrintf(BlScratchBuffer);
|
||||
EfiPrintf(L"\r\n");
|
||||
#endif
|
||||
/* Make it a UNICODE_STRING */
|
||||
RtlInitUnicodeString(&UnicodeString, BlScratchBuffer);
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ ImgpGetFileSize (
|
|||
}
|
||||
|
||||
/* We only support files less than 4GB in the Image Mapped */
|
||||
Size = FileInformation.FileSize;
|
||||
if (FileInformation.FileSize > ULONG_MAX)
|
||||
Size = FileInformation.Size;
|
||||
if (FileInformation.Size > ULONG_MAX)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -392,6 +392,7 @@ BlImgLoadImageWithProgress2 (
|
|||
Status = ImgpOpenFile(DeviceId, FileName, DeviceId, &FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
EfiPrintf(L"Error opening file: %lx\r\n", Status);
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
|
@ -399,6 +400,7 @@ BlImgLoadImageWithProgress2 (
|
|||
Status = ImgpGetFileSize(&FileHandle, &ImageSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
EfiPrintf(L"Error getting file size: %lx\r\n", Status);
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue