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
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
161 additions
and
298 deletions
+161
-298
bin2res.c
tools/bin2res.c
+161
-298
No files found.
tools/bin2res.c
View file @
fb9c47d5
...
...
@@ -3,8 +3,7 @@
* Converting binary resources from/to *.rc files
*
* Copyright 1999 Juergen Schmied
*
* 11/99 first release
* Copyright 2003 Dimitrie O. Paun
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -22,342 +21,206 @@
*/
#include "config.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 "wine/port.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#include <ctype.h>
#include <string.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
static
const
char
*
help
=
"Usage: bin2res [-x] | [-a] [-f] [-h] <rsrc.rc>
\n
"
" -a archive binaries into the <rsrc.rc> file
\n
"
" -x extract binaries from the <rsrc.rc> file
\n
"
" -f force processing of older resources
\n
"
" -h print this help screen and exit
\n
"
"
\n
"
"This tool allows the insertion/extractions of embedded binary
\n
"
"resources to/from .rc files, for storage within the cvs tree.
\n
"
"This is accomplished by placing a magic marker in a comment
\n
"
"just above the resource. The marker consists of the BINRES
\n
"
"string followed by the file name. For example, to insert a
\n
"
"brand new binary resource in a .rc file, place the marker
\n
"
"above empty brackets:
\n
"
" /* BINRES idb_std_small.bmp */
\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
"
;
extern
char
*
g_lpstrFileName
;
/* global options */
char
*
g_lpstrFileName
=
NULL
;
char
*
g_lpstrInputFile
=
NULL
;
int
b_to_binary
=
0
;
int
b_force_overwrite
=
0
;
void
usage
(
void
)
{
printf
(
help
);
exit
(
1
);
}
static
char
*
errorOpenFile
=
"Unable to open file.
\n
"
;
static
char
*
errorRCFormat
=
"Unexpexted syntax in rc file line %i
\n
"
;
int
insert_hexdump
(
FILE
*
outfile
,
FILE
*
infile
)
{
int
i
,
c
;
fprintf
(
outfile
,
"{
\n
'"
);
for
(
i
=
0
;
(
c
=
fgetc
(
infile
))
!=
EOF
;
i
++
)
{
if
(
i
&&
(
i
%
16
)
==
0
)
fprintf
(
outfile
,
"'
\n
'"
);
if
(
i
%
16
)
fprintf
(
outfile
,
" "
);
fprintf
(
outfile
,
"%02X"
,
c
);
}
fprintf
(
outfile
,
"'
\n
}"
);
return
1
;
}
void
usage
(
void
)
int
hex2bin
(
char
c
)
{
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
);
if
(
!
isxdigit
(
c
))
return
-
1024
;
if
(
isdigit
(
c
))
return
c
-
'0'
;
return
toupper
(
c
)
-
'A'
+
10
;
}
void
parse_options
(
int
argc
,
char
**
argv
)
int
extract_hexdump
(
FILE
*
outfile
,
FILE
*
infile
)
{
int
i
;
int
byte
,
c
;
while
(
(
c
=
fgetc
(
infile
))
!=
EOF
&&
c
!=
'}'
)
{
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
;
}
switch
(
argc
)
{
case
2
:
g_lpstrInputFile
=
argv
[
1
];
break
;
const
char
*
parse_marker
(
const
char
*
line
,
time_t
*
last_updated
)
{
static
char
res_file_name
[
PATH_MAX
],
*
rpos
,
*
wpos
;
struct
stat
st
;
case
3
:
case
4
:
case
5
:
for
(
i
=
1
;
i
<
argc
-
1
;
i
++
)
{
if
(
argv
[
i
][
0
]
!=
'-'
||
strlen
(
argv
[
i
])
!=
2
)
break
;
if
(
!
(
rpos
=
strstr
(
line
,
"BINRES"
)))
return
0
;
for
(
rpos
+=
6
;
*
rpos
&&
isspace
(
*
rpos
);
rpos
++
)
/**/
;
for
(
wpos
=
res_file_name
;
*
rpos
&&
!
isspace
(
*
rpos
);
)
*
wpos
++
=
*
rpos
++
;
*
wpos
=
0
;
if
(
argv
[
i
][
1
]
==
'd'
)
{
if
(
strcmp
(
"bin"
,
argv
[
i
+
1
])
==
0
)
{
b_to_binary
=
1
;
i
++
;
}
else
{
usage
();
}
*
last_updated
=
(
stat
(
res_file_name
,
&
st
)
<
0
)
?
0
:
st
.
st_mtime
;
}
else
if
(
argv
[
i
][
1
]
==
'f'
)
{
b_force_overwrite
=
1
;
}
else
{
usage
();
}
}
if
(
i
==
argc
-
1
)
{
g_lpstrInputFile
=
argv
[
i
];
break
;
}
default:
usage
();
}
return
res_file_name
;
}
int
insert_hex
(
char
*
infile
,
FILE
*
outfile
)
int
process_resources
(
const
char
*
input_file_name
,
int
inserting
,
int
force_processing
)
{
#ifdef HAVE_MMAP
unsigned
int
i
;
int
fd
;
struct
stat
st
;
LPBYTE
p_in_file
=
NULL
;
if
(
(
fd
=
open
(
infile
,
O_RDONLY
))
==-
1
)
char
buffer
[
2048
],
tmp_file_name
[
PATH_MAX
];
const
char
*
res_file_name
;
time_t
rc_last_update
,
res_last_update
;
FILE
*
fin
,
*
fres
,
*
ftmp
=
0
;
struct
stat
st
;
int
fd
,
c
;
if
(
!
(
fin
=
fopen
(
input_file_name
,
"r"
)))
return
0
;
if
(
stat
(
input_file_name
,
&
st
)
<
0
)
return
0
;
rc_last_update
=
st
.
st_mtime
;
if
(
inserting
)
{
strcpy
(
tmp_file_name
,
input_file_name
);
strcat
(
tmp_file_name
,
"-XXXXXX.temp"
);
if
((
fd
=
mkstemps
(
tmp_file_name
,
5
))
==
-
1
)
{
fprintf
(
stderr
,
errorOpenFile
);
exit
(
1
)
;
strcpy
(
tmp_file_name
,
"/tmp/bin2res-XXXXXX.temp"
);
if
((
fd
=
mkstemps
(
tmp_file_name
,
5
))
==
-
1
)
return
0
;
}
if
((
fstat
(
fd
,
&
st
)
==
-
1
)
||
(
p_in_file
=
mmap
(
NULL
,
st
.
st_size
,
PROT_READ
,
MAP_PRIVATE
,
fd
,
0
))
==
(
void
*
)
-
1
)
if
(
!
(
ftmp
=
fdopen
(
fd
,
"w"
)))
return
0
;
}
for
(
c
=
EOF
;
fgets
(
buffer
,
sizeof
(
buffer
),
fin
);
c
=
EOF
)
{
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
))
{
fprintf
(
stderr
,
errorOpenFile
);
close
(
fd
);
exit
(
1
);
printf
(
"skipping '%s'
\n
"
,
res_file_name
);
continue
;
}
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
);
}
printf
(
"processing '%s'
\n
"
,
res_file_name
);
while
(
(
c
=
fgetc
(
fin
))
!=
EOF
&&
c
!=
'{'
)
if
(
inserting
)
fputc
(
c
,
ftmp
);
if
(
c
==
EOF
)
break
;
fprintf
(
outfile
,
"{
\n
'"
);
i
=
0
;
while
(
1
)
if
(
!
(
fres
=
fopen
(
res_file_name
,
inserting
?
"r"
:
"w"
)))
break
;
if
(
inserting
)
{
c
=
fgetc
(
fp
);
if
(
c
==
EOF
)
{
fprintf
(
stderr
,
errorOpenFile
);
fclose
(
fp
);
exit
(
1
);
}
fprintf
(
outfile
,
"%02X"
,
c
);
if
(
++
i
>=
st
.
st_size
)
break
;
fprintf
(
outfile
,
"%s"
,
(
i
==
(
i
&
0xfffffff0
))
?
"'
\n
'"
:
" "
);
if
(
!
insert_hexdump
(
ftmp
,
fres
))
break
;
while
(
(
c
=
fgetc
(
fin
))
!=
EOF
&&
c
!=
'}'
)
/**/
;
}
fprintf
(
outfile
,
"'
\n
}"
);
fclose
(
fp
);
return
1
;
#endif
/* HAVE_MMAP */
}
int
convert_to_res
()
{
FILE
*
fin
,
*
ftemp
;
char
buffer
[
255
];
char
infile
[
255
];
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
))
else
{
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
);
}
}
if
(
!
extract_hexdump
(
fres
,
fin
))
break
;
}
fclose
(
fres
);
}
fclose
(
fin
);
fclose
(
ftemp
);
if
(
unlink
(
g_lpstrInputFile
)
==
-
1
)
{
perror
(
"unlink"
);
unlink
(
tmpfile
);
return
0
;
}
if
(
rename
(
tmpfile
,
g_lpstrInputFile
)
==
-
1
)
{
perror
(
"rename"
);
unlink
(
tmpfile
);
return
0
;
}
return
1
;
fclose
(
fin
);
error_open_file:
fprintf
(
stderr
,
errorOpenFile
);
return
0
;
if
(
inserting
)
{
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:
fprintf
(
stderr
,
errorRCFormat
,
line
);
return
0
;
return
c
==
EOF
;
}
int
convert_to_bin
(
)
int
main
(
int
argc
,
char
**
argv
)
{
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
;
int
convert_dir
=
0
,
optc
;
int
force_overwrite
=
0
;
const
char
*
input_file_name
;
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
))
while
((
optc
=
getopt
(
argc
,
argv
,
"axfh"
))
!=
EOF
)
{
switch
(
optc
)
{
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:
;
}
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
();
}
}
fclose
(
fin
);
return
1
;
error_open_file:
fprintf
(
stderr
,
errorOpenFile
);
return
0
;
if
(
optind
+
1
!=
argc
)
usage
();
input_file_name
=
argv
[
optind
];
error_rc_format:
fprintf
(
stderr
,
errorRCFormat
,
line
);
return
0
;
}
if
(
!
convert_dir
)
usage
();
int
main
(
int
argc
,
char
**
argv
)
{
parse_options
(
argc
,
argv
);
if
(
!
process_resources
(
input_file_name
,
convert_dir
==
'a'
,
force_overwrite
))
{
perror
(
"Processing failed"
);
exit
(
1
);
}
if
(
b_to_binary
==
0
)
{
convert_to_res
();
}
else
{
convert_to_bin
();
}
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