ReactOS  0.4.14-dev-606-g14ebc0b
mimeole.c
Go to the documentation of this file.
1 /*
2  * MIME OLE Interfaces
3  *
4  * Copyright 2006 Robert Shearman for CodeWeavers
5  * Copyright 2007 Huw Davies for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #define COBJMACROS
23 #define NONAMELESSUNION
24 
25 #include <stdarg.h>
26 #include <stdio.h>
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wine/winternl.h"
31 #include "winuser.h"
32 #include "objbase.h"
33 #include "ole2.h"
34 #include "mimeole.h"
35 #ifdef __REACTOS__
36 #include <winreg.h>
37 #endif
38 #include "propvarutil.h"
39 
40 #include "wine/heap.h"
41 #include "wine/list.h"
42 #include "wine/debug.h"
43 
44 #include "inetcomm_private.h"
45 
47 
48 typedef struct
49 {
52  DWORD flags; /* MIMEPROPFLAGS */
54 } property_t;
55 
56 typedef struct
57 {
58  struct list entry;
61 
62 static const property_t default_props[] =
63 {
64  {"X-Newsgroup", PID_HDR_NEWSGROUP, 0, VT_LPSTR},
65  {"Newsgroups", PID_HDR_NEWSGROUPS, 0, VT_LPSTR},
66  {"References", PID_HDR_REFS, 0, VT_LPSTR},
67  {"Subject", PID_HDR_SUBJECT, 0, VT_LPSTR},
68  {"From", PID_HDR_FROM, MPF_ADDRESS, VT_LPSTR},
69  {"Message-ID", PID_HDR_MESSAGEID, 0, VT_LPSTR},
70  {"Return-Path", PID_HDR_RETURNPATH, MPF_ADDRESS, VT_LPSTR},
71  {"Rr", PID_HDR_RR, 0, VT_LPSTR},
72  {"Return-Receipt-To", PID_HDR_RETRCPTO, MPF_ADDRESS, VT_LPSTR},
73  {"Apparently-To", PID_HDR_APPARTO, MPF_ADDRESS, VT_LPSTR},
74  {"Date", PID_HDR_DATE, 0, VT_LPSTR},
75  {"Received", PID_HDR_RECEIVED, 0, VT_LPSTR},
76  {"Reply-To", PID_HDR_REPLYTO, MPF_ADDRESS, VT_LPSTR},
77  {"X-Mailer", PID_HDR_XMAILER, 0, VT_LPSTR},
78  {"Bcc", PID_HDR_BCC, MPF_ADDRESS, VT_LPSTR},
79  {"MIME-Version", PID_HDR_MIMEVER, MPF_MIME, VT_LPSTR},
80  {"Content-Type", PID_HDR_CNTTYPE, MPF_MIME | MPF_HASPARAMS, VT_LPSTR},
81  {"Content-Transfer-Encoding", PID_HDR_CNTXFER, MPF_MIME, VT_LPSTR},
82  {"Content-ID", PID_HDR_CNTID, MPF_MIME, VT_LPSTR},
83  {"Content-Description", PID_HDR_CNTDESC, MPF_MIME, VT_LPSTR},
84  {"Content-Disposition", PID_HDR_CNTDISP, MPF_MIME | MPF_HASPARAMS, VT_LPSTR},
85  {"Content-Base", PID_HDR_CNTBASE, MPF_MIME, VT_LPSTR},
86  {"Content-Location", PID_HDR_CNTLOC, MPF_MIME, VT_LPSTR},
87  {"To", PID_HDR_TO, MPF_ADDRESS, VT_LPSTR},
88  {"Path", PID_HDR_PATH, 0, VT_LPSTR},
89  {"Followup-To", PID_HDR_FOLLOWUPTO, 0, VT_LPSTR},
90  {"Expires", PID_HDR_EXPIRES, 0, VT_LPSTR},
91  {"Cc", PID_HDR_CC, MPF_ADDRESS, VT_LPSTR},
92  {"Control", PID_HDR_CONTROL, 0, VT_LPSTR},
93  {"Distribution", PID_HDR_DISTRIB, 0, VT_LPSTR},
94  {"Keywords", PID_HDR_KEYWORDS, 0, VT_LPSTR},
95  {"Summary", PID_HDR_SUMMARY, 0, VT_LPSTR},
96  {"Approved", PID_HDR_APPROVED, 0, VT_LPSTR},
97  {"Lines", PID_HDR_LINES, 0, VT_LPSTR},
98  {"Xref", PID_HDR_XREF, 0, VT_LPSTR},
99  {"Organization", PID_HDR_ORG, 0, VT_LPSTR},
100  {"X-Newsreader", PID_HDR_XNEWSRDR, 0, VT_LPSTR},
101  {"X-Priority", PID_HDR_XPRI, 0, VT_LPSTR},
102  {"X-MSMail-Priority", PID_HDR_XMSPRI, 0, VT_LPSTR},
103  {"par:content-disposition:filename", PID_PAR_FILENAME, 0, VT_LPSTR},
104  {"par:content-type:boundary", PID_PAR_BOUNDARY, 0, VT_LPSTR},
105  {"par:content-type:charset", PID_PAR_CHARSET, 0, VT_LPSTR},
106  {"par:content-type:name", PID_PAR_NAME, 0, VT_LPSTR},
107  {"att:filename", PID_ATT_FILENAME, 0, VT_LPSTR},
108  {"att:pri-content-type", PID_ATT_PRITYPE, 0, VT_LPSTR},
109  {"att:sub-content-type", PID_ATT_SUBTYPE, 0, VT_LPSTR},
110  {"att:illegal-lines", PID_ATT_ILLEGAL, 0, VT_LPSTR},
111  {"att:rendered", PID_ATT_RENDERED, 0, VT_LPSTR},
112  {"att:sent-time", PID_ATT_SENTTIME, 0, VT_LPSTR},
113  {"att:priority", PID_ATT_PRIORITY, 0, VT_LPSTR},
114  {"Comment", PID_HDR_COMMENT, 0, VT_LPSTR},
115  {"Encoding", PID_HDR_ENCODING, 0, VT_LPSTR},
116  {"Encrypted", PID_HDR_ENCRYPTED, 0, VT_LPSTR},
117  {"X-Offsets", PID_HDR_OFFSETS, 0, VT_LPSTR},
118  {"X-Unsent", PID_HDR_XUNSENT, 0, VT_LPSTR},
119  {"X-ArticleId", PID_HDR_ARTICLEID, 0, VT_LPSTR},
120  {"Sender", PID_HDR_SENDER, MPF_ADDRESS, VT_LPSTR},
121  {"att:athena-server", PID_ATT_SERVER, 0, VT_LPSTR},
122  {"att:athena-account-id", PID_ATT_ACCOUNT, 0, VT_LPSTR},
123  {"att:athena-pop3-uidl", PID_ATT_UIDL, 0, VT_LPSTR},
124  {"att:athena-store-msgid", PID_ATT_STOREMSGID, 0, VT_LPSTR},
125  {"att:athena-user-name", PID_ATT_USERNAME, 0, VT_LPSTR},
126  {"att:athena-forward-to", PID_ATT_FORWARDTO, 0, VT_LPSTR},
127  {"att:athena-store-fdrid", PID_ATT_STOREFOLDERID,0, VT_LPSTR},
128  {"att:athena-ghosted", PID_ATT_GHOSTED, 0, VT_LPSTR},
129  {"att:athena-uncachedsize", PID_ATT_UNCACHEDSIZE, 0, VT_LPSTR},
130  {"att:athena-combined", PID_ATT_COMBINED, 0, VT_LPSTR},
131  {"att:auto-inlined", PID_ATT_AUTOINLINED, 0, VT_LPSTR},
132  {"Disposition-Notification-To", PID_HDR_DISP_NOTIFICATION_TO, 0, VT_LPSTR},
133  {"par:Content-Type:reply-type", PID_PAR_REPLYTYPE, 0, VT_LPSTR},
134  {"par:Content-Type:format", PID_PAR_FORMAT , 0, VT_LPSTR},
135  {"att:format", PID_ATT_FORMAT , 0, VT_LPSTR},
136  {"In-Reply-To", PID_HDR_INREPLYTO, 0, VT_LPSTR},
137  {"att:athena-account-name", PID_ATT_ACCOUNTNAME, 0, VT_LPSTR},
138  {NULL, 0, 0, 0}
139 };
140 
141 typedef struct
142 {
143  struct list entry;
144  char *name;
145  char *value;
146 } param_t;
147 
148 typedef struct
149 {
150  struct list entry;
151  const property_t *prop;
152  PROPVARIANT value;
153  struct list params;
154 } header_t;
155 
156 typedef struct MimeBody
157 {
160 
161  HBODY handle;
162 
163  struct list headers;
164  struct list new_props; /* FIXME: This should be in a PropertySchema */
169  void *data;
171  BODYOFFSETS body_offsets;
172 } MimeBody;
173 
174 typedef struct
175 {
180 } sub_stream_t;
181 
182 static inline sub_stream_t *impl_from_IStream(IStream *iface)
183 {
184  return CONTAINING_RECORD(iface, sub_stream_t, IStream_iface);
185 }
186 
188 {
190 
191  TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
192  *ppv = NULL;
193 
194  if(IsEqualIID(riid, &IID_IUnknown) ||
195  IsEqualIID(riid, &IID_ISequentialStream) ||
196  IsEqualIID(riid, &IID_IStream))
197  {
198  IStream_AddRef(iface);
199  *ppv = iface;
200  return S_OK;
201  }
202  return E_NOINTERFACE;
203 }
204 
206 {
209 
210  TRACE("(%p) ref=%d\n", This, ref);
211 
212  return ref;
213 }
214 
216 {
219 
220  TRACE("(%p) ref=%d\n", This, ref);
221 
222  if(!ref)
223  {
224  IStream_Release(This->base);
226  }
227  return ref;
228 }
229 
231  IStream* iface,
232  void *pv,
233  ULONG cb,
234  ULONG *pcbRead)
235 {
237  HRESULT hr;
238  LARGE_INTEGER tmp_pos;
239 
240  TRACE("(%p, %d, %p)\n", pv, cb, pcbRead);
241 
242  tmp_pos.QuadPart = This->pos.QuadPart + This->start.QuadPart;
243  IStream_Seek(This->base, tmp_pos, STREAM_SEEK_SET, NULL);
244 
245  if(This->pos.QuadPart + cb > This->length.QuadPart)
246  cb = This->length.QuadPart - This->pos.QuadPart;
247 
248  hr = IStream_Read(This->base, pv, cb, pcbRead);
249 
250  This->pos.QuadPart += *pcbRead;
251 
252  return hr;
253 }
254 
256  IStream* iface,
257  const void *pv,
258  ULONG cb,
259  ULONG *pcbWritten)
260 {
261  FIXME("stub\n");
262  return E_NOTIMPL;
263 }
264 
266  IStream* iface,
267  LARGE_INTEGER dlibMove,
268  DWORD dwOrigin,
269  ULARGE_INTEGER *plibNewPosition)
270 {
272  LARGE_INTEGER new_pos;
273 
274  TRACE("(%08x.%08x, %x, %p)\n", dlibMove.u.HighPart, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
275 
276  switch(dwOrigin)
277  {
278  case STREAM_SEEK_SET:
279  new_pos = dlibMove;
280  break;
281  case STREAM_SEEK_CUR:
282  new_pos.QuadPart = This->pos.QuadPart + dlibMove.QuadPart;
283  break;
284  case STREAM_SEEK_END:
285  new_pos.QuadPart = This->length.QuadPart + dlibMove.QuadPart;
286  break;
287  default:
288  return STG_E_INVALIDFUNCTION;
289  }
290 
291  if(new_pos.QuadPart < 0) new_pos.QuadPart = 0;
292  else if(new_pos.QuadPart > This->length.QuadPart) new_pos.QuadPart = This->length.QuadPart;
293 
294  This->pos.QuadPart = new_pos.QuadPart;
295 
296  if(plibNewPosition) *plibNewPosition = This->pos;
297  return S_OK;
298 }
299 
301  IStream* iface,
302  ULARGE_INTEGER libNewSize)
303 {
304  FIXME("stub\n");
305  return E_NOTIMPL;
306 }
307 
309  IStream* iface,
310  IStream *pstm,
312  ULARGE_INTEGER *pcbRead,
313  ULARGE_INTEGER *pcbWritten)
314 {
315  HRESULT hr = S_OK;
316  BYTE tmpBuffer[128];
317  ULONG bytesRead, bytesWritten, copySize;
318  ULARGE_INTEGER totalBytesRead;
319  ULARGE_INTEGER totalBytesWritten;
320 
321  TRACE("(%p)->(%p, %d, %p, %p)\n", iface, pstm, cb.u.LowPart, pcbRead, pcbWritten);
322 
323  totalBytesRead.QuadPart = 0;
324  totalBytesWritten.QuadPart = 0;
325 
326  while ( cb.QuadPart > 0 )
327  {
328  if ( cb.QuadPart >= sizeof(tmpBuffer) )
329  copySize = sizeof(tmpBuffer);
330  else
331  copySize = cb.u.LowPart;
332 
333  hr = IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
334  if (FAILED(hr)) break;
335 
336  totalBytesRead.QuadPart += bytesRead;
337 
338  if (bytesRead)
339  {
340  hr = IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
341  if (FAILED(hr)) break;
342  totalBytesWritten.QuadPart += bytesWritten;
343  }
344 
345  if (bytesRead != copySize)
346  cb.QuadPart = 0;
347  else
348  cb.QuadPart -= bytesRead;
349  }
350 
351  if (pcbRead) pcbRead->QuadPart = totalBytesRead.QuadPart;
352  if (pcbWritten) pcbWritten->QuadPart = totalBytesWritten.QuadPart;
353 
354  return hr;
355 }
356 
358  IStream* iface,
359  DWORD grfCommitFlags)
360 {
361  FIXME("stub\n");
362  return E_NOTIMPL;
363 }
364 
366  IStream* iface)
367 {
368  FIXME("stub\n");
369  return E_NOTIMPL;
370 }
371 
373  IStream* iface,
374  ULARGE_INTEGER libOffset,
376  DWORD dwLockType)
377 {
378  FIXME("stub\n");
379  return E_NOTIMPL;
380 }
381 
383  IStream* iface,
384  ULARGE_INTEGER libOffset,
386  DWORD dwLockType)
387 {
388  FIXME("stub\n");
389  return E_NOTIMPL;
390 }
391 
393  IStream* iface,
394  STATSTG *pstatstg,
395  DWORD grfStatFlag)
396 {
398  FIXME("(%p)->(%p, %08x)\n", This, pstatstg, grfStatFlag);
399  memset(pstatstg, 0, sizeof(*pstatstg));
400  pstatstg->cbSize = This->length;
401  return S_OK;
402 }
403 
405  IStream* iface,
406  IStream **ppstm)
407 {
408  FIXME("stub\n");
409  return E_NOTIMPL;
410 }
411 
412 static struct IStreamVtbl sub_stream_vtbl =
413 {
428 };
429 
431 {
433 
434  *out = NULL;
435  This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
436  if(!This) return E_OUTOFMEMORY;
437 
438  This->IStream_iface.lpVtbl = &sub_stream_vtbl;
439  This->ref = 1;
440  This->start = start;
441  This->length = length;
442  This->pos.QuadPart = 0;
443  IStream_AddRef(stream);
444  This->base = stream;
445 
446  *out = &This->IStream_iface;
447  return S_OK;
448 }
449 
451 {
452  STATSTG statstg = {NULL};
454  HRESULT hres;
455 
456  hres = IStream_Stat(stream, &statstg, STATFLAG_NONAME);
457  if(SUCCEEDED(hres)) {
458  *size = statstg.cbSize;
459  return S_OK;
460  }
461 
462  zero.QuadPart = 0;
463  return IStream_Seek(stream, zero, STREAM_SEEK_END, size);
464 }
465 
466 static inline MimeBody *impl_from_IMimeBody(IMimeBody *iface)
467 {
468  return CONTAINING_RECORD(iface, MimeBody, IMimeBody_iface);
469 }
470 
471 typedef struct propschema
472 {
473  IMimePropertySchema IMimePropertySchema_iface;
475 } propschema;
476 
477 static inline propschema *impl_from_IMimePropertySchema(IMimePropertySchema *iface)
478 {
479  return CONTAINING_RECORD(iface, propschema, IMimePropertySchema_iface);
480 }
481 
483 {
484  char *ret;
485  int len = strlen(str);
486  ret = HeapAlloc(GetProcessHeap(), 0, len + 1);
487  memcpy(ret, str, len + 1);
488  return ret;
489 }
490 
491 #define PARSER_BUF_SIZE 1024
492 
493 /*****************************************************
494  * copy_headers_to_buf [internal]
495  *
496  * Copies the headers into a '\0' terminated memory block and leave
497  * the stream's current position set to after the blank line.
498  */
500 {
501  char *buf = NULL;
502  DWORD size = PARSER_BUF_SIZE, offset = 0, last_end = 0;
503  HRESULT hr;
504  BOOL done = FALSE;
505 
506  *ptr = NULL;
507 
508  do
509  {
510  char *end;
511  DWORD read;
512 
513  if(!buf)
514  buf = HeapAlloc(GetProcessHeap(), 0, size + 1);
515  else
516  {
517  size *= 2;
518  buf = HeapReAlloc(GetProcessHeap(), 0, buf, size + 1);
519  }
520  if(!buf)
521  {
522  hr = E_OUTOFMEMORY;
523  goto fail;
524  }
525 
526  hr = IStream_Read(stm, buf + offset, size - offset, &read);
527  if(FAILED(hr)) goto fail;
528 
529  offset += read;
530  buf[offset] = '\0';
531 
532  if(read == 0) done = TRUE;
533 
534  while(!done && (end = strstr(buf + last_end, "\r\n")))
535  {
536  DWORD new_end = end - buf + 2;
537  if(new_end - last_end == 2)
538  {
540  off.QuadPart = (LONGLONG)new_end - offset;
541  IStream_Seek(stm, off, STREAM_SEEK_CUR, NULL);
542  buf[new_end] = '\0';
543  done = TRUE;
544  }
545  else
546  last_end = new_end;
547  }
548  } while(!done);
549 
550  *ptr = buf;
551  return S_OK;
552 
553 fail:
554  HeapFree(GetProcessHeap(), 0, buf);
555  return hr;
556 }
557 
558 static header_t *read_prop(MimeBody *body, char **ptr)
559 {
560  char *colon = strchr(*ptr, ':');
561  const property_t *prop;
562  header_t *ret;
563 
564  if(!colon) return NULL;
565 
566  *colon = '\0';
567 
568  for(prop = default_props; prop->name; prop++)
569  {
570  if(!lstrcmpiA(*ptr, prop->name))
571  {
572  TRACE("%s: found match with default property id %d\n", *ptr, prop->id);
573  break;
574  }
575  }
576 
577  if(!prop->name)
578  {
579  property_list_entry_t *prop_entry;
580  LIST_FOR_EACH_ENTRY(prop_entry, &body->new_props, property_list_entry_t, entry)
581  {
582  if(!lstrcmpiA(*ptr, prop_entry->prop.name))
583  {
584  TRACE("%s: found match with already added new property id %d\n", *ptr, prop_entry->prop.id);
585  prop = &prop_entry->prop;
586  break;
587  }
588  }
589  if(!prop->name)
590  {
591  prop_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*prop_entry));
592  prop_entry->prop.name = strdupA(*ptr);
593  prop_entry->prop.id = body->next_prop_id++;
594  prop_entry->prop.flags = 0;
595  prop_entry->prop.default_vt = VT_LPSTR;
596  list_add_tail(&body->new_props, &prop_entry->entry);
597  prop = &prop_entry->prop;
598  TRACE("%s: allocating new prop id %d\n", *ptr, prop_entry->prop.id);
599  }
600  }
601 
602  ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
603  ret->prop = prop;
604  PropVariantInit(&ret->value);
605  list_init(&ret->params);
606  *ptr = colon + 1;
607 
608  return ret;
609 }
610 
611 static void unfold_header(char *header, int len)
612 {
613  char *start = header, *cp = header;
614 
615  do {
616  while(*cp == ' ' || *cp == '\t')
617  {
618  cp++;
619  len--;
620  }
621  if(cp != start)
622  memmove(start, cp, len + 1);
623 
624  cp = strstr(start, "\r\n");
625  len -= (cp - start);
626  start = cp;
627  *start = ' ';
628  start++;
629  len--;
630  cp += 2;
631  } while(*cp == ' ' || *cp == '\t');
632 
633  *(start - 1) = '\0';
634 }
635 
636 static char *unquote_string(const char *str)
637 {
638  BOOL quoted = FALSE;
639  char *ret, *cp;
640 
641  while(*str == ' ' || *str == '\t') str++;
642 
643  if(*str == '"')
644  {
645  quoted = TRUE;
646  str++;
647  }
648  ret = strdupA(str);
649  for(cp = ret; *cp; cp++)
650  {
651  if(*cp == '\\')
652  memmove(cp, cp + 1, strlen(cp + 1) + 1);
653  else if(*cp == '"')
654  {
655  if(!quoted)
656  {
657  WARN("quote in unquoted string\n");
658  }
659  else
660  {
661  *cp = '\0';
662  break;
663  }
664  }
665  }
666  return ret;
667 }
668 
669 static void add_param(header_t *header, const char *p)
670 {
671  const char *key = p, *value, *cp = p;
672  param_t *param;
673  char *name;
674 
675  TRACE("got param %s\n", p);
676 
677  while (*key == ' ' || *key == '\t' ) key++;
678 
679  cp = strchr(key, '=');
680  if(!cp)
681  {
682  WARN("malformed parameter - skipping\n");
683  return;
684  }
685 
686  name = HeapAlloc(GetProcessHeap(), 0, cp - key + 1);
687  memcpy(name, key, cp - key);
688  name[cp - key] = '\0';
689 
690  value = cp + 1;
691 
692  param = HeapAlloc(GetProcessHeap(), 0, sizeof(*param));
693  param->name = name;
694  param->value = unquote_string(value);
695  list_add_tail(&header->params, &param->entry);
696 }
697 
698 static void split_params(header_t *header, char *value)
699 {
700  char *cp = value, *start = value;
701  BOOL in_quotes = FALSE, done_value = FALSE;
702 
703  while(*cp)
704  {
705  if(!in_quotes && *cp == ';')
706  {
707  *cp = '\0';
708  if(done_value) add_param(header, start);
709  done_value = TRUE;
710  start = cp + 1;
711  }
712  else if(*cp == '"')
713  in_quotes = !in_quotes;
714  cp++;
715  }
716  if(done_value) add_param(header, start);
717 }
718 
719 static void read_value(header_t *header, char **cur)
720 {
721  char *end = *cur, *value;
722  DWORD len;
723 
724  do {
725  end = strstr(end, "\r\n");
726  end += 2;
727  } while(*end == ' ' || *end == '\t');
728 
729  len = end - *cur;
730  value = HeapAlloc(GetProcessHeap(), 0, len + 1);
731  memcpy(value, *cur, len);
732  value[len] = '\0';
733 
735  TRACE("value %s\n", debugstr_a(value));
736 
737  if(header->prop->flags & MPF_HASPARAMS)
738  {
740  TRACE("value w/o params %s\n", debugstr_a(value));
741  }
742 
743  header->value.vt = VT_LPSTR;
744  header->value.u.pszVal = value;
745 
746  *cur = end;
747 }
748 
750 {
751  char *slash;
752  DWORD len;
753 
754  slash = strchr(header->value.u.pszVal, '/');
755  if(!slash)
756  {
757  WARN("malformed context type value\n");
758  return;
759  }
760  len = slash - header->value.u.pszVal;
761  body->content_pri_type = HeapAlloc(GetProcessHeap(), 0, len + 1);
762  memcpy(body->content_pri_type, header->value.u.pszVal, len);
763  body->content_pri_type[len] = '\0';
764  body->content_sub_type = strdupA(slash + 1);
765 }
766 
768 {
769  const char *encoding = header->value.u.pszVal;
770 
771  if(!_strnicmp(encoding, "base64", -1))
772  body->encoding = IET_BASE64;
773  else if(!_strnicmp(encoding, "quoted-printable", -1))
774  body->encoding = IET_QP;
775  else if(!_strnicmp(encoding, "7bit", -1))
776  body->encoding = IET_7BIT;
777  else if(!_strnicmp(encoding, "8bit", -1))
778  body->encoding = IET_8BIT;
779  else
780  FIXME("unknown encoding %s\n", debugstr_a(encoding));
781 }
782 
784 {
785  char *header_buf, *cur_header_ptr;
786  HRESULT hr;
787  header_t *header;
788 
789  hr = copy_headers_to_buf(stm, &header_buf);
790  if(FAILED(hr)) return hr;
791 
792  cur_header_ptr = header_buf;
793  while((header = read_prop(body, &cur_header_ptr)))
794  {
795  read_value(header, &cur_header_ptr);
796  list_add_tail(&body->headers, &header->entry);
797 
798  switch(header->prop->id) {
799  case PID_HDR_CNTTYPE:
801  break;
802  case PID_HDR_CNTXFER:
804  break;
805  }
806  }
807 
808  HeapFree(GetProcessHeap(), 0, header_buf);
809  return hr;
810 }
811 
812 static void empty_param_list(struct list *list)
813 {
814  param_t *param, *cursor2;
815 
817  {
818  list_remove(&param->entry);
822  }
823 }
824 
826 {
827  list_remove(&header->entry);
829  empty_param_list(&header->params);
830  heap_free(header);
831 }
832 
833 static void empty_header_list(struct list *list)
834 {
835  header_t *header, *cursor2;
836 
838  {
840  }
841 }
842 
843 static void empty_new_prop_list(struct list *list)
844 {
845  property_list_entry_t *prop, *cursor2;
846 
848  {
849  list_remove(&prop->entry);
850  HeapFree(GetProcessHeap(), 0, (char *)prop->prop.name);
851  HeapFree(GetProcessHeap(), 0, prop);
852  }
853 }
854 
855 static void release_data(REFIID riid, void *data)
856 {
857  if(!data) return;
858 
859  if(IsEqualIID(riid, &IID_IStream))
860  IStream_Release((IStream *)data);
861  else
862  FIXME("Unhandled data format %s\n", debugstr_guid(riid));
863 }
864 
865 static HRESULT find_prop(MimeBody *body, const char *name, header_t **prop)
866 {
867  header_t *header;
868 
869  *prop = NULL;
870 
872  {
873  if(ISPIDSTR(name))
874  {
875  if(STRTOPID(name) == header->prop->id)
876  {
877  *prop = header;
878  return S_OK;
879  }
880  }
881  else if(!lstrcmpiA(name, header->prop->name))
882  {
883  *prop = header;
884  return S_OK;
885  }
886  }
887 
888  return MIME_E_NOT_FOUND;
889 }
890 
891 static const property_t *find_default_prop(const char *name)
892 {
893  const property_t *prop_def = NULL;
894 
895  for(prop_def = default_props; prop_def->name; prop_def++)
896  {
897  if(ISPIDSTR(name))
898  {
899  if(STRTOPID(name) == prop_def->id)
900  {
901  break;
902  }
903  }
904  else if(!lstrcmpiA(name, prop_def->name))
905  {
906  break;
907  }
908  }
909 
910  if(prop_def->id)
911  TRACE("%s: found match with default property id %d\n", prop_def->name, prop_def->id);
912  else
913  prop_def = NULL;
914 
915  return prop_def;
916 }
917 
919  REFIID riid,
920  void** ppvObject)
921 {
922  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject);
923 
924  *ppvObject = NULL;
925 
926  if (IsEqualIID(riid, &IID_IUnknown) ||
929  IsEqualIID(riid, &IID_IMimePropertySet) ||
930  IsEqualIID(riid, &IID_IMimeBody))
931  {
932  *ppvObject = iface;
933  }
934 
935  if(*ppvObject)
936  {
937  IUnknown_AddRef((IUnknown*)*ppvObject);
938  return S_OK;
939  }
940 
941  FIXME("no interface for %s\n", debugstr_guid(riid));
942  return E_NOINTERFACE;
943 }
944 
946 {
949 
950  TRACE("(%p) ref=%d\n", This, ref);
951 
952  return ref;
953 }
954 
956 {
959 
960  TRACE("(%p) ref=%d\n", This, ref);
961 
962  if (!ref)
963  {
964  empty_header_list(&This->headers);
965  empty_new_prop_list(&This->new_props);
966 
967  HeapFree(GetProcessHeap(), 0, This->content_pri_type);
968  HeapFree(GetProcessHeap(), 0, This->content_sub_type);
969 
970  release_data(&This->data_iid, This->data);
971 
973  }
974 
975  return ref;
976 }
977 
979  IMimeBody* iface,
980  CLSID* pClassID)
981 {
983 
984  TRACE("(%p)->(%p)\n", This, pClassID);
985 
986  if(!pClassID)
987  return E_INVALIDARG;
988 
989  *pClassID = IID_IMimeBody;
990  return S_OK;
991 }
992 
994  IMimeBody* iface)
995 {
997  FIXME("(%p)->() stub\n", This);
998  return E_NOTIMPL;
999 }
1000 
1002 {
1003  MimeBody *This = impl_from_IMimeBody(iface);
1004  TRACE("(%p)->(%p)\n", This, pStm);
1005  return parse_headers(This, pStm);
1006 }
1007 
1008 static HRESULT WINAPI MimeBody_Save(IMimeBody *iface, IStream *pStm, BOOL fClearDirty)
1009 {
1010  MimeBody *This = impl_from_IMimeBody(iface);
1011  FIXME("(%p)->(%p, %d)\n", This, pStm, fClearDirty);
1012  return E_NOTIMPL;
1013 }
1014 
1016  IMimeBody* iface,
1017  ULARGE_INTEGER* pcbSize)
1018 {
1019  MimeBody *This = impl_from_IMimeBody(iface);
1020  FIXME("(%p)->(%p) stub\n", This, pcbSize);
1021  return E_NOTIMPL;
1022 }
1023 
1025  IMimeBody* iface)
1026 {
1027  MimeBody *This = impl_from_IMimeBody(iface);
1028  TRACE("(%p)->()\n", This);
1029  return S_OK;
1030 }
1031 
1033  IMimeBody* iface,
1034  LPCSTR pszName,
1035  LPMIMEPROPINFO pInfo)
1036 {
1037  MimeBody *This = impl_from_IMimeBody(iface);
1038  header_t *header;
1039  HRESULT hr;
1040  DWORD supported = PIM_PROPID | PIM_VTDEFAULT;
1041 
1042  TRACE("(%p)->(%s, %p) semi-stub\n", This, debugstr_a(pszName), pInfo);
1043 
1044  if(!pszName || !pInfo)
1045  return E_INVALIDARG;
1046 
1047  TRACE("mask 0x%04x\n", pInfo->dwMask);
1048 
1049  if(pInfo->dwMask & ~supported)
1050  FIXME("Unsupported mask flags 0x%04x\n", pInfo->dwMask & ~supported);
1051 
1052  hr = find_prop(This, pszName, &header);
1053  if(hr == S_OK)
1054  {
1055  if(pInfo->dwMask & PIM_CHARSET)
1056  pInfo->hCharset = 0;
1057  if(pInfo->dwMask & PIM_FLAGS)
1058  pInfo->dwFlags = 0x00000000;
1059  if(pInfo->dwMask & PIM_ROWNUMBER)
1060  pInfo->dwRowNumber = 0;
1061  if(pInfo->dwMask & PIM_ENCODINGTYPE)
1062  pInfo->ietEncoding = 0;
1063  if(pInfo->dwMask & PIM_VALUES)
1064  pInfo->cValues = 0;
1065  if(pInfo->dwMask & PIM_PROPID)
1066  pInfo->dwPropId = header->prop->id;
1067  if(pInfo->dwMask & PIM_VTDEFAULT)
1068  pInfo->vtDefault = header->prop->default_vt;
1069  if(pInfo->dwMask & PIM_VTCURRENT)
1070  pInfo->vtCurrent = 0;
1071  }
1072 
1073  return hr;
1074 }
1075 
1077  IMimeBody* iface,
1078  LPCSTR pszName,
1079  LPCMIMEPROPINFO pInfo)
1080 {
1081  MimeBody *This = impl_from_IMimeBody(iface);
1082  FIXME("(%p)->(%s, %p) stub\n", This, debugstr_a(pszName), pInfo);
1083  return E_NOTIMPL;
1084 }
1085 
1087  IMimeBody* iface,
1088  LPCSTR pszName,
1089  DWORD dwFlags,
1090  LPPROPVARIANT pValue)
1091 {
1092  MimeBody *This = impl_from_IMimeBody(iface);
1093  header_t *header;
1094  HRESULT hr;
1095 
1096  TRACE("(%p)->(%s, 0x%x, %p)\n", This, debugstr_a(pszName), dwFlags, pValue);
1097 
1098  if(!pszName || !pValue)
1099  return E_INVALIDARG;
1100 
1101  if(!ISPIDSTR(pszName) && !lstrcmpiA(pszName, "att:pri-content-type"))
1102  {
1103  PropVariantClear(pValue);
1104  pValue->vt = VT_LPSTR;
1105  pValue->u.pszVal = strdupA(This->content_pri_type);
1106  return S_OK;
1107  }
1108 
1109  hr = find_prop(This, pszName, &header);
1110  if(hr == S_OK)
1111  {
1112  TRACE("type %d->%d\n", header->value.vt, pValue->vt);
1113 
1114  hr = PropVariantChangeType(pValue, &header->value, 0, pValue->vt);
1115  if(FAILED(hr))
1116  FIXME("Conversion not currently supported (%d->%d)\n", header->value.vt, pValue->vt);
1117  }
1118 
1119  return hr;
1120 }
1121 
1123  IMimeBody* iface,
1124  LPCSTR pszName,
1125  DWORD dwFlags,
1126  LPCPROPVARIANT pValue)
1127 {
1128  MimeBody *This = impl_from_IMimeBody(iface);
1129  header_t *header;
1130  HRESULT hr;
1131 
1132  TRACE("(%p)->(%s, 0x%x, %p)\n", This, debugstr_a(pszName), dwFlags, pValue);
1133 
1134  if(!pszName || !pValue)
1135  return E_INVALIDARG;
1136 
1137  hr = find_prop(This, pszName, &header);
1138  if(hr != S_OK)
1139  {
1140  property_list_entry_t *prop_entry;
1141  const property_t *prop = NULL;
1142 
1143  LIST_FOR_EACH_ENTRY(prop_entry, &This->new_props, property_list_entry_t, entry)
1144  {
1145  if(ISPIDSTR(pszName))
1146  {
1147  if(STRTOPID(pszName) == prop_entry->prop.id)
1148  {
1149  TRACE("Found match with already added new property id %d\n", prop_entry->prop.id);
1150  prop = &prop_entry->prop;
1151  break;
1152  }
1153  }
1154  else if(!lstrcmpiA(pszName, prop_entry->prop.name))
1155  {
1156  TRACE("Found match with already added new property id %d\n", prop_entry->prop.id);
1157  prop = &prop_entry->prop;
1158  break;
1159  }
1160  }
1161 
1162  header = HeapAlloc(GetProcessHeap(), 0, sizeof(*header));
1163  if(!header)
1164  return E_OUTOFMEMORY;
1165 
1166  if(!prop)
1167  {
1168  const property_t *prop_def = NULL;
1169  prop_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*prop_entry));
1170  if(!prop_entry)
1171  {
1173  return E_OUTOFMEMORY;
1174  }
1175 
1176  prop_def = find_default_prop(pszName);
1177  if(prop_def)
1178  {
1179  prop_entry->prop.name = strdupA(prop_def->name);
1180  prop_entry->prop.id = prop_def->id;
1181  }
1182  else
1183  {
1184  if(ISPIDSTR(pszName))
1185  {
1186  HeapFree(GetProcessHeap(), 0, prop_entry);
1188  return MIME_E_NOT_FOUND;
1189  }
1190 
1191  prop_entry->prop.name = strdupA(pszName);
1192  prop_entry->prop.id = This->next_prop_id++;
1193  }
1194 
1195  prop_entry->prop.flags = 0;
1196  prop_entry->prop.default_vt = pValue->vt;
1197  list_add_tail(&This->new_props, &prop_entry->entry);
1198  prop = &prop_entry->prop;
1199  TRACE("Allocating new prop id %d\n", prop_entry->prop.id);
1200  }
1201 
1202  header->prop = prop;
1203  PropVariantInit(&header->value);
1204  list_init(&header->params);
1205  list_add_tail(&This->headers, &header->entry);
1206  }
1207 
1208  PropVariantCopy(&header->value, pValue);
1209 
1210  return S_OK;
1211 }
1212 
1214  IMimeBody* iface,
1215  LPCSTR pszName,
1216  DWORD dwFlags,
1217  LPPROPVARIANT pValue)
1218 {
1219  MimeBody *This = impl_from_IMimeBody(iface);
1220  FIXME("(%p)->(%s, 0x%x, %p) stub\n", This, debugstr_a(pszName), dwFlags, pValue);
1221  return E_NOTIMPL;
1222 }
1223 
1225  IMimeBody* iface,
1226  LPCSTR pszName)
1227 {
1228  MimeBody *This = impl_from_IMimeBody(iface);
1229  header_t *cursor;
1230  BOOL found;
1231 
1232  TRACE("(%p)->(%s) stub\n", This, debugstr_a(pszName));
1233 
1235  {
1236  if(ISPIDSTR(pszName))
1237  found = STRTOPID(pszName) == cursor->prop->id;
1238  else
1239  found = !lstrcmpiA(pszName, cursor->prop->name);
1240 
1241  if(found)
1242  {
1244  return S_OK;
1245  }
1246  }
1247 
1248  return MIME_E_NOT_FOUND;
1249 }
1250 
1252  IMimeBody* iface,
1253  ULONG cNames,
1254  LPCSTR* prgszName,
1255  IMimePropertySet* pPropertySet)
1256 {
1257  MimeBody *This = impl_from_IMimeBody(iface);
1258  FIXME("(%p)->(%d, %p, %p) stub\n", This, cNames, prgszName, pPropertySet);
1259  return E_NOTIMPL;
1260 }
1261 
1263  IMimeBody* iface,
1264  ULONG cNames,
1265  LPCSTR* prgszName,
1266  IMimePropertySet* pPropertySet)
1267 {
1268  MimeBody *This = impl_from_IMimeBody(iface);
1269  FIXME("(%p)->(%d, %p, %p) stub\n", This, cNames, prgszName, pPropertySet);
1270  return E_NOTIMPL;
1271 }
1272 
1274  IMimeBody* iface,
1275  ULONG cNames,
1276  LPCSTR* prgszName)
1277 {
1278  MimeBody *This = impl_from_IMimeBody(iface);
1279  FIXME("(%p)->(%d, %p) stub\n", This, cNames, prgszName);
1280  return E_NOTIMPL;
1281 }
1282 
1284  IMimeBody* iface,
1285  LPCSTR pszName,
1286  LPCSTR pszCriteria,
1287  boolean fSubString,
1288  boolean fCaseSensitive)
1289 {
1290  MimeBody *This = impl_from_IMimeBody(iface);
1291  FIXME("(%p)->(%s, %s, %d, %d) stub\n", This, debugstr_a(pszName), debugstr_a(pszCriteria), fSubString, fCaseSensitive);
1292  return E_NOTIMPL;
1293 }
1294 
1296  IMimeBody* iface,
1297  LPHCHARSET phCharset)
1298 {
1299  MimeBody *This = impl_from_IMimeBody(iface);
1300  FIXME("(%p)->(%p) stub\n", This, phCharset);
1301  *phCharset = NULL;
1302  return S_OK;
1303 }
1304 
1306  IMimeBody* iface,
1307  HCHARSET hCharset,
1308  CSETAPPLYTYPE applytype)
1309 {
1310  MimeBody *This = impl_from_IMimeBody(iface);
1311  FIXME("(%p)->(%p, %d) stub\n", This, hCharset, applytype);
1312  return E_NOTIMPL;
1313 }
1314 
1316  IMimeBody* iface,
1317  LPCSTR pszName,
1318  ULONG* pcParams,
1319  LPMIMEPARAMINFO* pprgParam)
1320 {
1321  MimeBody *This = impl_from_IMimeBody(iface);
1322  HRESULT hr;
1323  header_t *header;
1324 
1325  TRACE("(%p)->(%s, %p, %p)\n", iface, debugstr_a(pszName), pcParams, pprgParam);
1326 
1327  *pprgParam = NULL;
1328  *pcParams = 0;
1329 
1330  hr = find_prop(This, pszName, &header);
1331  if(hr != S_OK) return hr;
1332 
1333  *pcParams = list_count(&header->params);
1334  if(*pcParams)
1335  {
1336  IMimeAllocator *alloc;
1337  param_t *param;
1338  MIMEPARAMINFO *info;
1339 
1341 
1342  *pprgParam = info = IMimeAllocator_Alloc(alloc, *pcParams * sizeof(**pprgParam));
1344  {
1345  int len;
1346 
1347  len = strlen(param->name) + 1;
1348  info->pszName = IMimeAllocator_Alloc(alloc, len);
1349  memcpy(info->pszName, param->name, len);
1350  len = strlen(param->value) + 1;
1351  info->pszData = IMimeAllocator_Alloc(alloc, len);
1352  memcpy(info->pszData, param->value, len);
1353  info++;
1354  }
1355  IMimeAllocator_Release(alloc);
1356  }
1357  return S_OK;
1358 }
1359 
1361  IMimeBody* iface,
1362  LPCSTR pszPriType,
1363  LPCSTR pszSubType)
1364 {
1365  MimeBody *This = impl_from_IMimeBody(iface);
1366 
1367  TRACE("(%p)->(%s, %s)\n", This, debugstr_a(pszPriType), debugstr_a(pszSubType));
1368  if(pszPriType)
1369  {
1370  const char *pri = This->content_pri_type;
1371  if(!pri) pri = "text";
1372  if(lstrcmpiA(pri, pszPriType)) return S_FALSE;
1373  }
1374 
1375  if(pszSubType)
1376  {
1377  const char *sub = This->content_sub_type;
1378  if(!sub) sub = "plain";
1379  if(lstrcmpiA(sub, pszSubType)) return S_FALSE;
1380  }
1381 
1382  return S_OK;
1383 }
1384 
1386  IMimeBody* iface,
1387  REFIID riid,
1388  void** ppvObject)
1389 {
1390  MimeBody *This = impl_from_IMimeBody(iface);
1391  FIXME("(%p)->(%s, %p) stub\n", This, debugstr_guid(riid), ppvObject);
1392  return E_NOTIMPL;
1393 }
1394 
1396  IMimeBody* iface,
1397  IMimePropertySet** ppPropertySet)
1398 {
1399  MimeBody *This = impl_from_IMimeBody(iface);
1400  FIXME("(%p)->(%p) stub\n", This, ppPropertySet);
1401  return E_NOTIMPL;
1402 }
1403 
1405  IMimeBody* iface,
1406  const TYPEDID oid,
1407  LPCPROPVARIANT pValue)
1408 {
1409  MimeBody *This = impl_from_IMimeBody(iface);
1410  HRESULT hr = E_NOTIMPL;
1411  TRACE("(%p)->(%08x, %p)\n", This, oid, pValue);
1412 
1413  if(pValue->vt != TYPEDID_TYPE(oid))
1414  {
1415  WARN("Called with vartype %04x and oid %08x\n", pValue->vt, oid);
1416  return E_INVALIDARG;
1417  }
1418 
1419  switch(oid)
1420  {
1421  case OID_SECURITY_HWND_OWNER:
1422  FIXME("OID_SECURITY_HWND_OWNER (value %08x): ignoring\n", pValue->u.ulVal);
1423  hr = S_OK;
1424  break;
1425  case OID_TRANSMIT_BODY_ENCODING:
1426  FIXME("OID_TRANSMIT_BODY_ENCODING (value %08x): ignoring\n", pValue->u.ulVal);
1427  hr = S_OK;
1428  break;
1429  default:
1430  FIXME("Unhandled oid %08x\n", oid);
1431  }
1432 
1433  return hr;
1434 }
1435 
1437  IMimeBody* iface,
1438  const TYPEDID oid,
1439  LPPROPVARIANT pValue)
1440 {
1441  MimeBody *This = impl_from_IMimeBody(iface);
1442  FIXME("(%p)->(%08x, %p): stub\n", This, oid, pValue);
1443  return E_NOTIMPL;
1444 }
1445 
1447  IMimeBody* iface,
1448  DWORD dwFlags,
1449  IMimeEnumProperties** ppEnum)
1450 {
1451  MimeBody *This = impl_from_IMimeBody(iface);
1452  FIXME("(%p)->(0x%x, %p) stub\n", This, dwFlags, ppEnum);
1453  return E_NOTIMPL;
1454 }
1455 
1457  IMimeBody* iface,
1458  IMSGBODYTYPE bodytype)
1459 {
1460  MimeBody *This = impl_from_IMimeBody(iface);
1461 
1462  TRACE("(%p)->(%d)\n", This, bodytype);
1463  switch(bodytype)
1464  {
1465  case IBT_EMPTY:
1466  return This->data ? S_FALSE : S_OK;
1467  default:
1468  FIXME("Unimplemented bodytype %d - returning S_OK\n", bodytype);
1469  }
1470  return S_OK;
1471 }
1472 
1474  IMimeBody* iface,
1475  LPCSTR pszDisplay)
1476 {
1477  MimeBody *This = impl_from_IMimeBody(iface);
1478  FIXME("(%p)->(%s) stub\n", This, debugstr_a(pszDisplay));
1479  return E_NOTIMPL;
1480 }
1481 
1483  IMimeBody* iface,
1484  LPSTR* ppszDisplay)
1485 {
1486  MimeBody *This = impl_from_IMimeBody(iface);
1487  FIXME("(%p)->(%p) stub\n", This, ppszDisplay);
1488  return E_NOTIMPL;
1489 }
1490 
1492  IMimeBody* iface,
1493  LPBODYOFFSETS pOffsets)
1494 {
1495  MimeBody *This = impl_from_IMimeBody(iface);
1496  TRACE("(%p)->(%p)\n", This, pOffsets);
1497 
1498  *pOffsets = This->body_offsets;
1499 
1500  if(This->body_offsets.cbBodyEnd == 0) return MIME_E_NO_DATA;
1501  return S_OK;
1502 }
1503 
1505  IMimeBody* iface,
1506  ENCODINGTYPE* pietEncoding)
1507 {
1508  MimeBody *This = impl_from_IMimeBody(iface);
1509 
1510  TRACE("(%p)->(%p)\n", This, pietEncoding);
1511 
1512  *pietEncoding = This->encoding;
1513  return S_OK;
1514 }
1515 
1517  IMimeBody* iface,
1518  ENCODINGTYPE ietEncoding)
1519 {
1520  MimeBody *This = impl_from_IMimeBody(iface);
1521 
1522  TRACE("(%p)->(%d)\n", This, ietEncoding);
1523 
1524  This->encoding = ietEncoding;
1525  return S_OK;
1526 }
1527 
1529  IMimeBody* iface,
1530  ENCODINGTYPE ietEncoding,
1531  ULONG* pcbSize)
1532 {
1533  MimeBody *This = impl_from_IMimeBody(iface);
1534  FIXME("(%p)->(%d, %p) stub\n", This, ietEncoding, pcbSize);
1535  return E_NOTIMPL;
1536 }
1537 
1539  IMimeBody* iface,
1540  ENCODINGTYPE ietEncoding,
1541  IStream* pStream)
1542 {
1543  MimeBody *This = impl_from_IMimeBody(iface);
1544  FIXME("(%p)->(%d, %p) stub\n", This, ietEncoding, pStream);
1545  return E_NOTIMPL;
1546 }
1547 
1548 static const signed char base64_decode_table[] =
1549 {
1550  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 */
1551  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 */
1552  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20 */
1553  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30 */
1554  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40 */
1555  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50 */
1556  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60 */
1557  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70 */
1558 };
1559 
1561 {
1562  const unsigned char *ptr, *end;
1563  unsigned char buf[1024];
1565  unsigned char *ret;
1566  unsigned char in[4];
1567  IStream *output;
1568  DWORD size;
1569  int n = 0;
1570  HRESULT hres;
1571 
1572  pos.QuadPart = 0;
1573  hres = IStream_Seek(input, pos, STREAM_SEEK_SET, NULL);
1574  if(FAILED(hres))
1575  return hres;
1576 
1578  if(FAILED(hres))
1579  return hres;
1580 
1581  while(1) {
1582  hres = IStream_Read(input, buf, sizeof(buf), &size);
1583  if(FAILED(hres) || !size)
1584  break;
1585 
1586  ptr = ret = buf;
1587  end = buf + size;
1588 
1589  while(1) {
1590  /* skip invalid chars */
1591  while(ptr < end && (*ptr >= ARRAY_SIZE(base64_decode_table)
1592  || base64_decode_table[*ptr] == -1))
1593  ptr++;
1594  if(ptr == end)
1595  break;
1596 
1597  in[n++] = base64_decode_table[*ptr++];
1598  switch(n) {
1599  case 2:
1600  *ret++ = in[0] << 2 | in[1] >> 4;
1601  continue;
1602  case 3:
1603  *ret++ = in[1] << 4 | in[2] >> 2;
1604  continue;
1605  case 4:
1606  *ret++ = ((in[2] << 6) & 0xc0) | in[3];
1607  n = 0;
1608  }
1609  }
1610 
1611  if(ret > buf) {
1612  hres = IStream_Write(output, buf, ret - buf, NULL);
1613  if(FAILED(hres))
1614  break;
1615  }
1616  }
1617 
1618  if(SUCCEEDED(hres))
1619  hres = IStream_Seek(output, pos, STREAM_SEEK_SET, NULL);
1620  if(FAILED(hres)) {
1621  IStream_Release(output);
1622  return hres;
1623  }
1624 
1625  *ret_stream = output;
1626  return S_OK;
1627 }
1628 
1629 static int hex_digit(char c)
1630 {
1631  if('0' <= c && c <= '9')
1632  return c - '0';
1633  if('A' <= c && c <= 'F')
1634  return c - 'A' + 10;
1635  if('a' <= c && c <= 'f')
1636  return c - 'a' + 10;
1637  return -1;
1638 }
1639 
1640 static HRESULT decode_qp(IStream *input, IStream **ret_stream)
1641 {
1642  const unsigned char *ptr, *end;
1643  unsigned char *ret, prev = 0;
1644  unsigned char buf[1024];
1646  IStream *output;
1647  DWORD size;
1648  int n = -1;
1649  HRESULT hres;
1650 
1651  pos.QuadPart = 0;
1652  hres = IStream_Seek(input, pos, STREAM_SEEK_SET, NULL);
1653  if(FAILED(hres))
1654  return hres;
1655 
1657  if(FAILED(hres))
1658  return hres;
1659 
1660  while(1) {
1661  hres = IStream_Read(input, buf, sizeof(buf), &size);
1662  if(FAILED(hres) || !size)
1663  break;
1664 
1665  ptr = ret = buf;
1666  end = buf + size;
1667 
1668  while(ptr < end) {
1669  unsigned char byte = *ptr++;
1670 
1671  switch(n) {
1672  case -1:
1673  if(byte == '=')
1674  n = 0;
1675  else
1676  *ret++ = byte;
1677  continue;
1678  case 0:
1679  prev = byte;
1680  n = 1;
1681  continue;
1682  case 1:
1683  if(prev != '\r' || byte != '\n') {
1684  int h1 = hex_digit(prev), h2 = hex_digit(byte);
1685  if(h1 != -1 && h2 != -1)
1686  *ret++ = (h1 << 4) | h2;
1687  else
1688  *ret++ = '=';
1689  }
1690  n = -1;
1691  continue;
1692  }
1693  }
1694 
1695  if(ret > buf) {
1696  hres = IStream_Write(output, buf, ret - buf, NULL);
1697  if(FAILED(hres))
1698  break;
1699  }
1700  }
1701 
1702  if(SUCCEEDED(hres))
1703  hres = IStream_Seek(output, pos, STREAM_SEEK_SET, NULL);
1704  if(FAILED(hres)) {
1705  IStream_Release(output);
1706  return hres;
1707  }
1708 
1709  *ret_stream = output;
1710  return S_OK;
1711 }
1712 
1714  IMimeBody* iface,
1715  ENCODINGTYPE ietEncoding,
1716  IStream** ppStream)
1717 {
1718  MimeBody *This = impl_from_IMimeBody(iface);
1720  HRESULT hres;
1721 
1722  TRACE("(%p)->(%d %p)\n", This, ietEncoding, ppStream);
1723 
1724  if(This->encoding != ietEncoding) {
1725  switch(This->encoding) {
1726  case IET_BASE64:
1727  hres = decode_base64(This->data, ppStream);
1728  break;
1729  case IET_QP:
1730  hres = decode_qp(This->data, ppStream);
1731  break;
1732  default:
1733  FIXME("Decoding %d is not supported.\n", This->encoding);
1734  hres = S_FALSE;
1735  }
1736  if(ietEncoding != IET_BINARY)
1737  FIXME("Encoding %d is not supported.\n", ietEncoding);
1738  if(hres != S_FALSE)
1739  return hres;
1740  }
1741 
1742  start.QuadPart = 0;
1743  hres = get_stream_size(This->data, &size);
1744  if(SUCCEEDED(hres))
1745  hres = create_sub_stream(This->data, start, size, ppStream);
1746  return hres;
1747 }
1748 
1750  IMimeBody* iface,
1751  ENCODINGTYPE ietEncoding,
1752  LPCSTR pszPriType,
1753  LPCSTR pszSubType,
1754  REFIID riid,
1755  LPVOID pvObject)
1756 {
1757  MimeBody *This = impl_from_IMimeBody(iface);
1758  TRACE("(%p)->(%d, %s, %s, %s %p)\n", This, ietEncoding, debugstr_a(pszPriType), debugstr_a(pszSubType),
1759  debugstr_guid(riid), pvObject);
1760 
1761  if(IsEqualIID(riid, &IID_IStream))
1762  IStream_AddRef((IStream *)pvObject);
1763  else
1764  {
1765  FIXME("Unhandled object type %s\n", debugstr_guid(riid));
1766  return E_INVALIDARG;
1767  }
1768 
1769  if(This->data)
1770  release_data(&This->data_iid, This->data);
1771 
1772  This->data_iid = *riid;
1773  This->data = pvObject;
1774 
1775  IMimeBody_SetCurrentEncoding(iface, ietEncoding);
1776 
1777  /* FIXME: Update the content type.
1778  If pszPriType == NULL use 'application'
1779  If pszSubType == NULL use 'octet-stream' */
1780 
1781  return S_OK;
1782 }
1783 
1785  IMimeBody* iface)
1786 {
1787  MimeBody *This = impl_from_IMimeBody(iface);
1788  FIXME("(%p)->() stub\n", This);
1789  return E_NOTIMPL;
1790 }
1791 
1793  IMimeBody* iface,
1794  IMimeBody* pBody)
1795 {
1796  MimeBody *This = impl_from_IMimeBody(iface);
1797  FIXME("(%p)->(%p) stub\n", This, pBody);
1798  return E_NOTIMPL;
1799 }
1800 
1802  IMimeBody* iface,
1803  LPTRANSMITINFO pTransmitInfo)
1804 {
1805  MimeBody *This = impl_from_IMimeBody(iface);
1806  FIXME("(%p)->(%p) stub\n", This, pTransmitInfo);
1807  return E_NOTIMPL;
1808 }
1809 
1811  IMimeBody* iface,
1812  ENCODINGTYPE ietEncoding,
1813  LPCSTR pszFilePath)
1814 {
1815  MimeBody *This = impl_from_IMimeBody(iface);
1816  FIXME("(%p)->(%d, %s) stub\n", This, ietEncoding, debugstr_a(pszFilePath));
1817  return E_NOTIMPL;
1818 }
1819 
1821  IMimeBody* iface,
1822  LPHBODY phBody)
1823 {
1824  MimeBody *This = impl_from_IMimeBody(iface);
1825  TRACE("(%p)->(%p)\n", iface, phBody);
1826 
1827  if(!phBody)
1828  return E_INVALIDARG;
1829 
1830  *phBody = This->handle;
1831  return This->handle ? S_OK : MIME_E_NO_DATA;
1832 }
1833 
1834 static IMimeBodyVtbl body_vtbl =
1835 {
1841  MimeBody_Load,
1842  MimeBody_Save,
1879 };
1880 
1881 static HRESULT MimeBody_set_offsets(MimeBody *body, const BODYOFFSETS *offsets)
1882 {
1883  TRACE("setting offsets to %d, %d, %d, %d\n", offsets->cbBoundaryStart,
1884  offsets->cbHeaderStart, offsets->cbBodyStart, offsets->cbBodyEnd);
1885 
1886  body->body_offsets = *offsets;
1887  return S_OK;
1888 }
1889 
1890 #define FIRST_CUSTOM_PROP_ID 0x100
1891 
1893 {
1894  MimeBody *This;
1895  BODYOFFSETS body_offsets;
1896 
1897  This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1898  if (!This)
1899  return NULL;
1900 
1901  This->IMimeBody_iface.lpVtbl = &body_vtbl;
1902  This->ref = 1;
1903  This->handle = NULL;
1904  list_init(&This->headers);
1905  list_init(&This->new_props);
1906  This->next_prop_id = FIRST_CUSTOM_PROP_ID;
1907  This->content_pri_type = NULL;
1908  This->content_sub_type = NULL;
1909  This->encoding = IET_7BIT;
1910  This->data = NULL;
1911  This->data_iid = IID_NULL;
1912 
1913  body_offsets.cbBoundaryStart = body_offsets.cbHeaderStart = 0;
1914  body_offsets.cbBodyStart = body_offsets.cbBodyEnd = 0;
1915  MimeBody_set_offsets(This, &body_offsets);
1916 
1917  return This;
1918 }
1919 
1921 {
1922  MimeBody *mb;
1923 
1924  if(outer)
1925  return CLASS_E_NOAGGREGATION;
1926 
1927  if ((mb = mimebody_create()))
1928  {
1929  *ppv = &mb->IMimeBody_iface;
1930  return S_OK;
1931  }
1932  else
1933  {
1934  *ppv = NULL;
1935  return E_OUTOFMEMORY;
1936  }
1937 }
1938 
1939 typedef struct body_t
1940 {
1941  struct list entry;
1944 
1945  struct body_t *parent;
1946  struct list children;
1947 } body_t;
1948 
1949 typedef struct MimeMessage
1950 {
1954 
1955  struct list body_tree;
1957 } MimeMessage;
1958 
1960 {
1961  return CONTAINING_RECORD(iface, MimeMessage, IMimeMessage_iface);
1962 }
1963 
1965 {
1966  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
1967 
1968  if (IsEqualIID(riid, &IID_IUnknown) ||
1971  IsEqualIID(riid, &IID_IMimeMessageTree) ||
1972  IsEqualIID(riid, &IID_IMimeMessage))
1973  {
1974  *ppv = iface;
1975  IMimeMessage_AddRef(iface);
1976  return S_OK;
1977  }
1978 
1979  FIXME("no interface for %s\n", debugstr_guid(riid));
1980  *ppv = NULL;
1981  return E_NOINTERFACE;
1982 }
1983 
1985 {
1988 
1989  TRACE("(%p) ref=%d\n", This, ref);
1990 
1991  return ref;
1992 }
1993 
1994 static void empty_body_list(struct list *list)
1995 {
1996  body_t *body, *cursor2;
1998  {
1999  empty_body_list(&body->children);
2000  list_remove(&body->entry);
2001  IMimeBody_Release(&body->mime_body->IMimeBody_iface);
2002  HeapFree(GetProcessHeap(), 0, body);
2003  }
2004 }
2005 
2007 {
2010 
2011  TRACE("(%p) ref=%d\n", This, ref);
2012 
2013  if (!ref)
2014  {
2015  empty_body_list(&This->body_tree);
2016 
2017  if(This->stream) IStream_Release(This->stream);
2018  HeapFree(GetProcessHeap(), 0, This);
2019  }
2020 
2021  return ref;
2022 }
2023 
2024 /*** IPersist methods ***/
2026  IMimeMessage *iface,
2027  CLSID *pClassID)
2028 {
2029  FIXME("(%p)->(%p)\n", iface, pClassID);
2030  return E_NOTIMPL;
2031 }
2032 
2033 /*** IPersistStreamInit methods ***/
2035  IMimeMessage *iface)
2036 {
2037  FIXME("(%p)->()\n", iface);
2038  return E_NOTIMPL;
2039 }
2040 
2042 {
2043  body_t *body = HeapAlloc(GetProcessHeap(), 0, sizeof(*body));
2044  if(body)
2045  {
2046  body->mime_body = mime_body;
2047  body->index = index;
2048  list_init(&body->children);
2049  body->parent = parent;
2050 
2051  mime_body->handle = UlongToHandle(body->index);
2052  }
2053  return body;
2054 }
2055 
2056 typedef struct
2057 {
2058  struct list entry;
2059  BODYOFFSETS offsets;
2060 } offset_entry_t;
2061 
2062 static HRESULT create_body_offset_list(IStream *stm, const char *boundary, struct list *body_offsets)
2063 {
2064  HRESULT hr;
2065  DWORD read, boundary_start;
2066  int boundary_len = strlen(boundary);
2067  char *buf, *ptr, *overlap;
2068  DWORD start = 0, overlap_no;
2069  offset_entry_t *cur_body = NULL;
2070  BOOL is_first_line = TRUE;
2071  ULARGE_INTEGER cur;
2073 
2074  list_init(body_offsets);
2075 
2076  overlap_no = boundary_len + 5;
2077 
2078  overlap = buf = HeapAlloc(GetProcessHeap(), 0, overlap_no + PARSER_BUF_SIZE + 1);
2079 
2080  zero.QuadPart = 0;
2081  hr = IStream_Seek(stm, zero, STREAM_SEEK_CUR, &cur);
2082  start = cur.u.LowPart;
2083 
2084  do {
2085  hr = IStream_Read(stm, overlap, PARSER_BUF_SIZE, &read);
2086  if(FAILED(hr)) goto end;
2087  if(read == 0) break;
2088  overlap[read] = '\0';
2089 
2090  ptr = buf;
2091  while(1) {
2092  if(is_first_line) {
2093  is_first_line = FALSE;
2094  }else {
2095  ptr = strstr(ptr, "\r\n");
2096  if(!ptr)
2097  break;
2098  ptr += 2;
2099  }
2100 
2101  boundary_start = start + ptr - buf;
2102 
2103  if(*ptr == '-' && *(ptr + 1) == '-' && !memcmp(ptr + 2, boundary, boundary_len)) {
2104  ptr += boundary_len + 2;
2105 
2106  if(*ptr == '\r' && *(ptr + 1) == '\n')
2107  {
2108  ptr += 2;
2109  if(cur_body)
2110  {
2111  cur_body->offsets.cbBodyEnd = boundary_start - 2;
2112  list_add_tail(body_offsets, &cur_body->entry);
2113  }
2114  cur_body = HeapAlloc(GetProcessHeap(), 0, sizeof(*cur_body));
2115  cur_body->offsets.cbBoundaryStart = boundary_start;
2116  cur_body->offsets.cbHeaderStart = start + ptr - buf;
2117  }
2118  else if(*ptr == '-' && *(ptr + 1) == '-')
2119  {
2120  if(cur_body)
2121  {
2122  cur_body->offsets.cbBodyEnd = boundary_start - 2;
2123  list_add_tail(body_offsets, &cur_body->entry);
2124  goto end;
2125  }
2126  }
2127  }
2128  }
2129 
2130  if(overlap == buf) /* 1st iteration */
2131  {
2132  memmove(buf, buf + PARSER_BUF_SIZE - overlap_no, overlap_no);
2133  overlap = buf + overlap_no;
2134  start += read - overlap_no;
2135  }
2136  else
2137  {
2138  memmove(buf, buf + PARSER_BUF_SIZE, overlap_no);
2139  start += read;
2140  }
2141  } while(1);
2142 
2143 end:
2144  HeapFree(GetProcessHeap(), 0, buf);
2145  return hr;
2146 }
2147 
2149 {
2151  MimeBody *mime_body;
2152  HRESULT hr;
2153  body_t *body;
2155 
2156  pos.QuadPart = offset->cbHeaderStart;
2157  IStream_Seek(pStm, pos, STREAM_SEEK_SET, NULL);
2158 
2159  mime_body = mimebody_create();
2160  IMimeBody_Load(&mime_body->IMimeBody_iface, pStm);
2161 
2162  pos.QuadPart = 0;
2163  hr = IStream_Seek(pStm, pos, STREAM_SEEK_CUR, &start);
2164  offset->cbBodyStart = start.QuadPart;
2165  if (parent) MimeBody_set_offsets(mime_body, offset);
2166 
2167  length.QuadPart = offset->cbBodyEnd - offset->cbBodyStart;
2168  create_sub_stream(pStm, start, length, (IStream**)&mime_body->data);
2169  mime_body->data_iid = IID_IStream;
2170 
2171  body = new_body_entry(mime_body, msg->next_index++, parent);
2172 
2173  if(IMimeBody_IsContentType(&mime_body->IMimeBody_iface, "multipart", NULL) == S_OK)
2174  {
2175  MIMEPARAMINFO *param_info;
2176  ULONG count, i;
2177  IMimeAllocator *alloc;
2178 
2179  hr = IMimeBody_GetParameters(&mime_body->IMimeBody_iface, "Content-Type", &count,
2180  &param_info);
2181  if(hr != S_OK || count == 0) return body;
2182 
2184 
2185  for(i = 0; i < count; i++)
2186  {
2187  if(!lstrcmpiA(param_info[i].pszName, "boundary"))
2188  {
2189  struct list offset_list;
2190  offset_entry_t *cur, *cursor2;
2191  hr = create_body_offset_list(pStm, param_info[i].pszData, &offset_list);
2192  LIST_FOR_EACH_ENTRY_SAFE(cur, cursor2, &offset_list, offset_entry_t, entry)
2193  {
2194  body_t *sub_body;
2195 
2196  sub_body = create_sub_body(msg, pStm, &cur->offsets, body);
2197  list_add_tail(&body->children, &sub_body->entry);
2198  list_remove(&cur->entry);
2199  HeapFree(GetProcessHeap(), 0, cur);
2200  }
2201  break;
2202  }
2203  }
2204  IMimeAllocator_FreeParamInfoArray(alloc, count, param_info, TRUE);
2205  IMimeAllocator_Release(alloc);
2206  }
2207  return body;
2208 }
2209 
2211 {
2213  body_t *root_body;
2214  BODYOFFSETS offsets;
2215  ULARGE_INTEGER cur;
2217 
2218  TRACE("(%p)->(%p)\n", iface, pStm);
2219 
2220  if(This->stream)
2221  {
2222  FIXME("already loaded a message\n");
2223  return E_FAIL;
2224  }
2225 
2226  empty_body_list(&This->body_tree);
2227 
2228  IStream_AddRef(pStm);
2229  This->stream = pStm;
2230  offsets.cbBoundaryStart = offsets.cbHeaderStart = 0;
2231  offsets.cbBodyStart = offsets.cbBodyEnd = 0;
2232 
2233  root_body = create_sub_body(This, pStm, &offsets, NULL);
2234 
2235  zero.QuadPart = 0;
2236  IStream_Seek(pStm, zero, STREAM_SEEK_END, &cur);
2237  offsets.cbBodyEnd = cur.u.LowPart;
2238  MimeBody_set_offsets(root_body->mime_body, &offsets);
2239 
2240  list_add_head(&This->body_tree, &root_body->entry);
2241 
2242  return S_OK;
2243 }
2244 
2245 static HRESULT WINAPI MimeMessage_Save(IMimeMessage *iface, IStream *pStm, BOOL fClearDirty)
2246 {
2247  FIXME("(%p)->(%p, %s)\n", iface, pStm, fClearDirty ? "TRUE" : "FALSE");
2248  return E_NOTIMPL;
2249 }
2250 
2252  IMimeMessage *iface,
2253  ULARGE_INTEGER *pcbSize)
2254 {
2255  FIXME("(%p)->(%p)\n", iface, pcbSize);
2256  return E_NOTIMPL;
2257 }
2258 
2260  IMimeMessage *iface)
2261 {
2262  FIXME("(%p)->()\n", iface);
2263  return E_NOTIMPL;
2264 }
2265 
2266 /*** IMimeMessageTree methods ***/
2268  DWORD dwFlags)
2269 {
2271 
2272  FIXME("(%p)->(%p, 0x%x)\n", iface, ppStream, dwFlags);
2273 
2274  IStream_AddRef(This->stream);
2275  *ppStream = This->stream;
2276  return S_OK;
2277 }
2278 
2280  IMimeMessage *iface,
2281  ULONG *pcbSize,
2282  DWORD dwFlags)
2283 {
2284  FIXME("(%p)->(%p, 0x%x)\n", iface, pcbSize, dwFlags);
2285  return E_NOTIMPL;
2286 }
2287 
2289  IMimeMessage *iface,
2290  IStream *pStream)
2291 {
2292  FIXME("(%p)->(%p)\n", iface, pStream);
2293  return E_NOTIMPL;
2294 }
2295 
2297  IMimeMessage *iface,
2298  IStream *pStream,
2299  DWORD dwFlags)
2300 {
2301  FIXME("(%p)->(%p, 0x%x)\n", iface, pStream, dwFlags);
2302  return E_NOTIMPL;
2303 }
2304 
2305 
2307  IMimeMessage *iface,
2308  DWORD *pdwFlags)
2309 {
2310  FIXME("(%p)->(%p)\n", iface, pdwFlags);
2311  return E_NOTIMPL;
2312 }
2313 
2315  IMimeMessage *iface,
2316  DWORD dwFlags)
2317 {
2318  FIXME("(%p)->(0x%x)\n", iface, dwFlags);
2319  return S_OK;
2320 }
2321 
2322 
2324  IMimeMessage *iface)
2325 {
2326  FIXME("(%p)->()\n", iface);
2327  return E_NOTIMPL;
2328 }
2329 
2330 static HRESULT find_body(struct list *list, HBODY hbody, body_t **body)
2331 {
2332  body_t *cur;
2333  HRESULT hr;
2334 
2335  if(hbody == HBODY_ROOT)
2336  {
2338  return S_OK;
2339  }
2340 
2342  {
2343  if(cur->index == HandleToUlong(hbody))
2344  {
2345  *body = cur;
2346  return S_OK;
2347  }
2348  hr = find_body(&cur->children, hbody, body);
2349  if(hr == S_OK) return S_OK;
2350  }
2351  return S_FALSE;
2352 }
2353 
2355  void **ppvObject)
2356 {
2358  HRESULT hr;
2359  body_t *body;
2360 
2361  TRACE("(%p)->(%p, %s, %p)\n", iface, hBody, debugstr_guid(riid), ppvObject);
2362 
2363  hr = find_body(&This->body_tree, hBody, &body);
2364 
2365  if(hr != S_OK) return hr;
2366 
2367  if(IsEqualIID(riid, &IID_IMimeBody))
2368  {
2369  IMimeBody_AddRef(&body->mime_body->IMimeBody_iface);
2370  *ppvObject = &body->mime_body->IMimeBody_iface;
2371  return S_OK;
2372  }
2373 
2374  return E_NOINTERFACE;
2375 }
2376 
2378  IMimeMessage *iface,
2379  HBODY hBody,
2380  DWORD dwFlags,
2381  IStream *pStream)
2382 {
2383  FIXME("(%p)->(%p, 0x%x, %p)\n", iface, hBody, dwFlags, pStream);
2384  return E_NOTIMPL;
2385 }
2386 
2387 static HRESULT get_body(MimeMessage *msg, BODYLOCATION location, HBODY pivot, body_t **out)
2388 {
2389  body_t *root = LIST_ENTRY(list_head(&msg->body_tree), body_t, entry);
2390  body_t *body;
2391  HRESULT hr;
2392  struct list *list;
2393 
2394  if(location == IBL_ROOT)
2395  {
2396  *out = root;
2397  return S_OK;
2398  }
2399 
2400  hr = find_body(&msg->body_tree, pivot, &body);
2401 
2402  if(hr == S_OK)
2403  {
2404  switch(location)
2405  {
2406  case IBL_PARENT:
2407  if(body->parent)
2408  *out = body->parent;
2409  else
2410  hr = MIME_E_NOT_FOUND;
2411  break;
2412 
2413  case IBL_FIRST:
2414  list = list_head(&body->children);
2415  if(list)
2416  *out = LIST_ENTRY(list, body_t, entry);
2417  else
2418  hr = MIME_E_NOT_FOUND;
2419  break;
2420 
2421  case IBL_LAST:
2422  list = list_tail(&body->children);
2423  if(list)
2424  *out = LIST_ENTRY(list, body_t, entry);
2425  else
2426  hr = MIME_E_NOT_FOUND;
2427  break;
2428 
2429  case IBL_NEXT:
2430  list = list_next(&body->parent->children, &body->entry);
2431  if(list)
2432  *out = LIST_ENTRY(list, body_t, entry);
2433  else
2434  hr = MIME_E_NOT_FOUND;
2435  break;
2436 
2437  case IBL_PREVIOUS:
2438  list = list_prev(&body->parent->children, &body->entry);
2439  if(list)
2440  *out = LIST_ENTRY(list, body_t, entry);
2441  else
2442  hr = MIME_E_NOT_FOUND;
2443  break;
2444 
2445  default:
2446  hr = E_FAIL;
2447  break;
2448  }
2449  }
2450 
2451  return hr;
2452 }
2453 
2454 
2456  IMimeMessage *iface,
2457  BODYLOCATION location,
2458  HBODY hPivot,
2459  LPHBODY phBody)
2460 {
2461  FIXME("(%p)->(%d, %p, %p)\n", iface, location, hPivot, phBody);
2462  return E_NOTIMPL;
2463 }
2464 
2465 static HRESULT WINAPI MimeMessage_GetBody(IMimeMessage *iface, BODYLOCATION location, HBODY hPivot,
2466  HBODY *phBody)
2467 {
2469  body_t *body;
2470  HRESULT hr;
2471 
2472  TRACE("(%p)->(%d, %p, %p)\n", iface, location, hPivot, phBody);
2473 
2474  if(!phBody)
2475  return E_INVALIDARG;
2476 
2477  *phBody = NULL;
2478 
2479  hr = get_body(This, location, hPivot, &body);
2480 
2481  if(hr == S_OK) *phBody = UlongToHandle(body->index);
2482 
2483  return hr;
2484 }
2485 
2487  IMimeMessage *iface,
2488  HBODY hBody,
2489  DWORD dwFlags)
2490 {
2491  FIXME("(%p)->(%p, %08x)\n", iface, hBody, dwFlags);
2492  return E_NOTIMPL;
2493 }
2494 
2496  IMimeMessage *iface,
2497  HBODY hBody,
2498  BODYLOCATION location)
2499 {
2500  FIXME("(%p)->(%d)\n", iface, location);
2501  return E_NOTIMPL;
2502 }
2503 
2504 static void count_children(body_t *body, boolean recurse, ULONG *count)
2505 {
2506  body_t *child;
2507 
2508  LIST_FOR_EACH_ENTRY(child, &body->children, body_t, entry)
2509  {
2510  (*count)++;
2511  if(recurse) count_children(child, recurse, count);
2512  }
2513 }
2514 
2515 static HRESULT WINAPI MimeMessage_CountBodies(IMimeMessage *iface, HBODY hParent, boolean fRecurse,
2516  ULONG *pcBodies)
2517 {
2518  HRESULT hr;
2520  body_t *body;
2521 
2522  TRACE("(%p)->(%p, %s, %p)\n", iface, hParent, fRecurse ? "TRUE" : "FALSE", pcBodies);
2523 
2524  hr = find_body(&This->body_tree, hParent, &body);
2525  if(hr != S_OK) return hr;
2526 
2527  *pcBodies = 1;
2528  count_children(body, fRecurse, pcBodies);
2529 
2530  return S_OK;
2531 }
2532 
2533 static HRESULT find_next(MimeMessage *This, body_t *body, FINDBODY *find, HBODY *out)
2534 {
2535  struct list *ptr;
2536  HBODY next;
2537 
2538  for (;;)
2539  {
2540  if (!body) ptr = list_head( &This->body_tree );
2541  else
2542  {
2543  ptr = list_head( &body->children );
2544  while (!ptr)
2545  {
2546  if (!body->parent) return MIME_E_NOT_FOUND;
2547  if (!(ptr = list_next( &body->parent->children, &body->entry ))) body = body->parent;
2548  }
2549  }
2550 
2551  body = LIST_ENTRY( ptr, body_t, entry );
2552  next = UlongToHandle( body->index );
2553  find->dwReserved = body->index;
2554  if (IMimeBody_IsContentType(&body->mime_body->IMimeBody_iface, find->pszPriType,
2555  find->pszSubType) == S_OK)
2556  {
2557  *out = next;
2558  return S_OK;
2559  }
2560  }
2561  return MIME_E_NOT_FOUND;
2562 }
2563 
2564 static HRESULT WINAPI MimeMessage_FindFirst(IMimeMessage *iface, FINDBODY *pFindBody, HBODY *phBody)
2565 {
2567 
2568  TRACE("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
2569 
2570  pFindBody->dwReserved = 0;
2571  return find_next(This, NULL, pFindBody, phBody);
2572 }
2573 
2574 static HRESULT WINAPI MimeMessage_FindNext(IMimeMessage *iface, FINDBODY *pFindBody, HBODY *phBody)
2575 {
2577  body_t *body;
2578  HRESULT hr;
2579 
2580  TRACE("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
2581 
2582  hr = find_body( &This->body_tree, UlongToHandle( pFindBody->dwReserved ), &body );
2583  if (hr != S_OK) return MIME_E_NOT_FOUND;
2584  return find_next(This, body, pFindBody, phBody);
2585 }
2586 
2588  IMimeMessage *iface,
2589  HBODY hRelated,
2590  LPCSTR pszBase,
2591  LPCSTR pszURL,
2592  DWORD dwFlags,
2593  LPHBODY phBody)
2594 {
2595  FIXME("(%p)->(%p, %s, %s, 0x%x, %p)\n", iface, hRelated, pszBase, pszURL, dwFlags, phBody);
2596  return E_NOTIMPL;
2597 }
2598 
2600  IMimeMessage *iface,
2601  HBODY hBody,
2602  LPCSTR pszSubType,
2603  LPHBODY phMultipart)
2604 {
2605  FIXME("(%p)->(%p, %s, %p)\n", iface, hBody, pszSubType, phMultipart);
2606  return E_NOTIMPL;
2607 }
2608 
2610  IMimeMessage *iface,
2611  HBODY hBody,
2612  LPBODYOFFSETS pOffsets)
2613 {
2614  FIXME("(%p)->(%p, %p)\n", iface, hBody, pOffsets);
2615  return E_NOTIMPL;
2616 }
2617 
2619  IMimeMessage *iface,
2620  LPHCHARSET phCharset)
2621 {
2622  FIXME("(%p)->(%p)\n", iface, phCharset);
2623  *phCharset = NULL;
2624  return S_OK;
2625 }
2626 
2628  IMimeMessage *iface,
2629  HCHARSET hCharset,
2630  CSETAPPLYTYPE applytype)
2631 {
2632  FIXME("(%p)->(%p, %d)\n", iface, hCharset, applytype);
2633  return E_NOTIMPL;
2634 }
2635 
2637  IMimeMessage *iface,
2638  HBODY hBody,
2639  IMSGBODYTYPE bodytype)
2640 {
2641  HRESULT hr;
2642  IMimeBody *mime_body;
2643  TRACE("(%p)->(%p, %d)\n", iface, hBody, bodytype);
2644 
2645  hr = IMimeMessage_BindToObject(iface, hBody, &IID_IMimeBody, (void**)&mime_body);
2646  if(hr != S_OK) return hr;
2647 
2648  hr = IMimeBody_IsType(mime_body, bodytype);
2649  MimeBody_Release(mime_body);
2650  return hr;
2651 }
2652 
2654  IMimeMessage *iface,
2655  HBODY hBody,
2656  LPCSTR pszPriType,
2657  LPCSTR pszSubType)
2658 {
2659  HRESULT hr;
2660  IMimeBody *mime_body;
2661  TRACE("(%p)->(%p, %s, %s)\n", iface, hBody, debugstr_a(pszPriType),
2662  debugstr_a(pszSubType));
2663 
2664  hr = IMimeMessage_BindToObject(iface, hBody, &IID_IMimeBody, (void**)&mime_body);
2665  if(FAILED(hr)) return hr;
2666 
2667  hr = IMimeBody_IsContentType(mime_body, pszPriType, pszSubType);
2668  IMimeBody_Release(mime_body);
2669  return hr;
2670 }
2671 
2673  IMimeMessage *iface,
2674  HBODY hBody,
2675  LPCSTR pszName,
2676  LPCSTR pszCriteria,
2677  boolean fSubString,
2678  boolean fCaseSensitive)
2679 {
2680  FIXME("(%p)->(%p, %s, %s, %s, %s)\n", iface, hBody, pszName, pszCriteria, fSubString ? "TRUE" : "FALSE", fCaseSensitive ? "TRUE" : "FALSE");
2681  return E_NOTIMPL;
2682 }
2683 
2685  IMimeMessage *iface,
2686  HBODY hBody,
2687  LPCSTR pszName,
2688  DWORD dwFlags,
2689  LPPROPVARIANT pValue)
2690 {
2691  HRESULT hr;
2692  IMimeBody *mime_body;
2693 
2694  TRACE("(%p)->(%p, %s, 0x%x, %p)\n", iface, hBody, pszName, dwFlags, pValue);
2695 
2696  hr = IMimeMessage_BindToObject(iface, hBody, &IID_IMimeBody, (void**)&mime_body);
2697  if(hr != S_OK) return hr;
2698 
2699  hr = IMimeBody_GetProp(mime_body, pszName, dwFlags, pValue);
2700  IMimeBody_Release(mime_body);
2701 
2702  return hr;
2703 }
2704 
2706  IMimeMessage *iface,
2707  HBODY hBody,
2708  LPCSTR pszName,
2709  DWORD dwFlags,
2710  LPCPROPVARIANT pValue)
2711 {
2712  FIXME("(%p)->(%p, %s, 0x%x, %p)\n", iface, hBody, pszName, dwFlags, pValue);
2713  return E_NOTIMPL;
2714 }
2715 
2717  IMimeMessage *iface,
2718  HBODY hBody,
2719  LPCSTR pszName)
2720 {
2721  FIXME("(%p)->(%p, %s)\n", iface, hBody, pszName);
2722  return E_NOTIMPL;
2723 }
2724 
2726  IMimeMessage *iface,
2727  const TYPEDID oid,
2728  LPCPROPVARIANT pValue)
2729 {
2730  HRESULT hr = S_OK;
2731  TRACE("(%p)->(%08x, %p)\n", iface, oid, pValue);
2732 
2733  /* Message ID is checked before type.
2734  * OID 0x4D -> 0x56 and 0x58 aren't defined but will filtered out later.
2735  */
2736  if(TYPEDID_ID(oid) < TYPEDID_ID(OID_ALLOW_8BIT_HEADER) || TYPEDID_ID(oid) > TYPEDID_ID(OID_SECURITY_2KEY_CERT_BAG_64))
2737  {
2738  WARN("oid (%08x) out of range\n", oid);
2739  return MIME_E_INVALID_OPTION_ID;
2740  }
2741 
2742  if(pValue->vt != TYPEDID_TYPE(oid))
2743  {
2744  WARN("Called with vartype %04x and oid %08x\n", pValue->vt, oid);
2745  return S_OK;
2746  }
2747 
2748  switch(oid)
2749  {
2750  case OID_HIDE_TNEF_ATTACHMENTS:
2751  FIXME("OID_HIDE_TNEF_ATTACHMENTS (value %d): ignoring\n", pValue->u.boolVal);
2752  break;
2753  case OID_SHOW_MACBINARY:
2754  FIXME("OID_SHOW_MACBINARY (value %d): ignoring\n", pValue->u.boolVal);
2755  break;
2756  case OID_SAVEBODY_KEEPBOUNDARY:
2757  FIXME("OID_SAVEBODY_KEEPBOUNDARY (value %d): ignoring\n", pValue->u.boolVal);
2758  break;
2759  case OID_CLEANUP_TREE_ON_SAVE:
2760  FIXME("OID_CLEANUP_TREE_ON_SAVE (value %d): ignoring\n", pValue->u.boolVal);
2761  break;
2762  default:
2763  FIXME("Unhandled oid %08x\n", oid);
2764  hr = MIME_E_INVALID_OPTION_ID;
2765  }
2766 
2767  return hr;
2768 }
2769 
2771  IMimeMessage *iface,
2772  const TYPEDID oid,
2773  LPPROPVARIANT pValue)
2774 {
2775  FIXME("(%p)->(%08x, %p)\n", iface, oid, pValue);
2776  return E_NOTIMPL;
2777 }
2778 
2779 /*** IMimeMessage methods ***/
2781  IMimeMessage *iface,
2782  IStream *pRootStm,
2783  LPWEBPAGEOPTIONS pOptions,
2784  IMimeMessageCallback *pCallback,
2785  IMoniker **ppMoniker)
2786 {
2787  FIXME("(%p)->(%p, %p, %p, %p)\n", iface, pRootStm, pOptions, pCallback, ppMoniker);
2788  *ppMoniker = NULL;
2789  return E_NOTIMPL;
2790 }
2791 
2793  IMimeMessage *iface,
2794  LPCSTR pszName,
2795  DWORD dwFlags,
2796  LPPROPVARIANT pValue)
2797 {
2798  FIXME("(%p)->(%s, 0x%x, %p)\n", iface, pszName, dwFlags, pValue);
2799  return E_NOTIMPL;
2800 }
2801 
2803  IMimeMessage *iface,
2804  LPCSTR pszName,
2805  DWORD dwFlags,
2806  LPCPROPVARIANT pValue)
2807 {
2808  FIXME("(%p)->(%s, 0x%x, %p)\n", iface, pszName, dwFlags, pValue);
2809  return E_NOTIMPL;
2810 }
2811 
2813  IMimeMessage *iface,
2814  LPCSTR pszName)
2815 {
2816  FIXME("(%p)->(%s)\n", iface, pszName);
2817  return E_NOTIMPL;
2818 }
2819 
2821  IMimeMessage *iface,
2822  LPCSTR pszName,
2823  LPCSTR pszCriteria,
2824  boolean fSubString,
2825  boolean fCaseSensitive)
2826 {
2827  FIXME("(%p)->(%s, %s, %s, %s)\n", iface, pszName, pszCriteria, fSubString ? "TRUE" : "FALSE", fCaseSensitive ? "TRUE" : "FALSE");
2828  return E_NOTIMPL;
2829 }
2830 
2832  IMimeMessage *iface,
2833  DWORD dwTxtType,
2834  ENCODINGTYPE ietEncoding,
2835  IStream **pStream,
2836  LPHBODY phBody)
2837 {
2838  HRESULT hr;
2839  HBODY hbody;
2840  FINDBODY find_struct;
2841  IMimeBody *mime_body;
2842  static char text[] = "text";
2843  static char plain[] = "plain";
2844  static char html[] = "html";
2845 
2846  TRACE("(%p)->(%d, %d, %p, %p)\n", iface, dwTxtType, ietEncoding, pStream, phBody);
2847 
2848  find_struct.pszPriType = text;
2849 
2850  switch(dwTxtType)
2851  {
2852  case TXT_PLAIN:
2853  find_struct.pszSubType = plain;
2854  break;
2855  case TXT_HTML:
2856  find_struct.pszSubType = html;
2857  break;
2858  default:
2859  return MIME_E_INVALID_TEXT_TYPE;
2860  }
2861 
2862  hr = IMimeMessage_FindFirst(iface, &find_struct, &hbody);
2863  if(hr != S_OK)
2864  {
2865  TRACE("not found hr %08x\n", hr);
2866  *phBody = NULL;
2867  return hr;
2868  }
2869 
2870  IMimeMessage_BindToObject(iface, hbody, &IID_IMimeBody, (void**)&mime_body);
2871 
2872  IMimeBody_GetData(mime_body, ietEncoding, pStream);
2873  *phBody = hbody;
2874  IMimeBody_Release(mime_body);
2875  return hr;
2876 }
2877 
2879  IMimeMessage *iface,
2880  DWORD dwTxtType,
2881  ENCODINGTYPE ietEncoding,
2882  HBODY hAlternative,
2883  IStream *pStream,
2884  LPHBODY phBody)
2885 {
2886  FIXME("(%p)->(%d, %d, %p, %p, %p)\n", iface, dwTxtType, ietEncoding, hAlternative, pStream, phBody);
2887  return E_NOTIMPL;
2888 }
2889 
2891  IMimeMessage *iface,
2892  REFIID riid,
2893  void *pvObject,
2894  LPHBODY phBody)
2895 {
2896  FIXME("(%p)->(%s, %p, %p)\n", iface, debugstr_guid(riid), pvObject, phBody);
2897  return E_NOTIMPL;
2898 }
2899 
2901  IMimeMessage *iface,
2902  LPCSTR pszFilePath,
2903  IStream *pstmFile,
2904  LPHBODY phBody)
2905 {
2906  FIXME("(%p)->(%s, %p, %p)\n", iface, pszFilePath, pstmFile, phBody);
2907  return E_NOTIMPL;
2908 }
2909 
2911  IMimeMessage *iface,
2912  LPCSTR pszBase,
2913  LPCSTR pszURL,
2914  DWORD dwFlags,
2915  IStream *pstmURL,
2916  LPSTR *ppszCIDURL,
2917  LPHBODY phBody)
2918 {
2919  FIXME("(%p)->(%s, %s, 0x%x, %p, %p, %p)\n", iface, pszBase, pszURL, dwFlags, pstmURL, ppszCIDURL, phBody);
2920  return E_NOTIMPL;
2921 }
2922 
2924  IMimeMessage *iface,
2925  ULONG *pcAttach,
2926  LPHBODY *pprghAttach)
2927 {
2928  HRESULT hr;
2929  FINDBODY find_struct;
2930  HBODY hbody;
2931  LPHBODY array;
2932  ULONG size = 10;
2933 
2934  TRACE("(%p)->(%p, %p)\n", iface, pcAttach, pprghAttach);
2935 
2936  *pcAttach = 0;
2937  array = CoTaskMemAlloc(size * sizeof(HBODY));
2938 
2939  find_struct.pszPriType = find_struct.pszSubType = NULL;
2940  hr = IMimeMessage_FindFirst(iface, &find_struct, &hbody);
2941  while(hr == S_OK)
2942  {
2943  hr = IMimeMessage_IsContentType(iface, hbody, "multipart", NULL);
2944  TRACE("IsCT rets %08x %d\n", hr, *pcAttach);
2945  if(hr != S_OK)
2946  {
2947  if(*pcAttach + 1 > size)
2948  {
2949  size *= 2;
2950  array = CoTaskMemRealloc(array, size * sizeof(HBODY));
2951  }
2952  array[*pcAttach] = hbody;
2953  (*pcAttach)++;
2954  }
2955  hr = IMimeMessage_FindNext(iface, &find_struct, &hbody);
2956  }
2957 
2958  *pprghAttach = array;
2959  return S_OK;
2960 }
2961 
2963  IMimeMessage *iface,
2964  IMimeAddressTable **ppTable)
2965 {
2966  FIXME("(%p)->(%p)\n", iface, ppTable);
2967  return E_NOTIMPL;
2968 }
2969 
2971  IMimeMessage *iface,
2972  LPADDRESSPROPS pAddress)
2973 {
2974  FIXME("(%p)->(%p)\n", iface, pAddress);
2975  return E_NOTIMPL;
2976 }
2977 
2979  IMimeMessage *iface,
2980  DWORD dwAdrTypes,
2981  DWORD dwProps,
2982  LPADDRESSLIST pList)
2983 {
2984  FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, dwProps, pList);
2985  return E_NOTIMPL;
2986 }
2987 
2989  IMimeMessage *iface,
2990  DWORD dwAdrTypes,
2991  ADDRESSFORMAT format,
2992  LPSTR *ppszFormat)
2993 {
2994  FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, format, ppszFormat);
2995  return E_NOTIMPL;
2996 }
2997 
2999  IMimeMessage *iface,
3000  DWORD dwAdrTypes,
3001  DWORD dwProps,
3002  IMimeEnumAddressTypes **ppEnum)
3003 {
3004  FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, dwProps, ppEnum);
3005  return E_NOTIMPL;
3006 }
3007 
3009  IMimeMessage *iface,
3010  ULONG cbMaxPart,
3011  IMimeMessageParts **ppParts)
3012 {
3013  FIXME("(%p)->(%d, %p)\n", iface, cbMaxPart, ppParts);
3014  return E_NOTIMPL;
3015 }
3016 
3018  IMimeMessage *iface,
3019  IMoniker **ppMoniker)
3020 {
3021  FIXME("(%p)->(%p)\n", iface, ppMoniker);
3022  return E_NOTIMPL;
3023 }
3024 
3025 static const IMimeMessageVtbl MimeMessageVtbl =
3026 {
3083 };
3084 
3086 {
3087  MimeMessage *This;
3088  MimeBody *mime_body;
3089  body_t *root_body;
3090 
3091  TRACE("(%p, %p)\n", outer, obj);
3092 
3093  if (outer)
3094  {
3095  FIXME("outer unknown not supported yet\n");
3096  return E_NOTIMPL;
3097  }
3098 
3099  *obj = NULL;
3100 
3101  This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
3102  if (!This) return E_OUTOFMEMORY;
3103 
3104  This->IMimeMessage_iface.lpVtbl = &MimeMessageVtbl;
3105  This->ref = 1;
3106  This->stream = NULL;
3107  list_init(&This->body_tree);
3108  This->next_index = 1;
3109 
3110  mime_body = mimebody_create();
3111  root_body = new_body_entry(mime_body, This->next_index++, NULL);
3112  list_add_head(&This->body_tree, &root_body->entry);
3113 
3114  *obj = &This->IMimeMessage_iface;
3115  return S_OK;
3116 }
3117 
3118 /***********************************************************************
3119  * MimeOleCreateMessage (INETCOMM.@)
3120  */
3122 {
3123  TRACE("(%p, %p)\n", pUnkOuter, ppMessage);
3124  return MimeMessage_create(NULL, (void **)ppMessage);
3125 }
3126 
3127 /***********************************************************************
3128  * MimeOleSetCompatMode (INETCOMM.@)
3129  */
3131 {
3132  FIXME("(0x%x)\n", dwMode);
3133  return S_OK;
3134 }
3135 
3136 /***********************************************************************
3137  * MimeOleCreateVirtualStream (INETCOMM.@)
3138  */
3140 {
3141  HRESULT hr;
3142  FIXME("(%p)\n", ppStream);
3143 
3144  hr = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
3145  return hr;
3146 }
3147 
3148 typedef struct MimeSecurity
3149 {
3152 } MimeSecurity;
3153 
3155 {
3156  return CONTAINING_RECORD(iface, MimeSecurity, IMimeSecurity_iface);
3157 }
3158 
3160 {
3161  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
3162 
3163  if (IsEqualIID(riid, &IID_IUnknown) ||
3164  IsEqualIID(riid, &IID_IMimeSecurity))
3165  {
3166  *ppv = iface;
3167  IMimeSecurity_AddRef(iface);
3168  return S_OK;
3169  }
3170 
3171  FIXME("no interface for %s\n", debugstr_guid(riid));
3172  *ppv = NULL;
3173  return E_NOINTERFACE;
3174 }
3175 
3177 {
3179  LONG ref = InterlockedIncrement(&This->ref);
3180 
3181  TRACE("(%p) ref=%d\n", This, ref);
3182 
3183  return ref;
3184 }
3185 
3187 {
3189  LONG ref = InterlockedDecrement(&This->ref);
3190 
3191  TRACE("(%p) ref=%d\n", This, ref);
3192 
3193  if (!ref)
3194  HeapFree(GetProcessHeap(), 0, This);
3195 
3196  return ref;
3197 }
3198 
3200  IMimeSecurity* iface)
3201 {
3202  FIXME("(%p)->(): stub\n", iface);
3203  return S_OK;
3204 }
3205 
3207  IMimeSecurity* iface)
3208 {
3209  FIXME("(%p)->(): stub\n", iface);
3210  return E_NOTIMPL;
3211 }
3212 
3214  IMimeSecurity* iface,
3215  IMimeMessageTree* pTree,
3216  DWORD dwFlags)
3217 {
3218  FIXME("(%p)->(%p, %08x): stub\n", iface, pTree, dwFlags);
3219  return E_NOTIMPL;
3220 }
3221 
3223  IMimeSecurity* iface,
3224  IMimeMessageTree* pTree,
3225  HBODY hEncodeRoot,
3226  DWORD dwFlags)
3227 {
3228  FIXME("(%p)->(%p, %p, %08x): stub\n", iface, pTree, hEncodeRoot, dwFlags);
3229  return E_NOTIMPL;
3230 }
3231 
3233  IMimeSecurity* iface,
3234  IMimeMessageTree* pTree,
3235  DWORD dwFlags)
3236 {
3237  FIXME("(%p)->(%p, %08x): stub\n", iface, pTree, dwFlags);
3238  return E_NOTIMPL;
3239 }
3240 
3242  IMimeSecurity* iface,
3243  IMimeMessageTree* pTree,
3244  HBODY hDecodeRoot,
3245  DWORD dwFlags)
3246 {
3247  FIXME("(%p)->(%p, %p, %08x): stub\n", iface, pTree, hDecodeRoot, dwFlags);
3248  return E_NOTIMPL;
3249 }
3250 
3252  IMimeSecurity* iface,
3253  HCAPICERTSTORE hc,
3254  DWORD dwUsage,
3255  PCX509CERT pPrev,
3256  PCX509CERT* ppCert)
3257 {
3258  FIXME("(%p)->(%p, %08x, %p, %p): stub\n", iface, hc, dwUsage, pPrev, ppCert);
3259  return E_NOTIMPL;
3260 }
3261 
3263  IMimeSecurity* iface,
3264  const PCX509CERT pX509Cert,
3265  const CERTNAMETYPE cn,
3266  LPSTR* ppszName)
3267 {
3268  FIXME("(%p)->(%p, %08x, %p): stub\n", iface, pX509Cert, cn, ppszName);
3269  return E_NOTIMPL;
3270 }
3271 
3273  IMimeSecurity* iface,
3274  const HWND hwndParent,
3275  IMimeBody* pBody,
3276  DWORD* pdwSecType)
3277 {
3278  FIXME("(%p)->(%p, %p, %p): stub\n", iface, hwndParent, pBody, pdwSecType);
3279  return E_NOTIMPL;
3280 }
3281 
3283  IMimeSecurity* iface,
3284  const PCX509CERT pX509Cert,
3285  const CERTDATAID dataid,
3286  LPPROPVARIANT pValue)
3287 {
3288  FIXME("(%p)->(%p, %x, %p): stub\n", iface, pX509Cert, dataid, pValue);
3289  return E_NOTIMPL;
3290 }
3291 
3292 
3293 static const IMimeSecurityVtbl MimeSecurityVtbl =
3294 {
3308 };
3309 
3311 {
3312  MimeSecurity *This;
3313 
3314  *obj = NULL;
3315 
3316  if (outer) return CLASS_E_NOAGGREGATION;
3317 
3318  This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
3319  if (!This) return E_OUTOFMEMORY;
3320 
3321  This->IMimeSecurity_iface.lpVtbl = &MimeSecurityVtbl;
3322  This->ref = 1;
3323 
3324  *obj = &This->IMimeSecurity_iface;
3325  return S_OK;
3326 }
3327 
3328 /***********************************************************************
3329  * MimeOleCreateSecurity (INETCOMM.@)
3330  */
3332 {
3333  return MimeSecurity_create(NULL, (void **)ppSecurity);
3334 }
3335 
3337  IMimeAllocator* iface,
3338  REFIID riid,
3339  void **obj)
3340 {
3341  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), obj);
3342 
3343  if (IsEqualIID(riid, &IID_IUnknown) ||
3344  IsEqualIID(riid, &IID_IMalloc) ||
3345  IsEqualIID(riid, &IID_IMimeAllocator))
3346  {
3347  *obj = iface;
3348  IMimeAllocator_AddRef(iface);
3349  return S_OK;
3350  }
3351 
3352  FIXME("no interface for %s\n", debugstr_guid(riid));
3353  *obj = NULL;
3354  return E_NOINTERFACE;
3355 }
3356 
3358  IMimeAllocator* iface)
3359 {
3360  return 2;
3361 }
3362 
3364  IMimeAllocator* iface)
3365 {
3366  return 1;
3367 }
3368 
3370  IMimeAllocator* iface,
3371  SIZE_T cb)
3372 {
3373  return CoTaskMemAlloc(cb);
3374 }
3375 
3377  IMimeAllocator* iface,
3378  LPVOID pv,
3379  SIZE_T cb)
3380 {
3381  return CoTaskMemRealloc(pv, cb);
3382 }
3383 
3385  IMimeAllocator* iface,
3386  LPVOID pv)
3387 {
3388  CoTaskMemFree(pv);
3389 }
3390 
3392  IMimeAllocator* iface,
3393  LPVOID pv)
3394 {
3395  FIXME("stub\n");
3396  return 0;
3397 }
3398 
3400  IMimeAllocator* iface,
3401  LPVOID pv)
3402 {
3403  FIXME("stub\n");
3404  return 0;
3405 }
3406 
3408  IMimeAllocator* iface)
3409 {
3410  FIXME("stub\n");
3411  return;
3412 }
3413 
3415  IMimeAllocator* iface,
3416  ULONG cParams,
3417  LPMIMEPARAMINFO prgParam,
3418  boolean fFreeArray)
3419 {
3420  ULONG i;
3421  TRACE("(%p)->(%d, %p, %d)\n", iface, cParams, prgParam, fFreeArray);
3422 
3423  for(i = 0; i < cParams; i++)
3424  {
3425  IMimeAllocator_Free(iface, prgParam[i].pszName);
3426  IMimeAllocator_Free(iface, prgParam[i].pszData);
3427  }
3428  if(fFreeArray) IMimeAllocator_Free(iface, prgParam);
3429  return S_OK;
3430 }
3431 
3433  IMimeAllocator* iface,
3434  LPADDRESSLIST pList)
3435 {
3436  FIXME("stub\n");
3437  return E_NOTIMPL;
3438 }
3439 
3441  IMimeAllocator* iface,
3442  LPADDRESSPROPS pAddress)
3443 {
3444  FIXME("stub\n");
3445  return E_NOTIMPL;
3446 }
3447 
3449  IMimeAllocator* iface,
3450  ULONG cObjects,
3451  IUnknown **prgpUnknown,
3452  boolean fFreeArray)
3453 {
3454  FIXME("stub\n");
3455  return E_NOTIMPL;
3456 }
3457 
3458 
3460  IMimeAllocator* iface,
3461  ULONG cRows,
3462  LPENUMHEADERROW prgRow,
3463  boolean fFreeArray)
3464 {
3465  FIXME("stub\n");
3466  return E_NOTIMPL;
3467 }
3468 
3470  IMimeAllocator* iface,
3471  ULONG cProps,
3472  LPENUMPROPERTY prgProp,
3473  boolean fFreeArray)
3474 {
3475  FIXME("stub\n");
3476  return E_NOTIMPL;
3477 }
3478 
3480  IMimeAllocator* iface,
3481  THUMBBLOB *pthumbprint)
3482 {
3483  FIXME("stub\n");
3484  return E_NOTIMPL;
3485 }
3486 
3487 
3489  IMimeAllocator* iface,
3490  LPPROPVARIANT pProp)
3491 {
3492  FIXME("stub\n");
3493  return E_NOTIMPL;
3494 }
3495 
3496 static IMimeAllocatorVtbl mime_alloc_vtbl =
3497 {
3515 };
3516 
3517 static IMimeAllocator mime_allocator =
3518 {
3520 };
3521 
3523 {
3524  if(outer) return CLASS_E_NOAGGREGATION;
3525 
3526  *obj = &mime_allocator;
3527  return S_OK;
3528 }
3529 
3531 {
3532  return MimeAllocator_create(NULL, (void**)alloc);
3533 }
3534 
3536 {
3537  FIXME("(%p, %p)\n", outer, obj);
3538 
3539  *obj = NULL;
3540  if (outer) return CLASS_E_NOAGGREGATION;
3541 
3543 }
3544 
3545 /* IMimePropertySchema Interface */
3546 static HRESULT WINAPI propschema_QueryInterface(IMimePropertySchema *iface, REFIID riid, void **out)
3547 {
3549  TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), out);
3550 
3551  *out = NULL;
3552 
3553  if (IsEqualIID(riid, &IID_IUnknown) ||
3554  IsEqualIID(riid, &IID_IMimePropertySchema))
3555  {
3556  *out = iface;
3557  }
3558  else
3559  {
3560  FIXME("no interface for %s\n", debugstr_guid(riid));
3561  return E_NOINTERFACE;
3562  }
3563 
3564  IMimePropertySchema_AddRef(iface);
3565  return S_OK;
3566 }
3567 
3568 static ULONG WINAPI propschema_AddRef(IMimePropertySchema *iface)
3569 {
3571  LONG ref = InterlockedIncrement(&This->ref);
3572 
3573  TRACE("(%p) ref=%d\n", This, ref);
3574 
3575  return ref;
3576 }
3577 
3578 static ULONG WINAPI propschema_Release(IMimePropertySchema *iface)
3579 {
3581  LONG ref = InterlockedDecrement(&This->ref);
3582 
3583  TRACE("(%p) ref=%d\n", This, ref);
3584 
3585  if (!ref)
3586  {
3587  HeapFree(GetProcessHeap(), 0, This);
3588  }
3589 
3590  return ref;
3591 }
3592 
3593 static HRESULT WINAPI propschema_RegisterProperty(IMimePropertySchema *iface, const char *name, DWORD flags,
3594  DWORD rownumber, VARTYPE vtdefault, DWORD *propid)
3595 {
3597  FIXME("(%p)->(%s, %x, %d, %d, %p) stub\n", This, debugstr_a(name), flags, rownumber, vtdefault, propid);
3598  return E_NOTIMPL;
3599 }
3600 
3601 static HRESULT WINAPI propschema_ModifyProperty(IMimePropertySchema *iface, const char *name, DWORD flags,
3602  DWORD rownumber, VARTYPE vtdefault)
3603 {
3605  FIXME("(%p)->(%s, %x, %d, %d) stub\n", This, debugstr_a(name), flags, rownumber, vtdefault);
3606  return S_OK;
3607 }
3608 
3609 static HRESULT WINAPI propschema_GetPropertyId(IMimePropertySchema *iface, const char *name, DWORD *propid)
3610 {
3612  FIXME("(%p)->(%s, %p) stub\n", This, debugstr_a(name), propid);
3613  return E_NOTIMPL;
3614 }
3615 
3616 static HRESULT WINAPI propschema_GetPropertyName(IMimePropertySchema *iface, DWORD propid, char **name)
3617 {
3619  FIXME("(%p)->(%d, %p) stub\n", This, propid, name);
3620  return E_NOTIMPL;
3621 }
3622 
3623 static HRESULT WINAPI propschema_RegisterAddressType(IMimePropertySchema *iface, const char *name, DWORD *adrtype)
3624 {
3626  FIXME("(%p)->(%s, %p) stub\n", This, debugstr_a(name), adrtype);
3627  return E_NOTIMPL;
3628 }
3629 
3630 static IMimePropertySchemaVtbl prop_schema_vtbl =
3631 {
3640 };
3641 
3642 
3644 {
3645  propschema *This;
3646 
3647  TRACE("(%p) stub\n", schema);
3648 
3649  This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
3650  if (!This)
3651  return E_OUTOFMEMORY;
3652 
3653  This->IMimePropertySchema_iface.lpVtbl = &prop_schema_vtbl;
3654  This->ref = 1;
3655 
3656  *schema = &This->IMimePropertySchema_iface;
3657 
3658  return S_OK;
3659 }
3660 
3662  ADDRESSFORMAT addr_format, WCHAR **address)
3663 {
3664  FIXME("(%s, %p, %d, %d, %p) stub\n", debugstr_guid(riid), object, addr_type, addr_format, address);
3665 
3666  return E_NOTIMPL;
3667 }
3668 
3670 {
3671  FIXME("(%s %p)\n", debugstr_guid(riid), ppv);
3672  *ppv = NULL;
3673  return E_NOINTERFACE;
3674 }
3675 
3677 {
3678  TRACE("\n");
3679  return 2;
3680 }
3681 
3683 {
3684  TRACE("\n");
3685  return 1;
3686 }
3687 
3688 static const IUnknownVtbl mime_obj_vtbl = {
3692 };
3693 
3695 
3697  REFIID riid, void **out, IMoniker **moniker_new)
3698 {
3699  WCHAR *display_name, *mhtml_url;
3700  size_t len;
3701  HRESULT hres;
3702 
3703  static const WCHAR mhtml_prefixW[] = {'m','h','t','m','l',':'};
3704 
3705  WARN("(0x%08x, %p, %p, %s, %p, %p) semi-stub\n", bindf, moniker, binding, debugstr_guid(riid), out, moniker_new);
3706 
3707  if(!IsEqualGUID(&IID_IUnknown, riid)) {
3708  FIXME("Unsupported riid %s\n", debugstr_guid(riid));
3709  return E_NOINTERFACE;
3710  }
3711 
3712  hres = IMoniker_GetDisplayName(moniker, NULL, NULL, &display_name);
3713  if(FAILED(hres))
3714  return hres;
3715 
3716  TRACE("display name %s\n", debugstr_w(display_name));
3717 
3718  len = lstrlenW(display_name);
3719  mhtml_url = heap_alloc((len+1)*sizeof(WCHAR) + sizeof(mhtml_prefixW));
3720  if(!mhtml_url)
3721  return E_OUTOFMEMORY;
3722 
3723  memcpy(mhtml_url, mhtml_prefixW, sizeof(mhtml_prefixW));
3724  lstrcpyW(mhtml_url + ARRAY_SIZE(mhtml_prefixW), display_name);
3725  HeapFree(GetProcessHeap(), 0, display_name);
3726 
3727  hres = CreateURLMoniker(NULL, mhtml_url, moniker_new);
3728  heap_free(mhtml_url);
3729  if(FAILED(hres))
3730  return hres;
3731 
3732  /* FIXME: We most likely should start binding here and return something more meaningful as mime object. */
3733  *out = &mime_obj;
3734  return S_OK;
3735 }
struct _LARGE_INTEGER::@2220 u
static HRESULT WINAPI MimeBody_QueryInterface(IMimeBody *iface, REFIID riid, void **ppvObject)
Definition: mimeole.c:918
struct MimeBody MimeBody
static void free_header(header_t *header)
Definition: mimeole.c:825
Definition: mimeole.c:56
static int WINAPI MimeAlloc_DidAlloc(IMimeAllocator *iface, LPVOID pv)
Definition: mimeole.c:3399
struct list headers
Definition: mimeole.c:163
HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity)
Definition: mimeole.c:3331
static void empty_param_list(struct list *list)
Definition: mimeole.c:812
static struct IStreamVtbl sub_stream_vtbl
Definition: mimeole.c:412
IStream * stream
Definition: mimeole.c:1953
static HRESULT WINAPI MimeMessage_IsContentType(IMimeMessage *iface, HBODY hBody, LPCSTR pszPriType, LPCSTR pszSubType)
Definition: mimeole.c:2653
static HRESULT WINAPI MimeMessage_GetClassID(IMimeMessage *iface, CLSID *pClassID)
Definition: mimeole.c:2025
DWORD TYPEDID
Definition: mimeole.idl:205
static ULONG WINAPI MimeBody_AddRef(IMimeBody *iface)
Definition: mimeole.c:945
enum MIMEOLE::tagCSETAPPLYTYPE CSETAPPLYTYPE
static HRESULT WINAPI MimeBody_InitNew(IMimeBody *iface)
Definition: mimeole.c:1024
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static HRESULT WINAPI MimeMessage_GetTextBody(IMimeMessage *iface, DWORD dwTxtType, ENCODINGTYPE ietEncoding, IStream **pStream, LPHBODY phBody)
Definition: mimeole.c:2831
static HRESULT WINAPI MimeBody_GetOffsets(IMimeBody *iface, LPBODYOFFSETS pOffsets)
Definition: mimeole.c:1491
static void release_data(REFIID riid, void *data)
Definition: mimeole.c:855
static const property_t * find_default_prop(const char *name)
Definition: mimeole.c:891
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
static HRESULT WINAPI MimeMessage_GetProp(IMimeMessage *iface, LPCSTR pszName, DWORD dwFlags, LPPROPVARIANT pValue)
Definition: mimeole.c:2792
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
static ULONG WINAPI MimeSecurity_Release(IMimeSecurity *iface)
Definition: mimeole.c:3186
static MimeBody * mimebody_create(void)
Definition: mimeole.c:1892
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT MimeBody_set_offsets(MimeBody *body, const BODYOFFSETS *offsets)
Definition: mimeole.c:1881
static HRESULT WINAPI MimeMessage_QueryInterface(IMimeMessage *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1964
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:420
HRESULT MimeMessage_create(IUnknown *outer, void **obj)
Definition: mimeole.c:3085
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
static HRESULT WINAPI MimeMessage_CountBodies(IMimeMessage *iface, HBODY hParent, boolean fRecurse, ULONG *pcBodies)
Definition: mimeole.c:2515
static HRESULT WINAPI MimeSecurity_InitNew(IMimeSecurity *iface)
Definition: mimeole.c:3199
static HRESULT WINAPI MimeMessage_SaveOffsetTable(IMimeMessage *iface, IStream *pStream, DWORD dwFlags)
Definition: mimeole.c:2296
HRESULT hr
Definition: shlfolder.c:183
static void add_param(header_t *header, const char *p)
Definition: mimeole.c:669
static HRESULT WINAPI MimeAlloc_PropVariantClear(IMimeAllocator *iface, LPPROPVARIANT pProp)
Definition: mimeole.c:3488
static ULONG WINAPI MimeAlloc_AddRef(IMimeAllocator *iface)
Definition: mimeole.c:3357
static HRESULT WINAPI MimeBody_MoveProps(IMimeBody *iface, ULONG cNames, LPCSTR *prgszName, IMimePropertySet *pPropertySet)
Definition: mimeole.c:1262
const property_t * prop
Definition: mimeole.c:151
MimeBody * mime_body
Definition: mimeole.c:1943
static HRESULT WINAPI sub_stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
Definition: mimeole.c:187
static HRESULT WINAPI MimeAlloc_QueryInterface(IMimeAllocator *iface, REFIID riid, void **obj)
Definition: mimeole.c:3336
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
HRESULT WINAPI MimeOleSetCompatMode(DWORD dwMode)
Definition: mimeole.c:3130
static HRESULT WINAPI MimeBody_IsDirty(IMimeBody *iface)
Definition: mimeole.c:993
REFIID riid
Definition: precomp.h:44
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2968
static HRESULT WINAPI MimeMessage_ToMultipart(IMimeMessage *iface, HBODY hBody, LPCSTR pszSubType, LPHBODY phMultipart)
Definition: mimeole.c:2599
__WINE_SERVER_LIST_INLINE struct list * list_prev(const struct list *list, const struct list *elem)
Definition: list.h:123
HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessage)
Definition: mimeole.c:3121
static IMimeBodyVtbl body_vtbl
Definition: mimeole.c:1834
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
const WCHAR * text
Definition: package.c:1827
static ULONG WINAPI sub_stream_Release(IStream *iface)
Definition: mimeole.c:215
static HRESULT WINAPI MimeBody_IsType(IMimeBody *iface, IMSGBODYTYPE bodytype)
Definition: mimeole.c:1456
static HRESULT WINAPI MimeMessage_IsBodyType(IMimeMessage *iface, HBODY hBody, IMSGBODYTYPE bodytype)
Definition: mimeole.c:2636
GLuint GLuint GLsizei count
Definition: gl.h:1545
const GUID IID_IPersist
Definition: proxy.cpp:14
static void init_content_encoding(MimeBody *body, header_t *header)
Definition: mimeole.c:767
static HRESULT WINAPI propschema_GetPropertyId(IMimePropertySchema *iface, const char *name, DWORD *propid)
Definition: mimeole.c:3609
static HRESULT WINAPI MimeMessage_CreateWebPage(IMimeMessage *iface, IStream *pRootStm, LPWEBPAGEOPTIONS pOptions, IMimeMessageCallback *pCallback, IMoniker **ppMoniker)
Definition: mimeole.c:2780
struct _root root
static HRESULT WINAPI MimeMessage_AttachObject(IMimeMessage *iface, REFIID riid, void *pvObject, LPHBODY phBody)
Definition: mimeole.c:2890
#define WARN(fmt,...)
Definition: debug.h:111
static HRESULT WINAPI MimeMessage_GetAddressFormat(IMimeMessage *iface, DWORD dwAdrTypes, ADDRESSFORMAT format, LPSTR *ppszFormat)
Definition: mimeole.c:2988
#define HandleToUlong(h)
Definition: basetsd.h:79
DWORD index
Definition: mimeole.c:1942
GLintptr offset
Definition: glext.h:5920
static ULONG WINAPI MimeMessage_Release(IMimeMessage *iface)
Definition: mimeole.c:2006
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
Definition: list.h:96
REFIID LPVOID * ppv
Definition: atlbase.h:39
static HRESULT WINAPI MimeBody_BindToObject(IMimeBody *iface, REFIID riid, void **ppvObject)
Definition: mimeole.c:1385
static HRESULT WINAPI MimeAlloc_FreeEnumPropertyArray(IMimeAllocator *iface, ULONG cProps, LPENUMPROPERTY prgProp, boolean fFreeArray)
Definition: mimeole.c:3469
GLdouble n
Definition: glext.h:7729
#define PARSER_BUF_SIZE
Definition: mimeole.c:491
static HRESULT WINAPI MimeSecurity_QueryInterface(IMimeSecurity *iface, REFIID riid, void **ppv)
Definition: mimeole.c:3159
static HRESULT WINAPI MimeBody_GetCurrentEncoding(IMimeBody *iface, ENCODINGTYPE *pietEncoding)
Definition: mimeole.c:1504
DWORD next_index
Definition: mimeole.c:1956
static BYTE cn[]
Definition: cert.c:2938
static HRESULT WINAPI MimeMessage_GetOption(IMimeMessage *iface, const TYPEDID oid, LPPROPVARIANT pValue)
Definition: mimeole.c:2770
static HRESULT WINAPI MimeSecurity_EncodeMessage(IMimeSecurity *iface, IMimeMessageTree *pTree, DWORD dwFlags)
Definition: mimeole.c:3213
static HRESULT WINAPI MimeMessage_GetBody(IMimeMessage *iface, BODYLOCATION location, HBODY hPivot, HBODY *phBody)
Definition: mimeole.c:2465
const PROPVARIANT * LPCPROPVARIANT
Definition: mimeole.idl:206
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, PROPVAR_CHANGE_FLAGS flags, VARTYPE vt)
Definition: propvar.c:428
IMimeBody IMimeBody_iface
Definition: mimeole.c:158
static int hex_digit(char c)
Definition: mimeole.c:1629
static HRESULT WINAPI MimeMessage_Save(IMimeMessage *iface, IStream *pStm, BOOL fClearDirty)
Definition: mimeole.c:2245
HBODY handle
Definition: mimeole.c:161
static HRESULT WINAPI MimeBody_IsContentType(IMimeBody *iface, LPCSTR pszPriType, LPCSTR pszSubType)
Definition: mimeole.c:1360
static LPVOID WINAPI MimeAlloc_Alloc(IMimeAllocator *iface, SIZE_T cb)
Definition: mimeole.c:3369
static HRESULT WINAPI MimeBody_QueryProp(IMimeBody *iface, LPCSTR pszName, LPCSTR pszCriteria, boolean fSubString, boolean fCaseSensitive)
Definition: mimeole.c:1283
GLuint GLuint end
Definition: gl.h:1545
char * content_pri_type
Definition: mimeole.c:166
static HRESULT WINAPI MimeAlloc_FreeAddressProps(IMimeAllocator *iface, LPADDRESSPROPS pAddress)
Definition: mimeole.c:3440
static HRESULT WINAPI sub_stream_Revert(IStream *iface)
Definition: mimeole.c:365
static HRESULT decode_qp(IStream *input, IStream **ret_stream)
Definition: mimeole.c:1640
__WINE_SERVER_LIST_INLINE struct list * list_tail(const struct list *list)
Definition: list.h:137
LPCSTR name
Definition: mimeole.c:50
char * LPSTR
Definition: xmlstorage.h:182
static HRESULT create_body_offset_list(IStream *stm, const char *boundary, struct list *body_offsets)
Definition: mimeole.c:2062
static const IMimeMessageVtbl MimeMessageVtbl
Definition: mimeole.c:3025
#define lstrlenW
Definition: compat.h:415
#define E_FAIL
Definition: ddrawi.h:102
static void init_content_type(MimeBody *body, header_t *header)
Definition: mimeole.c:749
static HRESULT WINAPI MimeSecurity_DecodeMessage(IMimeSecurity *iface, IMimeMessageTree *pTree, DWORD dwFlags)
Definition: mimeole.c:3232
Definition: send.c:47
static HWND child
Definition: cursoricon.c:298
static HRESULT parse_headers(MimeBody *body, IStream *stm)
Definition: mimeole.c:783
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static HRESULT WINAPI MimeMessage_SplitMessage(IMimeMessage *iface, ULONG cbMaxPart, IMimeMessageParts **ppParts)
Definition: mimeole.c:3008
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static HRESULT WINAPI MimeBody_GetDisplayName(IMimeBody *iface, LPSTR *ppszDisplay)
Definition: mimeole.c:1482
static HRESULT WINAPI propschema_QueryInterface(IMimePropertySchema *iface, REFIID riid, void **out)
Definition: mimeole.c:3546
static HRESULT WINAPI sub_stream_Clone(IStream *iface, IStream **ppstm)
Definition: mimeole.c:404
__WINE_SERVER_LIST_INLINE struct list * list_head(const struct list *list)
Definition: list.h:131
IMimeSecurity IMimeSecurity_iface
Definition: mimeole.c:3150
struct _test_info info[]
Definition: SetCursorPos.c:19
static HRESULT WINAPI propschema_ModifyProperty(IMimePropertySchema *iface, const char *name, DWORD flags, DWORD rownumber, VARTYPE vtdefault)
Definition: mimeole.c:3601
static HRESULT WINAPI MimeMessage_EnumAddressTypes(IMimeMessage *iface, DWORD dwAdrTypes, DWORD dwProps, IMimeEnumAddressTypes **ppEnum)
Definition: mimeole.c:2998
static void split_params(header_t *header, char *value)
Definition: mimeole.c:698
static HRESULT WINAPI MimeMessage_GetSizeMax(IMimeMessage *iface, ULARGE_INTEGER *pcbSize)
Definition: mimeole.c:2251
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
static HRESULT WINAPI MimeMessage_BindToObject(IMimeMessage *iface, const HBODY hBody, REFIID riid, void **ppvObject)
Definition: mimeole.c:2354
DWORD id
Definition: mimeole.c:51
static HRESULT WINAPI MimeMessage_LoadOffsetTable(IMimeMessage *iface, IStream *pStream)
Definition: mimeole.c:2288
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HRESULT WINAPI MimeBody_SetProp(IMimeBody *iface, LPCSTR pszName, DWORD dwFlags, LPCPROPVARIANT pValue)
Definition: mimeole.c:1122
static HRESULT WINAPI MimeMessage_GetRootMoniker(IMimeMessage *iface, IMoniker **ppMoniker)
Definition: mimeole.c:3017
IMimePropertySchema IMimePropertySchema_iface
Definition: mimeole.c:473
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static HRESULT WINAPI MimeAlloc_FreeEnumHeaderRowArray(IMimeAllocator *iface, ULONG cRows, LPENUMHEADERROW prgRow, boolean fFreeArray)
Definition: mimeole.c:3459
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
GLenum const GLfloat * params
Definition: glext.h:5645
HBODY * LPHBODY
Definition: mimeole.idl:203
unsigned int BOOL
Definition: ntddk_ex.h:94
__WINE_SERVER_LIST_INLINE unsigned int list_count(const struct list *list)
Definition: list.h:155
long LONG
Definition: pedump.c:60
static HRESULT WINAPI MimeMessage_GetMessageSource(IMimeMessage *iface, IStream **ppStream, DWORD dwFlags)
Definition: mimeole.c:2267
static HRESULT WINAPI MimeBody_Save(IMimeBody *iface, IStream *pStm, BOOL fClearDirty)
Definition: mimeole.c:1008
static HRESULT WINAPI propschema_RegisterProperty(IMimePropertySchema *iface, const char *name, DWORD flags, DWORD rownumber, VARTYPE vtdefault, DWORD *propid)
Definition: mimeole.c:3593
#define debugstr_w
Definition: kernel32.h:32
static void empty_header_list(struct list *list)
Definition: mimeole.c:833
static HRESULT WINAPI sub_stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: mimeole.c:372
GLenum GLint ref
Definition: glext.h:6028
static HRESULT WINAPI MimeBody_GetClassID(IMimeBody *iface, CLSID *pClassID)
Definition: mimeole.c:978
_Check_return_ _CRTIMP int __cdecl _strnicmp(_In_reads_or_z_(_MaxCount) const char *_Str1, _In_reads_or_z_(_MaxCount) const char *_Str2, _In_ size_t _MaxCount)
static HRESULT copy_headers_to_buf(IStream *stm, char **ptr)
Definition: mimeole.c:499
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
#define S_FALSE
Definition: winerror.h:2357
static HRESULT WINAPI MimeMessage_AttachFile(IMimeMessage *iface, LPCSTR pszFilePath, IStream *pstmFile, LPHBODY phBody)
Definition: mimeole.c:2900
#define E_INVALIDARG
Definition: ddrawi.h:101
static LPVOID WINAPI MimeAlloc_Realloc(IMimeAllocator *iface, LPVOID pv, SIZE_T cb)
Definition: mimeole.c:3376
struct MimeMessage MimeMessage
const WCHAR * str
static HRESULT WINAPI MimeMessage_GetFlags(IMimeMessage *iface, DWORD *pdwFlags)
Definition: mimeole.c:2306
LONG ref
Definition: mimeole.c:1952
static HRESULT WINAPI MimeBody_Load(IMimeBody *iface, IStream *pStm)
Definition: mimeole.c:1001
smooth NULL
Definition: ftsmooth.c:416
static HRESULT WINAPI MimeBody_SaveToFile(IMimeBody *iface, ENCODINGTYPE ietEncoding, LPCSTR pszFilePath)
Definition: mimeole.c:1810
static HWND hwndParent
Definition: cryptui.c:300
static HRESULT WINAPI MimeMessage_SetCharset(IMimeMessage *iface, HCHARSET hCharset, CSETAPPLYTYPE applytype)
Definition: mimeole.c:2627
static HRESULT WINAPI MimeBody_EmptyData(IMimeBody *iface)
Definition: mimeole.c:1784
HRESULT MimeBody_create(IUnknown *outer, void **ppv)
Definition: mimeole.c:1920
static HRESULT WINAPI MimeMessage_MoveBody(IMimeMessage *iface, HBODY hBody, BODYLOCATION location)
Definition: mimeole.c:2495
static HRESULT WINAPI sub_stream_Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag)
Definition: mimeole.c:392
static HRESULT WINAPI MimeBody_Clone(IMimeBody *iface, IMimePropertySet **ppPropertySet)
Definition: mimeole.c:1395
static HRESULT WINAPI MimeBody_GetHandle(IMimeBody *iface, LPHBODY phBody)
Definition: mimeole.c:1820
static HRESULT WINAPI MimeAlloc_FreeParamInfoArray(IMimeAllocator *iface, ULONG cParams, LPMIMEPARAMINFO prgParam, boolean fFreeArray)
Definition: mimeole.c:3414
static HRESULT get_stream_size(IStream *stream, ULARGE_INTEGER *size)
Definition: mimeole.c:450
GLuint index
Definition: glext.h:6031
struct body_t * parent
Definition: mimeole.c:1945
static ULONG WINAPI sub_stream_AddRef(IStream *iface)
Definition: mimeole.c:205
const char * LPCSTR
Definition: xmlstorage.h:183
PROPVARIANT value
Definition: mimeole.c:152
static HRESULT WINAPI MimeBody_GetProp(IMimeBody *iface, LPCSTR pszName, DWORD dwFlags, LPPROPVARIANT pValue)
Definition: mimeole.c:1086
#define STG_E_INVALIDFUNCTION
Definition: winerror.h:2564
static IMimeAllocator mime_allocator
Definition: mimeole.c:3517
static ULONG WINAPI mime_obj_Release(IUnknown *iface)
Definition: mimeole.c:3682
Definition: mimeole.c:2056
static ULONG WINAPI MimeMessage_AddRef(IMimeMessage *iface)
Definition: mimeole.c:1984
#define debugstr_guid
Definition: kernel32.h:35
static HRESULT WINAPI sub_stream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: mimeole.c:255
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static ULONG WINAPI propschema_AddRef(IMimePropertySchema *iface)
Definition: mimeole.c:3568
HCHARSET * LPHCHARSET
Definition: mimeole.idl:202
struct list entry
Definition: mimeole.c:1941
WINE_DEFAULT_DEBUG_CHANNEL(inetcomm)
static HRESULT WINAPI MimeSecurity_EncodeBody(IMimeSecurity *iface, IMimeMessageTree *pTree, HBODY hEncodeRoot, DWORD dwFlags)
Definition: mimeole.c:3222
static HRESULT get_body(MimeMessage *msg, BODYLOCATION location, HBODY pivot, body_t **out)
Definition: mimeole.c:2387
enum MIMEOLE::tagENCODINGTYPE ENCODINGTYPE
struct list entry
Definition: mimeole.c:58
HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc)
Definition: ole2.c:3086
static void read_value(header_t *header, char **cur)
Definition: mimeole.c:719
int64_t LONGLONG
Definition: typedefs.h:66
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static HRESULT WINAPI MimeMessage_SetOption(IMimeMessage *iface, const TYPEDID oid, LPCPROPVARIANT pValue)
Definition: mimeole.c:2725
SIGDN PWSTR * ppszName
Definition: shobjidl.idl:593
static HRESULT WINAPI MimeMessage_QueryBodyProp(IMimeMessage *iface, HBODY hBody, LPCSTR pszName, LPCSTR pszCriteria, boolean fSubString, boolean fCaseSensitive)
Definition: mimeole.c:2672
#define TRACE(s)
Definition: solgame.cpp:4
static HRESULT WINAPI MimeMessage_GetCharset(IMimeMessage *iface, LPHCHARSET phCharset)
Definition: mimeole.c:2618
static HRESULT WINAPI MimeBody_SetDisplayName(IMimeBody *iface, LPCSTR pszDisplay)
Definition: mimeole.c:1473
GLsizeiptr size
Definition: glext.h:5919
static HRESULT WINAPI MimeMessage_SetTextBody(IMimeMessage *iface, DWORD dwTxtType, ENCODINGTYPE ietEncoding, HBODY hAlternative, IStream *pStream, LPHBODY phBody)
Definition: mimeole.c:2878
HRESULT hres
Definition: protocol.c:465
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
r parent
Definition: btrfs.c:2869
WCHAR * value
static HRESULT WINAPI MimeBody_DeleteExcept(IMimeBody *iface, ULONG cNames, LPCSTR *prgszName)
Definition: mimeole.c:1273
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define debugstr_a
Definition: kernel32.h:31
HRESULT WINAPI MimeOleGetAllocator(IMimeAllocator **alloc)
Definition: mimeole.c:3530
LONG HRESULT
Definition: typedefs.h:77
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static HRESULT WINAPI MimeSecurity_EnumCertificates(IMimeSecurity *iface, HCAPICERTSTORE hc, DWORD dwUsage, PCX509CERT pPrev, PCX509CERT *ppCert)
Definition: mimeole.c:3251
static HRESULT WINAPI MimeMessage_SetProp(IMimeMessage *iface, LPCSTR pszName, DWORD dwFlags, LPCPROPVARIANT pValue)
Definition: mimeole.c:2802
static ULONG WINAPI mime_obj_AddRef(IUnknown *iface)
Definition: mimeole.c:3676
#define UlongToHandle(ul)
Definition: basetsd.h:97
const GUID IID_IUnknown
static HRESULT WINAPI MimeBody_AppendProp(IMimeBody *iface, LPCSTR pszName, DWORD dwFlags, LPPROPVARIANT pValue)
Definition: mimeole.c:1213
static HRESULT WINAPI sub_stream_CopyTo(IStream *iface, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
Definition: mimeole.c:308
static const property_t default_props[]
Definition: mimeole.c:62
HRESULT WINAPI MimeOleObjectFromMoniker(BINDF bindf, IMoniker *moniker, IBindCtx *binding, REFIID riid, void **out, IMoniker **moniker_new)
Definition: mimeole.c:3696
static HRESULT WINAPI MimeBody_SetCurrentEncoding(IMimeBody *iface, ENCODINGTYPE ietEncoding)
Definition: mimeole.c:1516
GLfloat param
Definition: glext.h:5796
#define WINAPI
Definition: msvc.h:6
const GLubyte * c
Definition: glext.h:8905
static HRESULT WINAPI sub_stream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: mimeole.c:382
char * name
Definition: mimeole.c:144
static FILE * out
Definition: regtests2xml.c:44
IStream * base
Definition: mimeole.c:178
static void empty_new_prop_list(struct list *list)
Definition: mimeole.c:843
char * name
Definition: compiler.c:66
LONG ref
Definition: mimeole.c:159
static HRESULT WINAPI MimeBody_SetOption(IMimeBody *iface, const TYPEDID oid, LPCPROPVARIANT pValue)
Definition: mimeole.c:1404
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint address
Definition: glext.h:9393
static HRESULT create_sub_stream(IStream *stream, ULARGE_INTEGER start, ULARGE_INTEGER length, IStream **out)
Definition: mimeole.c:430
static MimeBody * impl_from_IMimeBody(IMimeBody *iface)
Definition: mimeole.c:466
static propschema * impl_from_IMimePropertySchema(IMimePropertySchema *iface)
Definition: mimeole.c:477
char * content_sub_type
Definition: mimeole.c:167
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static HRESULT WINAPI MimeMessage_InsertBody(IMimeMessage *iface, BODYLOCATION location, HBODY hPivot, LPHBODY phBody)
Definition: mimeole.c:2455
static HRESULT WINAPI MimeMessage_GetAttachments(IMimeMessage *iface, ULONG *pcAttach, LPHBODY *pprghAttach)
Definition: mimeole.c:2923
static HRESULT WINAPI MimeBody_GetPropInfo(IMimeBody *iface, LPCSTR pszName, LPMIMEPROPINFO pInfo)
Definition: mimeole.c:1032
GLbitfield flags
Definition: glext.h:7161
static HRESULT WINAPI MimeBody_GetSizeMax(IMimeBody *iface, ULARGE_INTEGER *pcbSize)
Definition: mimeole.c:1015
struct MimeSecurity MimeSecurity
struct body_t body_t
static body_t * create_sub_body(MimeMessage *msg, IStream *pStm, BODYOFFSETS *offset, body_t *parent)
Definition: mimeole.c:2148
static HRESULT find_body(struct list *list, HBODY hbody, body_t **body)
Definition: mimeole.c:2330
int ret
static double zero
Definition: j0_y0.c:96
static HRESULT WINAPI MimeMessage_DeleteBody(IMimeMessage *iface, HBODY hBody, DWORD dwFlags)
Definition: mimeole.c:2486
IStream IStream_iface
Definition: mimeole.c:176
#define index(s, c)
Definition: various.h:29
#define IID_NULL
Definition: guiddef.h:98
static const WCHAR mhtml_prefixW[]
Definition: protocol.c:62
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
static HRESULT WINAPI MimeMessage_QueryProp(IMimeMessage *iface, LPCSTR pszName, LPCSTR pszCriteria, boolean fSubString, boolean fCaseSensitive)
Definition: mimeole.c:2820
const GUID IID_IPersistStreamInit
static HRESULT WINAPI MimeBody_SetPropInfo(IMimeBody *iface, LPCSTR pszName, LPCMIMEPROPINFO pInfo)
Definition: mimeole.c:1076
GLuint GLuint stream
Definition: glext.h:7522
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
HKEY key
Definition: reg.c:42
const DOCKBAR PVOID HWND hParent
Definition: tooldock.h:22
static header_t * read_prop(MimeBody *body, char **ptr)
Definition: mimeole.c:558
static MimeMessage * impl_from_IMimeMessage(IMimeMessage *iface)
Definition: mimeole.c:1959
static void count_children(body_t *body, boolean recurse, ULONG *count)
Definition: mimeole.c:2504
uint32_t entry
Definition: isohybrid.c:63
static HRESULT WINAPI MimeBody_GetOption(IMimeBody *iface, const TYPEDID oid, LPPROPVARIANT pValue)
Definition: mimeole.c:1436
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static HRESULT WINAPI MimeMessage_InitNew(IMimeMessage *iface)
Definition: mimeole.c:2259
GLenum GLsizei len
Definition: glext.h:6722
struct list entry
Definition: mimeole.c:2058
unsigned char BYTE
Definition: mem.h:68
static HRESULT WINAPI MimeBody_GetData(IMimeBody *iface, ENCODINGTYPE ietEncoding, IStream **ppStream)
Definition: mimeole.c:1713
Definition: _list.h:228
REFIID LPVOID * ppvObject
Definition: precomp.h:44
char * value
Definition: compiler.c:67
static HRESULT WINAPI MimeMessage_DeleteBodyProp(IMimeMessage *iface, HBODY hBody, LPCSTR pszName)
Definition: mimeole.c:2716
static HRESULT WINAPI MimeMessage_Load(IMimeMessage *iface, IStream *pStm)
Definition: mimeole.c:2210
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
GLsizei const GLfloat * value
Definition: glext.h:6069
static HRESULT WINAPI MimeMessage_GetSender(IMimeMessage *iface, LPADDRESSPROPS pAddress)
Definition: mimeole.c:2970
static HRESULT WINAPI MimeBody_GetEstimatedSize(IMimeBody *iface, ENCODINGTYPE ietEncoding, ULONG *pcbSize)
Definition: mimeole.c:1528
ed encoding
Definition: write.c:2839
static HRESULT WINAPI MimeMessage_SetBodyProp(IMimeMessage *iface, HBODY hBody, LPCSTR pszName, DWORD dwFlags, LPCPROPVARIANT pValue)
Definition: mimeole.c:2705
static HRESULT WINAPI sub_stream_Commit(IStream *iface, DWORD grfCommitFlags)
Definition: mimeole.c:357
struct list body_tree
Definition: mimeole.c:1955
static HRESULT find_next(MimeMessage *This, body_t *body, FINDBODY *find, HBODY *out)
Definition: mimeole.c:2533
GLenum GLsizei GLuint GLint * bytesWritten
Definition: glext.h:11123
static HRESULT WINAPI MimeMessage_GetMessageSize(IMimeMessage *iface, ULONG *pcbSize, DWORD dwFlags)
Definition: mimeole.c:2279
static HRESULT WINAPI MimeBody_GetDataHere(IMimeBody *iface, ENCODINGTYPE ietEncoding, IStream *pStream)
Definition: mimeole.c:1538
static HRESULT WINAPI MimeBody_SetData(IMimeBody *iface, ENCODINGTYPE ietEncoding, LPCSTR pszPriType, LPCSTR pszSubType, REFIID riid, LPVOID pvObject)
Definition: mimeole.c:1749
LONG ref
Definition: mimeole.c:177
static IUnknown mime_obj
Definition: mimeole.c:3694
ULONG_PTR SIZE_T
Definition: typedefs.h:78
struct list new_props
Definition: mimeole.c:164
#define S_OK
Definition: intsafe.h:59
static HRESULT WINAPI MimeAlloc_FreeAddressList(IMimeAllocator *iface, LPADDRESSLIST pList)
Definition: mimeole.c:3432
HRESULT MimeSecurity_create(IUnknown *outer, void **obj)
Definition: mimeole.c:3310
static unsigned __int64 next
Definition: rand_nt.c:6
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
static HRESULT WINAPI MimeBody_SetCharset(IMimeBody *iface, HCHARSET hCharset, CSETAPPLYTYPE applytype)
Definition: mimeole.c:1305
static HRESULT WINAPI MimeMessage_GetAddressTypes(IMimeMessage *iface, DWORD dwAdrTypes, DWORD dwProps, LPADDRESSLIST pList)
Definition: mimeole.c:2978
#define InterlockedIncrement
Definition: armddk.h:53
GLenum GLenum GLenum input
Definition: glext.h:9031
const char cursor[]
Definition: icontest.c:13
#define lstrcpyW
Definition: compat.h:414
GLuint in
Definition: glext.h:9616
static ULONG WINAPI MimeBody_Release(IMimeBody *iface)
Definition: mimeole.c:955
IMimeMessage IMimeMessage_iface
Definition: mimeole.c:1951
static void WINAPI MimeAlloc_HeapMinimize(IMimeAllocator *iface)
Definition: mimeole.c:3407
static HRESULT WINAPI MimeBody_CopyProps(IMimeBody *iface, ULONG cNames, LPCSTR *prgszName, IMimePropertySet *pPropertySet)
Definition: mimeole.c:1251
static HRESULT WINAPI MimeMessage_FindNext(IMimeMessage *iface, FINDBODY *pFindBody, HBODY *phBody)
Definition: mimeole.c:2574
#define byte(x, n)
Definition: tomcrypt.h:118
static MimeSecurity * impl_from_IMimeSecurity(IMimeSecurity *iface)
Definition: mimeole.c:3154
GLuint start
Definition: gl.h:1545
#define ARRAY_SIZE(a)
Definition: main.h:24
HRESULT VirtualStream_create(IUnknown *outer, void **obj)
Definition: mimeole.c:3535
static const IMimeSecurityVtbl MimeSecurityVtbl
Definition: mimeole.c:3293
VARTYPE default_vt
Definition: mimeole.c:53
static HRESULT WINAPI MimeSecurity_GetCertData(IMimeSecurity *iface, const PCX509CERT pX509Cert, const CERTDATAID dataid, LPPROPVARIANT pValue)
Definition: mimeole.c:3282
static HRESULT WINAPI mime_obj_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: mimeole.c:3669
#define HeapReAlloc
Definition: compat.h:401
#define E_NOTIMPL
Definition: ddrawi.h:99
static IMimePropertySchemaVtbl prop_schema_vtbl
Definition: mimeole.c:3630
unsigned short VARTYPE
Definition: compat.h:1903
#define list
Definition: rosglue.h:35
static const void * body(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:100
static HRESULT WINAPI MimeMessage_GetBodyOffsets(IMimeMessage *iface, HBODY hBody, LPBODYOFFSETS pOffsets)
Definition: mimeole.c:2609
static HRESULT WINAPI MimeMessage_GetBodyProp(IMimeMessage *iface, HBODY hBody, LPCSTR pszName, DWORD dwFlags, LPPROPVARIANT pValue)
Definition: mimeole.c:2684
static HRESULT WINAPI sub_stream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: mimeole.c:265
struct list children
Definition: mimeole.c:1946
#define alloc
Definition: rosglue.h:13
static HRESULT WINAPI MimeMessage_DeleteProp(IMimeMessage *iface, LPCSTR pszName)
Definition: mimeole.c:2812
static HRESULT WINAPI MimeAlloc_ReleaseObjects(IMimeAllocator *iface, ULONG cObjects, IUnknown **prgpUnknown, boolean fFreeArray)
Definition: mimeole.c:3448
char * value
Definition: mimeole.c:145
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
const WCHAR * schema
HRESULT WINAPI MimeGetAddressFormatW(REFIID riid, void *object, DWORD addr_type, ADDRESSFORMAT addr_format, WCHAR **address)
Definition: mimeole.c:3661
Definition: main.c:39
property_t prop
Definition: mimeole.c:59
static ULONG WINAPI MimeSecurity_AddRef(IMimeSecurity *iface)
Definition: mimeole.c:3176
static HRESULT WINAPI MimeMessage_Commit(IMimeMessage *iface, DWORD dwFlags)
Definition: mimeole.c:2314
static HRESULT decode_base64(IStream *input, IStream **ret_stream)
Definition: mimeole.c:1560
char * strchr(const char *String, int ch)
Definition: utclib.c:501
static HRESULT WINAPI MimeBody_DeleteProp(IMimeBody *iface, LPCSTR pszName)
Definition: mimeole.c:1224
static ULONG WINAPI MimeAlloc_Release(IMimeAllocator *iface)
Definition: mimeole.c:3363
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
#define FIRST_CUSTOM_PROP_ID
Definition: mimeole.c:1890
static HRESULT WINAPI MimeBody_GetCharset(IMimeBody *iface, LPHCHARSET phCharset)
Def