Do at least something for SHDragDrop functions although that isn't the
[wine/multimedia.git] / tools / bin2res.c
blobd14c627713fab0a155fccf74c793183f641508c3
1 /************************************************
3 * Converting binary resources from/to *.rc files
5 * Copyright 1999 Juergen Schmied
7 * 11/99 first release
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "config.h"
26 #ifdef HAVE_SYS_PARAM_H
27 # include <sys/param.h>
28 #endif
29 #include <sys/types.h>
30 #include <sys/stat.h>
32 #include <ctype.h>
33 #include <string.h>
35 #include <stdio.h>
36 #include <stdlib.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 #ifdef HAVE_SYS_MMAN_H
41 # include <sys/mman.h>
42 #endif
44 #include "windef.h"
45 #include "winbase.h"
46 #include "wingdi.h"
47 #include "winuser.h"
49 extern char* g_lpstrFileName;
51 /* global options */
53 char* g_lpstrFileName = NULL;
54 char* g_lpstrInputFile = NULL;
55 int b_to_binary = 0;
56 int b_force_overwrite = 0;
58 static char* errorOpenFile = "Unable to open file.\n";
59 static char* errorRCFormat = "Unexpexted syntax in rc file line %i\n";
61 void usage(void)
63 printf("Usage: bin2res [-d bin] [input file]\n");
64 printf(" -d bin convert a *.res back to a binary\n");
65 printf(" -f force overwriting newer files\n");
66 exit(-1);
69 void parse_options(int argc, char **argv)
71 int i;
73 switch( argc )
75 case 2:
76 g_lpstrInputFile = argv[1];
77 break;
79 case 3:
80 case 4:
81 case 5:
82 for( i = 1; i < argc - 1; i++ )
84 if( argv[i][0] != '-' ||
85 strlen(argv[i]) != 2 ) break;
87 if( argv[i][1] == 'd')
89 if (strcmp ("bin", argv[i+1])==0)
91 b_to_binary =1;
92 i++;
94 else
96 usage();
100 else if ( argv[i][1] == 'f')
102 b_force_overwrite = 1;
104 else
106 usage();
109 if( i == argc - 1 )
111 g_lpstrInputFile = argv[i];
112 break;
114 default: usage();
118 int insert_hex (char * infile, FILE * outfile)
120 #ifdef HAVE_MMAP
121 unsigned int i;
122 int fd;
123 struct stat st;
124 LPBYTE p_in_file = NULL;
126 if( (fd = open( infile, O_RDONLY))==-1 )
128 fprintf(stderr, errorOpenFile );
129 exit(1);
131 if ((fstat(fd, &st) == -1) || (p_in_file = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == (void *)-1)
133 fprintf(stderr, errorOpenFile );
134 close(fd);
135 exit(1);
138 fprintf (outfile, "{\n '");
139 i = 0;
140 while (1)
142 fprintf(outfile, "%02X", p_in_file[i]);
143 if (++i >= st.st_size) break;
144 fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
146 fprintf (outfile, "'\n}");
147 munmap(p_in_file, st.st_size);
148 close(fd);
149 return 1;
150 #else /* HAVE_MMAP */
151 FILE* fp;
152 struct stat st;
153 unsigned int i;
154 int c;
156 fp = fopen( infile, "r" );
157 if ( fp == NULL )
159 fprintf(stderr, errorOpenFile );
160 exit(1);
162 if (fstat(fileno(fp), &st) == -1)
164 fprintf(stderr, errorOpenFile );
165 fclose(fp);
166 exit(1);
169 fprintf (outfile, "{\n '");
170 i = 0;
171 while (1)
173 c = fgetc(fp);
174 if ( c == EOF )
176 fprintf(stderr, errorOpenFile );
177 fclose(fp);
178 exit(1);
180 fprintf(outfile, "%02X", c);
181 if (++i >= st.st_size) break;
182 fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
184 fprintf (outfile, "'\n}");
186 fclose(fp);
187 return 1;
188 #endif /* HAVE_MMAP */
191 int convert_to_res ()
193 FILE *fin, *ftemp;
194 char buffer[255];
195 char infile[255];
196 char tmpfile[255];
197 char *pos;
198 int c, len;
199 struct stat st;
200 int line = 0;
201 time_t tinput;
202 long startpos, endpos;
204 strcpy( tmpfile, g_lpstrInputFile );
205 strcat( tmpfile, "-tmp" );
206 /* FIXME: should use better tmp name and create with O_EXCL */
207 if( (ftemp = fopen( tmpfile, "w")) == NULL ) goto error_open_file;
209 if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
210 tinput = st.st_ctime;
212 while ( NULL != fgets(buffer, 255, fin))
214 fputs(buffer, ftemp);
215 line++;
216 if ( (pos = strstr(buffer, "BINRES")) != NULL)
218 /* get the out-file name */
219 len = 0; pos += 6; startpos=0; endpos=0;
220 while ( *pos == ' ') pos++;
221 while ( pos[len] != ' ') len++;
222 strncpy(infile, pos, len);
223 infile[len]=0;
225 if ( (!stat(infile, &st) && st.st_ctime > tinput) || b_force_overwrite)
227 /* write a output file */
228 printf("[%s:c]", infile);
229 while((c = fgetc(fin))!='{' && c != EOF) fputc(c, ftemp);
230 if (c == EOF ) goto error_rc_format;
231 while((c = fgetc(fin))!='}' && c != EOF);
232 if (c == EOF ) goto error_rc_format;
234 insert_hex(infile, ftemp);
236 else
238 printf("[%s:s]", infile);
243 fclose(fin);
244 fclose(ftemp);
246 if (unlink(g_lpstrInputFile) == -1)
248 perror("unlink");
249 unlink(tmpfile);
250 return 0;
252 if (rename(tmpfile, g_lpstrInputFile) == -1)
254 perror("rename");
255 unlink(tmpfile);
256 return 0;
258 return 1;
260 error_open_file:
261 fprintf(stderr, errorOpenFile );
262 return 0;
264 error_rc_format:
265 fprintf(stderr, errorRCFormat, line);
266 return 0;
269 int convert_to_bin()
271 FILE *fin, *fout;
272 char buffer[255];
273 char outfile[255];
274 char *pos;
275 int len, index, in_resource;
276 unsigned int byte;
277 struct stat st;
278 int line = 0;
279 time_t tinput;
281 if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
282 tinput = st.st_ctime;
284 while ( NULL != fgets(buffer, 255, fin))
286 line++;
287 if ( (pos = strstr(buffer, "BINRES")) != NULL)
289 /* get the out-file name */
290 len = 0; pos += 6;
291 while ( *pos == ' ') pos++;
292 while ( pos[len] != ' ') len++;
293 strncpy(outfile, pos, len);
294 outfile[len]=0;
296 if ( stat(outfile, &st) || st.st_ctime < tinput || b_force_overwrite)
298 /* write a output file */
299 printf("[%s:c]", outfile);
300 if ( (fout = fopen( outfile, "w")) == NULL) goto error_open_file;
302 in_resource = 0;
303 while (1)
305 if ( NULL == fgets(buffer, 255, fin)) goto error_rc_format;
306 line++;
308 /* parse a line */
309 for ( index = 0; buffer[index] != 0; index++ )
311 if ( ! in_resource )
313 if ( buffer[index] == '{' ) in_resource = 1;
314 continue;
317 if ( buffer[index] == ' ' || buffer[index] == '\''|| buffer[index] == '\n' ) continue;
318 if ( buffer[index] == '}' ) goto end_of_resource;
319 if ( ! isxdigit(buffer[index])) goto error_rc_format;
320 index += sscanf(&buffer[index], "%02x", &byte);
321 fputc(byte, fout);
324 fclose(fout);
326 else
328 printf("[%s:s]", outfile);
330 end_of_resource: ;
334 fclose(fin);
335 return 1;
337 error_open_file:
338 fprintf(stderr, errorOpenFile );
339 return 0;
341 error_rc_format:
342 fprintf(stderr, errorRCFormat, line);
343 return 0;
346 int main(int argc, char **argv)
348 parse_options( argc, argv);
350 if (b_to_binary == 0)
352 convert_to_res();
354 else
356 convert_to_bin();
358 printf("\n");
359 return 0;