diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index 5c94c3a64a0..0817140e82b 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -472,7 +472,10 @@ NTSTATUS typedef NTSTATUS (*PBL_DEVICE_READ) ( - VOID + _In_ struct _BL_DEVICE_ENTRY* DeviceEntry, + _In_ PVOID Buffer, + _In_ ULONG Size, + _Out_ PULONG BytesRead ); typedef @@ -491,7 +494,8 @@ NTSTATUS typedef NTSTATUS (*PBL_DEVICE_SET_INFORMATION) ( - VOID + _In_ struct _BL_DEVICE_ENTRY* DeviceEntry, + _In_ struct _BL_DEVICE_INFORMATION* DeviceInformation ); typedef @@ -894,6 +898,9 @@ typedef struct _BL_BLOCK_DEVICE_INFORMATION BL_PARTITION_TYPE PartitionType; ULONG BlockSize; ULONG Alignment; + ULONGLONG MaxBlock; + ULONGLONG Offset; + ULONG Block; struct { union @@ -1483,6 +1490,21 @@ BlDeviceGetInformation ( _Out_ PBL_DEVICE_INFORMATION DeviceInformation ); +NTSTATUS +BlDeviceSetInformation ( + _In_ ULONG DeviceId, + _In_ PBL_DEVICE_INFORMATION DeviceInformation + ); + +NTSTATUS +BlDeviceReadAtOffset ( + _In_ ULONG DeviceId, + _In_ ULONG Size, + _In_ ULONGLONG Offset, + _In_ PVOID Buffer, + _Out_ PULONG BytesRead + ); + /* FILE I/O ROUTINES *********************************************************/ NTSTATUS diff --git a/reactos/boot/environ/lib/io/device.c b/reactos/boot/environ/lib/io/device.c index c2c768ad0b1..e4c9424ee40 100644 --- a/reactos/boot/environ/lib/io/device.c +++ b/reactos/boot/environ/lib/io/device.c @@ -14,10 +14,8 @@ typedef struct _BL_DEVICE_IO_INFORMATION { - ULONG Unknown0; - ULONG Unknown1; - ULONG Unknown2; - ULONG Unknown3; + ULONGLONG ReadCount; + ULONGLONG WriteCount; } BL_DEVICE_IO_INFORMATION, *PBL_DEVICE_IO_INFORMATION; LIST_ENTRY DmRegisteredDevices; @@ -69,6 +67,12 @@ BlockIoGetInformation ( _Out_ PBL_DEVICE_INFORMATION DeviceInformation ); +NTSTATUS +BlockIoSetInformation ( + _In_ PBL_DEVICE_ENTRY DeviceEntry, + _Out_ PBL_DEVICE_INFORMATION DeviceInformation + ); + BL_DEVICE_CALLBACKS BlockIoDeviceFunctionTable = { NULL, @@ -76,9 +80,33 @@ BL_DEVICE_CALLBACKS BlockIoDeviceFunctionTable = NULL, NULL, NULL, - BlockIoGetInformation + BlockIoGetInformation, + BlockIoSetInformation }; +NTSTATUS +BlockIoSetInformation ( + _In_ PBL_DEVICE_ENTRY DeviceEntry, + _Out_ PBL_DEVICE_INFORMATION DeviceInformation + ) +{ + PBL_BLOCK_DEVICE BlockDevice; + ULONGLONG Offset; + + BlockDevice = DeviceEntry->DeviceSpecificData; + + Offset = DeviceInformation->BlockDeviceInfo.Block * BlockDevice->BlockSize + DeviceInformation->BlockDeviceInfo.Offset; + if (Offset > ((BlockDevice->MaxBlock + 1) * BlockDevice->BlockSize - 1)) + { + return STATUS_INVALID_PARAMETER; + } + + BlockDevice->Block = Offset / BlockDevice->BlockSize; + BlockDevice->Offset = Offset % BlockDevice->BlockSize; + BlockDevice->Unknown = DeviceInformation->BlockDeviceInfo.Unknown; + return STATUS_SUCCESS; +} + NTSTATUS BlockIoGetInformation ( _In_ PBL_DEVICE_ENTRY DeviceEntry, @@ -96,6 +124,39 @@ BlockIoGetInformation ( return STATUS_SUCCESS; } +NTSTATUS +BlDeviceSetInformation ( + _In_ ULONG DeviceId, + _Out_ PBL_DEVICE_INFORMATION DeviceInformation + ) +{ + PBL_DEVICE_ENTRY DeviceEntry; + + if (!(DeviceInformation)) + { + return STATUS_INVALID_PARAMETER; + } + + if (DmTableEntries <= DeviceId) + { + return STATUS_INVALID_PARAMETER; + } + + DeviceEntry = DmDeviceTable[DeviceId]; + if (!DeviceEntry) + { + return STATUS_INVALID_PARAMETER; + } + + if (!(DeviceEntry->Flags & 1)) + { + return STATUS_INVALID_PARAMETER; + } + + DeviceInformation->DeviceType = DeviceEntry->DeviceDescriptor->DeviceType; + return DeviceEntry->Callbacks.SetInformation(DeviceEntry, DeviceInformation); +} + NTSTATUS BlDeviceGetInformation ( _In_ ULONG DeviceId, @@ -129,6 +190,73 @@ BlDeviceGetInformation ( return DeviceEntry->Callbacks.GetInformation(DeviceEntry, DeviceInformation); } +NTSTATUS +BlDeviceRead ( + _In_ ULONG DeviceId, + _In_ PVOID Buffer, + _In_ ULONG Size, + _Out_ PULONG BytesRead + ) +{ + PBL_DEVICE_ENTRY DeviceEntry; // ecx@3 + NTSTATUS Status; + ULONG BytesTransferred; + + if (Buffer + && DmTableEntries > DeviceId + && (DeviceEntry = DmDeviceTable[DeviceId]) != 0 + && DeviceEntry->Flags & 1 + && DeviceEntry->Flags & 2) + { + EfiPrintf(L"Calling read...\r\n"); + Status = DeviceEntry->Callbacks.Read(DeviceEntry, Buffer, Size, &BytesTransferred); + + if (!DeviceEntry->Unknown) + { + DmDeviceIoInformation.ReadCount += BytesTransferred; + } + + if (BytesRead) + { + *BytesRead = BytesTransferred; + } + } + else + { + Status = STATUS_INVALID_PARAMETER; + } + return Status; +} + +NTSTATUS +BlDeviceReadAtOffset ( + _In_ ULONG DeviceId, + _In_ ULONG Size, + _In_ ULONGLONG Offset, + _In_ PVOID Buffer, + _Out_ PULONG BytesRead + ) +{ + NTSTATUS Status; + BL_DEVICE_INFORMATION DeviceInformation; + + Status = BlDeviceGetInformation(DeviceId, &DeviceInformation); + if (Status >= 0) + { + DeviceInformation.BlockDeviceInfo.Block = Offset / DeviceInformation.BlockDeviceInfo.BlockSize; + DeviceInformation.BlockDeviceInfo.Offset = Offset % DeviceInformation.BlockDeviceInfo.BlockSize; + Status = BlDeviceSetInformation(DeviceId, &DeviceInformation); + + if (NT_SUCCESS(Status)) + { + EfiPrintf(L"Block: %d Offset: %d\r\n", DeviceInformation.BlockDeviceInfo.Block, DeviceInformation.BlockDeviceInfo.Offset); + Status = BlDeviceRead(DeviceId, Buffer, Size, BytesRead); + } + } + return Status; +} + + BOOLEAN BlpDeviceCompare ( _In_ PBL_DEVICE_DESCRIPTOR Device1, @@ -1496,10 +1624,8 @@ BlpDeviceInitialize ( InitializeListHead(&DmRegisteredDevices); /* Initialize device information */ - DmDeviceIoInformation.Unknown0 = 0; - DmDeviceIoInformation.Unknown1 = 0; - DmDeviceIoInformation.Unknown2 = 0; - DmDeviceIoInformation.Unknown3 = 0; + DmDeviceIoInformation.ReadCount = 0; + DmDeviceIoInformation.WriteCount = 0; /* Allocate the device table */ DmDeviceTable = BlMmAllocateHeap(DmTableEntries * sizeof(PVOID)); diff --git a/reactos/boot/environ/lib/io/fat.c b/reactos/boot/environ/lib/io/fat.c index 46f05959b7a..7945ddf96d5 100644 --- a/reactos/boot/environ/lib/io/fat.c +++ b/reactos/boot/environ/lib/io/fat.c @@ -9,6 +9,7 @@ /* INCLUDES ******************************************************************/ #include "bl.h" +#include "..\drivers\filesystems\fs_rec\fs_rec.h" /* DATA VARIABLES ************************************************************/ @@ -25,7 +26,39 @@ FatMount ( _Out_ PBL_FILE_ENTRY* FileEntry ) { - EfiPrintf(L"FAT Mount on Device %d TODO\r\n", DeviceId); + BL_DEVICE_INFORMATION DeviceInformation; + ULONG UnknownFlag; + NTSTATUS Status; + PACKED_BOOT_SECTOR FatBootSector; + + EfiPrintf(L"FAT Mount on Device %d\r\n", DeviceId); + + /* Capture thing */ + BlDeviceGetInformation(DeviceId, &DeviceInformation); + UnknownFlag = DeviceInformation.BlockDeviceInfo.Unknown; + + /* Set thing to 1 */ + DeviceInformation.BlockDeviceInfo.Unknown |= 1; + BlDeviceSetInformation(DeviceId, &DeviceInformation); + + /* Read the boot sector */ + EfiPrintf(L"Reading fat boot sector...\r\n"); + Status = BlDeviceReadAtOffset(DeviceId, + sizeof(FatBootSector), + 0, + &FatBootSector, + NULL); + + /* Restore thing back */ + DeviceInformation.BlockDeviceInfo.Unknown = UnknownFlag; + BlDeviceSetInformation(DeviceId, &DeviceInformation); + if (!NT_SUCCESS(Status)) + { + EfiPrintf(L"Failed reading drive: %lx\r\n", Status); + return Status; + } + + EfiPrintf(L"Drive read\r\n"); EfiStall(3000000); return STATUS_NOT_IMPLEMENTED; }