Author: mladen.turk(a)jboss.com
Date: 2008-04-02 08:19:00 -0400 (Wed, 02 Apr 2008)
New Revision: 1494
Modified:
trunk/build/install/xtool/NMAKEmakefile
trunk/build/install/xtool/xtool.c
Log:
Added image tool for figuring out the PE info
Modified: trunk/build/install/xtool/NMAKEmakefile
===================================================================
--- trunk/build/install/xtool/NMAKEmakefile 2008-04-01 18:39:17 UTC (rev 1493)
+++ trunk/build/install/xtool/NMAKEmakefile 2008-04-02 12:19:00 UTC (rev 1494)
@@ -29,7 +29,7 @@
SRCDIR = .
!ENDIF
-LFLAGS = $(LFLAGS) user32.lib shell32.lib advapi32.lib psapi.lib
+LFLAGS = $(LFLAGS) user32.lib shell32.lib advapi32.lib psapi.lib imagehlp.lib
version.lib
PDBFLAGS = -Fo$(WORKDIR)\ -Fd$(WORKDIR)\$(PROJECT)-src
OBJECTS = \
Modified: trunk/build/install/xtool/xtool.c
===================================================================
--- trunk/build/install/xtool/xtool.c 2008-04-01 18:39:17 UTC (rev 1493)
+++ trunk/build/install/xtool/xtool.c 2008-04-02 12:19:00 UTC (rev 1494)
@@ -57,6 +57,7 @@
#include <shellapi.h>
#include <psapi.h>
#include <shlobj.h>
+#include <imagehlp.h>
#include <stdio.h>
#include <stdlib.h>
@@ -107,7 +108,10 @@
#define x_isalpha(c) (isalpha(((unsigned char)(c))))
#define x_isdigit(c) (isdigit(((unsigned char)(c))))
#define x_isspace(c) (isspace(((unsigned char)(c))))
+#define x_tolower(c) (tolower(((unsigned char)(c))))
+#define x_toupper(c) (toupper(((unsigned char)(c))))
+
typedef enum {
SYSDLL_KERNEL32 = 0, // kernel32 From WinBase.h
SYSDLL_NTDLL = 1, // ntdll From our real kernel
@@ -154,6 +158,7 @@
static SYSTEM_INFO win_osinf;
static OSVERSIONINFOEXA win_osver;
static int verbose = 0;
+static int xquiet = 0;
/*
* ---------------------------------------------------------------------
@@ -260,7 +265,7 @@
0
};
-int x_cerror(int err)
+static int x_cerror(int err)
{
if (err == 0) {
if ((err = GetLastError()) == 0)
@@ -285,6 +290,17 @@
return c_errno_table[err];
}
+static int x_perror(int err, const char *msg)
+{
+ if (err == 0)
+ err = x_cerror(errno);
+ if (!xquiet) {
+ errno = err;
+ perror(msg);
+ }
+ return err;
+}
+
static void x_free(void *p)
{
if (p != NULL) {
@@ -296,8 +312,7 @@
{
void *p = calloc(1, size);
if (p == NULL) {
- perror("malloc");
- _exit(ENOMEM);
+ _exit(x_perror(ENOMEM, "malloc"));
}
return p;
}
@@ -306,8 +321,7 @@
{
void *p = calloc(1, size);
if (p == NULL) {
- perror("calloc");
- _exit(ENOMEM);
+ _exit(x_perror(ENOMEM, "calloc"));
}
return p;
}
@@ -316,8 +330,7 @@
{
m = realloc(m, size);
if (m == NULL) {
- perror("realloc");
- _exit(ENOMEM);
+ _exit(x_perror(ENOMEM, "realloc"));
}
return m;
}
@@ -524,6 +537,22 @@
return x_strdup(add);
}
+static char *x_strchr(const char *p, int ch, int icase)
+{
+ char c;
+
+ c = ch;
+ for (;; ++p) {
+ if (icase && (x_tolower(*p) == x_tolower(c)))
+ return (char *)p;
+ else if (*p == c)
+ return (char *)p;
+ if (*p == '\0')
+ return NULL;
+ }
+ /* NOTREACHED */
+}
+
static char *__argv0 = NULL;
static char *__pname = NULL;
static char *__ppath = NULL;
@@ -640,7 +669,7 @@
}
else if (exp[y] != '?') {
if (icase) {
- if (tolower((unsigned char)str[x]) != tolower((unsigned char)exp[y]))
+ if (x_tolower(str[x]) != x_tolower(exp[y]))
return 1;
}
else if (str[x] != exp[y])
@@ -986,7 +1015,7 @@
*ptr = '\0';
if (name[1] == ':') {
char *rv = x_strdup(name);
- *rv = toupper((unsigned char)*rv);
+ *rv = x_toupper(*rv);
return rv;
}
}
@@ -1098,7 +1127,7 @@
while (*string) {
if (icase)
- i = toupper(*string);
+ i = x_toupper(*string);
else
i = *string;
hash = hash * 33 + i;
@@ -1287,6 +1316,8 @@
static void vwarnx(const char *fmt, va_list ap)
{
+ if (xquiet)
+ return;
fprintf(stderr, "%s: ", getprogname());
if (fmt != NULL)
vfprintf(stderr, fmt, ap);
@@ -1320,7 +1351,7 @@
* Parse argc/argv argument vector.
* However this one allows both - and / as argument options
*/
-int getopt(int nargc, const char **nargv, const char *ostr)
+int getopt(int nargc, const char **nargv, const char *ostr, int icase)
{
static const char *place = EMSG; /* option letter processing */
char *oli = NULL; /* option letter list index */
@@ -1374,7 +1405,7 @@
* if the program (eg su) is looking for it.
*/
place = EMSG;
- if (strchr(ostr, first) == NULL)
+ if (x_strchr(ostr, first, icase) == NULL)
return EOF;
optopt = first;
}
@@ -1389,7 +1420,7 @@
optopt = *place++;
/* See if option letter is one the caller wanted... */
- if (optopt == BADARG || (oli = strchr(ostr, optopt)) == NULL) {
+ if (optopt == BADARG || (oli = x_strchr(ostr, optopt, icase)) == NULL) {
if (!optsbrk && optslash == '/' && first == optslash) {
/* Non option starting with / */
place = EMSG;
@@ -2194,7 +2225,7 @@
{
int ch;
- while ((ch = getopt(argc, argv, "s:V:g:r:qLRS-")) != EOF) {
+ while ((ch = getopt(argc, argv, "s:V:g:r:qLRS-", 0)) != EOF) {
printf("Valid argument = %c [%s]\n", ch, optarg);
}
argc -= optind;
@@ -2295,6 +2326,14 @@
}
}
+static void print_stdusage()
+{
+ fprintf(stderr, " -q Be quiet.\n");
+ fprintf(stderr, " -v --verbose Explain what is being done.\n");
+ fprintf(stderr, " --version Output version information and
exit.\n");
+ fprintf(stderr, " -h --help Display this help and exit.\n\n");
+}
+
/*
* ---------------------------------------------------------------------
* end of user interface
@@ -2312,9 +2351,7 @@
fprintf(stderr, "Usage: %s [OPTION]... DIRECTORY...\n", progname);
fprintf(stderr, "Create the DIRECTORY(ies), if they do not already
exist.\n");
fprintf(stderr, "Any intermediate directories in the path are created, if
needed\n\n");
- fprintf(stderr, " -v, -V, --verbose explain what is being done.\n");
- fprintf(stderr, " --version output version information and
exit.\n");
- fprintf(stderr, " -h, -H, --help display this help and exit.\n\n");
+ print_stdusage();
return retval;
}
@@ -2322,10 +2359,8 @@
{
fprintf(stderr, "Usage: %s [OPTION]... DIRECTORY...\n", progname);
fprintf(stderr, "Remove (unlink) the DIRECTORY(ies).\n\n");
- fprintf(stderr, " -r, -R, remove the contents of directories
recursively.\n\n");
- fprintf(stderr, " -v, -V, --verbose explain what is being done.\n");
- fprintf(stderr, " --version output version information and
exit.\n");
- fprintf(stderr, " -h, -H, --help display this help and exit.\n\n");
+ fprintf(stderr, " -r remove the contents of directories
recursively.\n\n");
+ print_stdusage();
return retval;
}
@@ -2333,15 +2368,13 @@
{
fprintf(stderr, "Usage: %s [OPTION]... FILE...\n", progname);
fprintf(stderr, "Update the access and modification times of each FILE to the
current time\n\n");
- fprintf(stderr, " -a, -A, change only the access time.\n");
- fprintf(stderr, " -c, -C, do not create any files.\n");
- fprintf(stderr, " -d, -D, STRING parse STRING and use it instead of current
time.\n");
- fprintf(stderr, " -m, -M, change only the modification
time.\n");
- fprintf(stderr, " -r, -R, FILE use this file time's instead current
time.\n");
- fprintf(stderr, " -t, -T, STAMP use [[CC]YY]MMDDhhmm[.ss] instead of
current time.\n\n");
- fprintf(stderr, " -v, -V, --verbose explain what is being done.\n");
- fprintf(stderr, " --version output version information and
exit.\n");
- fprintf(stderr, " -h, -H, --help display this help and exit.\n\n");
+ fprintf(stderr, " -a change only the access time.\n");
+ fprintf(stderr, " -c do not create any files.\n");
+ fprintf(stderr, " -d STRING parse STRING and use it instead of current
time.\n");
+ fprintf(stderr, " -m change only the modification time.\n");
+ fprintf(stderr, " -r FILE use this file time's instead current
time.\n");
+ fprintf(stderr, " -t STAMP use [[CC]YY]MMDDhhmm[.ss] instead of current
time.\n\n");
+ print_stdusage();
return retval;
}
@@ -2349,30 +2382,51 @@
{
fprintf(stderr, "Usage: %s [OPTION]... program [ARGUMENTS]\n", progname);
fprintf(stderr, "Execute program.\n\n");
- fprintf(stderr, " -c, -C, Replace cygwin paths.\n");
- fprintf(stderr, " -s, -S, Replace SUA paths.\n");
- fprintf(stderr, " -r, -R, Replace relative paths.\n");
- fprintf(stderr, " -e, -E, Keep existing environment.\n");
- fprintf(stderr, " -f, -F, Use forward slashes.\n\n");
- fprintf(stderr, " -v, -V, --verbose explain what is being done.\n");
- fprintf(stderr, " --version output version information and
exit.\n");
- fprintf(stderr, " -h, -H, --help display this help and exit.\n\n");
+ fprintf(stderr, " -c Replace cygwin paths.\n");
+ fprintf(stderr, " -s Replace SUA paths.\n");
+ fprintf(stderr, " -r Replace relative paths.\n");
+ fprintf(stderr, " -e Keep existing environment.\n");
+ fprintf(stderr, " -f Use forward slashes.\n\n");
+ print_stdusage();
return retval;
}
static int prog_mktemp_usage(int retval)
{
fprintf(stderr, "Usage: %s [OPTION]... [TEMPLATE]\n", progname);
- fprintf(stderr, "Execute program.\n\n");
- fprintf(stderr, " -d, -D, Make a directory instead file.\n");
- fprintf(stderr, " -q, -Q, Be quiet.\n");
- fprintf(stderr, " -u, -U, Unlink file or directory befor
exiting.\n\n");
- fprintf(stderr, " -v, -V, --verbose explain what is being done.\n");
- fprintf(stderr, " --version output version information and
exit.\n");
- fprintf(stderr, " -h, -H, --help display this help and exit.\n\n");
+ fprintf(stderr, "Make temporary file (unique).\n\n");
+ fprintf(stderr, " -d Make a directory instead file.\n");
+ fprintf(stderr, " -u Unlink file or directory befor
exiting.\n\n");
+ print_stdusage();
return retval;
}
+static int prog_image_usage(int retval)
+{
+ fprintf(stderr, "Usage: %s [OPTION]... FILE...\n", progname);
+ fprintf(stderr, "Get information about PE image\n\n");
+ fprintf(stderr, " -a Print all information.\n");
+ fprintf(stderr, " -l Print long information.\n");
+ fprintf(stderr, " -c Characteristcs (numeric).\n");
+ fprintf(stderr, " -C Characteristcs (described).\n");
+ fprintf(stderr, " -d Provided file is DLL.\n");
+ fprintf(stderr, " -m Architecture type of the image\n");
+ fprintf(stderr, " -t Date and time the image was created by the
linker\n");
+ fprintf(stderr, " -T Strftime format for -t\n");
+ fprintf(stderr, " -s Subsystem required to run this
image\n");
+ fprintf(stderr, " -S Number of bytes to commit for the
stack\n");
+ fprintf(stderr, " -b Preferred address of the image when it is
loaded in memory.\n");
+ fprintf(stderr, " -L Linker version used.\n");
+ fprintf(stderr, " -o Required operating system.\n");
+ fprintf(stderr, " -i Version number of the image.\n");
+ fprintf(stderr, " -f File Version (64-Bit number).\n");
+ fprintf(stderr, " -F File Version (from Resource).\n");
+ fprintf(stderr, " -p Product Version (64-Bit number).\n");
+ fprintf(stderr, " -P Product Version (from Resource).\n");
+ print_stdusage();
+ return retval;
+}
+
/*
* ---------------------------------------------------------------------
* end of programs usage
@@ -2390,30 +2444,30 @@
int i, ch, rv = 0;
verbose = 0;
- x_free(__pname);
- __pname = "mkdir";
- while ((ch = getopt(argc, argv, "hHvV")) != EOF) {
+ while ((ch = getopt(argc, argv, "hqv", 1)) != EOF) {
switch (ch) {
case '.':
- if (!strcmp(optarg, "verbose"))
+ if (!stricmp(optarg, "verbose"))
verbose = 1;
- else if (!strcmp(optarg, "version"))
+ else if (!stricmp(optarg, "version"))
return print_banner(1);
- else if (!strcmp(optarg, "help"))
+ else if (!stricmp(optarg, "help"))
return prog_mkdir_usage(0);
else
return prog_mkdir_usage(EINVAL);
break;
case 'v':
- case 'V':
verbose = 1;
break;
+ case 'q':
+ xquiet = 1;
+ break;
case 'h':
- case 'H':
return prog_mkdir_usage(0);
break;
case '?':
+ case ':':
return EINVAL;
break;
}
@@ -2436,33 +2490,32 @@
int i, ch, rv = 0;
int recurse = 0;
- x_free(__pname);
- __pname = "rmdir";
- while ((ch = getopt(argc, argv, "hHvVrR")) != EOF) {
+ while ((ch = getopt(argc, argv, "rhqv", 1)) != EOF) {
switch (ch) {
case '.':
- if (!strcmp(optarg, "verbose"))
+ if (!stricmp(optarg, "verbose"))
verbose = 1;
- else if (!strcmp(optarg, "version"))
+ else if (!stricmp(optarg, "version"))
return print_banner(1);
- else if (!strcmp(optarg, "help"))
+ else if (!stricmp(optarg, "help"))
return prog_rmdir_usage(0);
else
return prog_rmdir_usage(EINVAL);
break;
case 'v':
- case 'V':
verbose = 1;
break;
+ case 'q':
+ xquiet = 1;
+ break;
case 'h':
- case 'H':
return prog_rmdir_usage(0);
break;
case 'r':
- case 'R':
recurse = 1;
break;
case '?':
+ case ':':
return EINVAL;
break;
}
@@ -2496,52 +2549,46 @@
wchar_t file[X_MAX_PATH];
WIN32_FILE_ATTRIBUTE_DATA ad;
- x_free(__pname);
- __pname = "touch";
- while ((ch = getopt(argc, argv, "aAcCfFmMr:R:t:hHvV")) != EOF) {
+ while ((ch = getopt(argc, argv, "acfmr:t:hqv", 1)) != EOF) {
switch (ch) {
case '.':
- if (!strcmp(optarg, "verbose"))
+ if (!stricmp(optarg, "verbose"))
verbose = 1;
- else if (!strcmp(optarg, "version"))
+ else if (!stricmp(optarg, "version"))
return print_banner(1);
- else if (!strcmp(optarg, "help"))
+ else if (!stricmp(optarg, "help"))
return prog_touch_usage(0);
else
return prog_touch_usage(EINVAL);
break;
case 'v':
- case 'V':
verbose = 1;
break;
+ case 'q':
+ xquiet = 1;
+ break;
case 'h':
- case 'H':
return prog_touch_usage(0);
break;
case 'f':
- case 'F':
force = 1;
case 'c':
- case 'C':
create = OPEN_EXISTING;
break;
case 'a':
- case 'A':
flags |= 1;
break;
case 'm':
- case 'M':
flags |= 2;
break;
case 'r':
- case 'R':
from = optarg;
break;
case 't':
- case 'T':
tstr = optarg;
break;
case '?':
+ case ':':
return EINVAL;
break;
}
@@ -2697,50 +2744,45 @@
char **mainargv = NULL;
char wcpath[MAX_PATH + 32] = { 0 };
- x_free(__pname);
- __pname = "exec";
- while ((ch = getopt(argc, argv, "cCeEfFrRsShHvV")) != EOF) {
+ while ((ch = getopt(argc, argv, "cefrshqv", 1)) != EOF) {
switch (ch) {
case '.':
- if (!strcmp(optarg, "verbose"))
+ if (!stricmp(optarg, "verbose"))
verbose = 1;
- else if (!strcmp(optarg, "version"))
+ else if (!stricmp(optarg, "version"))
return print_banner(1);
- else if (!strcmp(optarg, "help"))
+ else if (!stricmp(optarg, "help"))
return prog_exec_usage(0);
else
return prog_exec_usage(EINVAL);
break;
case 'v':
- case 'V':
verbose = 1;
break;
+ case 'q':
+ xquiet = 1;
+ break;
case 'h':
- case 'H':
return prog_exec_usage(0);
break;
case 'c':
- case 'C':
cygwin = 1;
break;
case 's':
- case 'S':
suawin = 1;
break;
case 'e':
- case 'E':
keepenv = 1;
break;
case 'r':
- case 'R':
relpath = 1;
break;
case 'f':
- case 'F':
back = 0;
windrive[2] = '/';
break;
case '?':
+ case ':':
return EINVAL;
break;
}
@@ -2758,8 +2800,7 @@
/* TODO: Figure out the paths from
* the registry
*/
- rv = errno = ENOENT;
- perror("JAVA_HOME environment");
+ rv = x_perror(ENOENT, "JAVA_HOME environment");
goto cleanup;
}
strcpy(wcpath, jhome);
@@ -2773,8 +2814,7 @@
!stricmp(argv[0], "lib") ||
!stricmp(argv[0], "link")) {
if (!getmsvcpath()) {
- rv = errno = ENOENT;
- perror("Microsoft compiler");
+ rv = x_perror(ENOENT, "Microsoft compiler");
goto cleanup;
}
strcpy(wcpath, getmsvcpath());
@@ -2790,15 +2830,13 @@
if (cygwin) {
if (!(posixroot = getcygdrive(&drive, back))) {
- rv = errno = ENOENT;
- perror("Cygwing drive");
+ rv = x_perror(ENOENT, "Cygwing drive");
goto cleanup;
}
}
else if (suawin) {
if (!(posixroot = getsuadrive(&drive, back))) {
- rv = errno = ENOENT;
- perror("Posix drive");
+ rv = x_perror(ENOENT, "Posix drive");
goto cleanup;
}
}
@@ -2844,8 +2882,7 @@
fprintf(stdout, "%s: exit(%d)\n", mainargv[0], rv);
}
else {
- rv = errno = ENOENT;
- perror(mainargv[0]);
+ rv = x_perror(ENOENT, mainargv[0]);
}
cleanup:
@@ -2864,48 +2901,41 @@
{
int ch, rv = 0;
char path[MAX_PATH] = { 0 };
- int silent = 0;
int mdir = 0;
int unsafe = 0;
int randnum;
char patern[MAX_PATH];
register char *start, *trv, *suffp;
- x_free(__pname);
- __pname = "mktemp";
- while ((ch = getopt(argc, argv, "dDqQhHuUvV")) != EOF) {
+ while ((ch = getopt(argc, argv, "dquhqv", 1)) != EOF) {
switch (ch) {
case '.':
- if (!strcmp(optarg, "verbose"))
+ if (!stricmp(optarg, "verbose"))
verbose = 1;
- else if (!strcmp(optarg, "version"))
+ else if (!stricmp(optarg, "version"))
return print_banner(1);
- else if (!strcmp(optarg, "help"))
+ else if (!stricmp(optarg, "help"))
return prog_mktemp_usage(0);
else
return prog_mktemp_usage(1);
break;
case 'v':
- case 'V':
verbose = 1;
break;
+ case 'q':
+ xquiet = 1;
+ break;
case 'h':
- case 'H':
return prog_mktemp_usage(0);
break;
case 'd':
- case 'D':
mdir = 1;
break;
- case 'q':
- case 'Q':
- silent = 1;
- break;
case 'u':
- case 'U':
unsafe = 1;
break;
case '?':
+ case ':':
return 1;
break;
}
@@ -2918,22 +2948,17 @@
strcpy(patern, "tmp.XXXXXXXX");
if (GetTempPathA(MAX_PATH - strlen(patern) - 1, path) == 0) {
- if (!silent)
- perror("Temp Path");
+ x_perror(0, "Temp Path");
return 1;
}
strcat(path, patern);
x_backslash(path);
- printf("Temp base %s\n", path);
for (trv = path; *trv; ++trv)
;
suffp = trv;
--trv;
if (trv < path) {
- if (!silent) {
- errno = EINVAL;
- perror("Temp Path");
- }
+ x_perror(EINVAL, "Temp Path");
return 1;
}
@@ -2953,8 +2978,7 @@
if (errno == ENOENT) {
if (mdir) {
if (mkdir(path)) {
- if (!silent)
- perror(path);
+ x_perror(0, path);
return 1;
}
if (unsafe)
@@ -2963,8 +2987,7 @@
else {
FILE *fp = fopen(path, "w");
if (!fp) {
- if (!silent)
- perror(path);
+ x_perror(0, path);
return 1;
}
fclose(fp);
@@ -2979,10 +3002,7 @@
for (trv = start;;) {
char *pad;
if (*trv == '\0' || trv == suffp) {
- if (!silent) {
- errno = EINVAL;
- perror("Temp Path");
- }
+ x_perror(ENOENT, "Temp Path");
return 1;
}
pad = strchr((char *)padchar, *trv);
@@ -2999,12 +3019,558 @@
return rv;
}
+ struct Var {
+ WORD wLength;
+ WORD wValueLength;
+ WORD wType;
+ WCHAR szKey[1];
+ };
+
+static char *qresinfo(void *data, DWORD lang, const char *info)
+{
+ ULONG u;
+ void *rv;
+ char buff[1024];
+
+ if (lang) {
+ sprintf(buff, "\\StringFileInfo\\%02X%02X%02X%02X\\%s",
+ (lang & 0x0000ff00) >> 8,
+ (lang & 0x000000ff),
+ (lang & 0xff000000) >> 24,
+ (lang & 0x00ff0000) >> 16,
+ info);
+ }
+ else {
+ sprintf(buff, "\\StringFileInfo\\%04X04B0\\%s",
+ GetUserDefaultLangID(),
+ info);
+ }
+ if (VerQueryValueA(data, buff, &rv, &u))
+ return (char *)rv;
+ else
+ return 0;
+}
+
+
+static int prog_image(int argc, const char **argv, const char **env)
+{
+ int i, ch, rv = 0;
+ char *dllpath = NULL;
+ int prall = 0;
+ BOOL dotdll = FALSE;
+ LOADED_IMAGE img;
+ DWORD infosiz = 0;
+ void *pidata = NULL;
+ VS_FIXEDFILEINFO *fvi = NULL;
+
+ int lcnt = 0;
+ int pname = 0;
+ int plong = 0;
+ int pmachine = 0;
+ int ptime = 0;
+ int pnchar = 0;
+ int pschar = 0;
+ int psubsys = 0;
+ int pstack = 0;
+ int posver = 0;
+ int pimgver = 0;
+ int pbase = 0;
+ int plinker = 0;
+ int pnfver = 0;
+ int pnfveri = 0;
+ int pnpver = 0;
+ int pnpveri = 0;
+ char *tfmt = NULL;
+
+ while ((ch = getopt(argc, argv, "aAbBcCdDiIlLmMnNoOpPfFsStT:hHqQvV", 0)) !=
EOF) {
+ switch (ch) {
+ case '.':
+ if (!stricmp(optarg, "verbose"))
+ verbose = 1;
+ else if (!stricmp(optarg, "version"))
+ return print_banner(1);
+ else if (!stricmp(optarg, "help"))
+ return prog_mktemp_usage(0);
+ else if (!stricmp(optarg, "path"))
+ dllpath = x_strdup(optarg);
+ else
+ return prog_image_usage(1);
+ break;
+ case 'v':
+ case 'V':
+ verbose = 1;
+ break;
+ case 'q':
+ case 'Q':
+ xquiet = 1;
+ break;
+ case 'h':
+ case 'H':
+ return prog_image_usage(0);
+ break;
+ case 'a':
+ case 'A':
+ prall = 1;
+ pname = 1;
+ pmachine = 1;
+ ptime = 1;
+ pnchar = 1;
+ psubsys = 1;
+ pstack = 1;
+ pbase = 1;
+ pimgver = 1;
+ posver = 1;
+ plinker = 1;
+ pnpver = 1;
+ pnfver = 1;
+ pnpveri = 1;
+ pnfveri = 1;
+ break;
+ case 'b':
+ case 'B':
+ pbase = 1;
+ break;
+ case 'i':
+ case 'I':
+ pimgver = 1;
+ break;
+ case 'l':
+ plong = 1;
+ case 'L':
+ plinker = 1;
+ break;
+ case 'm':
+ case 'M':
+ pmachine = 1;
+ break;
+ case 'n':
+ case 'N':
+ pname = 1;
+ break;
+ case 'T':
+ tfmt = x_strdup(optarg);
+ case 't':
+ ptime = 1;
+ break;
+ case 'c':
+ pnchar = 1;
+ break;
+ case 'C':
+ pschar = 1;
+ break;
+ case 'o':
+ case 'O':
+ posver = 1;
+ break;
+ case 's':
+ psubsys = 1;
+ break;
+ case 'S':
+ pstack = 1;
+ break;
+ case 'F':
+ pnfveri = 1;
+ case 'f':
+ pnfver = 1;
+ break;
+ case 'P':
+ pnpveri = 1;
+ case 'p':
+ pnpver = 1;
+ break;
+ case 'd':
+ case 'D':
+ dotdll = TRUE;
+ break;
+ case '?':
+ case ':':
+ return 1;
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc < 1) {
+ return prog_image_usage(EINVAL);
+ }
+ for (i = 0; i < argc; i++) {
+ int lang = 0;
+ if (i) {
+ lcnt = 0;
+ fputc('\n', stdout);
+ }
+ if (!MapAndLoad((char *)argv[i], dllpath, &img, dotdll, TRUE)) {
+ return x_perror(0, argv[i]);
+ }
+ infosiz = GetFileVersionInfoSizeA(img.ModuleName, NULL);
+ if (infosiz) {
+ pidata = x_malloc(infosiz);
+ if (!GetFileVersionInfoA(img.ModuleName, 0,
+ infosiz, pidata)) {
+ rv = x_perror(0, img.ModuleName);
+ UnMapAndLoad(&img);
+ x_free(pidata);
+ return rv;
+ }
+ fvi = NULL;
+ if (pnpver || pnfver) {
+ UINT ul;
+ void *p;
+ if (!VerQueryValueA(pidata, "\\",
+ &fvi, &ul)) {
+ x_perror(0, img.ModuleName);
+ }
+ else {
+ if (fvi->dwSignature != 0xFEEF04BD)
+ fvi = NULL;
+ }
+ if (!VerQueryValueA(pidata, "\\VarFileInfo\\Translation",
+ &p, &ul)) {
+ x_perror(0, img.ModuleName);
+ }
+ else {
+ if (ul == 4)
+ memcpy(&lang, p, 4);
+ }
+ }
+ }
+ if (!pname && (pmachine + pstack + psubsys +
+ pnchar + pschar + posver + pimgver +
+ pbase + plinker + pnpver + pnfver) == 0)
+ pname = 1;
+ if (pname) {
+ fputs(img.ModuleName, stdout);
+ if (plong)
+ fputc('\n', stdout);
+ lcnt++;
+ }
+ if (pmachine) {
+ char machine[8] = { 0 };
+ switch (img.FileHeader->FileHeader.Machine) {
+ case IMAGE_FILE_MACHINE_I386:
+ strcpy(machine, "x86");
+ break;
+ case IMAGE_FILE_MACHINE_IA64:
+ strcpy(machine, "i64");
+ break;
+ case IMAGE_FILE_MACHINE_AMD64:
+ strcpy(machine, "x64");
+ break;
+ default:
+ sprintf(machine, "0x%04x",
+ img.FileHeader->FileHeader.Machine);
+ break;
+ }
+ if (plong) {
+ fputs("Machine: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+ fputs(machine, stdout);
+ if (plong)
+ fputc('\n', stdout);
+ }
+ if (ptime) {
+ char buff[64] = { 0 };
+ struct tm *lt;
+ time_t t = (time_t)img.FileHeader->FileHeader.TimeDateStamp;
+ lt = localtime(&t);
+ if (!tfmt)
+ tfmt = x_strdup("%Y-%m-%d %H:%M:%S");
+ if (!strftime(buff, 64, tfmt, lt)) {
+ rv = x_perror(errno, tfmt);
+ UnMapAndLoad(&img);
+ return rv;
+ }
+ if (plong) {
+ fputs("Linked: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+ fputs(buff, stdout);
+ if (plong)
+ fputc('\n', stdout);
+ }
+ if (psubsys) {
+ if (plong) {
+ fputs("Subsystem: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+ switch (img.FileHeader->OptionalHeader.Subsystem) {
+ case IMAGE_SUBSYSTEM_UNKNOWN:
+ fputs("unknown", stdout);
+ break;
+ case IMAGE_SUBSYSTEM_NATIVE:
+ fputs("native", stdout);
+ break;
+ case IMAGE_SUBSYSTEM_WINDOWS_GUI:
+ fputs("gui", stdout);
+ break;
+ case IMAGE_SUBSYSTEM_WINDOWS_CUI:
+ fputs("console", stdout);
+ break;
+ case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
+ fputs("ce", stdout);
+ break;
+ case IMAGE_SUBSYSTEM_POSIX_CUI:
+ fputs("posix", stdout);
+ break;
+ case 16:
+ fputs("boot", stdout);
+ break;
+ default:
+ fprintf(stdout, "%d",
+ img.FileHeader->OptionalHeader.Subsystem);
+ break;
+ }
+ if (plong)
+ fputc('\n', stdout);
+ }
+ if (pstack) {
+ if (plong) {
+ fputs("Stack: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+#ifdef _WIN64
+ fprintf(stdout, "%I64d",
+#else
+ fprintf(stdout, "%d",
+#endif
+ img.FileHeader->OptionalHeader.SizeOfStackReserve);
+ if (plong)
+ fputc('\n', stdout);
+ }
+ if (posver) {
+ if (plong) {
+ fputs("OperatingSystem: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+ fprintf(stdout, "%d.%d",
+ img.FileHeader->OptionalHeader.MajorOperatingSystemVersion,
+ img.FileHeader->OptionalHeader.MinorOperatingSystemVersion);
+ if (plong)
+ fputc('\n', stdout);
+ }
+ if (pimgver && fvi) {
+ if (plong) {
+ fputs("ImageVersion: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+ fprintf(stdout, "%d.%d",
+ img.FileHeader->OptionalHeader.MajorImageVersion,
+ img.FileHeader->OptionalHeader.MinorImageVersion);
+ if (plong)
+ fputc('\n', stdout);
+ }
+ if (pnfver && fvi) {
+ LARGE_INTEGER li;
+ char *p;
+ if (plong) {
+ fputs("FileVersion: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+ li.HighPart = fvi->dwFileVersionMS;
+ li.LowPart = fvi->dwFileVersionLS;
+ if (pnfveri && (p = qresinfo(pidata, lang, "FileVersion")))
{
+ fputs(p, stdout);
+ }
+ else
+ fprintf(stdout, "%I64d", li.QuadPart);
+ if (plong)
+ fputc('\n', stdout);
+ }
+
+ if (pnpver && fvi) {
+ LARGE_INTEGER li;
+ char *p;
+ if (plong) {
+ fputs("ProductVersion: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+ li.HighPart = fvi->dwProductVersionMS;
+ li.LowPart = fvi->dwProductVersionLS;
+ if (pnpveri && (p = qresinfo(pidata, lang,
"ProductVersion"))) {
+ fputs(p, stdout);
+ }
+ else
+ fprintf(stdout, "%I64d", li.QuadPart);
+ if (plong)
+ fputc('\n', stdout);
+ }
+ if (plinker) {
+ if (plong) {
+ fputs("LinkerVersion: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+ fprintf(stdout, "%d.%d",
+ img.FileHeader->OptionalHeader.MajorLinkerVersion,
+ img.FileHeader->OptionalHeader.MinorLinkerVersion);
+ if (plong)
+ fputc('\n', stdout);
+ }
+ if (pbase) {
+ if (plong) {
+ fputs("ImageBase: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+#ifdef _WIN64
+ fprintf(stdout, "0x%016I64x",
+#else
+ fprintf(stdout, "0x%08x",
+#endif
+ img.FileHeader->OptionalHeader.ImageBase);
+ if (plong)
+ fputc('\n', stdout);
+ }
+ if (pnchar || pschar) {
+ if (plong) {
+ fputs("Characteristics: ", stdout);
+ }
+ else {
+ if (lcnt++)
+ fputc('\t', stdout);
+ }
+ if (pnchar) {
+ fprintf(stdout, "0x%04x",
+ img.FileHeader->FileHeader.Characteristics);
+ if (pschar)
+ fputs(" (", stdout);
+ }
+ if (pschar) {
+ int cc = 0;
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_RELOCS_STRIPPED) {
+ fputs("reloc-stripped", stdout);
+ cc++;
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_EXECUTABLE_IMAGE) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("executable", stdout);
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_LINE_NUMS_STRIPPED) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("coff-lines-stripped", stdout);
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_LOCAL_SYMS_STRIPPED) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("coff-symtable-stripped", stdout);
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_LARGE_ADDRESS_AWARE) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("large-address", stdout);
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_32BIT_MACHINE) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("32-bit", stdout);
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("removable-swap", stdout);
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_NET_RUN_FROM_SWAP) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("net-swap", stdout);
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_DEBUG_STRIPPED) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("debug-stripped", stdout);
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_SYSTEM) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("filesystem", stdout);
+ }
+ if (img.FileHeader->FileHeader.Characteristics &
+ IMAGE_FILE_DLL) {
+ if (cc++)
+ fputs(", ", stdout);
+ fputs("dll", stdout);
+ }
+ if (pnchar)
+ fputc(')', stdout);
+ }
+ if (plong)
+ fputc('\n', stdout);
+ }
+ UnMapAndLoad(&img);
+ x_free(pidata);
+ pidata = NULL;
+ }
+ if (verbose)
+ fputc('\n', stdout);
+ return 0;
+}
+
/*
* ---------------------------------------------------------------------
* end of programs
* ---------------------------------------------------------------------
*/
+typedef int (*pmain_t)(int, const char **, const char **);
+
+static struct x_program {
+ const char *name;
+ pmain_t pmain;
+} x_programs[] = {
+ { "mkdir", prog_mkdir },
+ { "md", prog_mkdir },
+ { "rmdir", prog_rmdir },
+ { "rd", prog_rmdir },
+ { "touch", prog_touch },
+ { "exec", prog_exec },
+ { "mktemp", prog_mktemp },
+ { "image", prog_image },
+ { "coff", prog_image },
+
+ { NULL, NULL }
+};
+
/*
* ---------------------------------------------------------------------
* utf-8 main. Arguments passed are utf-8 encoded
@@ -3012,44 +3578,42 @@
*/
static int umain(int argc, const char **argv, const char **env)
{
- const char *name = progname;
+ const char *name = progname;
+ struct x_program *p;
+
if (*name == 'x' || *name == 'X')
name++;
- if (!stricmp(name, "mkdir"))
- return prog_mkdir(argc, argv, env);
- else {
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <command>\n",
- progname);
- return EINVAL;
+
+ p = &x_programs[0];
+ while (p->name) {
+ if (!stricmp(name, p->name)) {
+ x_free(__pname);
+ __pname = x_strdup(name);
+ return (*(p->pmain))(argc, argv, env);
}
- if (!stricmp(argv[1], "mkdir"))
- return prog_mkdir(--argc, ++argv, env);
- else if (!stricmp(argv[1], "rmdir"))
- return prog_rmdir(--argc, ++argv, env);
- else if (!stricmp(argv[1], "touch"))
- return prog_touch(--argc, ++argv, env);
- else if (!stricmp(argv[1], "exec"))
- return prog_exec(--argc, ++argv, env);
- else if (!stricmp(argv[1], "mktemp"))
- return prog_mktemp(--argc, ++argv, env);
- else if (!stricmp(argv[1], "test")) {
- argc -= 2;
- argv += 2;
- printf("Test %d %s\n", argc, *argv);
- if (argc && !strcmp(*argv, "ini"))
- return test_ini();
- if (argc && !strcmp(*argv, "path"))
- return test_path(--argc, ++argv, env);
+ p++;
+ }
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <command>\n",
+ progname);
+ print_programs();
+ return EINVAL;
+ }
+ --argc;
+ ++argv;
+ p = &x_programs[0];
+ while (p->name) {
+ if (!stricmp(argv[0], p->name)) {
+ x_free(__pname);
+ __pname = x_strdup(argv[0]);
+ return (*(p->pmain))(argc, argv, env);
}
- else {
- fprintf(stderr, "Usage: %s <command>\n",
- progname);
- print_programs();
- return EINVAL;
- }
+ p++;
}
- return 0;
+ fprintf(stderr, "Usage: %s <command>\n",
+ progname);
+ print_programs();
+ return EINVAL;
}
static void setup_env(const char **env)