Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
fb9c47d5
Commit
fb9c47d5
authored
Sep 18, 2003
by
Dimitrie O. Paun
Committed by
Alexandre Julliard
Sep 18, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Complete rewrite of bin2res, for a cleaner codebase.
Add online help describing how the program works. Sanitize command line options.
parent
59b2ad62
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
140 additions
and
277 deletions
+140
-277
bin2res.c
tools/bin2res.c
+140
-277
No files found.
tools/bin2res.c
View file @
fb9c47d5
...
@@ -3,8 +3,7 @@
...
@@ -3,8 +3,7 @@
* Converting binary resources from/to *.rc files
* Converting binary resources from/to *.rc files
*
*
* Copyright 1999 Juergen Schmied
* Copyright 1999 Juergen Schmied
*
* Copyright 2003 Dimitrie O. Paun
* 11/99 first release
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
...
@@ -22,342 +21,206 @@
...
@@ -22,342 +21,206 @@
*/
*/
#include "config.h"
#include "config.h"
#include "wine/port.h"
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#ifdef HAVE_SYS_PARAM_H
# include <unistd.h>
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#endif
#include "windef.h"
static
const
char
*
help
=
#include "winbase.h"
"Usage: bin2res [-x] | [-a] [-f] [-h] <rsrc.rc>
\n
"
#include "wingdi.h"
" -a archive binaries into the <rsrc.rc> file
\n
"
#include "winuser.h"
" -x extract binaries from the <rsrc.rc> file
\n
"
" -f force processing of older resources
\n
"
extern
char
*
g_lpstrFileName
;
" -h print this help screen and exit
\n
"
"
\n
"
/* global options */
"This tool allows the insertion/extractions of embedded binary
\n
"
"resources to/from .rc files, for storage within the cvs tree.
\n
"
char
*
g_lpstrFileName
=
NULL
;
"This is accomplished by placing a magic marker in a comment
\n
"
char
*
g_lpstrInputFile
=
NULL
;
"just above the resource. The marker consists of the BINRES
\n
"
int
b_to_binary
=
0
;
"string followed by the file name. For example, to insert a
\n
"
int
b_force_overwrite
=
0
;
"brand new binary resource in a .rc file, place the marker
\n
"
"above empty brackets:
\n
"
static
char
*
errorOpenFile
=
"Unable to open file.
\n
"
;
" /* BINRES idb_std_small.bmp */
\n
"
static
char
*
errorRCFormat
=
"Unexpexted syntax in rc file line %i
\n
"
;
" {}
\n
"
"To merge the binary resources into the .rc file, run:
\n
"
" bin2res -a myrsrc.rc
\n
"
"Only resources that are newer than the .rc are processed.
\n
"
"To extract the binary resources from the .rc file, run:
\n
"
" bin2res -x myrsrc.rc
\n
"
"Binary files newer than the .rc file are not overwritten.
\n
"
"
\n
"
"To force processing of all resources, use the -f flag.
\n
"
;
void
usage
(
void
)
void
usage
(
void
)
{
{
printf
(
"Usage: bin2res [-d bin] [input file]
\n
"
);
printf
(
help
);
printf
(
" -d bin convert a *.res back to a binary
\n
"
);
exit
(
1
);
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
*
out
file
)
int
insert_hex
dump
(
FILE
*
outfile
,
FILE
*
in
file
)
{
{
#ifdef HAVE_MMAP
int
i
,
c
;
unsigned
int
i
;
int
fd
;
struct
stat
st
;
LPBYTE
p_in_file
=
NULL
;
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
))
==
(
void
*
)
-
1
)
{
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
}"
);
munmap
(
p_in_file
,
st
.
st_size
);
close
(
fd
);
return
1
;
#else
/* HAVE_MMAP */
FILE
*
fp
;
struct
stat
st
;
unsigned
int
i
;
int
c
;
fp
=
fopen
(
infile
,
"r"
);
if
(
fp
==
NULL
)
{
fprintf
(
stderr
,
errorOpenFile
);
exit
(
1
);
}
if
(
fstat
(
fileno
(
fp
),
&
st
)
==
-
1
)
{
fprintf
(
stderr
,
errorOpenFile
);
fclose
(
fp
);
exit
(
1
);
}
fprintf
(
outfile
,
"{
\n
'"
);
fprintf
(
outfile
,
"{
\n
'"
);
i
=
0
;
for
(
i
=
0
;
(
c
=
fgetc
(
infile
))
!=
EOF
;
i
++
)
while
(
1
)
{
{
c
=
fgetc
(
fp
);
if
(
i
&&
(
i
%
16
)
==
0
)
fprintf
(
outfile
,
"'
\n
'"
);
if
(
c
==
EOF
)
if
(
i
%
16
)
fprintf
(
outfile
,
" "
);
{
fprintf
(
stderr
,
errorOpenFile
);
fclose
(
fp
);
exit
(
1
);
}
fprintf
(
outfile
,
"%02X"
,
c
);
fprintf
(
outfile
,
"%02X"
,
c
);
if
(
++
i
>=
st
.
st_size
)
break
;
fprintf
(
outfile
,
"%s"
,
(
i
==
(
i
&
0xfffffff0
))
?
"'
\n
'"
:
" "
);
}
}
fprintf
(
outfile
,
"'
\n
}"
);
fprintf
(
outfile
,
"'
\n
}"
);
fclose
(
fp
);
return
1
;
return
1
;
#endif
/* HAVE_MMAP */
}
}
int
convert_to_res
(
)
int
hex2bin
(
char
c
)
{
{
FILE
*
fin
,
*
ftemp
;
if
(
!
isxdigit
(
c
))
return
-
1024
;
char
buffer
[
255
];
if
(
isdigit
(
c
))
return
c
-
'0'
;
char
infile
[
255
];
return
toupper
(
c
)
-
'A'
+
10
;
char
tmpfile
[
255
];
}
char
*
pos
;
int
c
,
len
;
struct
stat
st
;
int
line
=
0
;
time_t
tinput
;
long
startpos
,
endpos
;
strcpy
(
tmpfile
,
g_lpstrInputFile
);
strcat
(
tmpfile
,
"-tmp"
);
/* FIXME: should use better tmp name and create with O_EXCL */
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
)
int
extract_hexdump
(
FILE
*
outfile
,
FILE
*
infile
)
{
{
/* write a output file */
int
byte
,
c
;
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
);
while
(
(
c
=
fgetc
(
infile
))
!=
EOF
&&
c
!=
'}'
)
}
else
{
{
printf
(
"[%s:s]"
,
infile
);
if
(
isspace
(
c
)
||
c
==
'\''
)
continue
;
}
byte
=
16
*
hex2bin
(
c
);
}
c
=
fgetc
(
infile
);
if
(
c
==
EOF
)
return
0
;
byte
+=
hex2bin
(
c
);
if
(
byte
<
0
)
return
0
;
fputc
(
byte
,
outfile
);
}
}
return
1
;
}
fclose
(
fin
);
const
char
*
parse_marker
(
const
char
*
line
,
time_t
*
last_updated
)
fclose
(
ftemp
);
{
static
char
res_file_name
[
PATH_MAX
],
*
rpos
,
*
wpos
;
struct
stat
st
;
if
(
unlink
(
g_lpstrInputFile
)
==
-
1
)
if
(
!
(
rpos
=
strstr
(
line
,
"BINRES"
)))
return
0
;
{
for
(
rpos
+=
6
;
*
rpos
&&
isspace
(
*
rpos
);
rpos
++
)
/**/
;
perror
(
"unlink"
);
for
(
wpos
=
res_file_name
;
*
rpos
&&
!
isspace
(
*
rpos
);
)
*
wpos
++
=
*
rpos
++
;
unlink
(
tmpfile
);
*
wpos
=
0
;
return
0
;
}
if
(
rename
(
tmpfile
,
g_lpstrInputFile
)
==
-
1
)
{
perror
(
"rename"
);
unlink
(
tmpfile
);
return
0
;
}
return
1
;
error_open_file:
*
last_updated
=
(
stat
(
res_file_name
,
&
st
)
<
0
)
?
0
:
st
.
st_mtime
;
fprintf
(
stderr
,
errorOpenFile
);
return
0
;
error_rc_format:
return
res_file_name
;
fprintf
(
stderr
,
errorRCFormat
,
line
);
return
0
;
}
}
int
convert_to_bin
(
)
int
process_resources
(
const
char
*
input_file_name
,
int
inserting
,
int
force_processing
)
{
{
FILE
*
fin
,
*
fout
;
char
buffer
[
2048
],
tmp_file_name
[
PATH_MAX
];
char
buffer
[
255
];
const
char
*
res_file_name
;
char
outfile
[
255
];
time_t
rc_last_update
,
res_last_update
;
char
*
pos
;
FILE
*
fin
,
*
fres
,
*
ftmp
=
0
;
int
len
,
index
,
in_resource
;
unsigned
int
byte
;
struct
stat
st
;
struct
stat
st
;
int
line
=
0
;
int
fd
,
c
;
time_t
tinput
;
if
(
(
fin
=
fopen
(
g_lpstrInputFile
,
"r"
))
==
NULL
||
stat
(
g_lpstrInputFile
,
&
st
))
goto
error_open_file
;
if
(
!
(
fin
=
fopen
(
input_file_name
,
"r"
)))
return
0
;
tinput
=
st
.
st_ctime
;
if
(
stat
(
input_file_name
,
&
st
)
<
0
)
return
0
;
rc_last_update
=
st
.
st_mtime
;
while
(
NULL
!=
fgets
(
buffer
,
255
,
fin
)
)
if
(
inserting
)
{
{
line
++
;
strcpy
(
tmp_file_name
,
input_file_name
);
if
(
(
pos
=
strstr
(
buffer
,
"BINRES"
))
!=
NULL
)
strcat
(
tmp_file_name
,
"-XXXXXX.temp"
);
{
if
((
fd
=
mkstemps
(
tmp_file_name
,
5
))
==
-
1
)
/* 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
;
strcpy
(
tmp_file_name
,
"/tmp/bin2res-XXXXXX.temp"
);
line
++
;
if
((
fd
=
mkstemps
(
tmp_file_name
,
5
))
==
-
1
)
return
0
;
}
if
(
!
(
ftmp
=
fdopen
(
fd
,
"w"
)))
return
0
;
}
/* parse a line */
for
(
c
=
EOF
;
fgets
(
buffer
,
sizeof
(
buffer
),
fin
);
c
=
EOF
)
for
(
index
=
0
;
buffer
[
index
]
!=
0
;
index
++
)
{
{
if
(
!
in_resource
)
if
(
inserting
)
fprintf
(
ftmp
,
"%s"
,
buffer
);
if
(
!
(
res_file_name
=
parse_marker
(
buffer
,
&
res_last_update
)))
continue
;
if
(
!
force_processing
&&
((
rc_last_update
<
res_last_update
)
==
!
inserting
))
{
{
if
(
buffer
[
index
]
==
'{'
)
in_resource
=
1
;
printf
(
"skipping '%s'
\n
"
,
res_file_name
)
;
continue
;
continue
;
}
}
if
(
buffer
[
index
]
==
' '
||
buffer
[
index
]
==
'\''
||
buffer
[
index
]
==
'\n'
)
continue
;
printf
(
"processing '%s'
\n
"
,
res_file_name
);
if
(
buffer
[
index
]
==
'}'
)
goto
end_of_resource
;
while
(
(
c
=
fgetc
(
fin
))
!=
EOF
&&
c
!=
'{'
)
if
(
!
isxdigit
(
buffer
[
index
]))
goto
error_rc_format
;
if
(
inserting
)
fputc
(
c
,
ftmp
);
index
+=
sscanf
(
&
buffer
[
index
],
"%02x"
,
&
byte
);
if
(
c
==
EOF
)
break
;
fputc
(
byte
,
fout
);
}
if
(
!
(
fres
=
fopen
(
res_file_name
,
inserting
?
"r"
:
"w"
)))
break
;
}
if
(
inserting
)
fclose
(
fout
);
{
if
(
!
insert_hexdump
(
ftmp
,
fres
))
break
;
while
(
(
c
=
fgetc
(
fin
))
!=
EOF
&&
c
!=
'}'
)
/**/
;
}
}
else
else
{
{
printf
(
"[%s:s]"
,
outfile
);
if
(
!
extract_hexdump
(
fres
,
fin
))
break
;
}
end_of_resource:
;
}
}
fclose
(
fres
);
}
}
fclose
(
fin
);
fclose
(
fin
);
return
1
;
error_open_file:
if
(
inserting
)
fprintf
(
stderr
,
errorOpenFile
);
{
return
0
;
fclose
(
ftmp
);
if
(
c
==
EOF
&&
rename
(
tmp_file_name
,
input_file_name
)
<
0
)
c
=
'.'
;
/* force an error */
else
unlink
(
tmp_file_name
);
}
error_rc_format:
return
c
==
EOF
;
fprintf
(
stderr
,
errorRCFormat
,
line
);
return
0
;
}
}
int
main
(
int
argc
,
char
**
argv
)
int
main
(
int
argc
,
char
**
argv
)
{
{
parse_options
(
argc
,
argv
);
int
convert_dir
=
0
,
optc
;
int
force_overwrite
=
0
;
const
char
*
input_file_name
;
if
(
b_to_binary
==
0
)
while
((
optc
=
getopt
(
argc
,
argv
,
"axfh"
))
!=
EOF
)
{
{
convert_to_res
();
switch
(
optc
)
{
case
'a'
:
case
'x'
:
if
(
convert_dir
)
usage
();
convert_dir
=
optc
;
break
;
case
'f'
:
force_overwrite
=
1
;
break
;
case
'h'
:
printf
(
help
);
exit
(
0
);
break
;
default:
usage
();
}
}
else
}
if
(
optind
+
1
!=
argc
)
usage
();
input_file_name
=
argv
[
optind
];
if
(
!
convert_dir
)
usage
();
if
(
!
process_resources
(
input_file_name
,
convert_dir
==
'a'
,
force_overwrite
))
{
{
convert_to_bin
();
perror
(
"Processing failed"
);
exit
(
1
);
}
}
printf
(
"
\n
"
);
return
0
;
return
0
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment