150
145
GUID_all_zero(guid);
153
pull_uint32_t(parser, &(guid->time_low));
154
pull_uint16_t(parser, &(guid->time_mid));
155
pull_uint16_t(parser, &(guid->time_hi_and_version));
156
pull_uint8_t(parser, &(guid->clock_seq[0]));
157
pull_uint8_t(parser, &(guid->clock_seq[1]));
148
if (!pull_uint32_t(parser, &(guid->time_low)))
150
if (!pull_uint16_t(parser, &(guid->time_mid)))
152
if (!pull_uint16_t(parser, &(guid->time_hi_and_version)))
154
if (!pull_uint8_t(parser, &(guid->clock_seq[0])))
156
if (!pull_uint8_t(parser, &(guid->clock_seq[1])))
158
158
for (i = 0; i < 6; ++i) {
159
pull_uint8_t(parser, &(guid->node[i]));
159
if (!pull_uint8_t(parser, &(guid->node[i])))
165
static bool pull_systime(struct fx_parser_context *parser, struct FILETIME *ft)
167
struct FILETIME filetime = {0,0};
169
if (parser->idx + 8 > parser->data.length ||
170
!pull_uint32_t(parser, &(filetime.dwLowDateTime)) ||
171
!pull_uint32_t(parser, &(filetime.dwHighDateTime)))
179
static bool pull_clsid(struct fx_parser_context *parser, struct FlatUID_r **pclsid)
181
struct FlatUID_r *clsid;
184
if (parser->idx + 16 > parser->data.length)
187
clsid = talloc_zero(parser->mem_ctx, struct FlatUID_r);
188
for (i = 0; i < 16; ++i) {
189
if (!pull_uint8_t(parser, &(clsid->ab[i])))
198
static bool pull_string8(struct fx_parser_context *parser, char **pstr)
203
if (!pull_uint32_t(parser, &length) ||
204
parser->idx + length > parser->data.length)
207
str = talloc_array(parser->mem_ctx, char, length + 1);
208
for (i = 0; i < length; i++) {
209
if (!pull_uint8_t(parser, (uint8_t*)&(str[i]))) {
184
241
val += parser->data.data[idx_local] << 8;
186
243
if (val == 0x0000) {
190
250
return fetch_ucs2_data(parser, idx_local-(parser->idx), data_read);
253
static bool pull_unicode(struct fx_parser_context *parser, char **pstr)
255
smb_ucs2_t *ucs2_data = NULL;
256
char *utf8_data = NULL;
260
if (!pull_uint32_t(parser, &length) ||
261
parser->idx + length > parser->data.length)
264
ucs2_data = talloc_zero_array(parser->mem_ctx, smb_ucs2_t, (length/2) + 1);
266
if (!fetch_ucs2_data(parser, length, &ucs2_data)) {
269
pull_ucs2_talloc(parser->mem_ctx, &utf8_data, ucs2_data, &utf8_len);
276
static bool pull_binary(struct fx_parser_context *parser, struct Binary_r *bin)
278
if (!pull_uint32_t(parser, &(bin->cb)) ||
279
parser->idx + bin->cb > parser->data.length)
282
bin->lpb = talloc_array(parser->mem_ctx, uint8_t, bin->cb + 1);
284
return pull_uint8_data(parser, bin->cb, &(bin->lpb));
194
288
pull a property value from the blob, starting at position idx
196
static bool fetch_property_value(struct fx_parser_context *parser, DATA_BLOB *buf, struct SPropValue *prop, uint32_t *len)
290
static bool fetch_property_value(struct fx_parser_context *parser, DATA_BLOB *buf, struct SPropValue *prop)
198
292
switch(prop->ulPropTag & 0xFFFF) {
295
if (!pull_uint32_t(parser, &(prop->value.null)))
201
pull_uint16_t(parser, &(prop->value.i));
301
if (!pull_uint16_t(parser, &(prop->value.i)))
206
pull_uint32_t(parser, &(prop->value.l));
307
if (!pull_uint32_t(parser, &(prop->value.l)))
211
pull_double(parser, (double *)&(prop->value.dbl));
313
if (!pull_double(parser, (double *)&(prop->value.dbl)))
216
pull_uint8_t(parser, &(prop->value.b));
319
if (parser->idx + 2 > parser->data.length ||
320
!pull_uint8_t(parser, &(prop->value.b)))
217
323
/* special case for fast transfer, 2 bytes instead of one */
224
pull_int64_t(parser, &(val));
330
if (!pull_int64_t(parser, &(val)))
225
332
prop->value.d = val;
231
if (parser->length == 0) {
232
pull_uint32_t(parser, &(parser->length));
234
prop->value.lpszA = talloc_array(parser->mem_ctx, char, parser->length + 1);
236
for (; parser->offset < parser->length; ++(parser->offset)) {
237
if (!pull_uint8_t(parser, (uint8_t*)&(prop->value.lpszA[parser->offset]))) {
241
ptr = (char*)prop->value.lpszA;
242
ptr += parser->length;
338
if (!pull_string8(parser, &str))
340
prop->value.lpszA = str;
248
/* TODO: rethink this to handle split buffers */
249
smb_ucs2_t *ucs2_data = NULL;
250
if (parser->length == 0) {
251
pull_uint32_t(parser, &(parser->length));
252
ucs2_data = talloc_array(parser->mem_ctx, smb_ucs2_t, parser->length/2);
255
char *utf8_data = NULL;
257
if (!fetch_ucs2_data(parser, parser->length, &ucs2_data)) {
346
if (!pull_unicode (parser, &str))
260
pull_ucs2_talloc(parser->mem_ctx, &utf8_data, ucs2_data, &utf8_len);
261
prop->value.lpszW = utf8_data;
348
prop->value.lpszW = str;
266
struct FILETIME filetime = {0,0};
267
pull_uint32_t(parser, &(filetime.dwLowDateTime));
268
pull_uint32_t(parser, &(filetime.dwHighDateTime));
269
prop->value.ft = filetime;
353
if (!pull_systime(parser, &prop->value.ft))
275
prop->value.lpguid = talloc_zero(parser->mem_ctx, struct FlatUID_r);
276
for (i = 0; i < 16; ++i) {
277
pull_uint8_t(parser, &(prop->value.lpguid->ab[i]));
359
if (!pull_clsid(parser, &prop->value.lpguid))
284
if (parser->length == 0) {
285
pull_uint32_t(parser, &(prop->value.bin.cb));
286
parser->length = prop->value.bin.cb;
287
prop->value.bin.lpb = talloc_array(parser->mem_ctx, uint8_t, parser->length + 1);
290
if (!pull_uint8_data(parser, &(prop->value.bin.lpb))) {
366
if (!pull_binary(parser, &prop->value.bin))
297
pull_uint32_t(parser, &(prop->value.object));
372
/* the object itself is sent too, thus download it as a binary,
373
not as a meaningless number, which is length of the object here */
374
if (!pull_binary(parser, &prop->value.bin))
381
if (!pull_uint32_t(parser, &num))
383
prop->value.err = num;
300
386
case PT_MV_BINARY:
302
/* TODO: handle partial count / length */
304
pull_uint32_t(parser, &(prop->value.MVbin.cValues));
389
if (!pull_uint32_t(parser, &(prop->value.MVbin.cValues)) ||
390
parser->idx + prop->value.MVbin.cValues * 4 > parser->data.length)
305
392
prop->value.MVbin.lpbin = talloc_array(parser->mem_ctx, struct Binary_r, prop->value.MVbin.cValues);
306
393
for (i = 0; i < prop->value.MVbin.cValues; i++) {
307
pull_uint32_t(parser, &(prop->value.MVbin.lpbin[i].cb));
308
parser->length = prop->value.MVbin.lpbin[i].cb;
309
prop->value.MVbin.lpbin[i].lpb = talloc_array(parser->mem_ctx, uint8_t, parser->length + 1);
311
if (!pull_uint8_data(parser, &(prop->value.MVbin.lpbin[i].lpb))) {
394
if (!pull_binary(parser, &(prop->value.MVbin.lpbin[i])))
402
if (!pull_uint32_t(parser, &(prop->value.MVi.cValues)) ||
403
parser->idx + prop->value.MVi.cValues * 2 > parser->data.length)
405
prop->value.MVi.lpi = talloc_array(parser->mem_ctx, uint16_t, prop->value.MVi.cValues);
406
for (i = 0; i < prop->value.MVi.cValues; i++) {
407
if (!pull_uint16_t(parser, &(prop->value.MVi.lpi[i])))
415
if (!pull_uint32_t(parser, &(prop->value.MVl.cValues)) ||
416
parser->idx + prop->value.MVl.cValues * 4 > parser->data.length)
418
prop->value.MVl.lpl = talloc_array(parser->mem_ctx, uint32_t, prop->value.MVl.cValues);
419
for (i = 0; i < prop->value.MVl.cValues; i++) {
420
if (!pull_uint32_t(parser, &(prop->value.MVl.lpl[i])))
429
if (!pull_uint32_t(parser, &(prop->value.MVszA.cValues)) ||
430
parser->idx + prop->value.MVszA.cValues * 4 > parser->data.length)
432
prop->value.MVszA.lppszA = (const char **) talloc_array(parser->mem_ctx, char *, prop->value.MVszA.cValues);
433
for (i = 0; i < prop->value.MVszA.cValues; i++) {
435
if (!pull_string8(parser, &str))
437
prop->value.MVszA.lppszA[i] = str;
444
if (!pull_uint32_t(parser, &(prop->value.MVguid.cValues)) ||
445
parser->idx + prop->value.MVguid.cValues * 16 > parser->data.length)
447
prop->value.MVguid.lpguid = talloc_array(parser->mem_ctx, struct FlatUID_r *, prop->value.MVguid.cValues);
448
for (i = 0; i < prop->value.MVguid.cValues; i++) {
449
if (!pull_clsid(parser, &(prop->value.MVguid.lpguid[i])))
459
if (!pull_uint32_t(parser, &(prop->value.MVszW.cValues)) ||
460
parser->idx + prop->value.MVszW.cValues * 4 > parser->data.length)
462
prop->value.MVszW.lppszW = (const char **) talloc_array(parser->mem_ctx, char *, prop->value.MVszW.cValues);
463
for (i = 0; i < prop->value.MVszW.cValues; i++) {
465
if (!pull_unicode(parser, &str))
467
prop->value.MVszW.lppszW[i] = str;
474
if (!pull_uint32_t(parser, &(prop->value.MVft.cValues)) ||
475
parser->idx + prop->value.MVft.cValues * 8 > parser->data.length)
477
prop->value.MVft.lpft = talloc_array(parser->mem_ctx, struct FILETIME, prop->value.MVft.cValues);
478
for (i = 0; i < prop->value.MVft.cValues; i++) {
479
if (!pull_systime(parser, &(prop->value.MVft.lpft[i])))
318
printf("unhandled conversion case in fetch_property_value(): 0x%x\n", (prop->ulPropTag & 0xFFFF));
485
printf("unhandled conversion case in fetch_property_value(): 0x%x\n", prop->ulPropTag);
319
486
OPENCHANGE_ASSERT();
324
static void pull_named_property(struct fx_parser_context *parser)
491
static bool pull_named_property(struct fx_parser_context *parser, enum MAPISTATUS *ms)
326
493
uint8_t type = 0;
327
pull_guid(parser, &(parser->namedprop.lpguid));
494
if (!pull_guid(parser, &(parser->namedprop.lpguid)))
328
496
/* printf("guid : %s\n", GUID_string(parser->mem_ctx, &(parser->namedprop.lpguid))); */
329
pull_uint8_t(parser, &type);
497
if (!pull_uint8_t(parser, &type))
331
500
parser->namedprop.ulKind = MNID_ID;
332
pull_uint32_t(parser, &(parser->namedprop.kind.lid));
501
if (!pull_uint32_t(parser, &(parser->namedprop.kind.lid)))
333
503
/* printf("LID dispid: 0x%08x\n", parser->namedprop.kind.lid); */
334
504
} else if (type == 1) {
335
505
smb_ucs2_t *ucs2_data = NULL;
337
507
parser->namedprop.ulKind = MNID_STRING;
338
fetch_ucs2_nullterminated(parser, &ucs2_data);
508
if (!fetch_ucs2_nullterminated(parser, &ucs2_data))
339
510
pull_ucs2_talloc(parser->mem_ctx, (char**)&(parser->namedprop.kind.lpwstr.Name), ucs2_data, &(utf8_len));
340
511
parser->namedprop.kind.lpwstr.NameSize = utf8_len;
341
512
/* printf("named: %s\n", parser->namedprop.kind.lpwstr.Name); */
442
622
if (pull_uint32_t(parser, &tag)) {
443
623
if (parser->op_delprop) {
444
parser->op_delprop(tag, parser->priv);
624
ms = parser->op_delprop(tag, parser->priv);
446
626
parser->state = ParserState_Entry;
448
628
parser->enough_data = false;
454
635
/* standard property thing */
455
parser->lpProp.ulPropTag = (enum MAPITAGS) parser->tag;
636
parser->lpProp.ulPropTag = (enum MAPITAGS) parser->tag;
456
637
parser->lpProp.dwAlignPad = 0;
457
638
if ((parser->lpProp.ulPropTag >> 16) & 0x8000) {
458
639
/* this is a named property */
459
640
// printf("tag: 0x%08x\n", parser->tag);
460
641
// TODO: this should probably be a separate parser state
461
642
// TODO: this needs to return the named property
462
pull_named_property(parser);
643
if (pull_named_property(parser, &ms)) {
644
parser->state = ParserState_HavePropTag;
646
parser->enough_data = false;
650
parser->state = ParserState_HavePropTag;
464
parser->state = ParserState_HavePropTag;
469
656
case ParserState_HavePropTag:
471
if (fetch_property_value(parser, &(parser->data), &(parser->lpProp), &(parser->length))) {
658
if (fetch_property_value(parser, &(parser->data), &(parser->lpProp))) {
472
659
// printf("position %i of %zi\n", parser->idx, parser->data.length);
473
660
if (parser->op_property) {
474
parser->op_property(parser->lpProp, parser->priv);
661
ms = parser->op_property(parser->lpProp, parser->priv);
476
663
parser->state = ParserState_Entry;
479
665
parser->enough_data = false;