📄 hdl.cpp
字号:
{ u_int32_t num_parts = buffer [0x001010f0]; const u_int32_t *data = (u_int32_t*) (buffer + 0x001010f5); u_int32_t i; if (buffer [0x00101000] == 0xed && buffer [0x00101001] == 0xfe && buffer [0x00101002] == 0xad && buffer [0x00101003] == 0xde) { /* 0xdeadfeed magic found */ osal_handle_t file; u_int64_t total_size = 0; /* calculate output file size */ for (i=0; i<num_parts; ++i) total_size += ((u_int64_t) get_u32 (data + i * 3 + 2)) << 8; pgs_prepare (pgs, total_size); /* create file and copy data */ result = osal_create_file (output_file, &file, total_size); if (result == OSAL_OK) { u_int8_t *aligned = (u_int8_t *)(void*) (((long) buffer + 511) & ~511); for (i=0; result == OSAL_OK && i<num_parts; ++i) { /* seek and copy */ u_int32_t start_s = get_u32 (data + i * 3 + 1) << 8; u_int32_t length_s = get_u32 (data + i * 3 + 2) / 2; u_int64_t curr = 0; while (length_s > 0 && result == OSAL_OK) { u_int32_t count_s = length_s < IIN_NUM_SECTORS ? length_s : IIN_NUM_SECTORS; result = hio->read (hio, start_s, count_s, aligned, &len); if (result == OSAL_OK) { u_int32_t written; result = osal_write (file, aligned, count_s * 512, &written); if (result == OSAL_OK) { start_s += count_s; length_s -= count_s; curr += count_s * 512; pgs_update (pgs, curr); } } } pgs_chunk_complete (pgs); } /* for */ result = osal_close (file) == OSAL_OK ? result : OSAL_ERR; } } else result = RET_NOT_HDL_PART; } hio->close (hio); } osal_free (buffer); } else result = RET_NO_MEM; } apa_ptable_free (table); } return (result);}/**************************************************************/static intinject_data (hio_t *hio, const apa_partition_table_t *table, u_int32_t starting_partition_sector, iin_t *iin, u_int32_t size_in_kb, const hdl_game_t *details, progress_t *pgs){ int result; u_int32_t i; const ps2_partition_header_t *part; char *buffer = (char *)osal_alloc (4 _MB); part = NULL; if (buffer != NULL) { result = RET_NOT_FOUND; for (i=0; i<table->part_count; ++i) if (get_u32 (&table->parts [i].header.start) == starting_partition_sector) { /* locate starting partition index */ part = &table->parts [i].header; /* verify apa */ result = (get_u32 (&part->checksum) == apa_partition_checksum (part) ? RET_OK : RET_BAD_APA); break; } } else result = RET_NO_MEM; if (result == RET_OK) { result = prepare_main (details, table, starting_partition_sector, size_in_kb, (u_int8_t*) buffer); if (result == RET_OK) { u_int32_t kb_remaining = size_in_kb; u_int32_t start_sector = 0; u_int32_t bytes; u_int32_t main_hdr_size_s = (4 _MB) / 512; pgs_prepare (pgs, (u_int64_t) (size_in_kb + 4 * 1024) * 1024); /* first: write main partition header (4MB total) */ result = hio->write (hio, get_u32 (&part->start), main_hdr_size_s, buffer, &bytes); if (result == OSAL_OK) result = bytes == 4 _MB ? OSAL_OK : OSAL_ERR; osal_free (buffer), buffer = NULL; /* track header, otherwise it would influence the progress calculation */ pgs_update (pgs, 4 _MB); pgs_chunk_complete (pgs); /* next: fill-in 1st partition */ if (result == RET_OK) { u_int64_t part_size = ((u_int64_t) get_u32 (&part->length)) * 512 - (4 _MB); u_int64_t chunk_length_in_bytes = ((u_int64_t) kb_remaining) * 1024 < part_size ? ((u_int64_t) kb_remaining) * 1024 : part_size; result = iin_copy_ex (iin, hio, start_sector, get_u32 (&part->start) + main_hdr_size_s, (u_int32_t) (chunk_length_in_bytes / IIN_SECTOR_SIZE), pgs); pgs_chunk_complete (pgs); start_sector += (u_int32_t) (chunk_length_in_bytes / IIN_SECTOR_SIZE); kb_remaining -= (u_int32_t) (chunk_length_in_bytes / 1024); } for (i=0; result == OSAL_OK && kb_remaining>0 && i!=get_u32 (&part->nsub); ++i) { /* next: fill-in remaining partitions */ u_int32_t sub_part_start_s = get_u32 (&part->subs [i].start); u_int64_t sub_part_size = (((u_int64_t) get_u32 (&part->subs [i].length)) * 512 - (1 _MB)); u_int32_t sub_part_hdr_size_s = (1 _MB) / 512; u_int64_t chunk_length = ((u_int64_t) kb_remaining) * 1024 < sub_part_size ? ((u_int64_t) kb_remaining) * 1024 : sub_part_size; result = iin_copy_ex (iin, hio, start_sector, sub_part_start_s + sub_part_hdr_size_s, (u_int32_t) (chunk_length / IIN_SECTOR_SIZE), pgs); pgs_chunk_complete (pgs); start_sector += (u_int32_t) (chunk_length / IIN_SECTOR_SIZE); kb_remaining -= (u_int32_t) (chunk_length / 1024); } if (result == RET_OK && kb_remaining != 0) result = RET_NO_SPACE; /* the game does not fit in the allocated space... why? */ /* finally: commit partition table */ if (result == OSAL_OK) result = apa_commit_ex (hio, table); } } if (buffer != NULL) osal_free (buffer); return (result);}/**************************************************************/inthdl_inject (hio_t *hio, iin_t *iin, hdl_game_t *details, progress_t *pgs){ apa_partition_table_t *table = NULL; int result = apa_ptable_read_ex (hio, &table); if (result == OSAL_OK) { u_int32_t sector_size, num_sectors; result = iin->stat (iin, §or_size, &num_sectors); if (result == OSAL_OK) { u_int64_t input_size = (u_int64_t) num_sectors * (u_int64_t) sector_size; u_int32_t size_in_kb = (u_int32_t) (input_size / 1024); u_int32_t size_in_mb = (u_int32_t) ((input_size + (1 _MB - 1)) / (1 _MB)); u_int32_t new_partition_start; if (details->partition_name [0] == '\0') hdl_pname (details->name, details->partition_name); result = apa_allocate_space (table, details->partition_name, size_in_mb, &new_partition_start, 0); /* order by size desc */ if (result == RET_OK) { result = inject_data (hio, table, new_partition_start, iin, size_in_kb, details, pgs); } } } if (table != NULL) apa_ptable_free (table); return (result);}/**************************************************************/static inthdl_ginfo_read (hio_t *hio, const ps2_partition_header_t *part, hdl_game_info_t *ginfo){ u_int32_t i, size; /* data we're interested in starts @ 0x101000 and is header * plus information for up to 65 partitions * (1 main + 64 sub) by 12 bytes each */ const u_int32_t offset = 0x101000; char buffer [1024]; int result; u_int32_t bytes; result = hio->read (hio, get_u32 (&part->start) + offset / 512, 2, buffer, &bytes); if (result == RET_OK) { if (bytes == 1024) { /* calculate total size */ size = get_u32 (&part->length); for (i=0; i<get_u32 (&part->nsub); ++i) size += get_u32 (&part->subs [i].length); memcpy (ginfo->partition_name, part->id, PS2_PART_IDMAX); ginfo->partition_name [PS2_PART_IDMAX] = '\0'; strcpy (ginfo->name, buffer + 0x101008 - offset); strcpy (ginfo->startup, buffer + 0x1010ac - offset); ginfo->compat_flags = buffer [0x1010a8 - offset]; ginfo->is_dvd = buffer [0x1010ec - offset] == 0x14; ginfo->start_sector = get_u32 (&part->start); ginfo->total_size_in_kb = size / 2; } else result = RET_ERR; } return (result);}/**************************************************************/inthdl_glist_read (hio_t *hio, hdl_games_list_t **glist){ apa_partition_table_t *ptable; int result; result = apa_ptable_read_ex (hio, &ptable); if (result == RET_OK) { u_int32_t i, count = 0; void *tmp; for (i=0; i<ptable->part_count; ++i) count += (get_u16 (&ptable->parts [i].header.flags) == 0x00 && get_u16 (&ptable->parts [i].header.type) == 0x1337); tmp = osal_alloc (sizeof (hdl_game_info_t) * count); if (tmp != NULL) { memset (tmp, 0, sizeof (hdl_game_info_t) * count); *glist = (hdl_games_list_t *)osal_alloc (sizeof (hdl_games_list_t)); if (*glist != NULL) { u_int32_t index = 0; memset (*glist, 0, sizeof (hdl_games_list_t)); (*glist)->count = count; (*glist)->games = (hdl_game_info_type *)tmp; (*glist)->total_chunks = ptable->total_chunks; (*glist)->free_chunks = ptable->free_chunks; for (i=0; result==RET_OK&&i<ptable->part_count; ++i) { const ps2_partition_header_t *part = &ptable->parts [i].header; if (get_u16 (&part->flags) == 0x00 && get_u16 (&part->type) == 0x1337) result = hdl_ginfo_read (hio, part, (*glist)->games + index++); } if (result != RET_OK) osal_free (*glist); } else result = RET_NO_MEM; if (result != RET_OK) osal_free (tmp); } else result = RET_NO_MEM; apa_ptable_free (ptable); } return (result);}/**************************************************************/voidhdl_glist_free (hdl_games_list_t *glist){ if (glist != NULL) { osal_free (glist->games); osal_free (glist); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -