|
|
|
@ -26,7 +26,7 @@ |
|
|
|
#include "file.h" |
|
|
|
|
|
|
|
#ifndef lint |
|
|
|
FILE_RCSID("@(#)$File: readcdf.c,v 1.37 2014/01/06 13:41:18 rrt Exp $") |
|
|
|
FILE_RCSID("@(#)$File: readcdf.c,v 1.40 2014/03/06 15:23:33 christos Exp $") |
|
|
|
#endif |
|
|
|
|
|
|
|
#include <stdlib.h> |
|
|
|
@ -77,6 +77,40 @@ static const struct nv { |
|
|
|
# define strcasestr strstr |
|
|
|
#endif |
|
|
|
|
|
|
|
static const struct cv { |
|
|
|
uint64_t clsid[2]; |
|
|
|
const char *mime; |
|
|
|
} clsid2mime[] = { |
|
|
|
{ |
|
|
|
#ifdef PHP_WIN32 |
|
|
|
{ 0x00000000000c1084ui64, 0x46000000000000c0ui64 }, |
|
|
|
#else |
|
|
|
{ 0x00000000000c1084LLU, 0x46000000000000c0LLU }, |
|
|
|
#endif |
|
|
|
"x-msi", |
|
|
|
} |
|
|
|
}, clsid2desc[] = { |
|
|
|
{ |
|
|
|
#ifdef PHP_WIN32 |
|
|
|
{ 0x00000000000c1084ui64, 0x46000000000000c0ui64 }, |
|
|
|
#else |
|
|
|
{ 0x00000000000c1084LLU, 0x46000000000000c0LLU }, |
|
|
|
#endif |
|
|
|
"MSI Installer", |
|
|
|
}, |
|
|
|
}; |
|
|
|
|
|
|
|
private const char * |
|
|
|
cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv) |
|
|
|
{ |
|
|
|
size_t i; |
|
|
|
for (i = 0; cv[i].mime != NULL; i++) { |
|
|
|
if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1]) |
|
|
|
return cv[i].mime; |
|
|
|
} |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
private const char * |
|
|
|
cdf_app_to_mime(const char *vbuf, const struct nv *nv) |
|
|
|
{ |
|
|
|
@ -95,7 +129,7 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv) |
|
|
|
|
|
|
|
private int |
|
|
|
cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, |
|
|
|
size_t count) |
|
|
|
size_t count, const cdf_directory_t *root_storage) |
|
|
|
{ |
|
|
|
size_t i; |
|
|
|
cdf_timestamp_t tp; |
|
|
|
@ -107,6 +141,9 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, |
|
|
|
|
|
|
|
memset(&ts, 0, sizeof(ts)); |
|
|
|
|
|
|
|
if (!NOTMIME(ms) && root_storage) |
|
|
|
str = cdf_clsid_to_mime(root_storage->d_storage_uuid, clsid2mime); |
|
|
|
|
|
|
|
for (i = 0; i < count; i++) { |
|
|
|
cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); |
|
|
|
switch (info[i].pi_type) { |
|
|
|
@ -163,7 +200,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, |
|
|
|
buf, vbuf) == -1) |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} else if (info[i].pi_id == |
|
|
|
} else if (str == NULL && info[i].pi_id == |
|
|
|
CDF_PROPERTY_NAME_OF_APPLICATION) { |
|
|
|
str = cdf_app_to_mime(vbuf, app2mime); |
|
|
|
} |
|
|
|
@ -217,7 +254,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, |
|
|
|
|
|
|
|
private int |
|
|
|
cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, |
|
|
|
const cdf_stream_t *sst) |
|
|
|
const cdf_stream_t *sst, const cdf_directory_t *root_storage) |
|
|
|
{ |
|
|
|
cdf_summary_info_header_t si; |
|
|
|
cdf_property_info_t *info; |
|
|
|
@ -228,6 +265,8 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, |
|
|
|
return -1; |
|
|
|
|
|
|
|
if (NOTMIME(ms)) { |
|
|
|
const char *str; |
|
|
|
|
|
|
|
if (file_printf(ms, "Composite Document File V2 Document") |
|
|
|
== -1) |
|
|
|
return -1; |
|
|
|
@ -255,9 +294,15 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, |
|
|
|
return -2; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (root_storage) { |
|
|
|
str = cdf_clsid_to_mime(root_storage->d_storage_uuid, clsid2desc); |
|
|
|
if (str) |
|
|
|
if (file_printf(ms, ", %s", str) == -1) |
|
|
|
return -2; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
m = cdf_file_property_info(ms, info, count); |
|
|
|
m = cdf_file_property_info(ms, info, count, root_storage); |
|
|
|
free(info); |
|
|
|
|
|
|
|
return m == -1 ? -2 : m; |
|
|
|
@ -275,6 +320,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, |
|
|
|
int i; |
|
|
|
const char *expn = ""; |
|
|
|
const char *corrupt = "corrupt: "; |
|
|
|
const cdf_directory_t *root_storage; |
|
|
|
|
|
|
|
info.i_fd = fd; |
|
|
|
info.i_buf = buf; |
|
|
|
@ -308,7 +354,8 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, |
|
|
|
goto out2; |
|
|
|
} |
|
|
|
|
|
|
|
if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) { |
|
|
|
if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst, |
|
|
|
&root_storage)) == -1) { |
|
|
|
expn = "Cannot read short stream"; |
|
|
|
goto out3; |
|
|
|
} |
|
|
|
@ -329,23 +376,21 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, |
|
|
|
#ifdef CDF_DEBUG |
|
|
|
cdf_dump_summary_info(&h, &scn); |
|
|
|
#endif |
|
|
|
if ((i = cdf_file_summary_info(ms, &h, &scn)) < 0) |
|
|
|
expn = "Can't expand summary_info"; |
|
|
|
if ((i = cdf_file_summary_info(ms, &h, &scn, root_storage)) < 0) |
|
|
|
expn = "Can't expand summary_info"; |
|
|
|
|
|
|
|
if (i == 0) { |
|
|
|
const char *str = NULL; |
|
|
|
cdf_directory_t *d; |
|
|
|
char name[__arraycount(d->d_name)]; |
|
|
|
size_t j, k; |
|
|
|
for (j = 0; j < dir.dir_len; j++) { |
|
|
|
|
|
|
|
for (j = 0; str == NULL && j < dir.dir_len; j++) { |
|
|
|
d = &dir.dir_tab[j]; |
|
|
|
for (k = 0; k < sizeof(name); k++) |
|
|
|
name[k] = (char)cdf_tole2(d->d_name[k]); |
|
|
|
if (NOTMIME(ms)) |
|
|
|
str = cdf_app_to_mime(name, name2desc); |
|
|
|
else |
|
|
|
str = cdf_app_to_mime(name, name2mime); |
|
|
|
if (str != NULL) |
|
|
|
break; |
|
|
|
str = cdf_app_to_mime(name, |
|
|
|
NOTMIME(ms) ? name2desc : name2mime); |
|
|
|
} |
|
|
|
if (NOTMIME(ms)) { |
|
|
|
if (str != NULL) { |
|
|
|
|