PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
part_driver_mbr.c
1#include "part_driver.h"
2#include <errno.h>
3#include <stdio.h>
4#include <string.h>
5#include <sysmem.h>
6
7#include <bdm.h>
8#include "mbr_types.h"
9
10#include "module_debug.h"
11
12int part_connect_mbr(struct block_device *bd)
13{
14 master_boot_record* pMbrBlock = NULL;
15 int rval = -1;
16 int ret;
17 int mountCount = 0;
18 int partIndex;
19
20 M_DEBUG("%s\n", __func__);
21
22 // Filter out any block device where sectorOffset != 0, as this will be a block device for a file system partition and not
23 // the raw device.
24 if (bd->sectorOffset != 0)
25 return rval;
26
27 // Allocate memory for MBR partition sector.
28 pMbrBlock = AllocSysMemory(ALLOC_FIRST, sizeof(master_boot_record), NULL);
29 if (pMbrBlock == NULL)
30 {
31 // Failed to allocate memory for mbr block.
32 M_DEBUG("Failed to allocate memory for MBR block\n");
33 return rval;
34 }
35
36 // Read the MBR block from the block device.
37 ret = bd->read(bd, 0, pMbrBlock, 1);
38 if (ret < 0)
39 {
40 // Failed to read MBR block from the block device.
41 M_DEBUG("Failed to read MBR sector from block device %d\n", ret);
42 return rval;
43 }
44
45 // Check the MBR boot signature.
46 if (pMbrBlock->boot_signature != MBR_BOOT_SIGNATURE)
47 {
48 // Boot signature is invalid, device is not valid MBR.
49 M_DEBUG("MBR boot signature is invalid, device is not MBR\n");
50 FreeSysMemory(pMbrBlock);
51 return rval;
52 }
53
54 // Check the first primary partition to see if this is a GPT protective MBR.
55 if (pMbrBlock->primary_partitions[0].partition_type == MBR_PART_TYPE_GPT_PROTECTIVE_MBR)
56 {
57 // We explicitly fail to connect GPT protective MBRs in order to let the GPT driver handle it.
58 FreeSysMemory(pMbrBlock);
59 return rval;
60 }
61
62 // Loop and parse the primary partition entries in the MBR block.
63 printf("Found MBR disk\n");
64 for (int i = 0; i < 4; i++)
65 {
66 // Check if the partition is active, checking the status bit is not reliable so check if the sector_count is greater than zero instead.
67 if (pMbrBlock->primary_partitions[i].sector_count == 0)
68 continue;
69
70 printf("Found partition type 0x%02x\n", pMbrBlock->primary_partitions[i].partition_type);
71
72 // TODO: Filter out unsupported partition types.
73
74 if ((partIndex = GetNextFreePartitionIndex()) == -1)
75 {
76 // No more free partition slots.
77 printf("Can't mount partition, no more free partition slots!\n");
78 continue;
79 }
80
81 // Create the pseudo block device for the partition.
82 g_part[partIndex].bd = bd;
83 g_part_bd[partIndex].name = bd->name;
84 g_part_bd[partIndex].devNr = bd->devNr;
85 g_part_bd[partIndex].parNr = i + 1;
86 g_part_bd[partIndex].parId = pMbrBlock->primary_partitions[i].partition_type;
87 g_part_bd[partIndex].sectorSize = bd->sectorSize;
88 g_part_bd[partIndex].sectorOffset = bd->sectorOffset + (u64)pMbrBlock->primary_partitions[i].first_lba;
89 g_part_bd[partIndex].sectorCount = pMbrBlock->primary_partitions[i].sector_count;
90 bdm_connect_bd(&g_part_bd[partIndex]);
91 mountCount++;
92 }
93
94 // If one or more partitions were mounted then return success.
95 rval = mountCount > 0 ? 0 : -1;
96
97 FreeSysMemory(pMbrBlock);
98 return rval;
99}