ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/ps2launchargs/source/uLaunchELF/hdl_info/apa.c
Revision: 1101
Committed: Wed Feb 7 05:08:54 2018 UTC (7 years, 8 months ago) by iritscen
Content type: text/x-csrc
File size: 9890 byte(s)
Log Message:
Added following to ps2launchargs:\n-Source code.\n-DLL needed to run ps2client.\n-Instructions for building uLaunchELF.

File Contents

# Content
1 //--------------------------------------------------------------
2 //File name: apa.c
3 //--------------------------------------------------------------
4 #include <thbase.h>
5 #include <sysclib.h>
6 #include <cdvdman.h>
7 #include <iomanX.h>
8 #include <sysmem.h>
9
10 #include "ps2_hdd.h"
11 #include "hdd.h"
12 #include "hdl.h"
13 #include "apa.h"
14
15 #define AUTO_DELETE_EMPTY
16
17 #define _MB * (1024 * 1024) /* really ugly :-) */
18
19 typedef struct ps2_partition_run_type
20 {
21 unsigned long sector;
22 u_long size_in_mb;
23 } ps2_partition_run_t;
24
25 //Remove this line, and uncomment the next line, to reactivate 'apa_check'
26 //static int apa_check(const apa_partition_table_t *table);
27
28 //--------------------------------------------------------------
29 u_long apa_partition_checksum(const ps2_partition_header_t *part)
30 {
31 const u_long *p = (const u_long*)part;
32 register u_long i;
33 u_long sum = 0;
34 for(i=1; i<256; ++i)
35 sum += get_u32(p + i);
36 return sum;
37 }
38 //------------------------------
39 //endfunc apa_partition_checksum
40 //--------------------------------------------------------------
41 static apa_partition_table_t* apa_ptable_alloc(void)
42 {
43 apa_partition_table_t *table = AllocSysMemory(0, sizeof (apa_partition_table_t), NULL);
44 if(table != NULL)
45 memset(table, 0, sizeof (apa_partition_table_t));
46 return table;
47 }
48 //------------------------------
49 //endfunc apa_ptable_alloc
50 //--------------------------------------------------------------
51 void apa_ptable_free(apa_partition_table_t *table)
52 {
53 if (table != NULL){
54 if (table->chunks_map != NULL)
55 FreeSysMemory(table->chunks_map);
56 if (table->parts != NULL)
57 FreeSysMemory(table->parts);
58 FreeSysMemory(table);
59 }
60 }
61 //------------------------------
62 //endfunc apa_ptable_free
63 //--------------------------------------------------------------
64 static int apa_part_add (apa_partition_table_t *table, const ps2_partition_header_t *part, int existing, int linked)
65 {
66 if (table->part_count == table->part_alloc_){ /* grow buffer */
67 u_long bytes = (table->part_alloc_ + 16) * sizeof (apa_partition_t);
68 apa_partition_t *tmp = AllocSysMemory(0, bytes, NULL);
69 if(tmp != NULL)
70 {
71 memset(tmp, 0, bytes);
72 if (table->parts != NULL) /* copy existing */
73 memcpy(tmp, table->parts, table->part_count * sizeof (apa_partition_t));
74 FreeSysMemory(table->parts);
75 table->parts = tmp;
76 table->part_alloc_ += 16;
77 }
78 else return -2;
79 }
80
81 memcpy(&table->parts[table->part_count].header, part, sizeof (ps2_partition_header_t));
82 table->parts[table->part_count].existing = existing;
83 table->parts[table->part_count].modified = !existing;
84 table->parts[table->part_count].linked = linked;
85 ++table->part_count;
86
87 return 0;
88 }
89 //------------------------------
90 //endfunc apa_part_add
91 //--------------------------------------------------------------
92 /* //Remove this line and a similar one below to reactivate 'apa_setup_statistics'
93 static int apa_setup_statistics(apa_partition_table_t *table)
94 {
95 u_long i;
96 char *map;
97
98 table->total_chunks = table->device_size_in_mb / 128;
99 map = AllocSysMemory(0, table->total_chunks * sizeof (char), NULL);
100 if(map != NULL)
101 {
102 for(i=0; i<table->total_chunks; ++i)
103 map [i] = MAP_AVAIL;
104
105 // build occupided/available space map
106 table->allocated_chunks = 0;
107 table->free_chunks = table->total_chunks;
108 for(i=0; i<table->part_count; ++i)
109 {
110 const ps2_partition_header_t *part = &table->parts [i].header;
111 u_long part_no = get_u32(&part->start) / ((128 _MB) / 512);
112 u_long num_parts = get_u32(&part->length) / ((128 _MB) / 512);
113
114 // "alloc" num_parts starting at part_no
115 while (num_parts)
116 {
117 if(map[part_no] == MAP_AVAIL)
118 map[part_no] = get_u32(&part->main) == 0 ? MAP_MAIN : MAP_SUB;
119 else
120 map[part_no] = MAP_COLL; // collision
121 ++part_no;
122 --num_parts;
123 ++table->allocated_chunks;
124 --table->free_chunks;
125 }
126 }
127
128 if(table->chunks_map != NULL)
129 FreeSysMemory(table->chunks_map);
130 table->chunks_map = map;
131
132 return 0;
133 }
134 else return -2;
135 }
136 */ //Remove this line and a similar one below to reactivate 'apa_setup_statistics'
137 //------------------------------
138 //endfunc apa_setup_statistics
139 //--------------------------------------------------------------
140 int apa_ptable_read_ex ( hio_t *hio, apa_partition_table_t **table)
141 {
142 u_long size_in_kb;
143 int result = hio->stat(hio, &size_in_kb);
144 if(result == 0){
145 u_long total_sectors;
146 // limit HDD size to 128GB - 1KB; that is: exclude the last 128MB chunk
147 //if (size_in_kb > 128 * 1024 * 1024 - 1)
148 // size_in_kb = 128 * 1024 * 1024 - 1;
149
150 total_sectors = size_in_kb * 2; /* 1KB = 2 sectors of 512 bytes, each */
151
152 *table = apa_ptable_alloc();
153 if(*table != NULL){
154 u_long sector = 0;
155 do {
156 u_long bytes;
157 ps2_partition_header_t part;
158 result = hio->read(hio, sector, sizeof(part) / 512, &part, &bytes);
159 if(result == 0){
160 if(bytes == sizeof(part) &&
161 get_u32(&part.checksum) == apa_partition_checksum(&part) &&
162 memcmp(part.magic, PS2_PARTITION_MAGIC, 4) == 0)
163 {
164 if(get_u32(&part.start) < total_sectors &&
165 get_u32(&part.start) + get_u32(&part.length) < total_sectors)
166 {
167 if((get_u16(&part.flags)==0x0000) && (get_u16(&part.type) ==0x1337))
168 result = apa_part_add(*table, &part, 1, 1);
169 if(result == 0)
170 sector = get_u32(&part.next);
171 } else { /* partition behind end-of-HDD */
172 result = 7; /* data behind end-of-HDD */
173 break;
174 }
175 } else
176 result = 1;
177 }
178 /* TODO: check whether next partition is not loaded already --
179 * do not deadlock; that is a quick-and-dirty hack */
180 if ((*table)->part_count > 10000)
181 result = 7;
182 } while (result == 0 && sector != 0);
183
184 if (result == 0){
185 (*table)->device_size_in_mb = size_in_kb / 1024;
186 //NB: uncommenting the next lines requires changes elsewhere too
187 //result = apa_setup_statistics (*table);
188 //if (result == 0)
189 //result = apa_check (*table);
190 }
191
192 if (result != 0){
193 result = 20000+(*table)->part_count;
194 apa_ptable_free (*table);
195 }
196 }
197 else result = -2;
198 }
199 return result;
200 }
201 //------------------------------
202 //endfunc apa_ptable_read_ex
203 //--------------------------------------------------------------
204 /* //Remove this line and a similar one below to reactivate 'apa_check'
205 static int apa_check (const apa_partition_table_t *table) {
206
207 u_long i, j, k;
208
209 const u_long total_sectors = table->device_size_in_mb * 1024 * 2;
210
211 for (i=0; i<table->part_count; ++i)
212 {
213 const ps2_partition_header_t *part = &table->parts [i].header;
214 if (get_u32 (&part->checksum) != apa_partition_checksum (part))
215 return 7; // bad checksum
216
217 if (get_u32 (&part->start) < total_sectors &&
218 get_u32 (&part->start) + get_u32 (&part->length) <= total_sectors)
219 ;
220 else
221 {
222 return 7; // data behind end-of-HDD
223 }
224
225 if ((get_u32 (&part->length) % ((128 _MB) / 512)) != 0)
226 return 7; // partition size not multiple to 128MB
227
228 if ((get_u32 (&part->start) % get_u32 (&part->length)) != 0)
229 return 7; // partition start not multiple on partition size
230
231 if (get_u32 (&part->main) == 0 &&
232 get_u16 (&part->flags) == 0 &&
233 get_u32 (&part->start) != 0)
234 { // check sub-partitions
235 u_long count = 0;
236 for (j=0; j<table->part_count; ++j)
237 {
238 const ps2_partition_header_t *part2 = &table->parts [j].header;
239 if (get_u32 (&part2->main) == get_u32 (&part->start))
240 { // sub-partition of current main partition
241 int found;
242 if (get_u16 (&part2->flags) != PS2_PART_FLAG_SUB)
243 return 7;
244
245 found = 0;
246 for (k=0; k<get_u32 (&part->nsub); ++k)
247 if (get_u32 (&part->subs [k].start) == get_u32 (&part2->start))
248 { // in list
249 if (get_u32 (&part->subs [k].length) != get_u32 (&part2->length))
250 return 7;
251 found = 1;
252 break;
253 }
254 if (!found)
255 return 7; // not found in the list
256
257 ++count;
258 }
259 }
260 if (count != get_u32 (&part->nsub))
261 return 7; // wrong number of sub-partitions
262 }
263 }
264
265 // verify double-linked list
266 for (i=0; i<table->part_count; ++i)
267 {
268 apa_partition_t *prev = table->parts + (i > 0 ? i - 1 : table->part_count - 1);
269 apa_partition_t *curr = table->parts + i;
270 apa_partition_t *next = table->parts + (i + 1 < table->part_count ? i + 1 : 0);
271 if (get_u32 (&curr->header.prev) != get_u32 (&prev->header.start) ||
272 get_u32 (&curr->header.next) != get_u32 (&next->header.start))
273 return 7; // bad links
274 }
275
276 return 0;
277 }
278 */ //Remove this line and a similar one above to reactivate 'apa_check'
279 //------------------------------
280 //endfunc apa_check
281 //--------------------------------------------------------------
282 u_long get_u32 (const void *buffer)
283 {
284 const u_char *p = buffer;
285 return ((((u_long) p[3]) << 24) |
286 (((u_long) p[2]) << 16) |
287 (((u_long) p[1]) << 8) |
288 (((u_long) p[0]) << 0));
289 }
290 //------------------------------
291 //endfunc get_u32
292 //--------------------------------------------------------------
293 void set_u32 (void *buffer, u_long val)
294 {
295 u_char *p = buffer;
296 p [3] = (u_char) (val >> 24);
297 p [2] = (u_char) (val >> 16);
298 p [1] = (u_char) (val >> 8);
299 p [0] = (u_char) (val >> 0);
300 }
301 //------------------------------
302 //endfunc set_u32
303 //--------------------------------------------------------------
304 u_short get_u16 (const void *buffer)
305 {
306 const u_char *p = buffer;
307 return ((((u_short) p[1]) << 8) |
308 (((u_short) p[0]) << 0));
309 }
310 //------------------------------
311 //endfunc get_u16
312 //--------------------------------------------------------------
313 void set_u16 (void *buffer, u_short val)
314 {
315 u_char *p = buffer;
316 p [1] = (u_char) (val >> 8);
317 p [0] = (u_char) (val >> 0);
318 }
319 //------------------------------
320 //endfunc set_u16
321 //--------------------------------------------------------------
322 //End of file: apa.c
323 //--------------------------------------------------------------

Properties

Name Value
svn:executable *