|
|
|
@ -1337,994 +1337,3 @@ create_vba_project(int record_count, const char *dir, struct uniq *U) |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_JSON |
|
|
|
|
#define cli_jsonnull(o,n)\ |
|
|
|
|
{ \
|
|
|
|
|
json_object *fpobj = json_object_new_string("null"); \
|
|
|
|
|
if (NULL == fpobj) { \
|
|
|
|
|
cli_errmsg("json: no memory for json string object.\n"); \
|
|
|
|
|
return CL_EMEM; \
|
|
|
|
|
} \
|
|
|
|
|
json_object_object_add(o, n, fpobj); \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define cli_jsonstr(o,n,s) \ |
|
|
|
|
{ \
|
|
|
|
|
json_object *fpobj = json_object_new_string(s); \
|
|
|
|
|
if (NULL == fpobj) { \
|
|
|
|
|
cli_errmsg("json: no memory for json string object.\n"); \
|
|
|
|
|
return CL_EMEM; \
|
|
|
|
|
} \
|
|
|
|
|
json_object_object_add(o, n, fpobj); \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define cli_jsonint(o,n,i) \ |
|
|
|
|
{ \
|
|
|
|
|
json_object *fpobj = json_object_new_int(i); \
|
|
|
|
|
if (NULL == fpobj) { \
|
|
|
|
|
cli_errmsg("json: no memory for json int object.\n"); \
|
|
|
|
|
return CL_EMEM; \
|
|
|
|
|
} \
|
|
|
|
|
json_object_object_add(o, n, fpobj); \
|
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
#define cli_jsonint64(o,n,i) \ |
|
|
|
|
{ \
|
|
|
|
|
json_object *fpobj = json_object_new_int64(i); \
|
|
|
|
|
if (NULL == fpobj) { \
|
|
|
|
|
cli_errmsg("json: no memory for json int object.\n"); \
|
|
|
|
|
return CL_EMEM; \
|
|
|
|
|
} \
|
|
|
|
|
json_object_object_add(o, n, fpobj); \
|
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
#define cli_jsonint64(o,n,i) cli_dbgmsg("%s: %lld [%llx]\n", n, i, i) |
|
|
|
|
|
|
|
|
|
#define cli_jsonbool(o,n,b) \ |
|
|
|
|
{ \
|
|
|
|
|
json_object *fpobj = json_object_new_boolean(b); \
|
|
|
|
|
if (NULL == fpobj) { \
|
|
|
|
|
cli_errmsg("json: no memory for json int object.\n"); \
|
|
|
|
|
return CL_EMEM; \
|
|
|
|
|
} \
|
|
|
|
|
json_object_object_add(o, n, fpobj); \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define cli_jsondouble(o,n,d) \ |
|
|
|
|
{ \
|
|
|
|
|
json_object *fpobj = json_object_new_double(d); \
|
|
|
|
|
if (NULL == fpobj) { \
|
|
|
|
|
cli_errmsg("json: no memory for json int object.\n"); \
|
|
|
|
|
return CL_EMEM; \
|
|
|
|
|
} \
|
|
|
|
|
json_object_object_add(o, n, fpobj); \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
#define cli_jsonnull(o,n) cli_dbgmsg("%s: null\n", n) |
|
|
|
|
#define cli_jsonstr(o,n,s) cli_dbgmsg("%s: \"%s\"\n", n, s) |
|
|
|
|
#define cli_jsonint(o,n,i) cli_dbgmsg("%s: %d [%x]\n", n, i, i) |
|
|
|
|
#define cli_jsonint64(o,n,i) cli_dbgmsg("%s: %lld [%llx]\n", n, i, i) |
|
|
|
|
#define cli_jsonbool(o,n,b) cli_dbgmsg("%s: %s\n", n, b ? "true":"false") |
|
|
|
|
#define cli_jsondouble(o,n,d) cli_dbgmsg("%s: %f\n", n, d) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#define WINUNICODE 0x04B0 |
|
|
|
|
#define PROPCNTLIMIT 25 |
|
|
|
|
#define PROPSTRLIMIT 100 |
|
|
|
|
|
|
|
|
|
#define sum16_endian_convert(v) le16_to_host((uint16_t)(v)) |
|
|
|
|
#define sum32_endian_convert(v) le32_to_host((uint32_t)(v)) |
|
|
|
|
#define sum64_endian_convert(v) le64_to_host((uint32_t)(v)) |
|
|
|
|
|
|
|
|
|
static char * |
|
|
|
|
get_property_name2(char *name, int size) |
|
|
|
|
{ |
|
|
|
|
int i, j; |
|
|
|
|
char *newname; |
|
|
|
|
|
|
|
|
|
if (*name == 0 || size <= 0 || size > 64) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
newname = (char *)cli_malloc(size * 7); |
|
|
|
|
if (!newname) { |
|
|
|
|
cli_errmsg("OLE2 [get_property_name2]: Unable to allocate memory for newname: %u\n", size * 7); |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
j = 0; |
|
|
|
|
/* size-2 to ignore trailing NULL */ |
|
|
|
|
for (i = 0; i < size - 2; i += 2) { |
|
|
|
|
if ((!(name[i] & 0x80)) && isprint(name[i])) { |
|
|
|
|
newname[j++] = tolower(name[i]); |
|
|
|
|
} else { |
|
|
|
|
if (name[i] < 10 && name[i] >= 0) { |
|
|
|
|
newname[j++] = '_'; |
|
|
|
|
newname[j++] = name[i] + '0'; |
|
|
|
|
} else { |
|
|
|
|
const uint16_t x = (((uint16_t) name[i]) << 8) | name[i + 1]; |
|
|
|
|
|
|
|
|
|
newname[j++] = '_'; |
|
|
|
|
newname[j++] = 'a' + ((x & 0xF)); |
|
|
|
|
newname[j++] = 'a' + ((x >> 4) & 0xF); |
|
|
|
|
newname[j++] = 'a' + ((x >> 8) & 0xF); |
|
|
|
|
newname[j++] = 'a' + ((x >> 16) & 0xF); |
|
|
|
|
newname[j++] = 'a' + ((x >> 24) & 0xF); |
|
|
|
|
} |
|
|
|
|
newname[j++] = '_'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
newname[j] = '\0'; |
|
|
|
|
if (strlen(newname) == 0) { |
|
|
|
|
free(newname); |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
return newname; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum summary_pidsi { |
|
|
|
|
SPID_CODEPAGE = 0x00000001, |
|
|
|
|
SPID_TITLE = 0x00000002, |
|
|
|
|
SPID_SUBJECT = 0x00000003, |
|
|
|
|
SPID_AUTHOR = 0x00000004, |
|
|
|
|
SPID_KEYWORDS = 0x00000005, |
|
|
|
|
SPID_COMMENTS = 0x00000006, |
|
|
|
|
SPID_TEMPLATE = 0x00000007, |
|
|
|
|
SPID_LASTAUTHOR = 0x00000008, |
|
|
|
|
SPID_REVNUMBER = 0x00000009, |
|
|
|
|
SPID_EDITTIME = 0x0000000A, |
|
|
|
|
SPID_LASTPRINTED = 0x0000000B, |
|
|
|
|
SPID_CREATEDTIME = 0x0000000C, |
|
|
|
|
SPID_MODIFIEDTIME = 0x0000000D, |
|
|
|
|
SPID_PAGECOUNT = 0x0000000E, |
|
|
|
|
SPID_WORDCOUNT = 0x0000000F, |
|
|
|
|
SPID_CHARCOUNT = 0x00000010, |
|
|
|
|
SPID_THUMBNAIL = 0x00000011, |
|
|
|
|
SPID_APPNAME = 0x00000012, |
|
|
|
|
SPID_SECURITY = 0x00000013 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum docsum_pidsi { |
|
|
|
|
DSPID_CODEPAGE = 0x00000001, |
|
|
|
|
DSPID_CATEGORY = 0x00000002, |
|
|
|
|
DSPID_PRESFORMAT = 0x00000003, |
|
|
|
|
DSPID_BYTECOUNT = 0x00000004, |
|
|
|
|
DSPID_LINECOUNT = 0x00000005, |
|
|
|
|
DSPID_PARCOUNT = 0x00000006, |
|
|
|
|
DSPID_SLIDECOUNT = 0x00000007, |
|
|
|
|
DSPID_NOTECOUNT = 0x00000008, |
|
|
|
|
DSPID_HIDDENCOUNT = 0x00000009, |
|
|
|
|
DSPID_MMCLIPCOUNT = 0x0000000A, |
|
|
|
|
DSPID_SCALE = 0x0000000B, |
|
|
|
|
DSPID_HEADINGPAIR = 0x0000000C, /* VT_VARIANT | VT_VECTOR */ |
|
|
|
|
DSPID_DOCPARTS = 0x0000000D, /* VT_VECTOR | VT_LPSTR */ |
|
|
|
|
DSPID_MANAGER = 0x0000000E, |
|
|
|
|
DSPID_COMPANY = 0x0000000F, |
|
|
|
|
DSPID_LINKSDIRTY = 0x00000010, |
|
|
|
|
DSPID_CCHWITHSPACES = 0x00000011, |
|
|
|
|
DSPID_SHAREDDOC = 0x00000013, /* must be false */ |
|
|
|
|
DSPID_LINKBASE = 0x00000014, /* moved to user-defined */ |
|
|
|
|
DSPID_HLINKS = 0x00000015, /* moved to user-defined */ |
|
|
|
|
DSPID_HYPERLINKSCHANGED = 0x00000016, |
|
|
|
|
DSPID_VERSION = 0x00000017, |
|
|
|
|
DSPID_DIGSIG = 0x00000018, |
|
|
|
|
DSPID_CONTENTTYPE = 0x0000001A, |
|
|
|
|
DSPID_CONTENTSTATUS = 0x0000001B, |
|
|
|
|
DSPID_LANGUAGE = 0x0000001C, |
|
|
|
|
DSPID_DOCVERSION = 0x0000001D |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum property_type { |
|
|
|
|
PT_EMPTY = 0x0000, |
|
|
|
|
PT_NULL = 0x0001, |
|
|
|
|
PT_INT16 = 0x0002, |
|
|
|
|
PT_INT32 = 0x0003, |
|
|
|
|
PT_FLOAT32 = 0x0004, |
|
|
|
|
PT_DOUBLE64 = 0x0005, |
|
|
|
|
PT_CURRENCY = 0x0006, |
|
|
|
|
PT_DATE = 0x0007, |
|
|
|
|
PT_BSTR = 0x0008, |
|
|
|
|
PT_ERROR = 0x000A, |
|
|
|
|
PT_BOOL = 0x000B, |
|
|
|
|
PT_DECIMAL = 0x000E, |
|
|
|
|
PT_INT8v1 = 0x0010, |
|
|
|
|
PT_UINT8 = 0x0011, |
|
|
|
|
PT_UINT16 = 0x0012, |
|
|
|
|
PT_UINT32 = 0x0013, |
|
|
|
|
PT_INT64 = 0x0014, |
|
|
|
|
PT_UINT64 = 0x0015, |
|
|
|
|
PT_INT32v1 = 0x0016, |
|
|
|
|
PT_UINT32v1 = 0x0017, |
|
|
|
|
PT_LPSTR = 0x001E, |
|
|
|
|
PT_LPWSTR = 0x001F, |
|
|
|
|
PT_FILETIME = 0x0040, |
|
|
|
|
PT_BLOB = 0x0041 |
|
|
|
|
/* More Types not currently handled */ |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
typedef struct summary_stub { |
|
|
|
|
uint16_t byte_order; |
|
|
|
|
uint16_t version; |
|
|
|
|
uint32_t system; /* implementation-specific */ |
|
|
|
|
uint8_t CLSID[16]; |
|
|
|
|
|
|
|
|
|
uint32_t num_propsets; /* 1 or 2 */ |
|
|
|
|
} summary_stub_t; |
|
|
|
|
|
|
|
|
|
typedef struct propset_summary_entry { |
|
|
|
|
uint8_t FMTID[16]; |
|
|
|
|
uint32_t offset; |
|
|
|
|
} propset_entry_t; |
|
|
|
|
|
|
|
|
|
typedef struct summary_ctx { |
|
|
|
|
cli_ctx *ctx; |
|
|
|
|
#ifdef HAVE_JSON |
|
|
|
|
json_object *summary; |
|
|
|
|
#else |
|
|
|
|
char *summary; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
uint16_t byte_order; |
|
|
|
|
uint16_t version; |
|
|
|
|
int16_t codepage; |
|
|
|
|
|
|
|
|
|
const char *propname; |
|
|
|
|
int writecp; /* used to trigger writing the codepage value */ |
|
|
|
|
} summary_ctx_t; |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
cli_vba_process_prop(summary_ctx_t *sctx, unsigned char *databuf, size_t buflen, uint32_t offset) |
|
|
|
|
{ |
|
|
|
|
uint16_t proptype, padding; |
|
|
|
|
|
|
|
|
|
if (offset+4 > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memcpy(&proptype, databuf+offset, sizeof(proptype)); |
|
|
|
|
offset+=sizeof(proptype); |
|
|
|
|
memcpy(&padding, databuf+offset, sizeof(padding)); |
|
|
|
|
offset+=sizeof(padding); |
|
|
|
|
/* endian conversion */ |
|
|
|
|
proptype = sum16_endian_convert(proptype); |
|
|
|
|
|
|
|
|
|
//cli_dbgmsg("proptype: 0x%04x\n", proptype);
|
|
|
|
|
if (padding != 0) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch (proptype) { |
|
|
|
|
case PT_EMPTY: |
|
|
|
|
cli_jsonnull(sctx->summary, sctx->propname); |
|
|
|
|
break; |
|
|
|
|
case PT_NULL: |
|
|
|
|
cli_jsonnull(sctx->summary, sctx->propname); |
|
|
|
|
break; |
|
|
|
|
case PT_INT16: |
|
|
|
|
{ |
|
|
|
|
int16_t dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* endian conversion */ |
|
|
|
|
dout = sum16_endian_convert(dout); |
|
|
|
|
|
|
|
|
|
if (sctx->writecp) sctx->codepage = dout; |
|
|
|
|
|
|
|
|
|
cli_jsonint(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_INT32: |
|
|
|
|
case PT_INT32v1: |
|
|
|
|
{ |
|
|
|
|
int32_t dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* endian conversion */ |
|
|
|
|
dout = sum32_endian_convert(dout); |
|
|
|
|
|
|
|
|
|
cli_jsonint(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_FLOAT32: /* review this please */ |
|
|
|
|
{ |
|
|
|
|
float dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* TODO - endian conversion */ |
|
|
|
|
|
|
|
|
|
cli_jsondouble(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_DATE: |
|
|
|
|
case PT_DOUBLE64: /* review this please */ |
|
|
|
|
{ |
|
|
|
|
double dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* TODO - endian conversion */ |
|
|
|
|
|
|
|
|
|
cli_jsondouble(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
case PT_CURRENCY: |
|
|
|
|
break; |
|
|
|
|
case PT_ERROR: |
|
|
|
|
break; |
|
|
|
|
*/ |
|
|
|
|
case PT_BOOL: |
|
|
|
|
{ |
|
|
|
|
uint16_t dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* no need for endian conversion */ |
|
|
|
|
|
|
|
|
|
cli_jsonbool(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
/* case PT_DECIMAL:
|
|
|
|
|
break;*/ |
|
|
|
|
case PT_INT8v1: |
|
|
|
|
{ |
|
|
|
|
int8_t dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* no need for endian conversion */ |
|
|
|
|
|
|
|
|
|
cli_jsonint(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_UINT8: |
|
|
|
|
{ |
|
|
|
|
uint8_t dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* no need for endian conversion */ |
|
|
|
|
|
|
|
|
|
cli_jsonint(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_UINT16: |
|
|
|
|
{ |
|
|
|
|
uint16_t dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* endian conversion */ |
|
|
|
|
dout = sum16_endian_convert(dout); |
|
|
|
|
|
|
|
|
|
if (sctx->writecp) sctx->codepage = dout; |
|
|
|
|
|
|
|
|
|
cli_jsonint(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_UINT32: |
|
|
|
|
case PT_UINT32v1: |
|
|
|
|
{ |
|
|
|
|
uint32_t dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* endian conversion */ |
|
|
|
|
dout = sum32_endian_convert(dout); |
|
|
|
|
|
|
|
|
|
cli_jsonint(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_INT64: |
|
|
|
|
{ |
|
|
|
|
int64_t dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* endian conversion */ |
|
|
|
|
dout = sum64_endian_convert(dout); |
|
|
|
|
|
|
|
|
|
cli_jsonint64(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_UINT64: |
|
|
|
|
{ |
|
|
|
|
uint64_t dout; |
|
|
|
|
if (offset+sizeof(dout) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&dout, databuf+offset, sizeof(dout)); |
|
|
|
|
offset+=sizeof(dout); |
|
|
|
|
/* endian conversion */ |
|
|
|
|
dout = sum64_endian_convert(dout); |
|
|
|
|
|
|
|
|
|
cli_jsonint64(sctx->summary, sctx->propname, dout); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_BSTR: |
|
|
|
|
case PT_LPSTR: |
|
|
|
|
if (sctx->codepage == 0) { |
|
|
|
|
cli_dbgmsg("vba_propset_json: current codepage is unknown, cannot parse char stream\n"); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
else if (sctx->codepage != WINUNICODE) { |
|
|
|
|
uint32_t strsize; |
|
|
|
|
char *outstr; |
|
|
|
|
|
|
|
|
|
if (offset+sizeof(strsize) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memcpy(&strsize, databuf+offset, sizeof(strsize)); |
|
|
|
|
offset+=sizeof(strsize); |
|
|
|
|
/* no need for endian conversion */ |
|
|
|
|
|
|
|
|
|
if (offset+strsize > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* limitation on string length */ |
|
|
|
|
if (strsize > PROPSTRLIMIT) { |
|
|
|
|
cli_dbgmsg("vba_process_prop: property string sized %lu truncated to size %lu\n", |
|
|
|
|
(unsigned long)strsize, (unsigned long)PROPSTRLIMIT); |
|
|
|
|
strsize = PROPSTRLIMIT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
outstr = cli_malloc(strsize+1); |
|
|
|
|
if (!outstr) { |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
strncpy(outstr, databuf+offset, strsize); |
|
|
|
|
outstr[strsize] = '\0'; /* guarentee a NULL-termination */ |
|
|
|
|
cli_jsonstr(sctx->summary, sctx->propname, outstr); |
|
|
|
|
free(outstr); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
/* fall-through for unicode strings */ |
|
|
|
|
case PT_LPWSTR: |
|
|
|
|
{ |
|
|
|
|
uint32_t strsize; |
|
|
|
|
char *outstr, *outstr2; |
|
|
|
|
|
|
|
|
|
if (offset+sizeof(strsize) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(&strsize, databuf+offset, sizeof(strsize)); |
|
|
|
|
offset+=sizeof(strsize); |
|
|
|
|
/* no need for endian conversion */ |
|
|
|
|
if (proptype == PT_LPSTR) { /* fall-through specifics */ |
|
|
|
|
if (strsize % 2) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
strsize*=2; /* Unicode strings are by length, not size */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (offset+strsize > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
outstr = cli_malloc(strsize+2); |
|
|
|
|
if (!outstr) { |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
strncpy(outstr, databuf+offset, strsize); |
|
|
|
|
outstr[strsize-1] = '\0'; /* guarentee a UTF-16 NULL-termination */ |
|
|
|
|
outstr[strsize] = '\0'; |
|
|
|
|
|
|
|
|
|
outstr2 = (char*)get_property_name2(outstr, strsize); |
|
|
|
|
cli_jsonstr(sctx->summary, sctx->propname, outstr); |
|
|
|
|
free(outstr); |
|
|
|
|
free(outstr2); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case PT_FILETIME: |
|
|
|
|
{ |
|
|
|
|
uint32_t ltime, htime; |
|
|
|
|
#ifdef HAVE_JSON |
|
|
|
|
#else |
|
|
|
|
uint64_t wtime = 0, utime =0; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (offset+sizeof(ltime)+sizeof(htime) > buflen) { |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
memcpy(<ime, databuf+offset, sizeof(ltime)); |
|
|
|
|
offset+=sizeof(ltime); |
|
|
|
|
memcpy(&htime, databuf+offset, sizeof(htime)); |
|
|
|
|
offset+=sizeof(ltime); |
|
|
|
|
ltime = sum32_endian_convert(ltime); |
|
|
|
|
htime = sum32_endian_convert(htime); |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_JSON |
|
|
|
|
/* Raw Output */ |
|
|
|
|
{ |
|
|
|
|
json_object *fpobj0, *fpobj1; |
|
|
|
|
json_object *fparr = json_object_new_array(); |
|
|
|
|
if (NULL == fparr) { |
|
|
|
|
cli_errmsg("vba_process_prop: no memory for json array object.\n"); |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fpobj0 = json_object_new_int(ltime); |
|
|
|
|
if (NULL == fpobj0) { |
|
|
|
|
cli_errmsg("vba_process_prop: no memory for json int object.\n"); |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
fpobj1 = json_object_new_int(htime); |
|
|
|
|
if (NULL == fpobj1) { |
|
|
|
|
cli_errmsg("vba_process_prop: no memory for json int object.\n"); |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
json_object_array_add(fparr, fpobj0); |
|
|
|
|
json_object_array_add(fparr, fpobj1); |
|
|
|
|
json_object_object_add(sctx->summary, sctx->propname, fparr); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
/* human-readable formatting */ |
|
|
|
|
wtime = htime; |
|
|
|
|
wtime <<= 32; |
|
|
|
|
wtime |= ltime; |
|
|
|
|
|
|
|
|
|
utime = wtime / 10000000; |
|
|
|
|
utime -= 11644473600LL; |
|
|
|
|
|
|
|
|
|
cli_jsonstr(sctx->summary, sctx->propname, ctime((timer_t*)&utime)); |
|
|
|
|
#endif |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
case PT_BLOB: |
|
|
|
|
break;*/ |
|
|
|
|
default: |
|
|
|
|
cli_dbgmsg("vba_process_prop: unhandled property type %04x for %s property\n",
|
|
|
|
|
proptype, sctx->propname); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return CL_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
cli_vba_docsum_propset_json(summary_ctx_t *sctx, fmap_t *sumfmap, propset_entry_t *entry) |
|
|
|
|
{ |
|
|
|
|
uint32_t size, numprops, limitprops; |
|
|
|
|
uint32_t propid, poffset; |
|
|
|
|
unsigned char *databuf, *ptr = NULL; |
|
|
|
|
unsigned i; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
sctx->codepage = 0; |
|
|
|
|
sctx->writecp = 0; |
|
|
|
|
sctx->propname = NULL; |
|
|
|
|
|
|
|
|
|
/* examine property set metadata */ |
|
|
|
|
databuf = (unsigned char*)fmap_need_off_once(sumfmap, entry->offset, 8); |
|
|
|
|
if (!databuf) { |
|
|
|
|
return CL_EREAD; |
|
|
|
|
} |
|
|
|
|
memcpy(&size, databuf, sizeof(size)); |
|
|
|
|
memcpy(&numprops, databuf+sizeof(size), sizeof(numprops)); |
|
|
|
|
|
|
|
|
|
/* endian conversion */ |
|
|
|
|
size = sum32_endian_convert(size); |
|
|
|
|
numprops = sum32_endian_convert(numprops); |
|
|
|
|
|
|
|
|
|
cli_dbgmsg("vba_docsum_propset_json: size: %u, numprops: %u\n", size, numprops); |
|
|
|
|
|
|
|
|
|
/* extract the property packet and advance past metadata */ |
|
|
|
|
databuf = (unsigned char*)fmap_need_off_once(sumfmap, entry->offset, size); |
|
|
|
|
if (!databuf) { |
|
|
|
|
return CL_EREAD; |
|
|
|
|
} |
|
|
|
|
ptr = databuf+sizeof(size)+sizeof(numprops); |
|
|
|
|
|
|
|
|
|
if (numprops > PROPCNTLIMIT) { |
|
|
|
|
limitprops = PROPCNTLIMIT; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
limitprops = numprops; |
|
|
|
|
} |
|
|
|
|
cli_dbgmsg("vba_docsum_propset_json: processing %u of %u (%u max) propeties\n", |
|
|
|
|
limitprops, numprops, PROPCNTLIMIT); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < limitprops; ++i) { |
|
|
|
|
memcpy(&propid, ptr, sizeof(propid)); |
|
|
|
|
ptr+=4; |
|
|
|
|
memcpy(&poffset, ptr, sizeof(poffset)); |
|
|
|
|
ptr+=4; |
|
|
|
|
/* endian conversion */ |
|
|
|
|
propid = sum32_endian_convert(propid); |
|
|
|
|
poffset = sum32_endian_convert(poffset); |
|
|
|
|
|
|
|
|
|
cli_dbgmsg("vba_docsum_propset_json: propid: 0x%08x, poffset: %u\n", propid, poffset); |
|
|
|
|
|
|
|
|
|
sctx->propname = NULL; sctx->writecp = 0; |
|
|
|
|
switch(propid) { |
|
|
|
|
case DSPID_CODEPAGE: |
|
|
|
|
sctx->writecp = 1; /* must be set ONLY for codepage */ |
|
|
|
|
if (!sctx->propname) sctx->propname = "CodePage"; |
|
|
|
|
case DSPID_CATEGORY: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Category"; |
|
|
|
|
case DSPID_PRESFORMAT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "PresentationTarget"; |
|
|
|
|
case DSPID_BYTECOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Bytes"; |
|
|
|
|
case DSPID_LINECOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Lines"; |
|
|
|
|
case DSPID_PARCOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Paragraphs"; |
|
|
|
|
case DSPID_SLIDECOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Slides"; |
|
|
|
|
case DSPID_NOTECOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Notes"; |
|
|
|
|
case DSPID_HIDDENCOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "HiddenSlides"; |
|
|
|
|
case DSPID_MMCLIPCOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "MMClips"; |
|
|
|
|
case DSPID_SCALE: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Scale"; |
|
|
|
|
case DSPID_HEADINGPAIR: /* VT_VARIANT | VT_VECTOR */ |
|
|
|
|
if (!sctx->propname) sctx->propname = "HeadingPairs"; |
|
|
|
|
case DSPID_DOCPARTS: /* VT_VECTOR | VT_LPSTR */ |
|
|
|
|
if (!sctx->propname) sctx->propname = "DocPartTitles"; |
|
|
|
|
case DSPID_MANAGER: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Manager"; |
|
|
|
|
case DSPID_COMPANY: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Company"; |
|
|
|
|
case DSPID_LINKSDIRTY: |
|
|
|
|
if (!sctx->propname) sctx->propname = "LinksDirty"; |
|
|
|
|
case DSPID_CCHWITHSPACES: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Char&WSCount"; |
|
|
|
|
case DSPID_SHAREDDOC: /* SHOULD BE FALSE! */ |
|
|
|
|
if (!sctx->propname) sctx->propname = "SharedDoc"; |
|
|
|
|
case DSPID_LINKBASE: /* moved to user-defined */ |
|
|
|
|
if (!sctx->propname) sctx->propname = "LinkBase"; |
|
|
|
|
case DSPID_HLINKS: /* moved to user-defined */ |
|
|
|
|
if (!sctx->propname) sctx->propname = "HyperLinks"; |
|
|
|
|
case DSPID_HYPERLINKSCHANGED: |
|
|
|
|
if (!sctx->propname) sctx->propname = "HyperLinksChanged"; |
|
|
|
|
case DSPID_VERSION: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Version"; |
|
|
|
|
case DSPID_DIGSIG: |
|
|
|
|
if (!sctx->propname) sctx->propname = "DigitalSig"; |
|
|
|
|
case DSPID_CONTENTTYPE: |
|
|
|
|
if (!sctx->propname) sctx->propname = "ContentType"; |
|
|
|
|
case DSPID_CONTENTSTATUS: |
|
|
|
|
if (!sctx->propname) sctx->propname = "ContentStatus"; |
|
|
|
|
case DSPID_LANGUAGE: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Language"; |
|
|
|
|
case DSPID_DOCVERSION: |
|
|
|
|
if (!sctx->propname) sctx->propname = "DocVersion"; |
|
|
|
|
|
|
|
|
|
ret = cli_vba_process_prop(sctx, databuf, size, poffset); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
cli_dbgmsg("vba_docsum_propset_json: unrecognized propid!\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return CL_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
cli_vba_summary_propset_json(summary_ctx_t *sctx, fmap_t *sumfmap, propset_entry_t *entry) |
|
|
|
|
{ |
|
|
|
|
uint32_t size, numprops, limitprops; |
|
|
|
|
uint32_t propid, poffset; |
|
|
|
|
unsigned char *databuf, *ptr = NULL; |
|
|
|
|
unsigned i; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
sctx->codepage = 0; |
|
|
|
|
sctx->writecp = 0; |
|
|
|
|
sctx->propname = NULL; |
|
|
|
|
|
|
|
|
|
/* examine property set metadata */ |
|
|
|
|
databuf = (unsigned char*)fmap_need_off_once(sumfmap, entry->offset, 8); |
|
|
|
|
if (!databuf) { |
|
|
|
|
return CL_EREAD; |
|
|
|
|
} |
|
|
|
|
memcpy(&size, databuf, sizeof(size)); |
|
|
|
|
memcpy(&numprops, databuf+sizeof(size), sizeof(numprops)); |
|
|
|
|
|
|
|
|
|
/* endian conversion */ |
|
|
|
|
size = sum32_endian_convert(size); |
|
|
|
|
numprops = sum32_endian_convert(numprops); |
|
|
|
|
|
|
|
|
|
cli_dbgmsg("vba_summary_propset_json: size: %u, numprops: %u\n", size, numprops); |
|
|
|
|
|
|
|
|
|
/* extract the property packet and advance past metadata */ |
|
|
|
|
databuf = (unsigned char*)fmap_need_off_once(sumfmap, entry->offset, size); |
|
|
|
|
if (!databuf) { |
|
|
|
|
return CL_EREAD; |
|
|
|
|
} |
|
|
|
|
ptr = databuf+sizeof(size)+sizeof(numprops); |
|
|
|
|
|
|
|
|
|
if (numprops > PROPCNTLIMIT) { |
|
|
|
|
limitprops = PROPCNTLIMIT; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
limitprops = numprops; |
|
|
|
|
} |
|
|
|
|
cli_dbgmsg("vba_summary_propset_json: processing %u of %u (%u max) propeties\n", |
|
|
|
|
limitprops, numprops, PROPCNTLIMIT); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < limitprops; ++i) { |
|
|
|
|
memcpy(&propid, ptr, sizeof(propid)); |
|
|
|
|
ptr+=4; |
|
|
|
|
memcpy(&poffset, ptr, sizeof(poffset)); |
|
|
|
|
ptr+=4; |
|
|
|
|
/* endian conversion */ |
|
|
|
|
propid = sum32_endian_convert(propid); |
|
|
|
|
poffset = sum32_endian_convert(poffset); |
|
|
|
|
|
|
|
|
|
cli_dbgmsg("vba_summary_propset_json: propid: 0x%08x, poffset: %u\n", propid, poffset); |
|
|
|
|
|
|
|
|
|
sctx->propname = NULL; sctx->writecp = 0; |
|
|
|
|
switch(propid) { |
|
|
|
|
case SPID_CODEPAGE: |
|
|
|
|
sctx->writecp = 1; /* must be set ONLY for codepage */ |
|
|
|
|
if (!sctx->propname) sctx->propname = "CodePage"; |
|
|
|
|
case SPID_TITLE: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Title"; |
|
|
|
|
case SPID_SUBJECT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Subject"; |
|
|
|
|
case SPID_AUTHOR: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Author"; |
|
|
|
|
case SPID_KEYWORDS: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Keywords"; |
|
|
|
|
case SPID_COMMENTS: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Comments"; |
|
|
|
|
case SPID_TEMPLATE: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Template"; |
|
|
|
|
case SPID_LASTAUTHOR: |
|
|
|
|
if (!sctx->propname) sctx->propname = "LastAuthor"; |
|
|
|
|
case SPID_REVNUMBER: |
|
|
|
|
if (!sctx->propname) sctx->propname = "RevNumber"; |
|
|
|
|
case SPID_EDITTIME: |
|
|
|
|
if (!sctx->propname) sctx->propname = "EditTime"; |
|
|
|
|
case SPID_LASTPRINTED: |
|
|
|
|
if (!sctx->propname) sctx->propname = "LastPrinted"; |
|
|
|
|
case SPID_CREATEDTIME: |
|
|
|
|
if (!sctx->propname) sctx->propname = "CreatedTime"; |
|
|
|
|
case SPID_MODIFIEDTIME: |
|
|
|
|
if (!sctx->propname) sctx->propname = "ModifiedTime"; |
|
|
|
|
case SPID_PAGECOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "PageCount"; |
|
|
|
|
case SPID_WORDCOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "WordCount"; |
|
|
|
|
case SPID_CHARCOUNT: |
|
|
|
|
if (!sctx->propname) sctx->propname = "CharCount"; |
|
|
|
|
case SPID_THUMBNAIL: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Thumbnail"; |
|
|
|
|
case SPID_APPNAME: |
|
|
|
|
if (!sctx->propname) sctx->propname = "AppName"; |
|
|
|
|
case SPID_SECURITY: |
|
|
|
|
if (!sctx->propname) sctx->propname = "Security"; |
|
|
|
|
|
|
|
|
|
ret = cli_vba_process_prop(sctx, databuf, size, poffset); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
cli_dbgmsg("vba_summary_propset_json: unrecognized propid!\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return CL_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
cli_vba_summary_json(cli_ctx *ctx, int fd, int mode) |
|
|
|
|
{ |
|
|
|
|
summary_ctx_t sctx; |
|
|
|
|
fmap_t *sumfmap; |
|
|
|
|
summary_stub_t sumstub; |
|
|
|
|
propset_entry_t pentry[2]; |
|
|
|
|
STATBUF statbuf; |
|
|
|
|
unsigned char *databuf; |
|
|
|
|
size_t maplen; |
|
|
|
|
int ret = CL_SUCCESS; |
|
|
|
|
|
|
|
|
|
if (ctx == NULL) { |
|
|
|
|
return -42; |
|
|
|
|
} |
|
|
|
|
sctx.ctx = ctx; |
|
|
|
|
|
|
|
|
|
if (fd < 0) { |
|
|
|
|
cli_dbgmsg("vba_summary_json: invalid file descriptor\n"); |
|
|
|
|
return -42; /* placeholder */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (FSTAT(fd, &statbuf) == -1) { |
|
|
|
|
cli_dbgmsg("vba_summary_json: cannot stat file descriptor\n"); |
|
|
|
|
return CL_ESTAT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sumfmap = fmap(fd, 0, statbuf.st_size); |
|
|
|
|
if (!sumfmap) { |
|
|
|
|
cli_dbgmsg("vba_summary_json: failed to get fmap\n"); |
|
|
|
|
return CL_EMAP; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
maplen = sumfmap->len; |
|
|
|
|
cli_dbgmsg("vba_summary_json: streamsize: %u\n", maplen); |
|
|
|
|
if (maplen < sizeof(summary_stub_t)) { |
|
|
|
|
cli_dbgmsg("vba_summary_json: stream is too small to contain summary stub!"); |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
databuf = (unsigned char*)fmap_need_off_once(sumfmap, 0, sizeof(summary_stub_t)); |
|
|
|
|
if (!databuf) { |
|
|
|
|
return CL_EREAD; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Process the Summary Stream */ |
|
|
|
|
memcpy(&sumstub, databuf, sizeof(summary_stub_t)); |
|
|
|
|
|
|
|
|
|
/* endian conversion */ |
|
|
|
|
sumstub.byte_order = le16_to_host(sumstub.byte_order); |
|
|
|
|
if (sumstub.byte_order != 0xfffe) { |
|
|
|
|
cli_dbgmsg("vba_summary_json: byteorder 0x%x is invalid\n", sumstub.byte_order); |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
sumstub.version = sum16_endian_convert(sumstub.version); |
|
|
|
|
sumstub.system = sum32_endian_convert(sumstub.system); |
|
|
|
|
sumstub.num_propsets = sum32_endian_convert(sumstub.num_propsets); |
|
|
|
|
|
|
|
|
|
cli_dbgmsg("vba_summary_json: byteorder 0x%x\n", sumstub.byte_order); |
|
|
|
|
|
|
|
|
|
/* summary context setup */ |
|
|
|
|
sctx.byte_order = sumstub.byte_order; |
|
|
|
|
sctx.version = sumstub.version; |
|
|
|
|
#ifdef HAVE_JSON |
|
|
|
|
sctx.summary = json_object_new_object(); |
|
|
|
|
if (!sctx.summary) { |
|
|
|
|
cli_errmsg("vba_summary_json: no memory for json object.\n"); |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
sctx.summary = NULL; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
sctx.codepage = 0; |
|
|
|
|
sctx.writecp = 0; |
|
|
|
|
|
|
|
|
|
cli_dbgmsg("vba_summary_json: %u property set(s) detected\n", sumstub.num_propsets); |
|
|
|
|
if (sumstub.num_propsets == 1) { |
|
|
|
|
databuf = (unsigned char*)fmap_need_off_once(sumfmap, sizeof(summary_stub_t), |
|
|
|
|
sizeof(propset_entry_t)); |
|
|
|
|
if (!databuf) { |
|
|
|
|
return CL_EREAD; |
|
|
|
|
} |
|
|
|
|
memcpy(pentry, databuf, sizeof(summary_stub_t)); |
|
|
|
|
/* endian conversion */ |
|
|
|
|
pentry[0].offset = sum32_endian_convert(pentry[0].offset); |
|
|
|
|
|
|
|
|
|
/* TODO - check return and mode */ |
|
|
|
|
if (!mode) { |
|
|
|
|
ret = cli_vba_summary_propset_json(&sctx, sumfmap, &pentry[0]); |
|
|
|
|
#ifdef HAVE_JSON |
|
|
|
|
json_object_object_add(ctx->properties, "SummaryInfo", sctx.summary); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
ret = cli_vba_docsum_propset_json(&sctx, sumfmap, &pentry[0]); |
|
|
|
|
#ifdef HAVE_JSON |
|
|
|
|
json_object_object_add(ctx->properties, "DocSummaryInfo", sctx.summary); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if (sumstub.num_propsets == 2) { |
|
|
|
|
databuf = (unsigned char*)fmap_need_off_once(sumfmap, sizeof(summary_stub_t), |
|
|
|
|
2*sizeof(propset_entry_t)); |
|
|
|
|
if (!databuf) { |
|
|
|
|
return CL_EREAD; |
|
|
|
|
} |
|
|
|
|
memcpy(pentry, databuf, 2*sizeof(summary_stub_t)); |
|
|
|
|
/* endian conversion */ |
|
|
|
|
pentry[0].offset = sum32_endian_convert(pentry[0].offset); |
|
|
|
|
pentry[1].offset = sum32_endian_convert(pentry[1].offset); |
|
|
|
|
|
|
|
|
|
/* multi-propset handling */ |
|
|
|
|
/* first propset is user-defined, ignored for now */ |
|
|
|
|
/* TODO - check return and mode */ |
|
|
|
|
if (!mode) { |
|
|
|
|
ret = cli_vba_summary_propset_json(&sctx, sumfmap, &pentry[0]); |
|
|
|
|
#ifdef HAVE_JSON |
|
|
|
|
json_object_object_add(ctx->properties, "SummaryInfo", sctx.summary); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
ret = cli_vba_docsum_propset_json(&sctx, sumfmap, &pentry[0]); |
|
|
|
|
#ifdef HAVE_JSON |
|
|
|
|
json_object_object_add(ctx->properties, "DocSummaryInfo", sctx.summary); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
cli_dbgmsg("vba_summary_json: invalid number of property sets\n"); |
|
|
|
|
return CL_EFORMAT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*------DEBUG------
|
|
|
|
|
int i; |
|
|
|
|
cli_dbgmsg("byte_order: %x\n", sumstub.byte_order); |
|
|
|
|
cli_dbgmsg("version: %x\n", sumstub.version); |
|
|
|
|
cli_dbgmsg("system: %x\n", sumstub.system); |
|
|
|
|
cli_dbgmsg("CLSID: "); |
|
|
|
|
for (i = 0; i < 16; ++i) { |
|
|
|
|
if (i == 3 || i == 5 || i == 7) { |
|
|
|
|
fprintf(stderr, "-"); |
|
|
|
|
} |
|
|
|
|
fprintf(stderr, "%02x", sumstub.CLSID[i]); |
|
|
|
|
} |
|
|
|
|
fprintf(stderr, "\n"); |
|
|
|
|
|
|
|
|
|
cli_dbgmsg("num_propsets: %u\n", sumstub.num_propsets); |
|
|
|
|
cli_dbgmsg("FMTID0: "); |
|
|
|
|
for (i = 0; i < 16; ++i) { |
|
|
|
|
if (i == 3 || i == 5 || i == 7) { |
|
|
|
|
fprintf(stderr, "-"); |
|
|
|
|
} |
|
|
|
|
fprintf(stderr, "%02x", pentry[0].FMTID[i]); |
|
|
|
|
} |
|
|
|
|
fprintf(stderr, "\n"); |
|
|
|
|
cli_dbgmsg("offset0: %u\n", pentry[0].offset); |
|
|
|
|
|
|
|
|
|
if (sumstub.num_propsets == 2) { |
|
|
|
|
cli_dbgmsg("FMTID1: "); |
|
|
|
|
for (i = 0; i < 16; ++i) { |
|
|
|
|
if (i == 3 || i == 5 || i == 7) { |
|
|
|
|
fprintf(stderr, "-"); |
|
|
|
|
} |
|
|
|
|
fprintf(stderr, "%02x", pentry[1].FMTID[i]); |
|
|
|
|
} |
|
|
|
|
fprintf(stderr, "\n"); |
|
|
|
|
cli_dbgmsg("offset1: %u\n", pentry[1].offset); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
json_object* newobj = json_object_new_object(); |
|
|
|
|
json_object* obj0 = json_object_new_boolean(1); |
|
|
|
|
json_object* obj1 = json_object_new_boolean(0); |
|
|
|
|
json_object* obj2 = json_object_new_int(-1); |
|
|
|
|
//json_object* obj3 = json_object_new_int64(-64);
|
|
|
|
|
|
|
|
|
|
json_object* obj4 = json_object_new_string("hello world!"); |
|
|
|
|
json_object* obj5 = json_object_new_string_len("hello world!", 5); |
|
|
|
|
|
|
|
|
|
json_object_object_add(newobj, "bool", obj0); |
|
|
|
|
json_object_object_add(newobj, "bool", obj1); |
|
|
|
|
json_object_object_add(newobj, "int", obj2); |
|
|
|
|
//json_object_object_add(newobj, "int64", obj3);
|
|
|
|
|
json_object_object_add(newobj, "string", obj4); |
|
|
|
|
json_object_object_add(newobj, "string_len", obj5); |
|
|
|
|
|
|
|
|
|
json_object_object_add(ctx->properties, "summary2", newobj); |
|
|
|
|
|
|
|
|
|
-----------------*/ |
|
|
|
|
|
|
|
|
|
funmap(sumfmap); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|