📄 olecod.c
字号:
fil_swriteU32 (output_block + 0x10, &U32magiczero); fil_swriteU32 (output_block + 0x14, &U32magiczero); fil_swriteU32 (output_block + 0x18, &U32magic1); fil_swriteU32 (output_block + 0x1c, &U32magic2); fil_swriteU32 (output_block + 0x20, &U32magic3); fil_swriteU32 (output_block + 0x24, &U32magiczero); fil_swriteU32 (output_block + 0x28, &U32magiczero); fil_swriteU32 (output_block + 0x34, &U32magiczero); fil_swriteU32 (output_block + 0x38, &U32magic4); fil_swriteU32 (output_block + 0x40, &U32magic5); fil_swriteU32 (output_block + 0x44, &U32magic6); fil_swriteU32 (output_block + 0x48, &U32magiczero); pos_block = 0x4c; return 0;}/* reviewed all cases */static int generate_recursive (MY_FILE * list){ MY_FILE *p_MY_FILE_list; verbose ("calling: generate_recursive ()"); switch (list->type) { /* reviewed when generating Input and sbfile */ case MY_FILE_list: for (p_MY_FILE_list = list->file.MY_FILE_list; (U32)((U8*)p_MY_FILE_list - (U8*)list->file.root_list) < list->size; p_MY_FILE_list++) test_call (generate_recursive (p_MY_FILE_list), int); break; /* reviewed when generating bbd_list, BDepot and SDepot */ case block_list: if (list == bbd_list) { test_call (write_block_list (BDepot_start_block, bbd_list, 0), int); write_until_output_block_boundary (1); break; } else if (list == BDepot) /* we want to skip generate BDepot by now */ break; else if (list == SDepot) /* we want to skip generate SDepot by now */ break; else assert ("list->type==block_list but list UNKNOWN in generate_recursive"==NULL); /* reviewed when generating Root */ case root_list: /* we want to skip generate Root by now */ assert (list == Root); break; case real: /* we are generating big and small streams here */ test_call (generate_real_file (list), int); break; default: assert ("list->type UNKNOWN in generate_recursive" == NULL); } return 0;}static int generate_SDepot (void){ verbose ("calling: generate_SDepot ()"); test_call (write_block_list (1, SDepot, 1), int); write_until_output_block_boundary (1); return 0;}static int generate_Root (void){ verbose ("calling: generate_Root ()"); test_call (write_root_list (Root), int); write_rest_of_output_block_with_null_pps (); write_until_output_block_boundary (0); return 0;}static int generate_BDepot (void){ MY_FILE SDepot_and_Root_block_list; MY_FILE file_block_list; U32 next_block_link; verbose ("calling: generate_BDepot ()"); next_block_link = 0xffffffffUL + header_blocks + 1; /* + 1 because is the ___next link___ */ /* 1. generate sbfile block list */ assert (next_block_link == sbfile_start_block + 1); /* + 1 because is the ___next link___ */ init_MY_FILE ((&file_block_list), block_list, sizeof (U32), NULL, BDepot->file.block_list); /* the blocks that takes sbfile are in the first entry in BDepot */ verboseU32 ((*(BDepot->file.block_list))); test_call (write_block_list (next_block_link, &file_block_list, 1), int); /* update next_block_link */ next_block_link += sbfile_blocks; /* 2. generate big streams block list */ assert (next_block_link == sbfile_start_block + sbfile_blocks + 1); /* + 1 because is the ___next link___ */ init_MY_FILE ((&file_block_list), block_list, BDepot->size - 3 * sizeof (U32), NULL, BDepot->file.block_list + 3); /* 3 because the first three entries in BDepot are sbfile, SDepot and Root */ test_call (write_block_list (next_block_link, &file_block_list, 1), int); /* update next_block_link */ next_block_link += sum_block_list (&file_block_list); /* 3. generate SDepot and Root block list */ if (sbfile->size > 0) /* if there are sbfile */ assert (next_block_link == SDepot_start_block + 1); /* + 1 because is the ___next link___ */ init_MY_FILE ((&SDepot_and_Root_block_list), block_list, 2 * sizeof (U32), NULL, BDepot->file.block_list + 1); /* + 1 because the first entry in BDepot is sbfile block */ test_call (write_block_list (next_block_link, &SDepot_and_Root_block_list, 1), int); /* 4. finish */ write_until_output_block_boundary (1); return 0;}static int generate_real_file (MY_FILE * MY_FILE_file){ FILE *file; int n_read; U8 * pps; U32 total_bytes; U32 sbfile_size; static U32 last_small_stream_next_block = 0; static int sbfile_start_block_set = 0; static int sbfile_may_need_write_until_boundary = 0; verbose ("calling: generate_real_file ()");/* FIXME MARK 3 */ /* all seems to be working until here... I hope. Test is welcome! */ /*verboseU16 (sbfile_start_block_set);*/ /*verboseU16 (sbfile_may_need_write_until_boundary);*/ /*verboseU16 (pos_block);*/ assert (pos_block <= 0x0200); assert (pos_block % 0x40 == 0); /* open real file */ assert (MY_FILE_file->file.real.name[0]); file = fopen (MY_FILE_file->file.real.name, "rb"); test_exitf (file != NULL, 11, dummy ()); /* write Root start_block's of this file */ if (MY_FILE_file->size >= 0x1000) { /* generating big stream */ /* first, end writting sbfile, if any */ if (sbfile_may_need_write_until_boundary) { /* this happens after all small strams have been generated but before the first big stream is generated */ write_until_output_block_boundary (1); sbfile_may_need_write_until_boundary = 0; } /* then, continue with this big stream */ /* write start block of this stream in its Root pps */ verboseU32 (next_block); pps = Root->file.root_list + MY_FILE_file->file.real.ppsnumber * 0x80; fil_swriteU32 (pps + 0x74, &next_block); } else { /* generating small stream */ /* do nothing, start block of small streams was written in proces_streams */ /* write start block of this stream in its Root pps */ pps = Root->file.root_list + MY_FILE_file->file.real.ppsnumber * 0x80; fil_swriteU32 (pps + 0x74, &last_small_stream_next_block); last_small_stream_next_block += *(MY_FILE_file->blocks); /* small blocks */ /* write sbfile start block in root directory pps in Root, if not done */ if (!sbfile_start_block_set) { /* this happens before generate the first small stream that makes sbfile */ verbose ("generating sbfile"); verbose ("SUPPOSING: first entry in Root is root entry"); /* write start block of sbfile */ assert (sbfile_start_block == next_block); fil_swriteU32 (Root->file.root_list + 0x74, &next_block); sbfile_size = sum_blocks_MY_FILE_list (sbfile) * 0x40; verboseU32 (sbfile_size); /* compare calculated sbfile size with original */ assert (sbfile_size == fil_sreadU32 (Root->file.root_list + 0x78)); sbfile_start_block_set = 1; sbfile_may_need_write_until_boundary = 1; } } verboseS (MY_FILE_file->file.real.name); total_bytes = 0; /* copy real file to output_file */ while (!feof (file)) { n_read = fread (output_block+pos_block, 1, 0x0200-pos_block, file); test_exitf (!ferror (file), 11, dummy ()); if (n_read < 0x0200-pos_block) /* if it was readed less than it could be possible */ assert (feof (file)); pos_block += (U16)n_read; total_bytes += n_read; check_output_block_boundary (); } test_exitf (total_bytes == MY_FILE_file->size, 12, dummy()); if (MY_FILE_file->size >= 0x1000) /* generating big stream */ write_until_output_block_boundary (1) else /* generating small stream */ write_until_output_block_small_boundary (1); /* close real file */ fclose (file); return 0;}intwrite_block_list (U32 start_count, MY_FILE * list, int write_end_chain){ U32 *p; U32 n; U32 end_chain = 0xfffffffeUL; U32 value_to_write; U32 delta; verbose ("calling: write_block_list ()"); assert (list->type == block_list); /* Was (list->type = block_list) - SG */ assert (pos_block <= 0x01fc); /* 0x01fc = 0x0200 - sizeof(U32) */ delta = start_count; if (list->size == 0) return 0; /* we are done */ for (p = list->file.block_list; (U32)((U8 *) p - (U8 *) list->file.block_list) < list->size; p++) { for (n = 0; n < *p; n++) { /* this allow bbd_list runs over the block number 2 */ check_output_block_boundary (); /* if it's the last block in chain */ if (write_end_chain && !(n + 1 < *p)) value_to_write = end_chain; else value_to_write = n + delta; fil_swriteU32 (output_block + pos_block, &value_to_write); pos_block += (U16)sizeof (U32); assert (pos_block <= 0x0200); } delta += n; } check_output_block_boundary (); return 0;}static int write_root_list (MY_FILE * list){ U8 * p; verbose ("calling: write_root_list ()"); assert (list != NULL); assert (pos_block == 0); assert (list->type == root_list); assert (list->size > 0); for (p = list->file.root_list; (U32)(p - list->file.root_list) < list->size; p += 0x80) { memcpy (output_block+(p-list->file.root_list)%0x0200, p, 0x80); /*verboseU8Array ((output_block+(p-list->file.root_list)%0x0200), 1, 0x80);*/ verboseU32 (fil_sreadU32 (p + 0x74));#ifdef VERBOSE { U32 written_start_block; U32 file_size; U8 * h; written_start_block = fil_sreadU32 ( output_block+(p-list->file.root_list)%0x0200 + 0x74 ); file_size = fil_sreadU32 ( output_block+(p-list->file.root_list)%0x0200 + 0x78 ); for (h = output_block+(p-list->file.root_list)%0x0200; *h; h+=2) if (isprint (*h)) printf ("%c", *h); else printf ("\\0x%02x", *h); printf (": "); verboseU32 (written_start_block); verboseU32 (file_size); }#endif pos_block += (U16)0x80; assert (pos_block <= (U16)0x0200); check_output_block_boundary (); } return 0;}static void ends (void){#ifdef VERBOSE static int called; verbose ("calling: ends ()"); if (called++) verbose ("DANGER: ends called more than once");#endif /* sbfile SDepot BDepot Root Input */ if (output_file != NULL) fclose (output_file);}/* reviewed when done */static void calculate_blocks (void){ MY_FILE big_streams_list; verbose ("calling: calculate_blocks ()"); /* preparing */ init_MY_FILE ((&big_streams_list), MY_FILE_list, Input.size - 5 * sizeof (MY_FILE), NULL, Input.file.MY_FILE_list + 5); /* 5 because the first 5 entries in Input are for bbd_list, BDepot, Root, SDepot and sbfile */ /* calculate sizes */ assert (*(BDepot->blocks) == *(bbd_list->file.block_list)); assert (*(Root->blocks) == size2blocks (Root->size, 0x0200)); verboseU32 ((*(sbfile->blocks))); verboseU32 ((size2blocks (sum_blocks_MY_FILE_list (sbfile) * 0x40, 0x0200))); assert (*(sbfile->blocks) == size2blocks_preserve_zero ( sum_blocks_MY_FILE_list (sbfile) * 0x40, 0x0200)); assert (*(SDepot->blocks) == size2blocks_preserve_zero ( (sum_block_list (SDepot) * sizeof (U32)), 0x0200)); BDepot_blocks = *(BDepot->blocks); SDepot_blocks = *(SDepot->blocks); Root_blocks = *(Root->blocks); sbfile_blocks = *(sbfile->blocks); big_streams_blocks = sum_blocks_MY_FILE_list (&big_streams_list); header_blocks = size2blocks ((19 + BDepot_blocks) * sizeof(U32), 0x0200); /* 19 + because the first 19 U32 doesn't belong to BDepot_blocks, but to header */ /* calculate starting */ sbfile_start_block = 0xffffffffUL + header_blocks; /* if there are sbfile, should start in sbfile_start_block */ Root_start_block = 0xffffffffUL + header_blocks + sbfile_blocks + big_streams_blocks + SDepot_blocks; /* 0xffffffffUL because first block is -1, second 0, third 1 and son on */ if (SDepot_blocks > 0) /* if there are small streams*/ SDepot_start_block = 0xffffffffUL + header_blocks + sbfile_blocks + big_streams_blocks; else /* SDepot_blocks == 0 */ /* if there are not small streams, neither sbfile, neither SDepot */ SDepot_start_block = 0xfffffffeUL; BDepot_start_block = 0xffffffffUL + header_blocks + sbfile_blocks + big_streams_blocks + SDepot_blocks + Root_blocks; verboseU32 (header_blocks); verboseU32 (big_streams_blocks); verboseU32 (sbfile_blocks); verboseU32 (SDepot_blocks);}#undef VERBOSE/* You can use next lines to print some parts of Structure *//*verboseU32Array (SDepot->file.block_list, SDepot->size / sizeof(U32));verboseU8Array (Root->file.root_list, Root->size / 0x80, 0x80);verboseU32Array (BDepot->file.block_list, BDepot->size / sizeof (U32));verboseU32 (*(bbd_list->file.block_list));*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -