From 04f7fe7de3394edd5f3cb5cb6efb946d4ceed0a6 Mon Sep 17 00:00:00 2001 From: Juergen Schmied Date: Sat, 13 Nov 1999 22:32:21 +0000 Subject: [PATCH] New tool to convert the binary resources in *.rc files (hexdumps) from and to a binary. --- documentation/resources | 45 +++++++ tools/.cvsignore | 1 + tools/Makefile.in | 7 +- tools/bin2res.c | 291 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 342 insertions(+), 2 deletions(-) create mode 100644 documentation/resources create mode 100644 tools/bin2res.c diff --git a/documentation/resources b/documentation/resources new file mode 100644 index 00000000000..d516d676369 --- /dev/null +++ b/documentation/resources @@ -0,0 +1,45 @@ +This document desribes tools for handling resources within wine + +### bin2res ### + + This tool allows the editing of embeded binary resources within + *.rc files. These resources are stored as hex dump so they can be + stored within the cvs. This makes the editing of the embeded + bitmaps and icons harder. + + ### Create binary files from.rc ### + + the resources in the.rc file has to be marked by a header: + + /* BINRES idb_std_small.bmp */ + IDB_STD_SMALL BITMAP LOADONCALL DISCARDABLE + { + '42 4D 20 07 00 00 00 00 00 00 76 00 00 00 28 00' + + BINRES is the keyword followed by a filename. + "bin2res -d bin rsrc.rc" generates binary files from all marked + resources. If the binary file is newer it gets not overwritten. + To force overwriting use the -f switch. + + ### Create a .rc file from binaries ### + + Put a header followed by empty brackets in the.rc file. + + /* BINRES idb_std_small.bmp */ + {} + + Then run "bin2res rsrc.rc". It will merge the resources into the + .rc file if the binary resources are newer than the.rc file. + To force the resources into the.rc file use the -f switch. + If there is already a resource with the same filename in the.rc + file it gets overwritten. + + ### output of bin2res ### + + bash-2.03# ../../tools/bin2res -d bin shres.rc + [000.ico:c][003.ico:c][008.ico:s][015.ico:s][034.ico:s] + + s means skiped, c means changed +--- + +juergen.schmied@debitel.net (11/99) diff --git a/tools/.cvsignore b/tools/.cvsignore index 149c7d926e5..d8a491f7942 100644 --- a/tools/.cvsignore +++ b/tools/.cvsignore @@ -1,4 +1,5 @@ Makefile +bin2res build fnt2bdf makedep diff --git a/tools/Makefile.in b/tools/Makefile.in index 16f7a1e1c89..7745fb7ebf2 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -4,10 +4,10 @@ TOPOBJDIR = .. SRCDIR = @srcdir@ VPATH = @srcdir@ -PROGRAMS = build@PROGEXT@ makedep@PROGEXT@ fnt2bdf@PROGEXT@ +PROGRAMS = build@PROGEXT@ makedep@PROGEXT@ fnt2bdf@PROGEXT@ bin2res@PROGEXT@ MODULE = none -C_SRCS = build.c makedep.c fnt2bdf.c +C_SRCS = build.c makedep.c fnt2bdf.c bin2res.c all: $(PROGRAMS) @@ -22,4 +22,7 @@ makedep@PROGEXT@: makedep.o fnt2bdf@PROGEXT@: fnt2bdf.o $(CC) $(CFLAGS) -o fnt2bdf@PROGEXT@ fnt2bdf.o +bin2res@PROGEXT@: bin2res.o + $(CC) $(CFLAGS) -o bin2res@PROGEXT@ bin2res.o + ### Dependencies: diff --git a/tools/bin2res.c b/tools/bin2res.c new file mode 100644 index 00000000000..58307397cc0 --- /dev/null +++ b/tools/bin2res.c @@ -0,0 +1,291 @@ +/************************************************ + * + * Converting binary resources from/to *.rc files + * + * Copyright 1999 Juergen Schmied + * + * 11/99 first release + */ + +#include "config.h" + +#ifdef HAVE_SYS_PARAM_H +# include +#endif +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include "winuser.h" + +extern char* g_lpstrFileName; + +/* global options */ + +char* g_lpstrFileName = NULL; +char* g_lpstrInputFile = NULL; +int b_to_binary = 0; +int b_force_overwrite = 0; +LPBYTE p_in_file = NULL; + +static char* errorOpenFile = "Unable to open file.\n"; +static char* errorRCFormat = "Unexpexted syntax in rc file line %i\n"; + +void usage(void) +{ + printf("Usage: bin2res [-d bin] [input file]\n"); + printf(" -d bin convert a *.res back to a binary\n"); + printf(" -f force overwriting newer files\n"); + exit(-1); +} + +void parse_options(int argc, char **argv) +{ + int i; + + switch( argc ) + { + case 2: + g_lpstrInputFile = argv[1]; + break; + + case 3: + case 4: + case 5: + for( i = 1; i < argc - 1; i++ ) + { + if( argv[i][0] != '-' || + strlen(argv[i]) != 2 ) break; + + if( argv[i][1] == 'd') + { + if (strcmp ("bin", argv[i+1])==0) + { + b_to_binary =1; + i++; + } + else + { + usage(); + } + + } + else if ( argv[i][1] == 'f') + { + b_force_overwrite = 1; + } + else + { + usage(); + } + } + if( i == argc - 1 ) + { + g_lpstrInputFile = argv[i]; + break; + } + default: usage(); + } +} + +int insert_hex (char * infile, FILE * outfile) +{ + int i; + int fd; + struct stat st; + + if( (fd = open( infile, O_RDONLY))==-1 ) + { + fprintf(stderr, errorOpenFile ); + exit(1); + } + if ((fstat(fd, &st) == -1) || (p_in_file = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) + { + fprintf(stderr, errorOpenFile ); + close(fd); + exit(1); + } + + fprintf (outfile, "{\n '"); + i = 0; + while (1) + { + fprintf(outfile, "%02X", p_in_file[i]); + if (++i >= st.st_size) break; + fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" "); + } + fprintf (outfile, "'\n}\n"); + munmap(p_in_file, st.st_size); + close(fd); + return 1; +} + +int convert_to_res () +{ + FILE *fin, *ftemp; + char buffer[255]; + char infile[255]; + char tmpfile[L_tmpnam]; + char *pos; + int c, len; + struct stat st; + int line = 0; + time_t tinput; + long startpos, endpos; + + tmpnam(tmpfile); + if( (ftemp = fopen( tmpfile, "w")) == NULL ) goto error_open_file; + + if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file; + tinput = st.st_ctime; + + while ( NULL != fgets(buffer, 255, fin)) + { + fputs(buffer, ftemp); + line++; + if ( (pos = strstr(buffer, "BINRES")) != NULL) + { + /* get the out-file name */ + len = 0; pos += 6; startpos=0; endpos=0; + while ( *pos == ' ') pos++; + while ( pos[len] != ' ') len++; + strncpy(infile, pos, len); + infile[len]=0; + + if ( (!stat(infile, &st) && st.st_ctime > tinput) || b_force_overwrite) + { + /* write a output file */ + printf("[%s:c]", infile); + while((c = fgetc(fin))!='{' && c != EOF) fputc(c, ftemp); + if (c == EOF ) goto error_rc_format; + while((c = fgetc(fin))!='}' && c != EOF); + if (c == EOF ) goto error_rc_format; + + insert_hex(infile, ftemp); + } + else + { + printf("[%s:s]", infile); + } + } + } + + fclose(fin); + fclose(ftemp); + if (rename(tmpfile, g_lpstrInputFile) == -1) + { + perror("rename"); + unlink(tmpfile); + return 0; + } + return 1; + +error_open_file: + fprintf(stderr, errorOpenFile ); + return 0; + +error_rc_format: + fprintf(stderr, errorRCFormat, line); + return 0; +} + +int convert_to_bin() +{ + FILE *fin, *fout; + char buffer[255]; + char outfile[255]; + char *pos; + int len, index, in_resource; + unsigned int byte; + struct stat st; + int line = 0; + time_t tinput; + + if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file; + tinput = st.st_ctime; + + while ( NULL != fgets(buffer, 255, fin)) + { + line++; + if ( (pos = strstr(buffer, "BINRES")) != NULL) + { + /* get the out-file name */ + len = 0; pos += 6; + while ( *pos == ' ') pos++; + while ( pos[len] != ' ') len++; + strncpy(outfile, pos, len); + outfile[len]=0; + + if ( stat(outfile, &st) || st.st_ctime < tinput || b_force_overwrite) + { + /* write a output file */ + printf("[%s:c]", outfile); + if ( (fout = fopen( outfile, "w")) == NULL) goto error_open_file; + + in_resource = 0; + while (1) + { + if ( NULL == fgets(buffer, 255, fin)) goto error_rc_format; + line++; + + /* parse a line */ + for ( index = 0; buffer[index] != 0; index++ ) + { + if ( ! in_resource ) + { + if ( buffer[index] == '{' ) in_resource = 1; + continue; + } + + if ( buffer[index] == ' ' || buffer[index] == '\''|| buffer[index] == '\n' ) continue; + if ( buffer[index] == '}' ) goto end_of_resource; + if ( ! isxdigit(buffer[index])) goto error_rc_format; + index += sscanf(&buffer[index], "%02x", &byte); + fputc(byte, fout); + } + } + fclose(fout); + } + else + { + printf("[%s:s]", outfile); + } +end_of_resource: + } + } + + fclose(fin); + return 1; + +error_open_file: + fprintf(stderr, errorOpenFile ); + return 0; + +error_rc_format: + fprintf(stderr, errorRCFormat, line); + return 0; +} + +int main(int argc, char **argv) +{ + parse_options( argc, argv); + + if (b_to_binary == 0) + { + convert_to_res(); + } + else + { + convert_to_bin(); + } + printf("\n"); + return 0; +}