partitions.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include <assert.h>
  2. #include <stdlib.h>
  3. #include "partitions.h"
  4. #include "debug.h"
  5. int LoadMBR(DISK_IMG *pImg, MBR *pMbr)
  6. {
  7. assert(sizeof(*pMbr) == 512);
  8. int err = ImgRead(pImg, 0, sizeof(*pMbr), pMbr);
  9. if(err < 0)
  10. {
  11. ERR("Failed to load MBR\n");
  12. return err;
  13. }
  14. if(pMbr->uBootSig != MBR_BOOT_SIG)
  15. {
  16. WARN("Invalid signature: %u\n", pMbr->uBootSig);
  17. return -1;
  18. }
  19. return 0;
  20. }
  21. void AddSubpartToVect(SUBPART_VECTOR *pVect, unsigned Offset, unsigned Size, unsigned PartIdx, unsigned SubpartIdx)
  22. {
  23. if(pVect->Count % 4 == 0)
  24. pVect->Entries = realloc(pVect->Entries, (pVect->Count + 4) * sizeof(SUBPARTITION));
  25. SUBPARTITION *pSubpart = &pVect->Entries[pVect->Count++];
  26. pSubpart->Offset = Offset;
  27. pSubpart->Size = Size;
  28. pSubpart->PartIdx = PartIdx;
  29. pSubpart->SubpartIdx = SubpartIdx;
  30. }
  31. int FindSubpartsOnPart(DISK_IMG *pImg, unsigned Offset, unsigned Size, unsigned PartIdx, SUBPART_VECTOR *pVect)
  32. {
  33. MBR Ebr;
  34. if(Size > 512)
  35. {
  36. int err = ImgRead(pImg, Offset, sizeof(Ebr), &Ebr);
  37. if(err < 0)
  38. return err;
  39. } else
  40. Ebr.uBootSig = 0;
  41. if(Ebr.uBootSig != MBR_BOOT_SIG)
  42. {
  43. // No subpartitions
  44. AddSubpartToVect(pVect, Offset, Size, PartIdx, 0);
  45. return 0;
  46. }
  47. unsigned i;
  48. for(i = 0; i < 4; ++i)
  49. {
  50. MBR_PARTITION *pPart = &Ebr.Partitions[i];
  51. if(pPart->Type == MBR_PART_FREE) continue;
  52. unsigned SubpartOffset = pPart->uFirstSectLba * 512;
  53. unsigned SubpartSize = pPart->cSect * 512;
  54. AddSubpartToVect(pVect, SubpartOffset, SubpartSize, PartIdx, i);
  55. TRACE("EBR[%u]: Type 0x%x uFirstSectLba 0x%x cSect 0x%x off 0x%x\n", i, pPart->Type, pPart->uFirstSectLba, pPart->cSect, pPart->uFirstSectLba*512);
  56. }
  57. return 0;
  58. }
  59. int FindSubpartitions(DISK_IMG *pImg, SUBPART_VECTOR *pVect)
  60. {
  61. pVect->Count = 0;
  62. pVect->Entries = NULL;
  63. MBR Mbr;
  64. int iRet = LoadMBR(pImg, &Mbr);
  65. if(iRet < 0)
  66. {
  67. // No partitions
  68. AddSubpartToVect(pVect, 0, ImgGetSize(pImg), 0, 0);
  69. return 0;
  70. }
  71. unsigned i;
  72. for(i = 0; i < MBR_PART_COUNT; ++i)
  73. {
  74. MBR_PARTITION *pPart = &Mbr.Partitions[i];
  75. if(pPart->Type == MBR_PART_MINIX14)
  76. {
  77. TRACE("Found MINIX partition: %u. MBR entry, lba 0x%x, size 0x%x\n", i, pPart->uFirstSectLba, pPart->cSect);
  78. unsigned Offset = pPart->uFirstSectLba * 512;
  79. unsigned Size = pPart->cSect * 512;
  80. FindSubpartsOnPart(pImg, Offset, Size, i, pVect);
  81. }
  82. else if(pPart->Type != MBR_PART_FREE)
  83. INFO("Unknown partition %u: type 0x%x, lba 0x%x, size 0x%x\n", i, pPart->Type, pPart->uFirstSectLba, pPart->cSect);
  84. }
  85. if(pVect->Count == 0)
  86. ERR("Failed to find a MINIX partition\n");
  87. return 0;
  88. }