1use alloc::vec::Vec;
9
10use super::{Error, Mbr, Result};
11use crate::{
12 DirectBlockDevice, PartitionDevice,
13 mbr::{PartitionEntry, PartitionKind},
14};
15
16pub fn create_partition_device<'a, D: DirectBlockDevice>(
53 device: &'a D,
54 partition: &PartitionEntry,
55) -> Result<PartitionDevice<'a, D>> {
56 if !partition.is_valid() {
57 return Err(Error::InvalidPartition);
58 }
59
60 device.open()?;
61 let block_size = device.get_block_size()?;
62
63 Ok(PartitionDevice::new(
64 device,
65 partition.start_block as _,
66 partition.block_count as _,
67 block_size,
68 ))
69}
70
71pub fn scan_mbr_partitions(
110 device: &impl DirectBlockDevice,
111) -> Result<Vec<(usize, PartitionEntry)>> {
112 let mbr = Mbr::read_from_device(device)?;
113
114 let mut partitions = Vec::new();
115 for (i, partition) in mbr.partitions.iter().enumerate() {
116 if partition.is_valid() {
117 partitions.push((i, *partition));
118 }
119 }
120
121 Ok(partitions)
122}
123
124pub fn validate_mbr(mbr: &Mbr) -> Result<()> {
160 mbr.validate()
161}
162
163pub fn create_all_partition_devices<'a, D: DirectBlockDevice>(
202 base_device: &'a D,
203 mbr: &super::Mbr,
204) -> Result<Vec<PartitionDevice<'a, D>>> {
205 mbr.create_all_partition_devices(base_device)
206}
207
208pub fn find_partitions_by_type(
243 mbr: &super::Mbr,
244 partition_type: PartitionKind,
245) -> Vec<(usize, &PartitionEntry)> {
246 mbr.find_partitions_by_type(partition_type)
247}
248
249pub fn has_valid_mbr(device: &impl DirectBlockDevice) -> bool {
282 match Mbr::read_from_device(device) {
283 Ok(mbr) => mbr.is_valid(),
284 Err(_) => false,
285 }
286}
287
288pub fn is_gpt_disk(device: &impl DirectBlockDevice) -> bool {
323 match Mbr::read_from_device(device) {
324 Ok(mbr) => mbr.has_gpt_protective_partition(),
325 Err(_) => false,
326 }
327}
328
329pub fn create_basic_mbr(
360 disk_signature: u32,
361 partition_type: PartitionKind,
362 total_sectors: u32,
363) -> Result<super::Mbr> {
364 Mbr::create_basic(disk_signature, partition_type, total_sectors)
365}
366
367pub fn clone_mbr(
404 source_device: &impl DirectBlockDevice,
405 target_device: &impl DirectBlockDevice,
406) -> Result<()> {
407 let mbr = Mbr::read_from_device(source_device)?;
408 mbr.validate()?;
409 mbr.write_to_device(target_device)?;
410 Ok(())
411}
412
413pub fn backup_mbr(device: &impl DirectBlockDevice) -> Result<[u8; 512]> {
448 let mbr = Mbr::read_from_device(device)?;
449 Ok(mbr.to_bytes())
450}
451
452pub fn restore_mbr(device: &impl DirectBlockDevice, backup: &[u8; 512]) -> Result<()> {
489 let mbr = Mbr::from_bytes(backup)?;
490 mbr.validate()?;
491 mbr.write_to_device(device)?;
492 Ok(())
493}
494
495pub fn format_disk_and_get_first_partition<'a, D: DirectBlockDevice>(
509 device: &'a D,
510 partition_type: PartitionKind,
511 disk_signature: Option<u32>,
512) -> Result<PartitionDevice<'a, D>> {
513 let mbr = if has_valid_mbr(device) {
515 Mbr::read_from_device(device)?
517 } else {
518 device.open()?;
520 let block_count = device.get_block_count()?;
521 device.close()?;
522
523 if block_count < 2048 {
524 return Err(Error::DeviceTooSmall);
525 }
526
527 let signature = disk_signature.unwrap_or({
529 0x12345678
532 });
533
534 let new_mbr = Mbr::create_basic(signature, partition_type, block_count as _)?;
535
536 new_mbr.write_to_device(device)?;
538
539 new_mbr
540 };
541
542 let valid_partitions = mbr.get_valid_partitions();
544 if valid_partitions.is_empty() {
545 return Err(Error::NoValidPartitions);
546 }
547
548 create_partition_device(device, valid_partitions[0])
550}
551
552#[cfg(test)]
553mod tests {
554 use super::*;
555 use crate::{DirectBaseOperations, MemoryDevice, Position, Size, mbr::Error};
556 use alloc::vec;
557
558 fn create_test_device_with_mbr() -> MemoryDevice<512> {
560 let mut data = vec![0u8; 4096 * 1024]; let mbr = create_test_mbr();
564 let mbr_bytes = mbr.to_bytes();
565 data[0..512].copy_from_slice(&mbr_bytes);
566
567 MemoryDevice::<512>::from_vec(data)
568 }
569
570 fn create_test_device_no_mbr() -> MemoryDevice<512> {
572 MemoryDevice::<512>::new(4096 * 1024)
573 }
574
575 fn create_test_mbr() -> Mbr {
577 let mut mbr = Mbr::new_with_signature(0x12345678);
578
579 let _ = mbr.add_partition(PartitionKind::Fat32Lba, 2048, 1024, true);
581 let _ = mbr.add_partition(PartitionKind::Linux, 4096, 2048, false);
582 let _ = mbr.add_partition(PartitionKind::HiddenFat16, 8192, 512, false);
583
584 mbr
585 }
586
587 #[test]
588 fn test_create_partition_device() {
589 let base_device = create_test_device_with_mbr();
590 let mbr = Mbr::read_from_device(&base_device).unwrap();
591 let entry = &mbr.partitions[0];
592
593 let device_result = create_partition_device(&base_device, entry);
594 assert!(device_result.is_ok());
595
596 let device = device_result.unwrap();
597 assert_eq!(device.get_start_lba(), entry.start_block as Size);
598 assert_eq!(device.get_block_count(), entry.block_count);
599 assert!(device.is_valid());
600 }
601
602 #[test]
603 fn test_create_partition_device_invalid() {
604 let base_device = create_test_device_with_mbr();
605 let invalid_partition = PartitionEntry::new_empty();
606
607 let device_result = create_partition_device(&base_device, &invalid_partition);
608 assert!(device_result.is_err());
609 assert_eq!(device_result.unwrap_err(), Error::InvalidPartition);
610 }
611
612 #[test]
613 fn test_scan_mbr_partitions() {
614 let device = create_test_device_with_mbr();
615
616 let scan_result = scan_mbr_partitions(&device);
617 assert!(scan_result.is_ok());
618
619 let partitions = scan_result.unwrap();
620 assert_eq!(partitions.len(), 3); assert_eq!(partitions[0].0, 0);
624 assert_eq!(partitions[1].0, 1);
625 assert_eq!(partitions[2].0, 2);
626
627 assert_eq!(partitions[0].1.kind, PartitionKind::Fat32Lba);
629 assert_eq!(partitions[1].1.kind, PartitionKind::Linux);
630 assert_eq!(partitions[2].1.kind, PartitionKind::HiddenFat16);
631 }
632
633 #[test]
634 fn test_scan_mbr_partitions_no_mbr() {
635 let device = create_test_device_no_mbr();
636
637 let scan_result = scan_mbr_partitions(&device);
638 assert!(scan_result.is_err());
639 }
640
641 #[test]
642 fn test_validate_mbr_valid() {
643 let mbr = create_test_mbr();
644 let validation_result = validate_mbr(&mbr);
645 assert!(validation_result.is_ok());
646 }
647
648 #[test]
649 fn test_validate_mbr_invalid_signature() {
650 let mut mbr = super::Mbr::new();
651 mbr.boot_signature = [0x00, 0x00];
653
654 let validation_result = validate_mbr(&mbr);
655 assert!(validation_result.is_err());
656 assert_eq!(validation_result.unwrap_err(), Error::InvalidSignature);
657 }
658
659 #[test]
660 fn test_validate_mbr_multiple_bootable() {
661 let mut mbr = Mbr::new_with_signature(0x12345678);
662
663 mbr.partitions[0] =
665 PartitionEntry::new_with_params(true, PartitionKind::Fat32Lba, 2048, 1024);
666 mbr.partitions[1] = PartitionEntry::new_with_params(true, PartitionKind::Linux, 4096, 2048);
667
668 let validation_result = validate_mbr(&mbr);
669 assert!(validation_result.is_err());
670 assert_eq!(
671 validation_result.unwrap_err(),
672 Error::MultipleBootablePartitions
673 );
674 }
675
676 #[test]
677 fn test_validate_mbr_overlapping_partitions() {
678 let mut mbr = Mbr::new_with_signature(0x12345678);
679
680 mbr.partitions[0] =
682 PartitionEntry::new_with_params(false, PartitionKind::Fat32Lba, 2048, 2048);
683 mbr.partitions[1] =
684 PartitionEntry::new_with_params(false, PartitionKind::Linux, 3000, 2048);
685
686 let validation_result = validate_mbr(&mbr);
687 assert!(validation_result.is_err());
688 assert_eq!(validation_result.unwrap_err(), Error::OverlappingPartitions);
689 }
690
691 #[test]
692 fn test_create_all_partition_devices() {
693 let base_device = create_test_device_with_mbr();
694 let mbr = create_test_mbr();
695
696 let devices_result = create_all_partition_devices(&base_device, &mbr);
697 assert!(devices_result.is_ok());
698
699 let devices = devices_result.unwrap();
700 assert_eq!(devices.len(), 3); for device in &devices {
704 assert!(device.is_valid());
705 }
706
707 assert_eq!(devices[0].get_start_lba(), Mbr::MINIMUM_START_BLOCK);
709 assert_eq!(devices[0].get_block_count(), 1024);
710 }
711
712 #[test]
713 fn test_find_partitions_by_type() {
714 let mbr = create_test_mbr();
715
716 let fat_partitions = find_partitions_by_type(&mbr, PartitionKind::Fat32Lba);
718 assert_eq!(fat_partitions.len(), 1);
719 assert_eq!(fat_partitions[0].0, 0); let linux_partitions = find_partitions_by_type(&mbr, PartitionKind::Linux);
723 assert_eq!(linux_partitions.len(), 1);
724 assert_eq!(linux_partitions[0].0, 1); let ntfs_partitions = find_partitions_by_type(&mbr, PartitionKind::NtfsExfat);
728 assert_eq!(ntfs_partitions.len(), 0);
729 }
730
731 #[test]
732 fn test_partition_statistics() {
733 let mbr = create_test_mbr();
734 let stats = mbr.get_statistics();
735
736 assert_eq!(stats.total_partitions, 3);
737 assert_eq!(stats.bootable_partitions, 1);
738 assert_eq!(stats.fat_partitions, 2); assert_eq!(stats.linux_partitions, 1);
740 assert_eq!(stats.hidden_partitions, 1); assert_eq!(stats.extended_partitions, 0);
742 assert_eq!(stats.unknown_partitions, 0);
743 assert_eq!(stats.total_used_sectors, 1024 + 2048 + 512); assert_eq!(stats.largest_partition_sectors, 2048);
745 assert_eq!(stats.smallest_partition_sectors, 512);
746 }
747
748 #[test]
749 fn test_partition_statistics_empty_mbr() {
750 let mbr = Mbr::new_with_signature(0x12345678);
751 let stats = mbr.get_statistics();
752
753 assert_eq!(stats.total_partitions, 0);
754 assert_eq!(stats.bootable_partitions, 0);
755 assert_eq!(stats.fat_partitions, 0);
756 assert_eq!(stats.linux_partitions, 0);
757 assert_eq!(stats.hidden_partitions, 0);
758 assert_eq!(stats.extended_partitions, 0);
759 assert_eq!(stats.unknown_partitions, 0);
760 assert_eq!(stats.total_used_sectors, 0);
761 assert_eq!(stats.largest_partition_sectors, 0);
762 assert_eq!(stats.smallest_partition_sectors, 0);
763 }
764
765 #[test]
766 fn test_has_valid_mbr() {
767 let valid_device = create_test_device_with_mbr();
768 assert!(has_valid_mbr(&valid_device));
769
770 let invalid_device = create_test_device_no_mbr();
771 assert!(!has_valid_mbr(&invalid_device));
772 }
773
774 #[test]
775 fn test_is_gpt_disk() {
776 let mut mbr = Mbr::new_with_signature(0x12345678);
778 let _ = mbr.add_partition(PartitionKind::GptProtective, 1, 0xFFFFFFFF, false);
779
780 let mut data = vec![0u8; 4096 * 1024];
781 let mbr_bytes = mbr.to_bytes();
782 data[0..512].copy_from_slice(&mbr_bytes);
783 let memory_device = MemoryDevice::<512>::from_vec(data);
784
785 assert!(is_gpt_disk(&memory_device));
786
787 let regular_device = create_test_device_with_mbr();
789 assert!(!is_gpt_disk(®ular_device));
790 }
791
792 #[test]
793 fn test_create_basic_mbr() {
794 let mbr_result = create_basic_mbr(0xABCDEF00, PartitionKind::Fat32Lba, 100000);
795 assert!(mbr_result.is_ok());
796
797 let mbr = mbr_result.unwrap();
798 assert!(mbr.is_valid());
799 assert_eq!(mbr.get_disk_signature(), 0xABCDEF00);
800
801 let valid_partitions = mbr.get_valid_partitions();
802 assert_eq!(valid_partitions.len(), 1);
803
804 let partition = &valid_partitions[0];
805 assert_eq!(partition.kind, PartitionKind::Fat32Lba);
806 assert_eq!(partition.start_block, 2048);
807 assert_eq!(partition.block_count, 100000 - 2048);
808 assert!(partition.bootable);
809 }
810
811 #[test]
812 fn test_create_basic_mbr_too_small() {
813 let mbr_result = create_basic_mbr(0x12345678, PartitionKind::Fat32Lba, 1000);
814 assert!(mbr_result.is_err());
815 assert_eq!(mbr_result.unwrap_err(), Error::DeviceTooSmall);
816 }
817
818 #[test]
819 fn test_clone_mbr() {
820 let source_device = create_test_device_with_mbr();
821 let target_data = vec![0u8; 4096 * 1024];
822 let target_device = MemoryDevice::<512>::from_vec(target_data);
823
824 let clone_result = clone_mbr(&source_device, &target_device);
825 assert!(clone_result.is_ok());
826
827 let source_mbr = Mbr::read_from_device(&source_device).unwrap();
829 let target_mbr = Mbr::read_from_device(&target_device).unwrap();
830
831 assert_eq!(source_mbr.to_bytes(), target_mbr.to_bytes());
832 }
833
834 #[test]
835 fn test_backup_and_restore_mbr() {
836 let device = create_test_device_with_mbr();
837
838 let backup_result = backup_mbr(&device);
840 assert!(backup_result.is_ok());
841 let backup = backup_result.unwrap();
842
843 let target_data = vec![0u8; 4096 * 1024];
845 let memory_device = MemoryDevice::<512>::from_vec(target_data);
846
847 let restore_result = restore_mbr(&memory_device, &backup);
849 assert!(restore_result.is_ok());
850
851 let original_mbr = Mbr::read_from_device(&device).unwrap();
853 let restored_mbr = Mbr::read_from_device(&memory_device).unwrap();
854
855 assert_eq!(original_mbr.to_bytes(), restored_mbr.to_bytes());
856 }
857
858 #[test]
859 fn test_backup_mbr_invalid_device() {
860 let invalid_device = create_test_device_no_mbr();
861
862 let backup_result = backup_mbr(&invalid_device);
863 assert!(backup_result.is_err());
864 }
865
866 #[test]
867 fn test_restore_mbr_invalid_backup() {
868 let device = create_test_device_no_mbr();
869 let invalid_backup = [0u8; 512]; let restore_result = restore_mbr(&device, &invalid_backup);
872 assert!(restore_result.is_err());
873 }
874
875 #[test]
876 fn test_utilities_with_complex_mbr() {
877 let mut mbr = Mbr::new_with_signature(0xDEADBEEF);
879
880 let _ = mbr.add_partition(PartitionKind::Fat16, 63, 1000, true);
881 let _ = mbr.add_partition(PartitionKind::ExtendedLba, 2048, 10000, false);
882 let _ = mbr.add_partition(PartitionKind::LinuxSwap, 15000, 2000, false);
883 let _ = mbr.add_partition(PartitionKind::Unknown(0x42), 20000, 5000, false);
884
885 let stats = mbr.get_statistics();
887 assert_eq!(stats.total_partitions, 4);
888 assert_eq!(stats.bootable_partitions, 1);
889 assert_eq!(stats.fat_partitions, 1);
890 assert_eq!(stats.linux_partitions, 1); assert_eq!(stats.extended_partitions, 1);
892 assert_eq!(stats.unknown_partitions, 1);
893
894 let extended = find_partitions_by_type(&mbr, PartitionKind::ExtendedLba);
896 assert_eq!(extended.len(), 1);
897 assert_eq!(extended[0].0, 1);
898
899 let unknown = find_partitions_by_type(&mbr, PartitionKind::Unknown(0x42));
900 assert_eq!(unknown.len(), 1);
901 assert_eq!(unknown[0].0, 3);
902 }
903
904 #[test]
905 fn test_edge_cases() {
906 let empty_mbr = Mbr::new_with_signature(0x12345678);
908
909 let stats = empty_mbr.get_statistics();
910 assert_eq!(stats.total_partitions, 0);
911
912 let partitions = find_partitions_by_type(&empty_mbr, PartitionKind::Fat32);
913 assert_eq!(partitions.len(), 0);
914
915 let mut empty_data = vec![0u8; 4096 * 1024];
917 let empty_mbr_bytes = empty_mbr.to_bytes();
918 empty_data[0..512].copy_from_slice(&empty_mbr_bytes);
919 let empty_device = MemoryDevice::<512>::from_vec(empty_data);
920
921 let scan_result = scan_mbr_partitions(&empty_device);
922 assert!(scan_result.is_ok());
923 assert_eq!(scan_result.unwrap().len(), 0);
924 }
925
926 #[test]
929 fn test_format_disk_and_get_first_partition_existing_mbr() {
930 let device = create_test_device_with_mbr();
931
932 let partition_device_result =
933 format_disk_and_get_first_partition(&device, PartitionKind::Fat32Lba, Some(0xABCDEF00));
934 assert!(partition_device_result.is_ok());
935
936 let partition_device = partition_device_result.unwrap();
937 assert!(partition_device.is_valid());
938 assert_eq!(partition_device.get_start_lba(), 2048); assert_eq!(partition_device.get_block_count(), 1024); }
941
942 #[test]
943 fn test_format_disk_and_get_first_partition_no_mbr() {
944 let device = create_test_device_no_mbr();
945
946 let partition_device_result =
947 format_disk_and_get_first_partition(&device, PartitionKind::Fat32Lba, Some(0x12345678));
948 assert!(partition_device_result.is_ok());
949
950 let partition_device = partition_device_result.unwrap();
951 assert!(partition_device.is_valid());
952 assert_eq!(partition_device.get_start_lba(), 2048); assert!(has_valid_mbr(&device));
956
957 let mbr = Mbr::read_from_device(&device).unwrap();
959 let valid_partitions = mbr.get_valid_partitions();
960 assert_eq!(valid_partitions.len(), 1);
961 assert_eq!(valid_partitions[0].kind, PartitionKind::Fat32Lba);
962 assert!(valid_partitions[0].bootable);
963 }
964
965 #[test]
966 fn test_format_disk_and_get_first_partition_default_signature() {
967 let device = create_test_device_no_mbr();
968
969 let partition_device_result = format_disk_and_get_first_partition(
970 &device,
971 PartitionKind::Linux,
972 None, );
974 assert!(partition_device_result.is_ok());
975
976 let partition_device = partition_device_result.unwrap();
977 assert!(partition_device.is_valid());
978
979 let mbr = Mbr::read_from_device(&device).unwrap();
981 assert_eq!(mbr.get_disk_signature(), 0x12345678); }
983
984 #[test]
985 fn test_format_disk_and_get_first_partition_device_too_small() {
986 let small_data = vec![0u8; 1024]; let small_device = MemoryDevice::<512>::from_vec(small_data);
989
990 let partition_device_result = format_disk_and_get_first_partition(
991 &small_device,
992 PartitionKind::Fat32Lba,
993 Some(0x12345678),
994 );
995 assert!(partition_device_result.is_err());
996 assert_eq!(partition_device_result.unwrap_err(), Error::DeviceTooSmall);
997 }
998
999 #[test]
1000 fn test_format_disk_and_get_first_partition_empty_mbr() {
1001 let mut data = vec![0u8; 4096 * 1024];
1003 let empty_mbr = Mbr::new_with_signature(0xDEADBEEF);
1004 let mbr_bytes = empty_mbr.to_bytes();
1005 data[0..512].copy_from_slice(&mbr_bytes);
1006
1007 let memory_device = MemoryDevice::<512>::from_vec(data);
1008 let device = memory_device;
1009
1010 let partition_device_result =
1011 format_disk_and_get_first_partition(&device, PartitionKind::Fat32Lba, Some(0x12345678));
1012 assert!(partition_device_result.is_err());
1013 assert_eq!(
1014 partition_device_result.unwrap_err(),
1015 Error::NoValidPartitions
1016 );
1017 }
1018
1019 #[test]
1020 fn test_format_disk_and_get_first_partition_different_types() {
1021 let partition_types = [
1023 PartitionKind::Fat32Lba,
1024 PartitionKind::Linux,
1025 PartitionKind::NtfsExfat,
1026 PartitionKind::ExtendedLba,
1027 ];
1028
1029 for partition_type in &partition_types {
1030 let device = create_test_device_no_mbr();
1031
1032 let partition_device_result =
1033 format_disk_and_get_first_partition(&device, *partition_type, Some(0xABCDEF00));
1034 assert!(partition_device_result.is_ok());
1035
1036 let partition_device = partition_device_result.unwrap();
1037 assert!(partition_device.is_valid());
1038
1039 let mbr = Mbr::read_from_device(&device).unwrap();
1041 let valid_partitions = mbr.get_valid_partitions();
1042 assert_eq!(valid_partitions.len(), 1);
1043 assert_eq!(valid_partitions[0].kind, *partition_type);
1044 }
1045 }
1046
1047 #[test]
1048 fn test_format_disk_and_write_read_data() {
1049 let device = create_test_device_no_mbr();
1050
1051 let partition_device_result =
1053 format_disk_and_get_first_partition(&device, PartitionKind::Fat32Lba, Some(0x12345678));
1054 assert!(partition_device_result.is_ok());
1055 let partition_device = partition_device_result.unwrap();
1056
1057 let test_data = b"Hello, Partition World! This is a test of writing and reading data from a partition device.";
1059 let mut write_buffer = vec![0u8; 512];
1060 write_buffer[0..test_data.len()].copy_from_slice(test_data);
1061
1062 let write_result = partition_device.write(&write_buffer, 0);
1064 assert!(write_result.is_ok());
1065 let bytes_written = write_result.unwrap();
1066 assert_eq!(bytes_written, 512);
1067
1068 let mut read_buffer = vec![0u8; 512];
1070 let read_result = partition_device.read(&mut read_buffer, 0);
1071 assert!(read_result.is_ok());
1072 let bytes_read = read_result.unwrap();
1073 assert_eq!(bytes_read, 512);
1074 assert_eq!(&read_buffer[0..test_data.len()], test_data);
1075
1076 let second_test_data = b"Second write test at offset";
1078 let second_position = 1024; let mut second_write_buffer = vec![0u8; 512];
1080 second_write_buffer[0..second_test_data.len()].copy_from_slice(second_test_data);
1081
1082 let write_result = partition_device.write(&second_write_buffer, second_position);
1084 assert!(write_result.is_ok());
1085
1086 let mut second_read_buffer = vec![0u8; 512];
1088 let read_result = partition_device.read(&mut second_read_buffer, second_position);
1089 assert!(read_result.is_ok());
1090 assert_eq!(
1091 &second_read_buffer[0..second_test_data.len()],
1092 second_test_data
1093 );
1094
1095 let mut final_read_buffer = vec![0u8; 512];
1097 let read_result = partition_device.read(&mut final_read_buffer, 0);
1098 assert!(read_result.is_ok());
1099 assert_eq!(&final_read_buffer[0..test_data.len()], test_data);
1100 }
1101
1102 #[test]
1103 fn test_partition_data_isolation() {
1104 let device = create_test_device_no_mbr();
1106
1107 let mut mbr = Mbr::new_with_signature(0x12345678);
1108
1109 let first_partition_size = 2048; let second_partition_start = 2048 + first_partition_size;
1112 let second_partition_size = 2048;
1113
1114 let _ = mbr.add_partition(PartitionKind::Fat32Lba, 2048, first_partition_size, true);
1115 let _ = mbr.add_partition(
1116 PartitionKind::Linux,
1117 second_partition_start,
1118 second_partition_size,
1119 false,
1120 );
1121
1122 let write_result = mbr.write_to_device(&device);
1124 assert!(write_result.is_ok());
1125
1126 let valid_partitions = mbr.get_valid_partitions();
1128 assert_eq!(valid_partitions.len(), 2);
1129
1130 let first_partition_device = create_partition_device(&device, valid_partitions[0]).unwrap();
1131 let second_partition_device =
1132 create_partition_device(&device, valid_partitions[1]).unwrap();
1133
1134 let first_data = b"Data for first partition - FAT32";
1136 let second_data = b"Data for second partition - Linux";
1137
1138 let mut first_buffer = vec![0u8; 512];
1139 first_buffer[0..first_data.len()].copy_from_slice(first_data);
1140 let write_result = first_partition_device.write(&first_buffer, 0);
1141 assert!(write_result.is_ok());
1142
1143 let mut second_buffer = vec![0u8; 512];
1144 second_buffer[0..second_data.len()].copy_from_slice(second_data);
1145 let write_result = second_partition_device.write(&second_buffer, 0);
1146 assert!(write_result.is_ok());
1147
1148 let _ = first_partition_device.set_position(512, &Position::Start(0));
1150 let _ = second_partition_device.set_position(512, &Position::Start(0));
1151
1152 let mut first_read_buffer = vec![0u8; 512];
1153 let mut second_read_buffer = vec![0u8; 512];
1154
1155 let read_result = first_partition_device.read(&mut first_read_buffer, 0);
1156 assert!(read_result.is_ok());
1157 let read_result = second_partition_device.read(&mut second_read_buffer, 0);
1158 assert!(read_result.is_ok());
1159
1160 assert_eq!(&first_read_buffer[0..first_data.len()], first_data);
1162 assert_eq!(&second_read_buffer[0..second_data.len()], second_data);
1163
1164 assert_ne!(&first_read_buffer[0..32], &second_read_buffer[0..32]);
1166 }
1167
1168 #[test]
1169 fn test_partition_bounds_checking() {
1170 let device = create_test_device_no_mbr();
1171
1172 let partition_device_result =
1173 format_disk_and_get_first_partition(&device, PartitionKind::Fat32Lba, Some(0x12345678));
1174 assert!(partition_device_result.is_ok());
1175 let partition_device = partition_device_result.unwrap();
1176
1177 let partition_size_bytes = partition_device.get_block_count() as u64 * 512;
1179 let beyond_bounds_position = partition_size_bytes;
1180
1181 let _ = partition_device
1182 .set_position(512, &Position::Start(beyond_bounds_position))
1183 .unwrap_err();
1184 let end_position = partition_size_bytes - 512;
1189 let set_position_result =
1190 partition_device.set_position(512, &Position::Start(end_position));
1191 assert!(set_position_result.is_ok());
1192
1193 let test_data = b"End of partition data";
1194 let mut write_buffer = vec![0u8; 512];
1195 write_buffer[0..test_data.len()].copy_from_slice(test_data);
1196
1197 let write_result = partition_device.write(&write_buffer, 0);
1198 assert!(write_result.is_ok());
1199
1200 let set_position_result =
1202 partition_device.set_position(512, &Position::Start(end_position));
1203 assert!(set_position_result.is_ok());
1204 let mut read_buffer = vec![0u8; 512];
1205 let read_result = partition_device.read(&mut read_buffer, 0);
1206 assert!(read_result.is_ok());
1207 assert_eq!(&read_buffer[0..test_data.len()], test_data);
1208 }
1209}