EFIAPI EFI_STATUS BootMonFsDelete ( IN EFI_FILE_PROTOCOL *This ) { EFI_STATUS Status; BOOTMON_FS_FILE *File; LIST_ENTRY *RegionToFlushLink; BOOTMON_FS_FILE_REGION *Region; HW_IMAGE_DESCRIPTION *Description; EFI_BLOCK_IO_PROTOCOL *BlockIo; UINT8 *EmptyBuffer; File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); if (File == NULL) { return EFI_DEVICE_ERROR; } Status = EFI_SUCCESS; if (BootMonFsFileNeedFlush (File)) { // Free the entries from the Buffer List RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink); do { Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink; // Get Next entry RegionToFlushLink = RemoveEntryList (RegionToFlushLink); // Free the buffers FreePool (Region->Buffer); FreePool (Region); } while (!IsListEmpty (&File->RegionToFlushLink)); } // If (RegionCount is greater than 0) then the file already exists if (File->HwDescription.RegionCount > 0) { Description = &File->HwDescription; BlockIo = File->Instance->BlockIo; // Create an empty buffer EmptyBuffer = AllocateZeroPool (BlockIo->Media->BlockSize); if (EmptyBuffer == NULL) { FreePool (File); return EFI_OUT_OF_RESOURCES; } // Invalidate the last Block Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, Description->BlockEnd, BlockIo->Media->BlockSize, EmptyBuffer); ASSERT_EFI_ERROR (Status); FreePool (EmptyBuffer); } // Remove the entry from the list RemoveEntryList (&File->Link); FreePool (File); return Status; }
/** Save lines in HBufferImage to disk. NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!! @param[in] DeviceName The device name. @param[in] Offset The offset. @param[in] Size The size. @retval EFI_SUCCESS The operation was successful. @retval EFI_OUT_OF_RESOURCES A memory allocation failed. @retval EFI_LOAD_ERROR A load error occured. @retval EFI_INVALID_PARAMETER A parameter was invalid. **/ EFI_STATUS HDiskImageSave ( IN CHAR16 *DeviceName, IN UINTN Offset, IN UINTN Size ) { CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_STATUS Status; EFI_HANDLE Handle; VOID *Buffer; UINTN Bytes; UINT64 ByteOffset; EDIT_FILE_TYPE BufferTypeBackup; // // if not modified, directly return // if (HBufferImage.Modified == FALSE) { return EFI_SUCCESS; } BufferTypeBackup = HBufferImage.BufferType; HBufferImage.BufferType = FileTypeDiskBuffer; DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName); if (DevicePath == NULL) { // StatusBarSetStatusString (L"Cannot Find Device"); return EFI_INVALID_PARAMETER; } DupDevicePath = DuplicateDevicePath(DevicePath); // // get blkio interface // Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle); FreePool(DupDevicePath); if (EFI_ERROR (Status)) { // StatusBarSetStatusString (L"Read Disk Failed"); return Status; } Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR (Status)) { // StatusBarSetStatusString (L"Read Disk Failed"); return Status; } Bytes = BlkIo->Media->BlockSize * Size; Buffer = AllocateZeroPool (Bytes); if (Buffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // concatenate the line list to a buffer // Status = HBufferImageListToBuffer (Buffer, Bytes); if (EFI_ERROR (Status)) { FreePool (Buffer); return Status; } ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize); // // write the buffer to disk // Status = BlkIo->WriteBlocks ( BlkIo, BlkIo->Media->MediaId, Offset, Bytes, Buffer ); FreePool (Buffer); if (EFI_ERROR (Status)) { return EFI_LOAD_ERROR; } // // now not modified // HBufferImage.Modified = FALSE; return EFI_SUCCESS; }
EFI_STATUS HDiskImageSave ( IN CHAR16 *DeviceName, IN UINTN Offset, IN UINTN Size ) /*++ Routine Description: Save lines in HBufferImage to disk NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!! Arguments: DeviceName - The device name Offset - The offset Size - The size Returns: EFI_SUCCESS EFI_LOAD_ERROR EFI_OUT_OF_RESOURCES EFI_INVALID_PARAMETER --*/ { EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_STATUS Status; VOID *Buffer; UINTN Bytes; UINT64 ByteOffset; HEFI_EDITOR_ACTIVE_BUFFER_TYPE BufferTypeBackup; // // if not modified, directly return // if (HBufferImage.Modified == FALSE) { return EFI_SUCCESS; } BufferTypeBackup = HBufferImage.BufferType; HBufferImage.BufferType = DISK_BUFFER; DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ShellGetMap (DeviceName); if (DevicePath == NULL) { return EFI_INVALID_PARAMETER; } Status = LibDevicePathToInterface ( &gEfiBlockIoProtocolGuid, DevicePath, &BlkIo ); if (EFI_ERROR (Status)) { return Status; } Bytes = BlkIo->Media->BlockSize * Size; Buffer = AllocatePool (Bytes); if (Buffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // concatenate the line list to a buffer // Status = HBufferImageListToBuffer (Buffer, Bytes); if (EFI_ERROR (Status)) { FreePool (Buffer); return Status; } ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize); // // write the buffer to disk // Status = BlkIo->WriteBlocks ( BlkIo, BlkIo->Media->MediaId, Offset, Bytes, Buffer ); FreePool (Buffer); if (EFI_ERROR (Status)) { return EFI_LOAD_ERROR; } // // now not modified // HBufferImage.Modified = FALSE; return EFI_SUCCESS; }
// // TDS 5.3 // EFI_STATUS BBTestWriteBlocksFunctionAutoTest ( IN EFI_BB_TEST_PROTOCOL *This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STANDARD_TEST_LIBRARY_PROTOCOL *StandardLib; EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlockIo; UINT32 MediaId; BOOLEAN RemovableMedia; BOOLEAN MediaPresent; BOOLEAN LogicalPartition; BOOLEAN ReadOnly; BOOLEAN WriteCaching; UINT32 BlockSize; UINT32 IoAlign; EFI_LBA LastBlock; UINTN BufferSize; UINT8 *Buffer; UINT8 *Buffer2; UINT8 *Buffer3; UINT32 BlockNumber; UINTN IndexI, IndexJ; UINTN NewBufferSize; EFI_LBA NewLba; UINTN Remainder; EFI_DEVICE_PATH_PROTOCOL *DevicePath; CHAR16 *DevicePathStr; EFI_TEST_ASSERTION AssertionTypeRead1; EFI_TEST_ASSERTION AssertionTypeRead2; EFI_TEST_ASSERTION AssertionTypeRead3; EFI_TEST_ASSERTION AssertionTypeWrite1; EFI_TEST_ASSERTION AssertionTypeWrite2; EFI_TEST_ASSERTION AssertionTypeComp1; EFI_TEST_ASSERTION AssertionTypeComp2; EFI_STATUS StatusRead1; EFI_STATUS StatusRead2; EFI_STATUS StatusRead3; EFI_STATUS StatusWrite1; EFI_STATUS StatusWrite2; UINTN CountComp1; UINTN CountComp2; // // Get the Standard Library Interface // Status = gtBS->HandleProtocol ( SupportHandle, &gEfiStandardTestLibraryGuid, &StandardLib ); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.HandleProtocol - Handle standard test library", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } BlockIo = (EFI_BLOCK_IO_PROTOCOL *)ClientInterface; // // Locate & record DevicePath for further investigation // LocateDevicePathFromBlockIo (BlockIo, &DevicePath, StandardLib); DevicePathStr = DevicePathToStr (DevicePath); if (DevicePathStr != NULL) { StandardLib->RecordMessage ( StandardLib, EFI_VERBOSE_LEVEL_DEFAULT, L"Current Device: %s", DevicePathStr ); Status = gtBS->FreePool (DevicePathStr); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free device path string", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } DevicePathStr = NULL; } // // Initialize variable // MediaId = BlockIo->Media->MediaId; RemovableMedia = BlockIo->Media->RemovableMedia; MediaPresent = BlockIo->Media->MediaPresent; LogicalPartition = BlockIo->Media->LogicalPartition; ReadOnly = BlockIo->Media->ReadOnly; WriteCaching = BlockIo->Media->WriteCaching; BlockSize = BlockIo->Media->BlockSize; IoAlign = BlockIo->Media->IoAlign; LastBlock = BlockIo->Media->LastBlock; BlockNumber = (UINT32) MINIMUM(LastBlock, MAX_NUMBER_OF_READ_BLOCK_BUFFER); BufferSize = BlockNumber * BlockSize; if (BufferSize == 0) { BufferSize = 512; } // // allocate buffer // Status = gtBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.AllocatePool - Allocate buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } Status = gtBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer2); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.AllocatePool - Allocate buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); gtBS->FreePool (Buffer); return Status; } Status = gtBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer3); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.AllocatePool - Allocate buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); gtBS->FreePool (Buffer); gtBS->FreePool (Buffer2); return Status; } // // Assertion Point 5.3.2.1 // ReadBlocks must succeed to read proper data from device with valid parameter // if ((MediaPresent == TRUE) && (ReadOnly == FALSE)) { for (IndexI = 1; IndexI < MAX_DIFFERENT_BUFFERSIZE_FOR_TEST; IndexI++) { // // prepare test data // BufferSize will range from BlockSize to MAX_DIFFERENT_BUFFERSIZE_FOR_TEST*BlockSize // NewBufferSize = IndexI * BlockSize; // //parameter verification on NewBufferSize // if (NewBufferSize > BufferSize) { break; } for (IndexJ = 0; IndexJ < 3 * MAX_DIFFERENT_LBA_FOR_TEST; IndexJ++) { // // prepare test data // if (IndexJ < MAX_DIFFERENT_LBA_FOR_TEST) { // from 1 to MAX_DIFFERENT_LBA_FOR_TEST NewLba = IndexJ; } else if (IndexJ < 2 * MAX_DIFFERENT_LBA_FOR_TEST) { // from (LastBlock - MAX_DIFFERENT_LBA_FOR_TEST - MAX_DIFFERENT_BUFFERSIZE_FOR_TEST) to (LastBlock - MAX_DIFFERENT_BUFFERSIZE_FOR_TEST) NewLba = IndexJ + LastBlock - 2 * MAX_DIFFERENT_LBA_FOR_TEST - MAX_DIFFERENT_BUFFERSIZE_FOR_TEST; } else { // from (LastBlock/2 - MAX_DIFFERENT_LBA_FOR_TEST/2) to (LastBlock/2 + MAX_DIFFERENT_LBA_FOR_TEST/2) NewLba = IndexJ - 2 * MAX_DIFFERENT_LBA_FOR_TEST + (DivU64x32 (LastBlock, 2, &Remainder) - MAX_DIFFERENT_LBA_FOR_TEST / 2); } // //parameter verification on NewLba // if (NewLba + NewBufferSize / BlockSize > LastBlock + 1) { continue; } // // To avoid the LOG information is destroied, the LOG information will // be recorded after the original data is written again. // // // Call ReadBlocks with the specified LBA and BufferSize // StatusRead1 = BlockIo->ReadBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer ); if (EFI_ERROR(StatusRead1)) { AssertionTypeRead1 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeRead1 = EFI_TEST_ASSERTION_PASSED; } // // Write specified buffer2 differ from buffer to the device // StatusWrite1 = BlockIo->WriteBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer2 ); if (EFI_ERROR(StatusWrite1)) { AssertionTypeWrite1 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeWrite1 = EFI_TEST_ASSERTION_PASSED; } // // if write-cached, then flush the data to physical device // if (WriteCaching) { BlockIo->FlushBlocks (BlockIo); } // // Read Block with same LBA and BufferSize again and save data into Buffer3 // StatusRead2 = BlockIo->ReadBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer3 ); if (EFI_ERROR(StatusRead2)) { AssertionTypeRead2 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeRead2 = EFI_TEST_ASSERTION_PASSED; } // // verification on Write and Read blocks on valid media // CountComp1 = VerifyBuffer (Buffer2, Buffer3, NewBufferSize); if (CountComp1 > 0) { AssertionTypeComp1 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeComp1 = EFI_TEST_ASSERTION_PASSED; } // // Write buffer read in the first call of ReadBlocks back to the device // StatusWrite2 = BlockIo->WriteBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer ); if (EFI_ERROR(StatusWrite2)) { AssertionTypeWrite2 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeWrite2 = EFI_TEST_ASSERTION_PASSED; } // // if write-cached, then flush the data to physical device // if (WriteCaching) { BlockIo->FlushBlocks (BlockIo); } // // Read Block with same LBA and BufferSize again and save data into Buffer3 // StatusRead3 = BlockIo->ReadBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer3 ); if (EFI_ERROR(StatusRead3)) { AssertionTypeRead3 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeRead3 = EFI_TEST_ASSERTION_PASSED; } // // verification on first and last call of ReadBlocks // CountComp2 = VerifyBuffer (Buffer, Buffer3, NewBufferSize); if (CountComp2 > 0) { AssertionTypeComp2 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeComp2 = EFI_TEST_ASSERTION_PASSED; } // // Record test results // StandardLib->RecordAssertion ( StandardLib, AssertionTypeRead1, gTestGenericFailureGuid, L"EFI_BLOCK_IO_PROTOCOL.ReadBlocks - Read Block with proper parameter from valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusRead1 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeWrite1, gBlockIoFunctionTestAssertionGuid009, L"EFI_BLOCK_IO_PROTOCOL.WriteBlocks - Write Block with proper parameter from valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusWrite1 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeRead2, gTestGenericFailureGuid, L"EFI_BLOCK_IO_PROTOCOL.ReadBlocks - Read Block with proper parameter from valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusRead2 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeComp1, gBlockIoFunctionTestAssertionGuid012, L"EFI_BLOCK_IO_PROTOCOL.WriteBlocks - Verification on Write and Read blocks on valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, DiffCount=%d", __FILE__, __LINE__, NewBufferSize, NewLba, CountComp1 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeWrite2, gBlockIoFunctionTestAssertionGuid013, L"EFI_BLOCK_IO_PROTOCOL.WriteBlocks - Write Block with proper parameter back to valid media ", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusWrite2 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeRead3, gTestGenericFailureGuid, L"EFI_BLOCK_IO_PROTOCOL.ReadBlocks - Read Block with proper parameter from valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusRead3 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeComp2, gBlockIoFunctionTestAssertionGuid016, L"EFI_BLOCK_IO_PROTOCOL.WriteBlocks - Verification on Write and Read blocks on valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, DiffCount=%d", __FILE__, __LINE__, NewBufferSize, NewLba, CountComp2 ); }//end of loop of Lba - IndexJ }//end of loop of BufferSize - IndexI } // // Free resources // Status = gtBS->FreePool (Buffer3); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } Status = gtBS->FreePool (Buffer2); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } Status = gtBS->FreePool (Buffer); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } return EFI_SUCCESS; }