From: Alex Ionescu Date: Mon, 5 Oct 2015 05:53:40 +0000 (+0000) Subject: [BOOTLIB]: X-Git-Tag: ReactOS-0.4.0~595 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=0cc3cfadf3c42152ce303bd2bda9500c45aa3a4b [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 --- diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.h b/reactos/boot/environ/app/bootmgr/bootmgr.h index e5342d42703..76dea63a728 100644 --- a/reactos/boot/environ/app/bootmgr/bootmgr.h +++ b/reactos/boot/environ/app/bootmgr/bootmgr.h @@ -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 *****************************************************************/ diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index 025ff6da13b..aa4a608ede4 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -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; diff --git a/reactos/boot/environ/lib/io/etfs.c b/reactos/boot/environ/lib/io/etfs.c index bf0742875bf..eddf2bb9c04 100644 --- a/reactos/boot/environ/lib/io/etfs.c +++ b/reactos/boot/environ/lib/io/etfs.c @@ -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"; diff --git a/reactos/boot/environ/lib/io/file.c b/reactos/boot/environ/lib/io/file.c index ce0cb722d74..0984354e985 100644 --- a/reactos/boot/environ/lib/io/file.c +++ b/reactos/boot/environ/lib/io/file.c @@ -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); } } diff --git a/reactos/boot/environ/lib/misc/debug.c b/reactos/boot/environ/lib/misc/debug.c index 773d78f8901..a4c82e2cb05 100644 --- a/reactos/boot/environ/lib/misc/debug.c +++ b/reactos/boot/environ/lib/misc/debug.c @@ -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); diff --git a/reactos/boot/environ/lib/misc/image.c b/reactos/boot/environ/lib/misc/image.c index 7573755104c..e3009fcc8e8 100644 --- a/reactos/boot/environ/lib/misc/image.c +++ b/reactos/boot/environ/lib/misc/image.c @@ -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; }