4 * Copyright 2006 Robert Shearman for CodeWeavers
5 * Copyright 2007 Huw Davies for CodeWeavers
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.
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.
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
23 #define NONAMELESSUNION
35 #include "wine/list.h"
36 #include "wine/debug.h"
38 #include "inetcomm_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);
46 DWORD flags; /* MIMEPROPFLAGS */
54 } property_list_entry_t;
56 static const property_t default_props[] =
58 {"References", PID_HDR_REFS, 0, VT_LPSTR},
59 {"Subject", PID_HDR_SUBJECT, 0, VT_LPSTR},
60 {"From", PID_HDR_FROM, MPF_ADDRESS, VT_LPSTR},
61 {"Message-ID", PID_HDR_MESSAGEID, 0, VT_LPSTR},
62 {"Return-Path", PID_HDR_RETURNPATH, MPF_ADDRESS, VT_LPSTR},
63 {"Date", PID_HDR_DATE, 0, VT_LPSTR},
64 {"Received", PID_HDR_RECEIVED, 0, VT_LPSTR},
65 {"Reply-To", PID_HDR_REPLYTO, MPF_ADDRESS, VT_LPSTR},
66 {"X-Mailer", PID_HDR_XMAILER, 0, VT_LPSTR},
67 {"Bcc", PID_HDR_BCC, MPF_ADDRESS, VT_LPSTR},
68 {"MIME-Version", PID_HDR_MIMEVER, MPF_MIME, VT_LPSTR},
69 {"Content-Type", PID_HDR_CNTTYPE, MPF_MIME | MPF_HASPARAMS, VT_LPSTR},
70 {"Content-Transfer-Encoding", PID_HDR_CNTXFER, MPF_MIME, VT_LPSTR},
71 {"Content-ID", PID_HDR_CNTID, MPF_MIME, VT_LPSTR},
72 {"Content-Disposition", PID_HDR_CNTDISP, MPF_MIME, VT_LPSTR},
73 {"To", PID_HDR_TO, MPF_ADDRESS, VT_LPSTR},
74 {"Cc", PID_HDR_CC, MPF_ADDRESS, VT_LPSTR},
75 {"Sender", PID_HDR_SENDER, MPF_ADDRESS, VT_LPSTR},
76 {"In-Reply-To", PID_HDR_INREPLYTO, 0, VT_LPSTR},
90 const property_t *prop;
95 typedef struct MimeBody
97 const IMimeBodyVtbl *lpVtbl;
103 struct list new_props; /* FIXME: This should be in a PropertySchema */
105 char *content_pri_type;
106 char *content_sub_type;
107 ENCODINGTYPE encoding;
112 static inline MimeBody *impl_from_IMimeBody( IMimeBody *iface )
114 return (MimeBody *)((char*)iface - FIELD_OFFSET(MimeBody, lpVtbl));
117 static LPSTR strdupA(LPCSTR str)
120 int len = strlen(str);
121 ret = HeapAlloc(GetProcessHeap(), 0, len + 1);
122 memcpy(ret, str, len + 1);
126 #define PARSER_BUF_SIZE 1024
128 /*****************************************************
129 * copy_headers_to_buf [internal]
131 * Copies the headers into a '\0' terminated memory block and leave
132 * the stream's current position set to after the blank line.
134 static HRESULT copy_headers_to_buf(IStream *stm, char **ptr)
137 DWORD size = PARSER_BUF_SIZE, offset = 0, last_end = 0;
149 buf = HeapAlloc(GetProcessHeap(), 0, size + 1);
153 buf = HeapReAlloc(GetProcessHeap(), 0, buf, size + 1);
161 hr = IStream_Read(stm, buf + offset, size - offset, &read);
162 if(FAILED(hr)) goto fail;
167 if(read == 0) done = 1;
169 while(!done && (end = strstr(buf + last_end, "\r\n")))
171 DWORD new_end = end - buf + 2;
172 if(new_end - last_end == 2)
175 off.QuadPart = new_end;
176 IStream_Seek(stm, off, STREAM_SEEK_SET, NULL);
189 HeapFree(GetProcessHeap(), 0, buf);
193 static header_t *read_prop(MimeBody *body, char **ptr)
195 char *colon = strchr(*ptr, ':');
196 const property_t *prop;
199 if(!colon) return NULL;
203 for(prop = default_props; prop->name; prop++)
205 if(!strcasecmp(*ptr, prop->name))
207 TRACE("%s: found match with default property id %d\n", *ptr, prop->id);
214 property_list_entry_t *prop_entry;
215 LIST_FOR_EACH_ENTRY(prop_entry, &body->new_props, property_list_entry_t, entry)
217 if(!strcasecmp(*ptr, prop_entry->prop.name))
219 TRACE("%s: found match with already added new property id %d\n", *ptr, prop_entry->prop.id);
220 prop = &prop_entry->prop;
226 prop_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*prop_entry));
227 prop_entry->prop.name = strdupA(*ptr);
228 prop_entry->prop.id = body->next_prop_id++;
229 prop_entry->prop.flags = 0;
230 prop_entry->prop.default_vt = VT_LPSTR;
231 list_add_tail(&body->new_props, &prop_entry->entry);
232 prop = &prop_entry->prop;
233 TRACE("%s: allocating new prop id %d\n", *ptr, prop_entry->prop.id);
237 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
239 PropVariantInit(&ret->value);
240 list_init(&ret->params);
246 static void unfold_header(char *header, int len)
248 char *start = header, *cp = header;
251 while(*cp == ' ' || *cp == '\t')
257 memmove(start, cp, len + 1);
259 cp = strstr(start, "\r\n");
266 } while(*cp == ' ' || *cp == '\t');
271 static char *unquote_string(const char *str)
276 while(*str == ' ' || *str == '\t') str++;
284 for(cp = ret; *cp; cp++)
287 memmove(cp, cp + 1, strlen(cp + 1) + 1);
292 WARN("quote in unquoted string\n");
304 static void add_param(header_t *header, const char *p)
306 const char *key = p, *value, *cp = p;
310 TRACE("got param %s\n", p);
312 while (*key == ' ' || *key == '\t' ) key++;
314 cp = strchr(key, '=');
317 WARN("malformed parameter - skipping\n");
321 name = HeapAlloc(GetProcessHeap(), 0, cp - key + 1);
322 memcpy(name, key, cp - key);
323 name[cp - key] = '\0';
327 param = HeapAlloc(GetProcessHeap(), 0, sizeof(*param));
329 param->value = unquote_string(value);
330 list_add_tail(&header->params, ¶m->entry);
333 static void split_params(header_t *header, char *value)
335 char *cp = value, *start = value;
341 if(!in_quote && *cp == ';')
344 if(done_value) add_param(header, start);
349 in_quote = !in_quote;
352 if(done_value) add_param(header, start);
355 static void read_value(header_t *header, char **cur)
357 char *end = *cur, *value;
361 end = strstr(end, "\r\n");
363 } while(*end == ' ' || *end == '\t');
366 value = HeapAlloc(GetProcessHeap(), 0, len + 1);
367 memcpy(value, *cur, len);
370 unfold_header(value, len);
371 TRACE("value %s\n", debugstr_a(value));
373 if(header->prop->flags & MPF_HASPARAMS)
375 split_params(header, value);
376 TRACE("value w/o params %s\n", debugstr_a(value));
379 header->value.vt = VT_LPSTR;
380 header->value.u.pszVal = value;
385 static void init_content_type(MimeBody *body, header_t *header)
390 if(header->prop->id != PID_HDR_CNTTYPE)
392 ERR("called with header %s\n", header->prop->name);
396 slash = strchr(header->value.u.pszVal, '/');
399 WARN("malformed context type value\n");
402 len = slash - header->value.u.pszVal;
403 body->content_pri_type = HeapAlloc(GetProcessHeap(), 0, len + 1);
404 memcpy(body->content_pri_type, header->value.u.pszVal, len);
405 body->content_pri_type[len] = '\0';
406 body->content_sub_type = strdupA(slash + 1);
409 static HRESULT parse_headers(MimeBody *body, IStream *stm)
411 char *header_buf, *cur_header_ptr;
415 hr = copy_headers_to_buf(stm, &header_buf);
416 if(FAILED(hr)) return hr;
418 cur_header_ptr = header_buf;
419 while((header = read_prop(body, &cur_header_ptr)))
421 read_value(header, &cur_header_ptr);
422 list_add_tail(&body->headers, &header->entry);
424 if(header->prop->id == PID_HDR_CNTTYPE)
425 init_content_type(body, header);
428 HeapFree(GetProcessHeap(), 0, header_buf);
432 static void empty_param_list(struct list *list)
434 param_t *param, *cursor2;
436 LIST_FOR_EACH_ENTRY_SAFE(param, cursor2, list, param_t, entry)
438 list_remove(¶m->entry);
439 HeapFree(GetProcessHeap(), 0, param->name);
440 HeapFree(GetProcessHeap(), 0, param->value);
441 HeapFree(GetProcessHeap(), 0, param);
445 static void empty_header_list(struct list *list)
447 header_t *header, *cursor2;
449 LIST_FOR_EACH_ENTRY_SAFE(header, cursor2, list, header_t, entry)
451 list_remove(&header->entry);
452 PropVariantClear(&header->value);
453 empty_param_list(&header->params);
454 HeapFree(GetProcessHeap(), 0, header);
458 static void empty_new_prop_list(struct list *list)
460 property_list_entry_t *prop, *cursor2;
462 LIST_FOR_EACH_ENTRY_SAFE(prop, cursor2, list, property_list_entry_t, entry)
464 list_remove(&prop->entry);
465 HeapFree(GetProcessHeap(), 0, (char *)prop->prop.name);
466 HeapFree(GetProcessHeap(), 0, prop);
470 static void release_data(REFIID riid, void *data)
474 if(IsEqualIID(riid, &IID_IStream))
475 IStream_Release((IStream *)data);
477 FIXME("Unhandled data format %s\n", debugstr_guid(riid));
480 static HRESULT find_prop(MimeBody *body, const char *name, header_t **prop)
486 LIST_FOR_EACH_ENTRY(header, &body->headers, header_t, entry)
488 if(!strcasecmp(name, header->prop->name))
495 return MIME_E_NOT_FOUND;
498 static HRESULT WINAPI MimeBody_QueryInterface(IMimeBody* iface,
502 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject);
506 if (IsEqualIID(riid, &IID_IUnknown) ||
507 IsEqualIID(riid, &IID_IPersist) ||
508 IsEqualIID(riid, &IID_IPersistStreamInit) ||
509 IsEqualIID(riid, &IID_IMimePropertySet) ||
510 IsEqualIID(riid, &IID_IMimeBody))
517 IUnknown_AddRef((IUnknown*)*ppvObject);
521 FIXME("no interface for %s\n", debugstr_guid(riid));
522 return E_NOINTERFACE;
525 static ULONG WINAPI MimeBody_AddRef(IMimeBody* iface)
527 MimeBody *This = impl_from_IMimeBody(iface);
528 TRACE("(%p)->()\n", iface);
529 return InterlockedIncrement(&This->refs);
532 static ULONG WINAPI MimeBody_Release(IMimeBody* iface)
534 MimeBody *This = impl_from_IMimeBody(iface);
537 TRACE("(%p)->()\n", iface);
539 refs = InterlockedDecrement(&This->refs);
542 empty_header_list(&This->headers);
543 empty_new_prop_list(&This->new_props);
545 HeapFree(GetProcessHeap(), 0, This->content_pri_type);
546 HeapFree(GetProcessHeap(), 0, This->content_sub_type);
548 release_data(&This->data_iid, This->data);
550 HeapFree(GetProcessHeap(), 0, This);
556 static HRESULT WINAPI MimeBody_GetClassID(
565 static HRESULT WINAPI MimeBody_IsDirty(
572 static HRESULT WINAPI MimeBody_Load(
576 MimeBody *This = impl_from_IMimeBody(iface);
577 TRACE("(%p)->(%p)\n", iface, pStm);
578 return parse_headers(This, pStm);
581 static HRESULT WINAPI MimeBody_Save(
590 static HRESULT WINAPI MimeBody_GetSizeMax(
592 ULARGE_INTEGER* pcbSize)
598 static HRESULT WINAPI MimeBody_InitNew(
601 TRACE("%p->()\n", iface);
605 static HRESULT WINAPI MimeBody_GetPropInfo(
608 LPMIMEPROPINFO pInfo)
614 static HRESULT WINAPI MimeBody_SetPropInfo(
617 LPCMIMEPROPINFO pInfo)
623 static HRESULT WINAPI MimeBody_GetProp(
627 LPPROPVARIANT pValue)
633 static HRESULT WINAPI MimeBody_SetProp(
637 LPCPROPVARIANT pValue)
643 static HRESULT WINAPI MimeBody_AppendProp(
647 LPPROPVARIANT pValue)
653 static HRESULT WINAPI MimeBody_DeleteProp(
661 static HRESULT WINAPI MimeBody_CopyProps(
665 IMimePropertySet* pPropertySet)
671 static HRESULT WINAPI MimeBody_MoveProps(
675 IMimePropertySet* pPropertySet)
681 static HRESULT WINAPI MimeBody_DeleteExcept(
690 static HRESULT WINAPI MimeBody_QueryProp(
695 boolean fCaseSensitive)
701 static HRESULT WINAPI MimeBody_GetCharset(
703 LPHCHARSET phCharset)
709 static HRESULT WINAPI MimeBody_SetCharset(
712 CSETAPPLYTYPE applytype)
718 static HRESULT WINAPI MimeBody_GetParameters(
722 LPMIMEPARAMINFO* pprgParam)
724 MimeBody *This = impl_from_IMimeBody(iface);
728 TRACE("(%p)->(%s, %p, %p)\n", iface, debugstr_a(pszName), pcParams, pprgParam);
733 hr = find_prop(This, pszName, &header);
734 if(hr != S_OK) return hr;
736 *pcParams = list_count(&header->params);
739 IMimeAllocator *alloc;
743 MimeOleGetAllocator(&alloc);
745 *pprgParam = info = IMimeAllocator_Alloc(alloc, *pcParams * sizeof(**pprgParam));
746 LIST_FOR_EACH_ENTRY(param, &header->params, param_t, entry)
750 len = strlen(param->name) + 1;
751 info->pszName = IMimeAllocator_Alloc(alloc, len);
752 memcpy(info->pszName, param->name, len);
753 len = strlen(param->value) + 1;
754 info->pszData = IMimeAllocator_Alloc(alloc, len);
755 memcpy(info->pszData, param->value, len);
758 IMimeAllocator_Release(alloc);
763 static HRESULT WINAPI MimeBody_IsContentType(
768 MimeBody *This = impl_from_IMimeBody(iface);
770 TRACE("(%p)->(%s, %s)\n", This, debugstr_a(pszPriType), debugstr_a(pszSubType));
773 const char *pri = This->content_pri_type;
774 if(!pri) pri = "text";
775 if(strcasecmp(pri, pszPriType)) return S_FALSE;
780 const char *sub = This->content_sub_type;
781 if(!sub) sub = "plain";
782 if(strcasecmp(sub, pszSubType)) return S_FALSE;
788 static HRESULT WINAPI MimeBody_BindToObject(
797 static HRESULT WINAPI MimeBody_Clone(
799 IMimePropertySet** ppPropertySet)
805 static HRESULT WINAPI MimeBody_SetOption(
808 LPCPROPVARIANT pValue)
814 static HRESULT WINAPI MimeBody_GetOption(
817 LPPROPVARIANT pValue)
823 static HRESULT WINAPI MimeBody_EnumProps(
826 IMimeEnumProperties** ppEnum)
832 static HRESULT WINAPI MimeBody_IsType(
834 IMSGBODYTYPE bodytype)
840 static HRESULT WINAPI MimeBody_SetDisplayName(
848 static HRESULT WINAPI MimeBody_GetDisplayName(
856 static HRESULT WINAPI MimeBody_GetOffsets(
858 LPBODYOFFSETS pOffsets)
864 static HRESULT WINAPI MimeBody_GetCurrentEncoding(
866 ENCODINGTYPE* pietEncoding)
868 MimeBody *This = impl_from_IMimeBody(iface);
870 TRACE("(%p)->(%p)\n", This, pietEncoding);
872 *pietEncoding = This->encoding;
876 static HRESULT WINAPI MimeBody_SetCurrentEncoding(
878 ENCODINGTYPE ietEncoding)
880 MimeBody *This = impl_from_IMimeBody(iface);
882 TRACE("(%p)->(%d)\n", This, ietEncoding);
884 This->encoding = ietEncoding;
888 static HRESULT WINAPI MimeBody_GetEstimatedSize(
890 ENCODINGTYPE ietEncoding,
897 static HRESULT WINAPI MimeBody_GetDataHere(
899 ENCODINGTYPE ietEncoding,
906 static HRESULT WINAPI MimeBody_GetData(
908 ENCODINGTYPE ietEncoding,
915 static HRESULT WINAPI MimeBody_SetData(
917 ENCODINGTYPE ietEncoding,
923 MimeBody *This = impl_from_IMimeBody(iface);
924 TRACE("(%p)->(%d, %s, %s, %s %p)\n", This, ietEncoding, debugstr_a(pszPriType), debugstr_a(pszSubType),
925 debugstr_guid(riid), pvObject);
927 if(IsEqualIID(riid, &IID_IStream))
928 IStream_AddRef((IStream *)pvObject);
931 FIXME("Unhandled object type %s\n", debugstr_guid(riid));
936 FIXME("release old data\n");
938 This->data_iid = *riid;
939 This->data = pvObject;
941 IMimeBody_SetCurrentEncoding(iface, ietEncoding);
943 /* FIXME: Update the content type.
944 If pszPriType == NULL use 'application'
945 If pszSubType == NULL use 'octet-stream' */
950 static HRESULT WINAPI MimeBody_EmptyData(
957 static HRESULT WINAPI MimeBody_CopyTo(
965 static HRESULT WINAPI MimeBody_GetTransmitInfo(
967 LPTRANSMITINFO pTransmitInfo)
973 static HRESULT WINAPI MimeBody_SaveToFile(
975 ENCODINGTYPE ietEncoding,
982 static HRESULT WINAPI MimeBody_GetHandle(
986 MimeBody *This = impl_from_IMimeBody(iface);
987 TRACE("(%p)->(%p)\n", iface, phBody);
989 *phBody = This->handle;
990 return This->handle ? S_OK : MIME_E_NO_DATA;
993 static IMimeBodyVtbl body_vtbl =
995 MimeBody_QueryInterface,
1002 MimeBody_GetSizeMax,
1004 MimeBody_GetPropInfo,
1005 MimeBody_SetPropInfo,
1008 MimeBody_AppendProp,
1009 MimeBody_DeleteProp,
1012 MimeBody_DeleteExcept,
1014 MimeBody_GetCharset,
1015 MimeBody_SetCharset,
1016 MimeBody_GetParameters,
1017 MimeBody_IsContentType,
1018 MimeBody_BindToObject,
1024 MimeBody_SetDisplayName,
1025 MimeBody_GetDisplayName,
1026 MimeBody_GetOffsets,
1027 MimeBody_GetCurrentEncoding,
1028 MimeBody_SetCurrentEncoding,
1029 MimeBody_GetEstimatedSize,
1030 MimeBody_GetDataHere,
1035 MimeBody_GetTransmitInfo,
1036 MimeBody_SaveToFile,
1040 #define FIRST_CUSTOM_PROP_ID 0x100
1042 HRESULT MimeBody_create(IUnknown *outer, void **obj)
1048 if(outer) return CLASS_E_NOAGGREGATION;
1050 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1051 if (!This) return E_OUTOFMEMORY;
1053 This->lpVtbl = &body_vtbl;
1055 This->handle = NULL;
1056 list_init(&This->headers);
1057 list_init(&This->new_props);
1058 This->next_prop_id = FIRST_CUSTOM_PROP_ID;
1059 This->content_pri_type = NULL;
1060 This->content_sub_type = NULL;
1061 This->encoding = IET_7BIT;
1063 This->data_iid = IID_NULL;
1065 *obj = (IMimeBody *)&This->lpVtbl;
1069 typedef struct MimeMessage
1071 const IMimeMessageVtbl *lpVtbl;
1076 static HRESULT WINAPI MimeMessage_QueryInterface(IMimeMessage *iface, REFIID riid, void **ppv)
1078 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
1080 if (IsEqualIID(riid, &IID_IUnknown) ||
1081 IsEqualIID(riid, &IID_IPersist) ||
1082 IsEqualIID(riid, &IID_IPersistStreamInit) ||
1083 IsEqualIID(riid, &IID_IMimeMessageTree) ||
1084 IsEqualIID(riid, &IID_IMimeMessage))
1087 IUnknown_AddRef(iface);
1091 FIXME("no interface for %s\n", debugstr_guid(riid));
1093 return E_NOINTERFACE;
1096 static ULONG WINAPI MimeMessage_AddRef(IMimeMessage *iface)
1098 MimeMessage *This = (MimeMessage *)iface;
1099 TRACE("(%p)->()\n", iface);
1100 return InterlockedIncrement(&This->refs);
1103 static ULONG WINAPI MimeMessage_Release(IMimeMessage *iface)
1105 MimeMessage *This = (MimeMessage *)iface;
1108 TRACE("(%p)->()\n", iface);
1110 refs = InterlockedDecrement(&This->refs);
1113 HeapFree(GetProcessHeap(), 0, This);
1119 /*** IPersist methods ***/
1120 static HRESULT WINAPI MimeMessage_GetClassID(
1121 IMimeMessage *iface,
1124 FIXME("(%p)->(%p)\n", iface, pClassID);
1128 /*** IPersistStreamInit methods ***/
1129 static HRESULT WINAPI MimeMessage_IsDirty(
1130 IMimeMessage *iface)
1132 FIXME("(%p)->()\n", iface);
1136 static HRESULT WINAPI MimeMessage_Load(
1137 IMimeMessage *iface,
1139 FIXME("(%p)->(%p)\n", iface, pStm);
1143 static HRESULT WINAPI MimeMessage_Save(
1144 IMimeMessage *iface,
1148 FIXME("(%p)->(%p, %s)\n", iface, pStm, fClearDirty ? "TRUE" : "FALSE");
1152 static HRESULT WINAPI MimeMessage_GetSizeMax(
1153 IMimeMessage *iface,
1154 ULARGE_INTEGER *pcbSize)
1156 FIXME("(%p)->(%p)\n", iface, pcbSize);
1160 static HRESULT WINAPI MimeMessage_InitNew(
1161 IMimeMessage *iface)
1163 FIXME("(%p)->()\n", iface);
1167 /*** IMimeMessageTree methods ***/
1168 static HRESULT WINAPI MimeMessage_GetMessageSource(
1169 IMimeMessage *iface,
1173 FIXME("(%p)->(%p, 0x%x)\n", iface, ppStream, dwFlags);
1177 static HRESULT WINAPI MimeMessage_GetMessageSize(
1178 IMimeMessage *iface,
1182 FIXME("(%p)->(%p, 0x%x)\n", iface, pcbSize, dwFlags);
1186 static HRESULT WINAPI MimeMessage_LoadOffsetTable(
1187 IMimeMessage *iface,
1190 FIXME("(%p)->(%p)\n", iface, pStream);
1194 static HRESULT WINAPI MimeMessage_SaveOffsetTable(
1195 IMimeMessage *iface,
1199 FIXME("(%p)->(%p, 0x%x)\n", iface, pStream, dwFlags);
1204 static HRESULT WINAPI MimeMessage_GetFlags(
1205 IMimeMessage *iface,
1208 FIXME("(%p)->(%p)\n", iface, pdwFlags);
1212 static HRESULT WINAPI MimeMessage_Commit(
1213 IMimeMessage *iface,
1216 FIXME("(%p)->(0x%x)\n", iface, dwFlags);
1221 static HRESULT WINAPI MimeMessage_HandsOffStorage(
1222 IMimeMessage *iface)
1224 FIXME("(%p)->()\n", iface);
1228 static HRESULT WINAPI MimeMessage_BindToObject(
1229 IMimeMessage *iface,
1234 FIXME("(%p)->(%p, %s, %p)\n", iface, hBody, debugstr_guid(riid), ppvObject);
1238 static HRESULT WINAPI MimeMessage_SaveBody(
1239 IMimeMessage *iface,
1244 FIXME("(%p)->(%p, 0x%x, %p)\n", iface, hBody, dwFlags, pStream);
1248 static HRESULT WINAPI MimeMessage_InsertBody(
1249 IMimeMessage *iface,
1250 BODYLOCATION location,
1254 FIXME("(%p)->(%d, %p, %p)\n", iface, location, hPivot, phBody);
1258 static HRESULT WINAPI MimeMessage_GetBody(
1259 IMimeMessage *iface,
1260 BODYLOCATION location,
1264 FIXME("(%p)->(%d, %p, %p)\n", iface, location, hPivot, phBody);
1268 static HRESULT WINAPI MimeMessage_DeleteBody(
1269 IMimeMessage *iface,
1273 FIXME("(%p)->(%p, %08x)\n", iface, hBody, dwFlags);
1277 static HRESULT WINAPI MimeMessage_MoveBody(
1278 IMimeMessage *iface,
1280 BODYLOCATION location)
1282 FIXME("(%p)->(%d)\n", iface, location);
1286 static HRESULT WINAPI MimeMessage_CountBodies(
1287 IMimeMessage *iface,
1292 FIXME("(%p)->(%p, %s, %p)\n", iface, hParent, fRecurse ? "TRUE" : "FALSE", pcBodies);
1296 static HRESULT WINAPI MimeMessage_FindFirst(
1297 IMimeMessage *iface,
1298 LPFINDBODY pFindBody,
1301 FIXME("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
1305 static HRESULT WINAPI MimeMessage_FindNext(
1306 IMimeMessage *iface,
1307 LPFINDBODY pFindBody,
1310 FIXME("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
1314 static HRESULT WINAPI MimeMessage_ResolveURL(
1315 IMimeMessage *iface,
1322 FIXME("(%p)->(%p, %s, %s, 0x%x, %p)\n", iface, hRelated, pszBase, pszURL, dwFlags, phBody);
1326 static HRESULT WINAPI MimeMessage_ToMultipart(
1327 IMimeMessage *iface,
1330 LPHBODY phMultipart)
1332 FIXME("(%p)->(%p, %s, %p)\n", iface, hBody, pszSubType, phMultipart);
1336 static HRESULT WINAPI MimeMessage_GetBodyOffsets(
1337 IMimeMessage *iface,
1339 LPBODYOFFSETS pOffsets)
1341 FIXME("(%p)->(%p, %p)\n", iface, hBody, pOffsets);
1345 static HRESULT WINAPI MimeMessage_GetCharset(
1346 IMimeMessage *iface,
1347 LPHCHARSET phCharset)
1349 FIXME("(%p)->(%p)\n", iface, phCharset);
1353 static HRESULT WINAPI MimeMessage_SetCharset(
1354 IMimeMessage *iface,
1356 CSETAPPLYTYPE applytype)
1358 FIXME("(%p)->(%p, %d)\n", iface, hCharset, applytype);
1362 static HRESULT WINAPI MimeMessage_IsBodyType(
1363 IMimeMessage *iface,
1365 IMSGBODYTYPE bodytype)
1367 FIXME("(%p)->(%p, %d)\n", iface, hBody, bodytype);
1371 static HRESULT WINAPI MimeMessage_IsContentType(
1372 IMimeMessage *iface,
1377 FIXME("(%p)->(%p, %s, %s)\n", iface, hBody, pszPriType, pszSubType);
1381 static HRESULT WINAPI MimeMessage_QueryBodyProp(
1382 IMimeMessage *iface,
1387 boolean fCaseSensitive)
1389 FIXME("(%p)->(%p, %s, %s, %s, %s)\n", iface, hBody, pszName, pszCriteria, fSubString ? "TRUE" : "FALSE", fCaseSensitive ? "TRUE" : "FALSE");
1393 static HRESULT WINAPI MimeMessage_GetBodyProp(
1394 IMimeMessage *iface,
1398 LPPROPVARIANT pValue)
1400 FIXME("(%p)->(%p, %s, 0x%x, %p)\n", iface, hBody, pszName, dwFlags, pValue);
1404 static HRESULT WINAPI MimeMessage_SetBodyProp(
1405 IMimeMessage *iface,
1409 LPCPROPVARIANT pValue)
1411 FIXME("(%p)->(%p, %s, 0x%x, %p)\n", iface, hBody, pszName, dwFlags, pValue);
1415 static HRESULT WINAPI MimeMessage_DeleteBodyProp(
1416 IMimeMessage *iface,
1420 FIXME("(%p)->(%p, %s)\n", iface, hBody, pszName);
1424 static HRESULT WINAPI MimeMessage_SetOption(
1425 IMimeMessage *iface,
1427 LPCPROPVARIANT pValue)
1429 FIXME("(%p)->(%d, %p)\n", iface, oid, pValue);
1433 static HRESULT WINAPI MimeMessage_GetOption(
1434 IMimeMessage *iface,
1436 LPPROPVARIANT pValue)
1438 FIXME("(%p)->(%d, %p)\n", iface, oid, pValue);
1442 /*** IMimeMessage methods ***/
1443 static HRESULT WINAPI MimeMessage_CreateWebPage(
1444 IMimeMessage *iface,
1446 LPWEBPAGEOPTIONS pOptions,
1447 IMimeMessageCallback *pCallback,
1448 IMoniker **ppMoniker)
1450 FIXME("(%p)->(%p, %p, %p, %p)\n", iface, pRootStm, pOptions, pCallback, ppMoniker);
1455 static HRESULT WINAPI MimeMessage_GetProp(
1456 IMimeMessage *iface,
1459 LPPROPVARIANT pValue)
1461 FIXME("(%p)->(%s, 0x%x, %p)\n", iface, pszName, dwFlags, pValue);
1465 static HRESULT WINAPI MimeMessage_SetProp(
1466 IMimeMessage *iface,
1469 LPCPROPVARIANT pValue)
1471 FIXME("(%p)->(%s, 0x%x, %p)\n", iface, pszName, dwFlags, pValue);
1475 static HRESULT WINAPI MimeMessage_DeleteProp(
1476 IMimeMessage *iface,
1479 FIXME("(%p)->(%s)\n", iface, pszName);
1483 static HRESULT WINAPI MimeMessage_QueryProp(
1484 IMimeMessage *iface,
1488 boolean fCaseSensitive)
1490 FIXME("(%p)->(%s, %s, %s, %s)\n", iface, pszName, pszCriteria, fSubString ? "TRUE" : "FALSE", fCaseSensitive ? "TRUE" : "FALSE");
1494 static HRESULT WINAPI MimeMessage_GetTextBody(
1495 IMimeMessage *iface,
1497 ENCODINGTYPE ietEncoding,
1501 FIXME("(%p)->(%d, %d, %p, %p)\n", iface, dwTxtType, ietEncoding, pStream, phBody);
1505 static HRESULT WINAPI MimeMessage_SetTextBody(
1506 IMimeMessage *iface,
1508 ENCODINGTYPE ietEncoding,
1513 FIXME("(%p)->(%d, %d, %p, %p, %p)\n", iface, dwTxtType, ietEncoding, hAlternative, pStream, phBody);
1517 static HRESULT WINAPI MimeMessage_AttachObject(
1518 IMimeMessage *iface,
1523 FIXME("(%p)->(%s, %p, %p)\n", iface, debugstr_guid(riid), pvObject, phBody);
1527 static HRESULT WINAPI MimeMessage_AttachFile(
1528 IMimeMessage *iface,
1533 FIXME("(%p)->(%s, %p, %p)\n", iface, pszFilePath, pstmFile, phBody);
1537 static HRESULT WINAPI MimeMessage_AttachURL(
1538 IMimeMessage *iface,
1546 FIXME("(%p)->(%s, %s, 0x%x, %p, %p, %p)\n", iface, pszBase, pszURL, dwFlags, pstmURL, ppszCIDURL, phBody);
1550 static HRESULT WINAPI MimeMessage_GetAttachments(
1551 IMimeMessage *iface,
1553 LPHBODY *pprghAttach)
1555 FIXME("(%p)->(%p, %p)\n", iface, pcAttach, pprghAttach);
1559 static HRESULT WINAPI MimeMessage_GetAddressTable(
1560 IMimeMessage *iface,
1561 IMimeAddressTable **ppTable)
1563 FIXME("(%p)->(%p)\n", iface, ppTable);
1567 static HRESULT WINAPI MimeMessage_GetSender(
1568 IMimeMessage *iface,
1569 LPADDRESSPROPS pAddress)
1571 FIXME("(%p)->(%p)\n", iface, pAddress);
1575 static HRESULT WINAPI MimeMessage_GetAddressTypes(
1576 IMimeMessage *iface,
1579 LPADDRESSLIST pList)
1581 FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, dwProps, pList);
1585 static HRESULT WINAPI MimeMessage_GetAddressFormat(
1586 IMimeMessage *iface,
1588 ADDRESSFORMAT format,
1591 FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, format, ppszFormat);
1595 static HRESULT WINAPI MimeMessage_EnumAddressTypes(
1596 IMimeMessage *iface,
1599 IMimeEnumAddressTypes **ppEnum)
1601 FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, dwProps, ppEnum);
1605 static HRESULT WINAPI MimeMessage_SplitMessage(
1606 IMimeMessage *iface,
1608 IMimeMessageParts **ppParts)
1610 FIXME("(%p)->(%d, %p)\n", iface, cbMaxPart, ppParts);
1614 static HRESULT WINAPI MimeMessage_GetRootMoniker(
1615 IMimeMessage *iface,
1616 IMoniker **ppMoniker)
1618 FIXME("(%p)->(%p)\n", iface, ppMoniker);
1622 static const IMimeMessageVtbl MimeMessageVtbl =
1624 MimeMessage_QueryInterface,
1626 MimeMessage_Release,
1627 MimeMessage_GetClassID,
1628 MimeMessage_IsDirty,
1631 MimeMessage_GetSizeMax,
1632 MimeMessage_InitNew,
1633 MimeMessage_GetMessageSource,
1634 MimeMessage_GetMessageSize,
1635 MimeMessage_LoadOffsetTable,
1636 MimeMessage_SaveOffsetTable,
1637 MimeMessage_GetFlags,
1639 MimeMessage_HandsOffStorage,
1640 MimeMessage_BindToObject,
1641 MimeMessage_SaveBody,
1642 MimeMessage_InsertBody,
1643 MimeMessage_GetBody,
1644 MimeMessage_DeleteBody,
1645 MimeMessage_MoveBody,
1646 MimeMessage_CountBodies,
1647 MimeMessage_FindFirst,
1648 MimeMessage_FindNext,
1649 MimeMessage_ResolveURL,
1650 MimeMessage_ToMultipart,
1651 MimeMessage_GetBodyOffsets,
1652 MimeMessage_GetCharset,
1653 MimeMessage_SetCharset,
1654 MimeMessage_IsBodyType,
1655 MimeMessage_IsContentType,
1656 MimeMessage_QueryBodyProp,
1657 MimeMessage_GetBodyProp,
1658 MimeMessage_SetBodyProp,
1659 MimeMessage_DeleteBodyProp,
1660 MimeMessage_SetOption,
1661 MimeMessage_GetOption,
1662 MimeMessage_CreateWebPage,
1663 MimeMessage_GetProp,
1664 MimeMessage_SetProp,
1665 MimeMessage_DeleteProp,
1666 MimeMessage_QueryProp,
1667 MimeMessage_GetTextBody,
1668 MimeMessage_SetTextBody,
1669 MimeMessage_AttachObject,
1670 MimeMessage_AttachFile,
1671 MimeMessage_AttachURL,
1672 MimeMessage_GetAttachments,
1673 MimeMessage_GetAddressTable,
1674 MimeMessage_GetSender,
1675 MimeMessage_GetAddressTypes,
1676 MimeMessage_GetAddressFormat,
1677 MimeMessage_EnumAddressTypes,
1678 MimeMessage_SplitMessage,
1679 MimeMessage_GetRootMoniker,
1682 /***********************************************************************
1683 * MimeOleCreateMessage (INETCOMM.@)
1685 HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessage)
1689 TRACE("(%p, %p)\n", pUnkOuter, ppMessage);
1693 FIXME("outer unknown not supported yet\n");
1699 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1700 if (!This) return E_OUTOFMEMORY;
1702 This->lpVtbl = &MimeMessageVtbl;
1705 *ppMessage = (IMimeMessage *)&This->lpVtbl;
1709 /***********************************************************************
1710 * MimeOleSetCompatMode (INETCOMM.@)
1712 HRESULT WINAPI MimeOleSetCompatMode(DWORD dwMode)
1714 FIXME("(0x%x)\n", dwMode);
1718 /***********************************************************************
1719 * MimeOleCreateVirtualStream (INETCOMM.@)
1721 HRESULT WINAPI MimeOleCreateVirtualStream(IStream **ppStream)
1724 FIXME("(%p)\n", ppStream);
1726 hr = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
1730 typedef struct MimeSecurity
1732 const IMimeSecurityVtbl *lpVtbl;
1737 static HRESULT WINAPI MimeSecurity_QueryInterface(
1738 IMimeSecurity* iface,
1742 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), obj);
1744 if (IsEqualIID(riid, &IID_IUnknown) ||
1745 IsEqualIID(riid, &IID_IMimeSecurity))
1748 IUnknown_AddRef(iface);
1752 FIXME("no interface for %s\n", debugstr_guid(riid));
1754 return E_NOINTERFACE;
1757 static ULONG WINAPI MimeSecurity_AddRef(
1758 IMimeSecurity* iface)
1760 MimeSecurity *This = (MimeSecurity *)iface;
1761 TRACE("(%p)->()\n", iface);
1762 return InterlockedIncrement(&This->refs);
1765 static ULONG WINAPI MimeSecurity_Release(
1766 IMimeSecurity* iface)
1768 MimeSecurity *This = (MimeSecurity *)iface;
1771 TRACE("(%p)->()\n", iface);
1773 refs = InterlockedDecrement(&This->refs);
1776 HeapFree(GetProcessHeap(), 0, This);
1782 static HRESULT WINAPI MimeSecurity_InitNew(
1783 IMimeSecurity* iface)
1785 FIXME("(%p)->(): stub\n", iface);
1789 static HRESULT WINAPI MimeSecurity_CheckInit(
1790 IMimeSecurity* iface)
1792 FIXME("(%p)->(): stub\n", iface);
1796 static HRESULT WINAPI MimeSecurity_EncodeMessage(
1797 IMimeSecurity* iface,
1798 IMimeMessageTree* pTree,
1801 FIXME("(%p)->(%p, %08x): stub\n", iface, pTree, dwFlags);
1805 static HRESULT WINAPI MimeSecurity_EncodeBody(
1806 IMimeSecurity* iface,
1807 IMimeMessageTree* pTree,
1811 FIXME("(%p)->(%p, %p, %08x): stub\n", iface, pTree, hEncodeRoot, dwFlags);
1815 static HRESULT WINAPI MimeSecurity_DecodeMessage(
1816 IMimeSecurity* iface,
1817 IMimeMessageTree* pTree,
1820 FIXME("(%p)->(%p, %08x): stub\n", iface, pTree, dwFlags);
1824 static HRESULT WINAPI MimeSecurity_DecodeBody(
1825 IMimeSecurity* iface,
1826 IMimeMessageTree* pTree,
1830 FIXME("(%p)->(%p, %p, %08x): stub\n", iface, pTree, hDecodeRoot, dwFlags);
1834 static HRESULT WINAPI MimeSecurity_EnumCertificates(
1835 IMimeSecurity* iface,
1841 FIXME("(%p)->(%p, %08x, %p, %p): stub\n", iface, hc, dwUsage, pPrev, ppCert);
1845 static HRESULT WINAPI MimeSecurity_GetCertificateName(
1846 IMimeSecurity* iface,
1847 const PCX509CERT pX509Cert,
1848 const CERTNAMETYPE cn,
1851 FIXME("(%p)->(%p, %08x, %p): stub\n", iface, pX509Cert, cn, ppszName);
1855 static HRESULT WINAPI MimeSecurity_GetMessageType(
1856 IMimeSecurity* iface,
1857 const HWND hwndParent,
1861 FIXME("(%p)->(%p, %p, %p): stub\n", iface, hwndParent, pBody, pdwSecType);
1865 static HRESULT WINAPI MimeSecurity_GetCertData(
1866 IMimeSecurity* iface,
1867 const PCX509CERT pX509Cert,
1868 const CERTDATAID dataid,
1869 LPPROPVARIANT pValue)
1871 FIXME("(%p)->(%p, %x, %p): stub\n", iface, pX509Cert, dataid, pValue);
1876 static const IMimeSecurityVtbl MimeSecurityVtbl =
1878 MimeSecurity_QueryInterface,
1879 MimeSecurity_AddRef,
1880 MimeSecurity_Release,
1881 MimeSecurity_InitNew,
1882 MimeSecurity_CheckInit,
1883 MimeSecurity_EncodeMessage,
1884 MimeSecurity_EncodeBody,
1885 MimeSecurity_DecodeMessage,
1886 MimeSecurity_DecodeBody,
1887 MimeSecurity_EnumCertificates,
1888 MimeSecurity_GetCertificateName,
1889 MimeSecurity_GetMessageType,
1890 MimeSecurity_GetCertData
1893 /***********************************************************************
1894 * MimeOleCreateSecurity (INETCOMM.@)
1896 HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity)
1900 TRACE("(%p)\n", ppSecurity);
1904 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1905 if (!This) return E_OUTOFMEMORY;
1907 This->lpVtbl = &MimeSecurityVtbl;
1910 *ppSecurity = (IMimeSecurity *)&This->lpVtbl;
1917 IMimeAllocatorVtbl *lpVtbl;
1920 static HRESULT WINAPI MimeAlloc_QueryInterface(
1921 IMimeAllocator* iface,
1925 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), obj);
1927 if (IsEqualIID(riid, &IID_IUnknown) ||
1928 IsEqualIID(riid, &IID_IMalloc) ||
1929 IsEqualIID(riid, &IID_IMimeAllocator))
1932 IUnknown_AddRef(iface);
1936 FIXME("no interface for %s\n", debugstr_guid(riid));
1938 return E_NOINTERFACE;
1941 static ULONG WINAPI MimeAlloc_AddRef(
1942 IMimeAllocator* iface)
1947 static ULONG WINAPI MimeAlloc_Release(
1948 IMimeAllocator* iface)
1953 static LPVOID WINAPI MimeAlloc_Alloc(
1954 IMimeAllocator* iface,
1957 return CoTaskMemAlloc(cb);
1960 static LPVOID WINAPI MimeAlloc_Realloc(
1961 IMimeAllocator* iface,
1965 return CoTaskMemRealloc(pv, cb);
1968 static void WINAPI MimeAlloc_Free(
1969 IMimeAllocator* iface,
1972 return CoTaskMemFree(pv);
1975 static ULONG WINAPI MimeAlloc_GetSize(
1976 IMimeAllocator* iface,
1983 static int WINAPI MimeAlloc_DidAlloc(
1984 IMimeAllocator* iface,
1991 static void WINAPI MimeAlloc_HeapMinimize(
1992 IMimeAllocator* iface)
1998 static HRESULT WINAPI MimeAlloc_FreeParamInfoArray(
1999 IMimeAllocator* iface,
2001 LPMIMEPARAMINFO prgParam,
2005 TRACE("(%p)->(%d, %p, %d)\n", iface, cParams, prgParam, fFreeArray);
2007 for(i = 0; i < cParams; i++)
2009 IMimeAllocator_Free(iface, prgParam[i].pszName);
2010 IMimeAllocator_Free(iface, prgParam[i].pszData);
2012 if(fFreeArray) IMimeAllocator_Free(iface, prgParam);
2016 static HRESULT WINAPI MimeAlloc_FreeAddressList(
2017 IMimeAllocator* iface,
2018 LPADDRESSLIST pList)
2024 static HRESULT WINAPI MimeAlloc_FreeAddressProps(
2025 IMimeAllocator* iface,
2026 LPADDRESSPROPS pAddress)
2032 static HRESULT WINAPI MimeAlloc_ReleaseObjects(
2033 IMimeAllocator* iface,
2035 IUnknown **prgpUnknown,
2043 static HRESULT WINAPI MimeAlloc_FreeEnumHeaderRowArray(
2044 IMimeAllocator* iface,
2046 LPENUMHEADERROW prgRow,
2053 static HRESULT WINAPI MimeAlloc_FreeEnumPropertyArray(
2054 IMimeAllocator* iface,
2056 LPENUMPROPERTY prgProp,
2063 static HRESULT WINAPI MimeAlloc_FreeThumbprint(
2064 IMimeAllocator* iface,
2065 THUMBBLOB *pthumbprint)
2072 static HRESULT WINAPI MimeAlloc_PropVariantClear(
2073 IMimeAllocator* iface,
2074 LPPROPVARIANT pProp)
2080 static IMimeAllocatorVtbl mime_alloc_vtbl =
2082 MimeAlloc_QueryInterface,
2090 MimeAlloc_HeapMinimize,
2091 MimeAlloc_FreeParamInfoArray,
2092 MimeAlloc_FreeAddressList,
2093 MimeAlloc_FreeAddressProps,
2094 MimeAlloc_ReleaseObjects,
2095 MimeAlloc_FreeEnumHeaderRowArray,
2096 MimeAlloc_FreeEnumPropertyArray,
2097 MimeAlloc_FreeThumbprint,
2098 MimeAlloc_PropVariantClear
2101 static MimeAllocator mime_allocator =
2106 HRESULT MimeAllocator_create(IUnknown *outer, void **obj)
2108 if(outer) return CLASS_E_NOAGGREGATION;
2110 *obj = &mime_allocator;
2114 HRESULT WINAPI MimeOleGetAllocator(IMimeAllocator **alloc)
2116 return MimeAllocator_create(NULL, (void**)alloc);