PS2SDK
PS2 Homebrew Libraries
part_driver.c
1 //---------------------------------------------------------------------------
2 // File name: part_driver.c
3 //---------------------------------------------------------------------------
4 #include <stdio.h>
5 #include <errno.h>
6 #ifdef BUILDING_USBHDFSD
7 #include <usbhdfsd.h>
8 #endif /* BUILDING_USBHDFSD */
9 #include "usbhd_common.h"
10 #include "scache.h"
11 #include "part_driver.h"
12 #ifdef BUILDING_USBHDFSD
13 #include "mass_stor.h"
14 #endif /* BUILDING_USBHDFSD */
15 #ifdef BUILDING_IEEE1394_DISK
16 #include "sbp2_disk.h"
17 #endif /* BUILDING_IEEE1394_DISK */
18 #include "fat_driver.h"
19 
20 // #define DEBUG //comment out this line when not debugging
21 
22 #include "mass_debug.h"
23 
24 #define READ_SECTOR(d, a, b) scache_readSector((d)->cache, (a), (void **)&b)
25 
26 typedef struct _part_record
27 {
28  unsigned char sid; // system id- 4=16bit FAT (16bit sector numbers)
29  // 5=extended partition
30  // 6=16bit FAT (32bit sector numbers)
31  unsigned int start; // start sector of the partition
32  unsigned int count; // length of the partititon (total number of sectors)
33 } part_record;
34 
35 typedef struct _part_table
36 {
37  part_record record[4]; // maximum of 4 primary partitions
38 } part_table;
39 
40 typedef struct _part_raw_record
41 {
42  unsigned char active; // Set to 80h if this partition is active / bootable
43  unsigned char startH; // Partition's starting head.
44  unsigned char startST[2]; // Partition's starting sector and track.
45  unsigned char sid; // Partition's system ID number.
46  unsigned char endH; // Partition's ending head.
47  unsigned char endST[2]; // Partition's ending sector and track.
48  unsigned char startLBA[4]; // Starting LBA (sector)
49  unsigned char size[4]; // Partition size in sectors.
51 
52 //---------------------------------------------------------------------------
53 #if defined(BUILDING_USBHDFSD)
54 static USBHD_INLINE int part_getPartitionRecord(mass_dev *dev, part_raw_record *raw, part_record *rec)
55 #elif defined(BUILDING_IEEE1394_DISK)
56 static USBHD_INLINE int part_getPartitionRecord(struct SBP2Device *dev, part_raw_record *raw, part_record *rec)
57 #else
58 static USBHD_INLINE int part_getPartitionRecord(void *dev, part_raw_record *raw, part_record *rec)
59 #endif
60 {
61  rec->sid = raw->sid;
62  rec->start = getUI32(raw->startLBA);
63  rec->count = getUI32(raw->size);
64 
65  // Ignore partitions that have a partition type/system ID set to 0.
66  if (rec->sid != 0x00) { /* Windows appears to check if the start LBA is not 0 and whether the start LBA is within the disk.
67  There may be checks against the size, but I didn't manage to identify a pattern.
68  If the disk has no partition table (i.e. disks with "removable" media), then this check is also one safeguard. */
69  if ((rec->start == 0) || (rec->start >= dev->maxLBA))
70  return -1;
71 
72  return 0;
73  }
74 
75  return 1;
76 }
77 
78 //---------------------------------------------------------------------------
79 #if defined(BUILDING_USBHDFSD)
80 static int part_getPartitionTable(mass_dev *dev, part_table *part)
81 #elif defined(BUILDING_IEEE1394_DISK)
82 static int part_getPartitionTable(struct SBP2Device *dev, part_table *part)
83 #else
84 static int part_getPartitionTable(void *dev, part_table *part)
85 #endif
86 {
87  int ret;
88  unsigned int i;
89  unsigned char *sbuf;
90 
91  ret = READ_SECTOR(dev, 0, sbuf); // read sector 0 - Disk MBR or boot sector
92  if (ret < 0) {
93  XPRINTF("part_getPartitionTable read failed %d!\n", ret);
94  return -EIO;
95  }
96 
97  /* A VBR (i.e. diskette-like) also shares this signature, in the same place.
98  Hence passing this check only indicates the presence of a VBR/MBR, but does not indicate which it is. */
99  printf("USBHDFSD: boot signature %X %X\n", sbuf[0x1FE], sbuf[0x1FF]);
100  if (sbuf[0x1FE] == 0x55 && sbuf[0x1FF] == 0xAA) {
101  int partitions;
102 
103  for (partitions = 0, i = 0; i < 4; i++) {
104  part_raw_record *part_raw;
105 
106  part_raw = (part_raw_record *)(sbuf + 0x01BE + (i * 16));
107  ret = part_getPartitionRecord(dev, part_raw, &part->record[i]);
108  if (ret < 0)
109  return 0; // Invalid record encountered, so the table is probably invalid.
110  else if (ret == 0) // Count the number of valid entries.
111  partitions++;
112  }
113 
114  // Check the number of partitions validated. Having all entries set to 0, could mean it is not a MBR.
115  return (partitions == 0 ? 0 : 4);
116  } else {
117  for (i = 0; i < 4; i++) {
118  part->record[i].sid = 0;
119  }
120  return 0;
121  }
122 }
123 
124 //---------------------------------------------------------------------------
125 #if defined(BUILDING_USBHDFSD)
126 int part_connect(mass_dev *dev)
127 #elif defined(BUILDING_IEEE1394_DISK)
128 int part_connect(struct SBP2Device *dev)
129 #else
130 int part_connect(void *dev)
131 #endif
132 {
133  part_table partTable;
134  int parts;
135 #ifdef BUILDING_USBHDFSD
136  XPRINTF("part_connect devId %i \n", dev->devId);
137 #endif /* BUILDING_USBHDFSD */
138 #ifdef BUILDING_IEEE1394_DISK
139  XPRINTF("part_connect devId %i \n", dev->nodeID);
140 #endif /* BUILDING_IEEE1394_DISK */
141 
142  if ((parts = part_getPartitionTable(dev, &partTable)) < 0)
143  return -1;
144 
145  if (parts > 0) {
146  unsigned int count = 0, i;
147  for (i = 0; i < (unsigned int)parts; i++) {
148  if (
149  partTable.record[i].sid == 6 ||
150  partTable.record[i].sid == 4 ||
151  partTable.record[i].sid == 1 || // fat 16, fat 12
152  partTable.record[i].sid == 0x0B ||
153  partTable.record[i].sid == 0x0C || // fat 32
154  partTable.record[i].sid == 0x0E) // fat 16 LBA
155  {
156  XPRINTF("mount partition %d id %02x\n", i, partTable.record[i].sid);
157  if (fat_mount(dev, partTable.record[i].start, partTable.record[i].count) >= 0)
158  count++;
159  }
160  }
161 
162  if (count == 0) {
163  printf("USBHDFSD: error - no mountable partitions.\n");
164  return -1;
165  }
166  } else { /* No partition table detected, so try to use "floppy" option and hope for the best. */
167  printf("USBHDFSD: mount drive\n");
168  if (fat_mount(dev, 0, dev->maxLBA) < 0)
169  return -1;
170  }
171 
172  return 0;
173 }
174 
175 //---------------------------------------------------------------------------
176 #if defined(BUILDING_USBHDFSD)
177 void part_disconnect(mass_dev *dev)
178 #elif defined(BUILDING_IEEE1394_DISK)
179 void part_disconnect(struct SBP2Device *dev)
180 #else
181 int part_connect(void *dev)
182 #endif
183 {
184 #ifdef BUILDING_USBHDFSD
185  printf("USBHDFSD: part_disconnect devId %i \n", dev->devId);
186 #endif /* BUILDING_USBHDFSD */
187 #ifdef BUILDING_IEEE1394_DISK
188  XPRINTF("part_disconnect devId %i \n", dev->nodeID);
189 #endif /* BUILDING_IEEE1394_DISK */
190  fat_forceUnmount(dev);
191 }
192 
193 //---------------------------------------------------------------------------
194 // End of file: part_driver.c
195 //---------------------------------------------------------------------------
_mass_dev
Definition: usbhdfsd.h:64
EIO
#define EIO
Definition: errno.h:29
_part_table
Definition: part_driver.c:35
count
u32 count
start sector of fragmented bd/file
Definition: usbhdfsd-common.h:3
_part_raw_record
Definition: part_driver.c:40
stdio.h
_part_record
Definition: part_driver.c:26
SBP2Device
Definition: sbp2_disk.h:125
errno.h
usbhdfsd.h