Changeset 3426 for trunk/tools/wrc/writeres.c
- Timestamp:
- Apr 19, 2000, 4:46:07 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/wrc/writeres.c
r979 r3426 6 6 */ 7 7 8 /******************************************************************************* 9 * Defined Constants And Macros * 10 *******************************************************************************/ 8 #include "config.h" 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <assert.h> 14 #include <time.h> 15 16 #include "wrc.h" 17 #include "writeres.h" 18 #include "genres.h" 19 #include "newstruc.h" 20 #include "utils.h" 21 22 #ifdef NEED_UNDERSCORE_PREFIX 23 char Underscore[] = "_"; 24 #else 25 char Underscore[] = ""; 26 #endif 27 11 28 #define MASM 1 12 29 #ifdef MASM … … 23 40 #define COMMENT_LINE ";" 24 41 #define OR "or" 42 char s_file_head_str[] = 43 ";/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n" 44 ";/* Source : %s */\n" 45 ";/* Cmdline: %s */\n" 46 ";/* Date : %s */\n" 47 "\n" 48 "\t.386p\n" 49 "\t.model flat\n" 50 "\t.data\n" 51 "\n" 52 ; 53 54 char s_file_tail_str[] = 55 "\tend\n" 56 ";/* <eof> */\n" 57 "\n" 58 ; 59 25 60 #else 26 61 #define DIRECTIVE_BYTE ".byte" … … 36 71 #define COMMENT_LINE 37 72 #define OR "|" 73 74 char s_file_head_str[] = 75 "/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n" 76 "/* Source : %s */\n" 77 "/* Cmdline: %s */\n" 78 "/* Date : %s */\n" 79 "\n" 80 "\t.data\n" 81 "\n" 82 ; 83 84 char s_file_tail_str[] = 85 "/* <eof> */\n" 86 "\n" 87 ; 88 38 89 #endif 39 90 40 /******************************************************************************* 41 * Header Files * 42 *******************************************************************************/ 43 #include "config.h" 44 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <assert.h> 49 #include <time.h> 50 51 #include "wrc.h" 52 #include "writeres.h" 53 #include "genres.h" 54 #include "newstruc.h" 55 #include "utils.h" 56 91 char s_file_autoreg_str[] = 92 "\t.text\n" 93 ".LAuto_Register:\n" 94 "\tpushl\t$%s%s\n" 57 95 #ifdef NEED_UNDERSCORE_PREFIX 58 char Underscore[] = "_"; 96 "\tcall\t_LIBRES_RegisterResources\n" 59 97 #else 60 char Underscore[] = ""; 98 "\tcall\tLIBRES_RegisterResources\n" 61 99 #endif 62 63 char s_file_head_str[] = 64 COMMENT_LINE"/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n" 65 COMMENT_LINE"/* Source : %s */\n" 66 COMMENT_LINE"/* Cmdline: %s */\n" 67 COMMENT_LINE"/* Date : %s */\n" 68 "\n" 69 #ifdef MASM 70 "\t.386p\n" 71 "\t.model flat\n" 72 #endif 73 "\t.data\n" 74 "\n" 75 ; 76 77 char s_file_tail_str[] = 78 #ifdef MASM 79 "\tend\n" 100 "\taddl\t$4,%%esp\n" 101 "\tret\n\n" 102 #ifdef __NetBSD__ 103 ".stabs \"___CTOR_LIST__\",22,0,0,.LAuto_Register\n\n" 80 104 #else 81 "/* <eof> */\n"82 "\n"105 "\t.section .ctors,\"aw\"\n" 106 "\t.long\t.LAuto_Register\n\n" 83 107 #endif 84 ; 85 86 char s_file_autoreg_str[] = 87 #ifdef MASM 88 "" 89 #else 90 "\t.text\n" 91 LOCAL_PREFIX"LAuto_Register:\n" 92 "\tpushl\t$%s%s\n" 93 #ifdef NEED_UNDERSCORE_PREFIX 94 "\tcall\t_LIBRES_RegisterResources\n" 95 #else 96 "\tcall\tLIBRES_RegisterResources\n" 97 #endif 98 "\taddl\t$4,%%esp\n" 99 "\tret\n\n" 100 #ifdef __NetBSD__ 101 ".stabs \"___CTOR_LIST__\",22,0,0,.LAuto_Register\n\n" 102 #else 103 "\t.section .ctors,\"aw\"\n" 104 "\t"DIRECTIVE_LONG"\t.LAuto_Register\n\n" 105 #endif 106 #endif 107 ; 108 ; 108 109 109 110 char h_file_head_str[] = 110 111 112 113 114 115 111 "/*\n" 112 " * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n" 113 " * Source : %s\n" 114 " * Cmdline: %s\n" 115 " * Date : %s" 116 " */\n" 116 117 "\n" 117 "#ifndef __%08lx_H\n"/* This becomes the date of compile */118 119 120 121 122 118 "#ifndef __%08lx_H\n" /* This becomes the date of compile */ 119 "#define __%08lx_H\n" 120 "\n" 121 "#include <wrc_rsc.h>\n" 122 "\n" 123 ; 123 124 124 125 char h_file_tail_str[] = 125 126 127 126 "#endif\n" 127 "/* <eof> */\n\n" 128 ; 128 129 129 130 char _NEResTab[] = "_NEResTab"; … … 132 133 133 134 /* Variables used for resource sorting */ 134 res_count_t *rcarray = NULL; 135 int rccount = 0; 136 int n_id_entries = 0; /* win32 only: Nr of unique ids in the type-level array */137 int n_name_entries = 0; 138 139 static int direntries; 135 res_count_t *rcarray = NULL; /* Type-level count array */ 136 int rccount = 0; /* Nr of entries in the type-level array */ 137 int n_id_entries = 0; /* win32 only: Nr of unique ids in the type-level array */ 138 int n_name_entries = 0; /* win32 only: Nr of unique namess in the type-level array */ 139 140 static int direntries; /* win32 only: Total number of unique resources */ 140 141 141 142 time_t now; … … 143 144 /* 144 145 ***************************************************************************** 145 * Function 146 * Syntax 147 * Input 148 * outname- Filename to write to149 * top- The resource-tree to convert150 * Output 151 * Description 152 * Remarks 146 * Function : write_resfile 147 * Syntax : void write_resfile(char *outname, resource_t *top) 148 * Input : 149 * outname - Filename to write to 150 * top - The resource-tree to convert 151 * Output : 152 * Description : 153 * Remarks : 153 154 ***************************************************************************** 154 155 */ 155 156 void write_resfile(char *outname, resource_t *top) 156 157 { 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 put_dword(res, 0);/* ResSize */172 put_dword(res, 0x00000020);/* HeaderSize */173 put_word(res, 0xffff);/* ResType */174 175 put_word(res, 0xffff);/* ResName */176 177 put_dword(res, 0);/* DataVersion */178 put_word(res, 0);/* Memory options */179 put_word(res, 0);/* Language */180 put_dword(res, 0);/* Version */181 put_dword(res, 0);/* Charateristics */182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 158 FILE *fo; 159 int ret; 160 char zeros[3] = {0, 0, 0}; 161 162 fo = fopen(outname, "wb"); 163 if(!fo) 164 { 165 error("Could not open %s\n", outname); 166 } 167 168 if(win32) 169 { 170 /* Put an empty resource first to signal win32 format */ 171 res_t *res = new_res(); 172 put_dword(res, 0); /* ResSize */ 173 put_dword(res, 0x00000020); /* HeaderSize */ 174 put_word(res, 0xffff); /* ResType */ 175 put_word(res, 0); 176 put_word(res, 0xffff); /* ResName */ 177 put_word(res, 0); 178 put_dword(res, 0); /* DataVersion */ 179 put_word(res, 0); /* Memory options */ 180 put_word(res, 0); /* Language */ 181 put_dword(res, 0); /* Version */ 182 put_dword(res, 0); /* Charateristics */ 183 ret = fwrite(res->data, 1, res->size, fo); 184 if(ret != res->size) 185 { 186 fclose(fo); 187 error("Error writing %s", outname); 188 } 189 free(res); 190 } 191 192 for(; top; top = top->next) 193 { 194 if(!top->binres) 195 continue; 196 197 ret = fwrite(top->binres->data, 1, top->binres->size, fo); 198 if(ret != top->binres->size) 199 { 200 fclose(fo); 201 error("Error writing %s", outname); 202 } 203 if(win32 && (top->binres->size & 0x03)) 204 { 205 /* Write padding */ 206 ret = fwrite(zeros, 1, 4 - (top->binres->size & 0x03), fo); 207 if(ret != 4 - (top->binres->size & 0x03)) 208 { 209 fclose(fo); 210 error("Error writing %s", outname); 211 } 212 } 213 } 214 fclose(fo); 214 215 } 215 216 216 217 /* 217 218 ***************************************************************************** 218 * Function 219 * Syntax 220 * Input 221 * Output 222 * Description 223 * Remarks 219 * Function : write_s_res 220 * Syntax : void write_s_res(FILE *fp, res_t *res) 221 * Input : 222 * Output : 223 * Description : 224 * Remarks : 224 225 ***************************************************************************** 225 226 */ 226 #define BYTESPERLINE 227 #define BYTESPERLINE 8 227 228 void write_s_res(FILE *fp, res_t *res) 228 229 { 229 230 231 232 233 234 235 236 237 fprintf(fp, "\t"DIRECTIVE_BYTE"\t");238 239 240 241 242 243 244 245 246 247 fprintf(fp, "\t"DIRECTIVE_BYTE"\t");248 249 250 251 252 253 254 230 int idx = res->dataidx; 231 int end = res->size; 232 int rest = (end - idx) % BYTESPERLINE; 233 int lines = (end - idx) / BYTESPERLINE; 234 int i, j; 235 236 for(i = 0 ; i < lines; i++) 237 { 238 fprintf(fp, "\t%s\t", DIRECTIVE_BYTE); 239 for(j = 0; j < BYTESPERLINE; j++, idx++) 240 { 241 fprintf(fp, BYTEFRMT"%s", res->data[idx] & 0xff, 242 j == BYTESPERLINE-1 ? "" : ", "); 243 } 244 fprintf(fp, "\n"); 245 } 246 if(rest) 247 { 248 fprintf(fp, "\t%s\t", DIRECTIVE_BYTE); 249 for(j = 0; j < rest; j++, idx++) 250 { 251 fprintf(fp, BYTEFRMT"%s", res->data[idx] & 0xff, 252 j == rest-1 ? "" : ", "); 253 } 254 fprintf(fp, "\n"); 255 } 255 256 } 256 257 257 258 /* 258 259 ***************************************************************************** 259 * Function 260 * Syntax 261 * Input 262 * Output 263 * Description 264 * Remarks 260 * Function : write_name_str 261 * Syntax : void write_name_str(FILE *fp, name_id_t *nid) 262 * Input : 263 * Output : 264 * Description : 265 * Remarks : One level self recursive for string type conversion 265 266 ***************************************************************************** 266 267 */ 267 268 void write_name_str(FILE *fp, name_id_t *nid) 268 269 { 269 270 271 272 273 274 275 276 277 278 279 280 281 282 res.size++;/* We need to write the lenth byte as well */283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 270 res_t res; 271 assert(nid->type == name_str); 272 273 if(!win32 && nid->name.s_name->type == str_char) 274 { 275 res.size = strlen(nid->name.s_name->str.cstr); 276 if(res.size > 254) 277 error("Can't write strings larger than 254 bytes"); 278 if(res.size == 0) 279 internal_error(__FILE__, __LINE__, "Attempt to write empty string"); 280 res.dataidx = 0; 281 res.data = (char *)xmalloc(res.size + 1); 282 res.data[0] = (char)res.size; 283 res.size++; /* We need to write the lenth byte as well */ 284 strcpy(res.data+1, nid->name.s_name->str.cstr); 285 write_s_res(fp, &res); 286 free(res.data); 287 } 288 else if(!win32 && nid->name.s_name->type == str_unicode) 289 { 290 name_id_t lnid; 291 string_t str; 292 293 lnid.type = name_str; 294 lnid.name.s_name = &str; 295 str.type = str_char; 296 str.str.cstr = dupwstr2cstr(nid->name.s_name->str.wstr); 297 write_name_str(fp, &lnid); 298 free(str.str.cstr); 299 } 300 else if(win32 && nid->name.s_name->type == str_char) 301 { 302 name_id_t lnid; 303 string_t str; 304 305 lnid.type = name_str; 306 lnid.name.s_name = &str; 307 str.type = str_unicode; 308 str.str.wstr = dupcstr2wstr(nid->name.s_name->str.cstr); 309 write_name_str(fp, &lnid); 310 free(str.str.wstr); 311 } 312 else if(win32 && nid->name.s_name->type == str_unicode) 313 { 314 res.size = wstrlen(nid->name.s_name->str.wstr); 315 if(res.size > 65534) 316 error("Can't write strings larger than 65534 bytes"); 317 if(res.size == 0) 318 internal_error(__FILE__, __LINE__, "Attempt to write empty string"); 319 res.dataidx = 0; 320 res.data = (char *)xmalloc((res.size + 1) * 2); 321 ((short *)res.data)[0] = (short)res.size; 322 wstrcpy((short *)(res.data+2), nid->name.s_name->str.wstr); 323 res.size *= 2; /* Function writes bytes, not shorts... */ 324 res.size += 2; /* We need to write the length word as well */ 325 write_s_res(fp, &res); 326 free(res.data); 327 } 328 else 329 { 330 internal_error(__FILE__, __LINE__, "Hmm, requested to write a string of unknown type %d", 331 nid->name.s_name->type); 332 } 332 333 } 333 334 334 335 /* 335 336 ***************************************************************************** 336 * Function 337 * Syntax 338 * Input 339 * Output 340 * Description 341 * Remarks 337 * Function : compare_name_id 338 * Syntax : int compare_name_id(name_id_t *n1, name_id_t *n2) 339 * Input : 340 * Output : 341 * Description : 342 * Remarks : 342 343 ***************************************************************************** 343 344 */ 344 345 int compare_name_id(name_id_t *n1, name_id_t *n2) 345 346 { 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 347 if(n1->type == name_ord && n2->type == name_ord) 348 { 349 return n1->name.i_name - n2->name.i_name; 350 } 351 else if(n1->type == name_str && n2->type == name_str) 352 { 353 if(n1->name.s_name->type == str_char 354 && n2->name.s_name->type == str_char) 355 { 356 return strcasecmp(n1->name.s_name->str.cstr, n2->name.s_name->str.cstr); 357 } 358 else if(n1->name.s_name->type == str_unicode 359 && n2->name.s_name->type == str_unicode) 360 { 361 return wstricmp(n1->name.s_name->str.wstr, n2->name.s_name->str.wstr); 362 } 363 else 364 { 365 internal_error(__FILE__, __LINE__, "Can't yet compare strings of mixed type"); 366 } 367 } 368 else if(n1->type == name_ord && n2->type == name_str) 369 return 1; 370 else if(n1->type == name_str && n2->type == name_ord) 371 return -1; 372 else 373 internal_error(__FILE__, __LINE__, "Comparing name-ids with unknown types (%d, %d)", 374 n1->type, n2->type); 375 376 return 0; /* Keep the compiler happy */ 376 377 } 377 378 378 379 /* 379 380 ***************************************************************************** 380 * Function 381 * Syntax 382 * Input 383 * Output 384 * Description 385 * Remarks 381 * Function : find_counter 382 * Syntax : res_count_t *find_counter(name_id_t *type) 383 * Input : 384 * Output : 385 * Description : 386 * Remarks : 386 387 ***************************************************************************** 387 388 */ 388 389 res_count_t *find_counter(name_id_t *type) 389 390 { 390 391 392 393 394 395 396 391 int i; 392 for(i = 0; i < rccount; i++) 393 { 394 if(!compare_name_id(type, &(rcarray[i].type))) 395 return &rcarray[i]; 396 } 397 return NULL; 397 398 } 398 399 399 400 /* 400 401 ***************************************************************************** 401 * Function 402 * Syntax 403 * Input 404 * Output 405 * Description 406 * Remarks 407 * 408 * 409 * 410 * 402 * Function : count_resources 403 * Syntax : res_count_t *count_resources(resource_t *top) 404 * Input : 405 * Output : 406 * Description : 407 * Remarks : The whole lot is converted into arrays because they are 408 * easy sortable. Makes the lot almost unreadable, but it 409 * works (I hope). Basically you have to keep in mind that 410 * the lot is a three-dimensional structure for win32 and a 411 * two-dimensional structure for win16. 411 412 ***************************************************************************** 412 413 */ 413 #define RCT(v) 414 #define RCT(v) (*((resource_t **)(v))) 414 415 /* qsort sorting function */ 415 416 int sort_name_id(const void *e1, const void *e2) 416 417 { 417 418 return compare_name_id(RCT(e1)->name, RCT(e2)->name); 418 419 } 419 420 420 421 int sort_language(const void *e1, const void *e2) 421 422 { 422 423 424 425 426 423 assert((RCT(e1)->lan) != NULL); 424 assert((RCT(e2)->lan) != NULL); 425 426 return MAKELANGID(RCT(e1)->lan->id, RCT(e1)->lan->sub) 427 - MAKELANGID(RCT(e2)->lan->id, RCT(e2)->lan->sub); 427 428 } 428 429 #undef RCT 429 #define RCT(v) 430 #define RCT(v) ((res_count_t *)(v)) 430 431 int sort_type(const void *e1, const void *e2) 431 432 { 432 433 return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type)); 433 434 } 434 435 #undef RCT … … 436 437 void count_resources(resource_t *top) 437 438 { 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 439 resource_t *rsc; 440 res_count_t *rcp; 441 name_id_t nid; 442 int i, j; 443 444 for(rsc = top; rsc; rsc = rsc->next) 445 { 446 if(!rsc->binres) 447 continue; 448 switch(rsc->type) 449 { 450 case res_dlgex: 451 nid.name.i_name = WRC_RT_DIALOG; 452 nid.type = name_ord; 453 break; 454 case res_menex: 455 nid.name.i_name = WRC_RT_MENU; 456 nid.type = name_ord; 457 break; 458 case res_usr: 459 nid = *(rsc->res.usr->type); 460 break; 461 default: 462 nid.name.i_name = rsc->type; 463 nid.type = name_ord; 464 } 465 466 if((rcp = find_counter(&nid)) == NULL) 467 { 468 /* Count the number of uniq ids and names */ 469 470 if(nid.type == name_ord) 471 n_id_entries++; 472 else 473 n_name_entries++; 474 475 if(!rcarray) 476 { 477 rcarray = (res_count_t *)xmalloc(sizeof(res_count_t)); 478 rccount = 1; 479 rcarray[0].count = 1; 480 rcarray[0].type = nid; 481 rcarray[0].rscarray = (resource_t **)xmalloc(sizeof(resource_t *)); 482 rcarray[0].rscarray[0] = rsc; 483 } 484 else 485 { 486 rccount++; 487 rcarray = (res_count_t *)xrealloc(rcarray, rccount * sizeof(res_count_t)); 488 rcarray[rccount-1].count = 1; 489 rcarray[rccount-1].type = nid; 490 rcarray[rccount-1].rscarray = (resource_t **)xmalloc(sizeof(resource_t *)); 491 rcarray[rccount-1].rscarray[0] = rsc; 492 } 493 } 494 else 495 { 496 rcp->count++; 497 rcp->rscarray = (resource_t **)xrealloc(rcp->rscarray, rcp->count * sizeof(resource_t *)); 498 rcp->rscarray[rcp->count-1] = rsc; 499 } 500 } 501 502 if(!win32) 503 { 504 /* We're done, win16 requires no special sorting */ 505 return; 506 } 507 508 /* We now have a unsorted list of types with an array of res_count_t 509 * in rcarray[0..rccount-1]. And we have names of one type in the 510 * rcarray[x].rsc[0..rcarray[x].count-1] arrays. 511 * The list needs to be sorted for win32's top level tree structure. 512 */ 513 514 /* Sort the types */ 515 if(rccount > 1) 516 qsort(rcarray, rccount, sizeof(rcarray[0]), sort_type); 517 518 /* Now sort the name-id arrays */ 519 for(i = 0; i < rccount; i++) 520 { 521 if(rcarray[i].count > 1) 522 qsort(rcarray[i].rscarray, rcarray[i].count, sizeof(rcarray[0].rscarray[0]), sort_name_id); 523 } 524 525 /* Now split the name-id arrays into name/language 526 * subs. Don't look at the awfull expressions... 527 * We do this by taking the array elements out of rscarray and putting 528 * together a new array in rsc32array. 529 */ 530 for(i = 0; i < rccount; i++) 531 { 532 res_count_t *rcap; 533 534 assert(rcarray[i].count >= 1); 535 536 /* rcap points to the current type we are dealing with */ 537 rcap = &(rcarray[i]); 538 539 /* Insert the first name-id */ 540 rcap->rsc32array = (res32_count_t *)xmalloc(sizeof(res32_count_t)); 541 rcap->count32 = 1; 542 rcap->rsc32array[0].rsc = (resource_t **)xmalloc(sizeof(resource_t *)); 543 rcap->rsc32array[0].count = 1; 544 rcap->rsc32array[0].rsc[0] = rcap->rscarray[0]; 545 if(rcap->rscarray[0]->name->type == name_ord) 546 { 547 rcap->n_id_entries = 1; 548 rcap->n_name_entries = 0; 549 } 550 else 551 { 552 rcap->n_id_entries = 0; 553 rcap->n_name_entries = 1; 554 } 555 556 /* Now loop over the resting resources of the current type 557 * to find duplicate names (which should have different 558 * languages). 559 */ 560 for(j = 1; j < rcap->count; j++) 561 { 562 res32_count_t *r32cp; 563 564 /* r32cp points to the current res32_count structure 565 * that holds the resource name we are processing. 566 */ 567 r32cp = &(rcap->rsc32array[rcap->count32-1]); 568 569 if(!compare_name_id(r32cp->rsc[0]->name, rcarray[i].rscarray[j]->name)) 570 { 571 /* Names are the same, add to list */ 572 r32cp->count++; 573 r32cp->rsc = (resource_t **)xrealloc(r32cp->rsc, r32cp->count * sizeof(resource_t *)); 574 r32cp->rsc[r32cp->count-1] = rcap->rscarray[j]; 575 } 576 else 577 { 578 /* New name-id, sort the old one by 579 * language and create new list 580 */ 581 if(r32cp->count > 1) 582 qsort(r32cp->rsc, r32cp->count, sizeof(r32cp->rsc[0]), sort_language); 583 rcap->count32++; 584 rcap->rsc32array = (res32_count_t*)xrealloc(rcap->rsc32array, rcap->count32 * sizeof(res32_count_t)); 585 rcap->rsc32array[rcap->count32-1].rsc = (resource_t **)xmalloc(sizeof(resource_t *)); 586 rcap->rsc32array[rcap->count32-1].count = 1; 587 rcap->rsc32array[rcap->count32-1].rsc[0] = rcap->rscarray[j]; 588 589 if(rcap->rscarray[j]->name->type == name_ord) 590 rcap->n_id_entries++; 591 else 592 rcap->n_name_entries++; 593 } 594 } 595 /* Also sort the languages of the last name group */ 596 if(rcap->rsc32array[rcap->count32-1].count > 1) 597 qsort(rcap->rsc32array[rcap->count32-1].rsc, 598 rcap->rsc32array[rcap->count32-1].count, 599 sizeof(rcap->rsc32array[rcap->count32-1].rsc[0]), 600 sort_language); 601 } 601 602 } 602 603 603 604 /* 604 605 ***************************************************************************** 605 * Function 606 * Syntax 607 * Input 608 * Output 609 * Description 610 * Remarks 606 * Function : write_pe_segment 607 * Syntax : void write_pe_segment(FILE *fp, resource_t *top) 608 * Input : 609 * Output : 610 * Description : 611 * Remarks : 611 612 ***************************************************************************** 612 613 */ 613 614 void write_pe_segment(FILE *fp, resource_t *top) 614 615 { 615 int i; 616 617 fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n"); 618 fprintf(fp, "%s%s:\n", prefix, _PEResTab); 619 fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _PEResTab); 620 /* Flags */ 621 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); 622 /* Time/Date stamp */ 623 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now); 624 /* Version */ 625 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */ 626 /* # of id entries, # of name entries */ 627 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d, %d\n", n_name_entries, n_id_entries); 628 629 /* Write the type level of the tree */ 630 for(i = 0; i < rccount; i++) 631 { 632 res_count_t *rcp; 633 char *label; 634 635 rcp = &rcarray[i]; 636 637 /* TypeId */ 638 if(rcp->type.type == name_ord) 639 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rcp->type.name.i_name); 640 else 641 { 642 char *name = prep_nid_for_label(&(rcp->type)); 643 fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s_%s_typename - %s%s) "OR" "HEXBIT31"\n", 644 prefix, 645 name, 646 prefix, 647 _PEResTab); 648 } 649 /* Offset */ 650 label = prep_nid_for_label(&(rcp->type)); 651 fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s - %s%s) "OR" "HEXBIT31"\n", 652 label, 653 prefix, 654 _PEResTab); 655 } 656 657 /* Write the name level of the tree */ 658 659 for(i = 0; i < rccount; i++) 660 { 661 res_count_t *rcp; 662 char *typelabel; 663 char *namelabel; 664 int j; 665 666 rcp = &rcarray[i]; 667 668 typelabel = xstrdup(prep_nid_for_label(&(rcp->type))); 669 fprintf(fp, LOCAL_PREFIX"L%s:\n", typelabel); 670 671 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* Flags */ 672 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now); /* TimeDate */ 673 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */ 674 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries); 675 for(j = 0; j < rcp->count32; j++) 676 { 677 resource_t *rsc = rcp->rsc32array[j].rsc[0]; 678 /* NameId */ 679 if(rsc->name->type == name_ord) 680 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rsc->name->name.i_name); 681 else 682 { 683 char *label = prep_nid_for_label(rsc->name); 684 fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s_%d_%s_name - %s%s) "OR" "HEXBIT31"\n", 685 prefix, 686 rsc->type, 687 label, 688 prefix, 689 _PEResTab); 690 } 691 /* Maybe FIXME: Unescape the tree (ommit 0x80000000) and 692 * put the offset to the resource data entry. 693 * ?? Is unescaping worth while ?? 694 */ 695 /* Offset */ 696 namelabel = prep_nid_for_label(rsc->name); 697 fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s_%s - %s%s) "OR" "HEXBIT31"\n", 698 typelabel, 699 namelabel, 700 prefix, 701 _PEResTab); 702 } 703 free(typelabel); 704 } 705 706 /* Write the language level of the tree */ 707 708 for(i = 0; i < rccount; i++) 709 { 710 res_count_t *rcp; 711 char *namelabel; 712 char *typelabel; 713 int j; 714 715 rcp = &rcarray[i]; 716 typelabel = xstrdup(prep_nid_for_label(&(rcp->type))); 717 718 for(j = 0; j < rcp->count32; j++) 719 { 720 res32_count_t *r32cp = &(rcp->rsc32array[j]); 721 int k; 722 723 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name)); 724 fprintf(fp, LOCAL_PREFIX"L%s_%s:\n", typelabel, namelabel); 725 726 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* Flags */ 727 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now); /* TimeDate */ 728 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */ 729 fprintf(fp, "\t"DIRECTIVE_WORD"\t0, %d\n", r32cp->count); 730 731 for(k = 0; k < r32cp->count; k++) 732 { 733 resource_t *rsc = r32cp->rsc[k]; 734 assert(rsc->lan != NULL); 735 /* LanguageId */ 736 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0); 737 /* Offset */ 738 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"L%s_%s_%d - %s%s\n", 739 typelabel, 740 namelabel, 741 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0, 742 prefix, 743 _PEResTab); 744 } 745 free(namelabel); 746 } 747 free(typelabel); 748 } 749 750 /* Write the resource table itself */ 751 fprintf(fp, "%s_ResourceDirectory:\n", prefix); 752 fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDirectory\n", prefix); 753 direntries = 0; 754 755 for(i = 0; i < rccount; i++) 756 { 757 res_count_t *rcp; 758 char *namelabel; 759 char *typelabel; 760 int j; 761 762 rcp = &rcarray[i]; 763 typelabel = xstrdup(prep_nid_for_label(&(rcp->type))); 764 765 for(j = 0; j < rcp->count32; j++) 766 { 767 res32_count_t *r32cp = &(rcp->rsc32array[j]); 768 int k; 769 770 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name)); 771 772 for(k = 0; k < r32cp->count; k++) 773 { 774 resource_t *rsc = r32cp->rsc[k]; 775 776 assert(rsc->lan != NULL); 777 778 fprintf(fp, LOCAL_PREFIX"L%s_%s_%d:\n", 779 typelabel, 780 namelabel, 781 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0); 782 783 /* Data RVA */ 784 fprintf(fp, "\t"DIRECTIVE_LONG"\t%s%s_data - %s%s\n", 785 prefix, 786 rsc->c_name, 787 prefix, 788 _PEResTab); 789 /* Size */ 790 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", 791 rsc->binres->size - rsc->binres->dataidx); 792 /* CodePage */ 793 fprintf(fp, "\t"DIRECTIVE_LONG"\t%ld\n", codepage); 794 /* Reserved */ 795 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); 796 797 direntries++; 798 } 799 free(namelabel); 800 } 801 free(typelabel); 802 } 616 int i; 617 618 fprintf(fp, "\t%s\t4\n", DIRECTIVE_ALIGN); 619 fprintf(fp, "%s%s:\n", prefix, _PEResTab); 620 fprintf(fp, "\t%s\t%s%s\n", DIRECTIVE_GLOBAL, prefix, _PEResTab); 621 /* Flags */ 622 fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG); 623 /* Time/Date stamp */ 624 fprintf(fp, "\t%s\t"LONGFRMT"\n", DIRECTIVE_LONG, (long)now); 625 /* Version */ 626 fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG); /* FIXME: must version be filled out? */ 627 /* # of id entries, # of name entries */ 628 fprintf(fp, "\t%s\t%d, %d\n", DIRECTIVE_WORD, n_name_entries, n_id_entries); 629 630 /* Write the type level of the tree */ 631 for(i = 0; i < rccount; i++) 632 { 633 res_count_t *rcp; 634 char *label; 635 636 rcp = &rcarray[i]; 637 638 /* TypeId */ 639 if(rcp->type.type == name_ord) 640 fprintf(fp, "\t%s\t%d\n", DIRECTIVE_LONG, rcp->type.name.i_name); 641 else 642 { 643 char *name = prep_nid_for_label(&(rcp->type)); 644 fprintf(fp, "\t%s\t(%s_%s_typename - %s%s) %s %s\n", 645 DIRECTIVE_LONG, prefix, 646 name, 647 prefix, 648 _PEResTab, OR, HEXBIT31); 649 } 650 /* Offset */ 651 label = prep_nid_for_label(&(rcp->type)); 652 fprintf(fp, "\t%s\t(%sL%s - %s%s) %s %s\n", 653 DIRECTIVE_LONG, LOCAL_PREFIX, label, 654 prefix, 655 _PEResTab, OR, HEXBIT31); 656 } 657 658 /* Write the name level of the tree */ 659 660 for(i = 0; i < rccount; i++) 661 { 662 res_count_t *rcp; 663 char *typelabel; 664 char *namelabel; 665 int j; 666 667 rcp = &rcarray[i]; 668 669 typelabel = xstrdup(prep_nid_for_label(&(rcp->type))); 670 fprintf(fp, "%sL%s:\n", LOCAL_PREFIX, typelabel); 671 672 fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG); /* Flags */ 673 fprintf(fp, "\t%s\t"LONGFRMT"\n", DIRECTIVE_LONG, (long)now); /* TimeDate */ 674 fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG); /* FIXME: must version be filled out? */ 675 fprintf(fp, "\t%s\t%d, %d\n", DIRECTIVE_WORD, rcp->n_name_entries, rcp->n_id_entries); 676 for(j = 0; j < rcp->count32; j++) 677 { 678 resource_t *rsc = rcp->rsc32array[j].rsc[0]; 679 /* NameId */ 680 if(rsc->name->type == name_ord) 681 fprintf(fp, "\t%s\t%d\n", DIRECTIVE_LONG, rsc->name->name.i_name); 682 else 683 { 684 fprintf(fp, "\t%s\t(%s%s_name - %s%s) %s %s\n", 685 DIRECTIVE_LONG, prefix, 686 rsc->c_name, 687 prefix, 688 _PEResTab, OR, HEXBIT31); 689 } 690 /* Maybe FIXME: Unescape the tree (ommit 0x80000000) and 691 * put the offset to the resource data entry. 692 * ?? Is unescaping worth while ?? 693 */ 694 /* Offset */ 695 namelabel = prep_nid_for_label(rsc->name); 696 fprintf(fp, "\t%s\t(%sL%s_%s - %s%s) %s %s\n", 697 DIRECTIVE_LONG, LOCAL_PREFIX, typelabel, 698 namelabel, 699 prefix, 700 _PEResTab, OR, HEXBIT31); 701 } 702 free(typelabel); 703 } 704 705 /* Write the language level of the tree */ 706 707 for(i = 0; i < rccount; i++) 708 { 709 res_count_t *rcp; 710 char *namelabel; 711 char *typelabel; 712 int j; 713 714 rcp = &rcarray[i]; 715 typelabel = xstrdup(prep_nid_for_label(&(rcp->type))); 716 717 for(j = 0; j < rcp->count32; j++) 718 { 719 res32_count_t *r32cp = &(rcp->rsc32array[j]); 720 int k; 721 722 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name)); 723 fprintf(fp, "%sL%s_%s:\n", LOCAL_PREFIX, typelabel, namelabel); 724 725 fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG); /* Flags */ 726 fprintf(fp, "\t%s\t"LONGFRMT"\n", DIRECTIVE_LONG, (long)now); /* TimeDate */ 727 fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG); /* FIXME: must version be filled out? */ 728 fprintf(fp, "\t%s\t0, %d\n", DIRECTIVE_WORD, r32cp->count); 729 730 for(k = 0; k < r32cp->count; k++) 731 { 732 resource_t *rsc = r32cp->rsc[k]; 733 assert(rsc->lan != NULL); 734 /* LanguageId */ 735 fprintf(fp, "\t%s\t"LONGFRMT"\n", DIRECTIVE_LONG, rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0); 736 /* Offset */ 737 fprintf(fp, "\t%s\t%sL%s_%s_%d - %s%s\n", 738 DIRECTIVE_LONG, LOCAL_PREFIX, typelabel, 739 namelabel, 740 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0, 741 prefix, 742 _PEResTab); 743 } 744 free(namelabel); 745 } 746 free(typelabel); 747 } 748 749 /* Write the resource table itself */ 750 fprintf(fp, "%s_ResourceDirectory:\n", prefix); 751 fprintf(fp, "\t%s\t%s_ResourceDirectory\n", DIRECTIVE_GLOBAL, prefix); 752 direntries = 0; 753 754 for(i = 0; i < rccount; i++) 755 { 756 res_count_t *rcp; 757 char *namelabel; 758 char *typelabel; 759 int j; 760 761 rcp = &rcarray[i]; 762 typelabel = xstrdup(prep_nid_for_label(&(rcp->type))); 763 764 for(j = 0; j < rcp->count32; j++) 765 { 766 res32_count_t *r32cp = &(rcp->rsc32array[j]); 767 int k; 768 769 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name)); 770 771 for(k = 0; k < r32cp->count; k++) 772 { 773 resource_t *rsc = r32cp->rsc[k]; 774 775 assert(rsc->lan != NULL); 776 777 fprintf(fp, "%sL%s_%s_%d:\n", 778 LOCAL_PREFIX, typelabel, 779 namelabel, 780 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0); 781 782 /* Data RVA */ 783 fprintf(fp, "\t%s\t%s%s_data - %s%s\n", 784 DIRECTIVE_LONG, prefix, 785 rsc->c_name, 786 prefix, 787 _PEResTab); 788 /* Size */ 789 fprintf(fp, "\t%s\t%d\n", 790 DIRECTIVE_LONG, rsc->binres->size - rsc->binres->dataidx); 791 /* CodePage */ 792 fprintf(fp, "\t%s\t%ld\n", DIRECTIVE_LONG, codepage); 793 /* Reserved */ 794 fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG); 795 796 direntries++; 797 } 798 free(namelabel); 799 } 800 free(typelabel); 801 } 803 802 } 804 803 805 804 /* 806 805 ***************************************************************************** 807 * Function 808 * Syntax 809 * Input 810 * Output 811 * Description 812 * Remarks 806 * Function : write_ne_segment 807 * Syntax : void write_ne_segment(FILE *fp, resource_t *top) 808 * Input : 809 * Output : 810 * Description : 811 * Remarks : 813 812 ***************************************************************************** 814 813 */ 815 814 void write_ne_segment(FILE *fp, resource_t *top) 816 815 { 817 818 819 fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n");820 821 fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _NEResTab);822 823 824 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d\n", alignment_pwr);825 826 827 828 829 830 831 832 833 fprintf(fp, "\t"DIRECTIVE_WORD"\t"SHORTFRMT"\n", rcp->type.name.i_name | 0x8000);834 835 fprintf(fp, "\t"DIRECTIVE_WORD"\t%s_%s_typename - %s%s\n",836 837 838 839 840 841 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d\n", rcp->count);842 843 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");844 845 846 816 int i, j; 817 818 fprintf(fp, "\t%s\t4\n", DIRECTIVE_ALIGN); 819 fprintf(fp, "%s%s:\n", prefix, _NEResTab); 820 fprintf(fp, "\t%s\t%s%s\n", DIRECTIVE_GLOBAL, prefix, _NEResTab); 821 822 /* AlignmentShift */ 823 fprintf(fp, "\t%s\t%d\n", DIRECTIVE_WORD, alignment_pwr); 824 825 /* TypeInfo */ 826 for(i = 0; i < rccount; i++) 827 { 828 res_count_t *rcp = &rcarray[i]; 829 830 /* TypeId */ 831 if(rcp->type.type == name_ord) 832 fprintf(fp, "\t%s\t"SHORTFRMT"\n", DIRECTIVE_WORD, rcp->type.name.i_name | 0x8000); 833 else 834 fprintf(fp, "\t%s\t%s_%s_typename - %s%s\n", 835 DIRECTIVE_WORD, prefix, 836 rcp->type.name.s_name->str.cstr, 837 prefix, 838 _NEResTab); 839 /* ResourceCount */ 840 fprintf(fp, "\t%s\t%d\n", DIRECTIVE_WORD, rcp->count); 841 /* Reserved */ 842 fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG); 843 /* NameInfo */ 844 for(j = 0; j < rcp->count; j++) 845 { 847 846 /* 848 847 * VERY IMPORTANT: … … 853 852 * All other things are as the MS doc describes (alignment etc.) 854 853 */ 855 856 fprintf(fp, "\t"DIRECTIVE_WORD"\t(%s%s_data - %s%s) >> %d\n",857 858 859 860 861 862 863 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d\n",864 865 866 fprintf(fp, "\t"DIRECTIVE_WORD"\t"SHORTFRMT"\n", (WORD)rcp->rscarray[j]->memopt);867 868 869 fprintf(fp, "\t"DIRECTIVE_WORD"\t"SHORTFRMT"\n", rcp->rscarray[j]->name->name.i_name | 0x8000);870 871 fprintf(fp, "\t"DIRECTIVE_WORD"\t%s%s_name - %s%s\n",872 873 874 875 876 877 fprintf(fp, "\t"DIRECTIVE_WORD"\t0, 0\n");878 879 880 881 fprintf(fp, "\t"DIRECTIVE_WORD"\t0\n");854 /* Offset */ 855 fprintf(fp, "\t%s\t(%s%s_data - %s%s) >> %d\n", 856 DIRECTIVE_WORD, prefix, 857 rcp->rscarray[j]->c_name, 858 prefix, 859 _NEResTab, 860 alignment_pwr); 861 /* Length */ 862 fprintf(fp, "\t%s\t%d\n", 863 DIRECTIVE_WORD, rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx); 864 /* Flags */ 865 fprintf(fp, "\t%s\t"SHORTFRMT"\n", DIRECTIVE_WORD, (WORD)rcp->rscarray[j]->memopt); 866 /* Id */ 867 if(rcp->rscarray[j]->name->type == name_ord) 868 fprintf(fp, "\t%s\t"SHORTFRMT"\n", DIRECTIVE_WORD, rcp->rscarray[j]->name->name.i_name | 0x8000); 869 else 870 fprintf(fp, "\t%s\t%s%s_name - %s%s\n", 871 DIRECTIVE_WORD, prefix, 872 rcp->rscarray[j]->c_name, 873 prefix, 874 _NEResTab); 875 /* Handle and Usage */ 876 fprintf(fp, "\t%s\t0, 0\n", DIRECTIVE_WORD); 877 } 878 } 879 /* EndTypes */ 880 fprintf(fp, "\t%s\t0\n", DIRECTIVE_WORD); 882 881 } 883 882 884 883 /* 885 884 ***************************************************************************** 886 * Function 887 * Syntax 888 * Input 889 * Output 890 * Description 891 * Remarks 885 * Function : write_rsc_names 886 * Syntax : void write_rsc_names(FILE *fp, resource_t *top) 887 * Input : 888 * Output : 889 * Description : 890 * Remarks : 892 891 ***************************************************************************** 893 892 */ 894 893 void write_rsc_names(FILE *fp, resource_t *top) 895 894 { 896 int i, j; 897 898 if(win32) 899 { 900 /* Write the names */ 901 902 for(i = 0; i < rccount; i++) 903 { 904 res_count_t *rcp; 905 906 rcp = &rcarray[i]; 907 908 if(rcp->type.type == name_str) 909 { 910 char *name = prep_nid_for_label(&(rcp->type)); 911 fprintf(fp, "%s_%s_typename:\n", 912 prefix, 913 name); 914 write_name_str(fp, &(rcp->type)); 915 } 916 917 for(j = 0; j < rcp->count32; j++) 918 { 919 resource_t *rsc = rcp->rsc32array[j].rsc[0]; 920 921 if(rsc->name->type == name_str) 922 { 923 char *name = prep_nid_for_label(rsc->name); 924 925 fprintf(fp, "%s_%d_%s_name:\n", 926 prefix, rsc->type, 927 name); 928 write_name_str(fp, rsc->name); 929 } 930 } 931 } 932 } 933 else 934 { 935 /* ResourceNames */ 936 for(i = 0; i < rccount; i++) 937 { 938 res_count_t *rcp = &rcarray[i]; 939 940 for(j = 0; j < rcp->count; j++) 941 { 942 if(rcp->type.type == name_str) 943 { 944 fprintf(fp, "%s_%s_typename:\n", 945 prefix, 946 rcp->type.name.s_name->str.cstr); 947 write_name_str(fp, &(rcp->type)); 948 } 949 if(rcp->rscarray[j]->name->type == name_str) 950 { 951 fprintf(fp, "%s%s_name:\n", 952 prefix, 953 rcp->rscarray[j]->c_name); 954 write_name_str(fp, rcp->rscarray[j]->name); 955 } 956 } 957 } 958 /* EndNames */ 959 960 /* This is to end the NE resource table */ 961 if(create_dir) 962 fprintf(fp, "\t"DIRECTIVE_BYTE"\t0\n"); 963 } 964 965 fprintf(fp, "\n"); 895 int i, j; 896 897 if(win32) 898 { 899 /* Write the names */ 900 901 for(i = 0; i < rccount; i++) 902 { 903 res_count_t *rcp; 904 905 rcp = &rcarray[i]; 906 907 if(rcp->type.type == name_str) 908 { 909 char *name = prep_nid_for_label(&(rcp->type)); 910 fprintf(fp, "%s_%s_typename:\n", 911 prefix, 912 name); 913 write_name_str(fp, &(rcp->type)); 914 } 915 916 for(j = 0; j < rcp->count32; j++) 917 { 918 resource_t *rsc = rcp->rsc32array[j].rsc[0]; 919 920 if(rsc->name->type == name_str) 921 { 922 fprintf(fp, "%s%s_name:\n", 923 prefix, 924 rsc->c_name); 925 write_name_str(fp, rsc->name); 926 } 927 } 928 } 929 } 930 else 931 { 932 /* ResourceNames */ 933 for(i = 0; i < rccount; i++) 934 { 935 res_count_t *rcp = &rcarray[i]; 936 937 for(j = 0; j < rcp->count; j++) 938 { 939 if(rcp->type.type == name_str) 940 { 941 fprintf(fp, "%s_%s_typename:\n", 942 prefix, 943 rcp->type.name.s_name->str.cstr); 944 write_name_str(fp, &(rcp->type)); 945 } 946 if(rcp->rscarray[j]->name->type == name_str) 947 { 948 fprintf(fp, "%s%s_name:\n", 949 prefix, 950 rcp->rscarray[j]->c_name); 951 write_name_str(fp, rcp->rscarray[j]->name); 952 } 953 } 954 } 955 /* EndNames */ 956 957 /* This is to end the NE resource table */ 958 if(create_dir) 959 fprintf(fp, "\t%s\t0\n", DIRECTIVE_BYTE); 960 } 961 962 fprintf(fp, "\n"); 966 963 } 967 964 968 965 /* 969 966 ***************************************************************************** 970 * Function 971 * Syntax 972 * Input 973 * outname- Filename to write to974 * top- The resource-tree to convert975 * Output 976 * Description 977 * Remarks 967 * Function : write_s_file 968 * Syntax : void write_s_file(char *outname, resource_t *top) 969 * Input : 970 * outname - Filename to write to 971 * top - The resource-tree to convert 972 * Output : 973 * Description : 974 * Remarks : 978 975 ***************************************************************************** 979 976 */ 980 977 void write_s_file(char *outname, resource_t *top) 981 978 { 982 FILE *fo; 983 resource_t *rsc; 984 985 fo = fopen(outname, "wt"); 986 if(!fo) 987 { 988 error("Could not open %s\n", outname); 989 return; 990 } 991 992 { 993 char *s, *p; 994 now = time(NULL); 995 s = ctime(&now); 996 p = strchr(s, '\n'); 997 if(p) *p = '\0'; 998 fprintf(fo, s_file_head_str, input_name ? input_name : "stdin", 999 cmdline, s); 1000 } 1001 1002 /* Get an idea how many we have and restructure the tables */ 1003 count_resources(top); 1004 1005 /* First write the segment tables */ 1006 if(create_dir) 1007 { 1008 if(win32) 1009 write_pe_segment(fo, top); 1010 else 1011 write_ne_segment(fo, top); 1012 } 1013 1014 /* Dump the names */ 1015 write_rsc_names(fo, top); 1016 1017 if(create_dir) 1018 fprintf(fo, LOCAL_PREFIX"LResTabEnd:\n"); 1019 1020 if(!indirect_only) 1021 { 1022 /* Write the resource data */ 1023 fprintf(fo, "\n"COMMENT_LINE"/* Resource binary data */\n\n"); 1024 for(rsc = top; rsc; rsc = rsc->next) 1025 { 1026 if(!rsc->binres) 1027 continue; 1028 1029 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t%d\n", win32 ? 4 : alignment); 1030 fprintf(fo, "%s%s_data:\n", prefix, rsc->c_name); 1031 if(global) 1032 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s_data\n", prefix, rsc->c_name); 1033 1034 write_s_res(fo, rsc->binres); 1035 1036 fprintf(fo, "\n"); 1037 } 1038 1039 if(create_dir) 1040 { 1041 /* Add a resource descriptor for built-in and elf-dlls */ 1042 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n"); 1043 fprintf(fo, "%s_ResourceDescriptor:\n", prefix); 1044 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDescriptor\n", prefix); 1045 fprintf(fo, "%s_ResourceTable:\n", prefix); 1046 if(global) 1047 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceTable\n", prefix); 1048 fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, win32 ? _PEResTab : _NEResTab); 1049 fprintf(fo, "%s_NumberOfResources:\n", prefix); 1050 if(global) 1051 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_NumberOfResources\n", prefix); 1052 fprintf(fo, "\t"DIRECTIVE_LONG"\t%d\n", direntries); 1053 fprintf(fo, "%s_ResourceSectionSize:\n", prefix); 1054 if(global) 1055 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceSectionSize\n", prefix); 1056 fprintf(fo, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"LResTabEnd - %s%s\n", prefix, win32 ? _PEResTab : _NEResTab); 1057 if(win32) 1058 { 1059 fprintf(fo, "%s_ResourcesEntries:\n", prefix); 1060 if(global) 1061 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourcesEntries\n", prefix); 1062 fprintf(fo, "\t"DIRECTIVE_LONG"\t%s_ResourceDirectory\n", prefix); 1063 } 1064 } 1065 } 1066 1067 if(indirect) 1068 { 1069 /* Write the indirection structures */ 1070 fprintf(fo, "\n"COMMENT_LINE"/* Resource indirection structures */\n\n"); 1071 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n"); 1072 for(rsc = top; rsc; rsc = rsc->next) 1073 { 1074 int type; 1075 char *type_name = NULL; 1076 char *label; 1077 1078 if(!rsc->binres) 1079 continue; 1080 1081 switch(rsc->type) 1082 { 1083 case res_menex: 1084 type = WRC_RT_MENU; 1085 break; 1086 case res_dlgex: 1087 type = WRC_RT_DIALOG; 1088 break; 1089 case res_usr: 1090 assert(rsc->res.usr->type != NULL); 1091 type_name = prep_nid_for_label(rsc->res.usr->type); 1092 type = 0; 1093 break; 1094 default: 1095 type = rsc->type; 1096 } 1097 1098 /* 1099 * This follows a structure like: 1100 * struct wrc_resource { 1101 * INT32 id; 1102 * RSCNAME *resname; 1103 * INT32 restype; 1104 * RSCNAME *typename; 1105 * void *data; 1106 * UINT32 datasize; 1107 * }; 1108 * The 'RSCNAME' is a pascal-style string where the 1109 * first byte/word denotes the size and the rest the string 1110 * itself. 1111 */ 1112 fprintf(fo, "%s%s:\n", prefix, rsc->c_name); 1113 if(global) 1114 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, rsc->c_name); 1115 label = prep_nid_for_label(rsc->name); 1116 fprintf(fo, "\t"DIRECTIVE_LONG"\t%d, %s%s%s%s, %d, %s%s%s%s, %s%s_data, %d\n", 1117 rsc->name->type == name_ord ? rsc->name->name.i_name : 0, 1118 rsc->name->type == name_ord ? "0" : prefix, 1119 rsc->name->type == name_ord ? "" : "_", 1120 rsc->name->type == name_ord ? "" : label, 1121 rsc->name->type == name_ord ? "" : "_name", 1122 type, 1123 type ? "0" : prefix, 1124 type ? "" : "_", 1125 type ? "" : type_name, 1126 type ? "" : "_typename", 1127 prefix, 1128 rsc->c_name, 1129 rsc->binres->size - rsc->binres->dataidx); 1130 fprintf(fo, "\n"); 1131 } 1132 fprintf(fo, "\n"); 1133 1134 /* Write the indirection table */ 1135 fprintf(fo, COMMENT_LINE"/* Resource indirection table */\n\n"); 1136 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n"); 1137 fprintf(fo, "%s%s:\n", prefix, _ResTable); 1138 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _ResTable); 1139 for(rsc = top; rsc; rsc = rsc->next) 1140 { 1141 fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, rsc->c_name); 1142 } 1143 fprintf(fo, "\t"DIRECTIVE_LONG"\t0\n"); 1144 fprintf(fo, "\n"); 1145 } 1146 1147 if(auto_register) 1148 fprintf(fo, s_file_autoreg_str, prefix, _ResTable); 1149 1150 fprintf(fo, s_file_tail_str); 1151 fclose(fo); 979 FILE *fo; 980 resource_t *rsc; 981 982 fo = fopen(outname, "wt"); 983 if(!fo) 984 { 985 error("Could not open %s\n", outname); 986 return; 987 } 988 989 { 990 char *s, *p; 991 now = time(NULL); 992 s = ctime(&now); 993 p = strchr(s, '\n'); 994 if(p) *p = '\0'; 995 fprintf(fo, s_file_head_str, input_name ? input_name : "stdin", 996 cmdline, s); 997 } 998 999 /* Get an idea how many we have and restructure the tables */ 1000 count_resources(top); 1001 1002 /* First write the segment tables */ 1003 if(create_dir) 1004 { 1005 if(win32) 1006 write_pe_segment(fo, top); 1007 else 1008 write_ne_segment(fo, top); 1009 } 1010 1011 /* Dump the names */ 1012 write_rsc_names(fo, top); 1013 1014 if(create_dir) 1015 fprintf(fo, "%sLResTabEnd:\n", LOCAL_PREFIX); 1016 1017 if(!indirect_only) 1018 { 1019 /* Write the resource data */ 1020 #ifdef MASM 1021 fprintf(fo, "\n;/* Resource binary data */\n\n"); 1022 #else 1023 fprintf(fo, "\n/* Resource binary data */\n\n"); 1024 #endif 1025 for(rsc = top; rsc; rsc = rsc->next) 1026 { 1027 if(!rsc->binres) 1028 continue; 1029 1030 fprintf(fo, "\t%s\t%d\n", DIRECTIVE_ALIGN, win32 ? 4 : alignment); 1031 fprintf(fo, "%s%s_data:\n", prefix, rsc->c_name); 1032 if(global) 1033 fprintf(fo, "\t%s\t%s%s_data\n", DIRECTIVE_GLOBAL, prefix, rsc->c_name); 1034 1035 write_s_res(fo, rsc->binres); 1036 1037 fprintf(fo, "\n"); 1038 } 1039 1040 if(create_dir) 1041 { 1042 /* Add a resource descriptor for built-in and elf-dlls */ 1043 fprintf(fo, "\t%s\t4\n", DIRECTIVE_ALIGN); 1044 fprintf(fo, "%s_ResourceDescriptor:\n", prefix); 1045 fprintf(fo, "\t%s\t%s_ResourceDescriptor\n", DIRECTIVE_GLOBAL, prefix); 1046 fprintf(fo, "%s_ResourceTable:\n", prefix); 1047 if(global) 1048 fprintf(fo, "\t%s\t%s_ResourceTable\n", DIRECTIVE_GLOBAL, prefix); 1049 fprintf(fo, "\t%s\t%s%s\n", DIRECTIVE_LONG, prefix, win32 ? _PEResTab : _NEResTab); 1050 fprintf(fo, "%s_NumberOfResources:\n", prefix); 1051 if(global) 1052 fprintf(fo, "\t%s\t%s_NumberOfResources\n", DIRECTIVE_GLOBAL, prefix); 1053 fprintf(fo, "\t%s\t%d\n", DIRECTIVE_LONG, direntries); 1054 fprintf(fo, "%s_ResourceSectionSize:\n", prefix); 1055 if(global) 1056 fprintf(fo, "\t%s\t%s_ResourceSectionSize\n", DIRECTIVE_GLOBAL, prefix); 1057 fprintf(fo, "\t%s\t%sLResTabEnd - %s%s\n", DIRECTIVE_LONG, LOCAL_PREFIX, prefix, win32 ? _PEResTab : _NEResTab); 1058 if(win32) 1059 { 1060 fprintf(fo, "%s_ResourcesEntries:\n", prefix); 1061 if(global) 1062 fprintf(fo, "\t%s\t%s_ResourcesEntries\n", DIRECTIVE_GLOBAL, prefix); 1063 fprintf(fo, "\t%s\t%s_ResourceDirectory\n", DIRECTIVE_LONG, prefix); 1064 } 1065 } 1066 } 1067 1068 if(indirect) 1069 { 1070 /* Write the indirection structures */ 1071 fprintf(fo, "\n/* Resource indirection structures */\n\n"); 1072 fprintf(fo, "\t%s\t4\n", DIRECTIVE_ALIGN); 1073 for(rsc = top; rsc; rsc = rsc->next) 1074 { 1075 int type; 1076 char *type_name = NULL; 1077 1078 if(!rsc->binres) 1079 continue; 1080 1081 switch(rsc->type) 1082 { 1083 case res_menex: 1084 type = WRC_RT_MENU; 1085 break; 1086 case res_dlgex: 1087 type = WRC_RT_DIALOG; 1088 break; 1089 case res_usr: 1090 assert(rsc->res.usr->type != NULL); 1091 type_name = prep_nid_for_label(rsc->res.usr->type); 1092 type = 0; 1093 break; 1094 default: 1095 type = rsc->type; 1096 } 1097 1098 /* 1099 * This follows a structure like: 1100 * struct wrc_resource { 1101 * INT32 id; 1102 * RSCNAME *resname; 1103 * INT32 restype; 1104 * RSCNAME *typename; 1105 * void *data; 1106 * UINT32 datasize; 1107 * }; 1108 * The 'RSCNAME' is a pascal-style string where the 1109 * first byte/word denotes the size and the rest the string 1110 * itself. 1111 */ 1112 fprintf(fo, "%s%s:\n", prefix, rsc->c_name); 1113 if(global) 1114 fprintf(fo, "\t%s\t%s%s\n", DIRECTIVE_GLOBAL, prefix, rsc->c_name); 1115 fprintf(fo, "\t%s\t%d, %s%s%s, %d, %s%s%s%s, %s%s_data, %d\n", 1116 DIRECTIVE_LONG, 1117 rsc->name->type == name_ord ? rsc->name->name.i_name : 0, 1118 rsc->name->type == name_ord ? "0" : prefix, 1119 rsc->name->type == name_ord ? "" : rsc->c_name, 1120 rsc->name->type == name_ord ? "" : "_name", 1121 type, 1122 type ? "0" : prefix, 1123 type ? "" : "_", 1124 type ? "" : type_name, 1125 type ? "" : "_typename", 1126 prefix, 1127 rsc->c_name, 1128 rsc->binres->size - rsc->binres->dataidx); 1129 fprintf(fo, "\n"); 1130 } 1131 fprintf(fo, "\n"); 1132 1133 /* Write the indirection table */ 1134 fprintf(fo, "/* Resource indirection table */\n\n"); 1135 fprintf(fo, "\t%s\t4\n", DIRECTIVE_ALIGN); 1136 fprintf(fo, "%s%s:\n", prefix, _ResTable); 1137 fprintf(fo, "\t%s\t%s%s\n", DIRECTIVE_GLOBAL, prefix, _ResTable); 1138 for(rsc = top; rsc; rsc = rsc->next) 1139 { 1140 fprintf(fo, "\t%s\t%s%s\n", DIRECTIVE_LONG, prefix, rsc->c_name); 1141 } 1142 fprintf(fo, "\t%s\t0\n", DIRECTIVE_LONG); 1143 fprintf(fo, "\n"); 1144 } 1145 1146 if(auto_register) 1147 fprintf(fo, s_file_autoreg_str, prefix, _ResTable); 1148 1149 fprintf(fo, s_file_tail_str); 1150 fclose(fo); 1152 1151 } 1153 1152 1154 1153 /* 1155 1154 ***************************************************************************** 1156 * Function 1157 * Syntax 1158 * Input 1159 * outname- Filename to write to1160 * top- The resource-tree to convert1161 * Output 1162 * Description 1163 * Remarks 1155 * Function : write_h_file 1156 * Syntax : void write_h_file(char *outname, resource_t *top) 1157 * Input : 1158 * outname - Filename to write to 1159 * top - The resource-tree to convert 1160 * Output : 1161 * Description : 1162 * Remarks : 1164 1163 ***************************************************************************** 1165 1164 */ 1166 1165 void write_h_file(char *outname, resource_t *top) 1167 1166 { 1168 1169 1170 1167 FILE *fo; 1168 resource_t *rsc; 1169 char *h_prefix; 1171 1170 1172 1171 #ifdef NEED_UNDERSCORE_PREFIX 1173 1172 h_prefix = prefix + 1; 1174 1173 #else 1175 1174 h_prefix = prefix; 1176 1175 #endif 1177 1176 1178 1179 1180 1181 1182 1183 1184 1185 1177 fo = fopen(outname, "wt"); 1178 if(!fo) 1179 { 1180 error("Could not open %s\n", outname); 1181 } 1182 1183 time(&now); 1184 fprintf(fo, h_file_head_str, input_name ? input_name : "stdin", 1186 1185 cmdline, ctime(&now), (long)now, (long)now); 1187 1186 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 } 1238 1239 1187 /* First write the segment tables reference */ 1188 if(create_dir) 1189 { 1190 fprintf(fo, "extern %schar %s%s[];\n\n", 1191 constant ? "const " : "", 1192 h_prefix, 1193 win32 ? _PEResTab : _NEResTab); 1194 } 1195 1196 /* Write the resource data */ 1197 for(rsc = top; global && rsc; rsc = rsc->next) 1198 { 1199 if(!rsc->binres) 1200 continue; 1201 1202 fprintf(fo, "extern %schar %s%s_data[];\n", 1203 constant ? "const " : "", 1204 h_prefix, 1205 rsc->c_name); 1206 } 1207 1208 if(indirect) 1209 { 1210 if(global) 1211 fprintf(fo, "\n"); 1212 1213 /* Write the indirection structures */ 1214 for(rsc = top; global && rsc; rsc = rsc->next) 1215 { 1216 fprintf(fo, "extern %swrc_resource%d_t %s%s;\n", 1217 constant ? "const " : "", 1218 win32 ? 32 : 16, 1219 h_prefix, 1220 rsc->c_name); 1221 } 1222 1223 if(global) 1224 fprintf(fo, "\n"); 1225 1226 /* Write the indirection table */ 1227 fprintf(fo, "extern %swrc_resource%d_t %s%s[];\n\n", 1228 constant ? "const " : "", 1229 win32 ? 32 : 16, 1230 h_prefix, 1231 _ResTable); 1232 } 1233 1234 fprintf(fo, h_file_tail_str); 1235 fclose(fo); 1236 } 1237 1238
Note:
See TracChangeset
for help on using the changeset viewer.