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;
110 BODYOFFSETS body_offsets;
113 static inline MimeBody *impl_from_IMimeBody( IMimeBody *iface )
115 return (MimeBody *)((char*)iface - FIELD_OFFSET(MimeBody, lpVtbl));
118 static LPSTR strdupA(LPCSTR str)
121 int len = strlen(str);
122 ret = HeapAlloc(GetProcessHeap(), 0, len + 1);
123 memcpy(ret, str, len + 1);
127 #define PARSER_BUF_SIZE 1024
129 /*****************************************************
130 * copy_headers_to_buf [internal]
132 * Copies the headers into a '\0' terminated memory block and leave
133 * the stream's current position set to after the blank line.
135 static HRESULT copy_headers_to_buf(IStream *stm, char **ptr)
138 DWORD size = PARSER_BUF_SIZE, offset = 0, last_end = 0;
150 buf = HeapAlloc(GetProcessHeap(), 0, size + 1);
154 buf = HeapReAlloc(GetProcessHeap(), 0, buf, size + 1);
162 hr = IStream_Read(stm, buf + offset, size - offset, &read);
163 if(FAILED(hr)) goto fail;
168 if(read == 0) done = 1;
170 while(!done && (end = strstr(buf + last_end, "\r\n")))
172 DWORD new_end = end - buf + 2;
173 if(new_end - last_end == 2)
176 off.QuadPart = new_end;
177 IStream_Seek(stm, off, STREAM_SEEK_SET, NULL);
190 HeapFree(GetProcessHeap(), 0, buf);
194 static header_t *read_prop(MimeBody *body, char **ptr)
196 char *colon = strchr(*ptr, ':');
197 const property_t *prop;
200 if(!colon) return NULL;
204 for(prop = default_props; prop->name; prop++)
206 if(!strcasecmp(*ptr, prop->name))
208 TRACE("%s: found match with default property id %d\n", *ptr, prop->id);
215 property_list_entry_t *prop_entry;
216 LIST_FOR_EACH_ENTRY(prop_entry, &body->new_props, property_list_entry_t, entry)
218 if(!strcasecmp(*ptr, prop_entry->prop.name))
220 TRACE("%s: found match with already added new property id %d\n", *ptr, prop_entry->prop.id);
221 prop = &prop_entry->prop;
227 prop_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*prop_entry));
228 prop_entry->prop.name = strdupA(*ptr);
229 prop_entry->prop.id = body->next_prop_id++;
230 prop_entry->prop.flags = 0;
231 prop_entry->prop.default_vt = VT_LPSTR;
232 list_add_tail(&body->new_props, &prop_entry->entry);
233 prop = &prop_entry->prop;
234 TRACE("%s: allocating new prop id %d\n", *ptr, prop_entry->prop.id);
238 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
240 PropVariantInit(&ret->value);
241 list_init(&ret->params);
247 static void unfold_header(char *header, int len)
249 char *start = header, *cp = header;
252 while(*cp == ' ' || *cp == '\t')
258 memmove(start, cp, len + 1);
260 cp = strstr(start, "\r\n");
267 } while(*cp == ' ' || *cp == '\t');
272 static char *unquote_string(const char *str)
277 while(*str == ' ' || *str == '\t') str++;
285 for(cp = ret; *cp; cp++)
288 memmove(cp, cp + 1, strlen(cp + 1) + 1);
293 WARN("quote in unquoted string\n");
305 static void add_param(header_t *header, const char *p)
307 const char *key = p, *value, *cp = p;
311 TRACE("got param %s\n", p);
313 while (*key == ' ' || *key == '\t' ) key++;
315 cp = strchr(key, '=');
318 WARN("malformed parameter - skipping\n");
322 name = HeapAlloc(GetProcessHeap(), 0, cp - key + 1);
323 memcpy(name, key, cp - key);
324 name[cp - key] = '\0';
328 param = HeapAlloc(GetProcessHeap(), 0, sizeof(*param));
330 param->value = unquote_string(value);
331 list_add_tail(&header->params, ¶m->entry);
334 static void split_params(header_t *header, char *value)
336 char *cp = value, *start = value;
342 if(!in_quote && *cp == ';')
345 if(done_value) add_param(header, start);
350 in_quote = !in_quote;
353 if(done_value) add_param(header, start);
356 static void read_value(header_t *header, char **cur)
358 char *end = *cur, *value;
362 end = strstr(end, "\r\n");
364 } while(*end == ' ' || *end == '\t');
367 value = HeapAlloc(GetProcessHeap(), 0, len + 1);
368 memcpy(value, *cur, len);
371 unfold_header(value, len);
372 TRACE("value %s\n", debugstr_a(value));
374 if(header->prop->flags & MPF_HASPARAMS)
376 split_params(header, value);
377 TRACE("value w/o params %s\n", debugstr_a(value));
380 header->value.vt = VT_LPSTR;
381 header->value.u.pszVal = value;
386 static void init_content_type(MimeBody *body, header_t *header)
391 if(header->prop->id != PID_HDR_CNTTYPE)
393 ERR("called with header %s\n", header->prop->name);
397 slash = strchr(header->value.u.pszVal, '/');
400 WARN("malformed context type value\n");
403 len = slash - header->value.u.pszVal;
404 body->content_pri_type = HeapAlloc(GetProcessHeap(), 0, len + 1);
405 memcpy(body->content_pri_type, header->value.u.pszVal, len);
406 body->content_pri_type[len] = '\0';
407 body->content_sub_type = strdupA(slash + 1);
410 static HRESULT parse_headers(MimeBody *body, IStream *stm)
412 char *header_buf, *cur_header_ptr;
416 hr = copy_headers_to_buf(stm, &header_buf);
417 if(FAILED(hr)) return hr;
419 cur_header_ptr = header_buf;
420 while((header = read_prop(body, &cur_header_ptr)))
422 read_value(header, &cur_header_ptr);
423 list_add_tail(&body->headers, &header->entry);
425 if(header->prop->id == PID_HDR_CNTTYPE)
426 init_content_type(body, header);
429 HeapFree(GetProcessHeap(), 0, header_buf);
433 static void empty_param_list(struct list *list)
435 param_t *param, *cursor2;
437 LIST_FOR_EACH_ENTRY_SAFE(param, cursor2, list, param_t, entry)
439 list_remove(¶m->entry);
440 HeapFree(GetProcessHeap(), 0, param->name);
441 HeapFree(GetProcessHeap(), 0, param->value);
442 HeapFree(GetProcessHeap(), 0, param);
446 static void empty_header_list(struct list *list)
448 header_t *header, *cursor2;
450 LIST_FOR_EACH_ENTRY_SAFE(header, cursor2, list, header_t, entry)
452 list_remove(&header->entry);
453 PropVariantClear(&header->value);
454 empty_param_list(&header->params);
455 HeapFree(GetProcessHeap(), 0, header);
459 static void empty_new_prop_list(struct list *list)
461 property_list_entry_t *prop, *cursor2;
463 LIST_FOR_EACH_ENTRY_SAFE(prop, cursor2, list, property_list_entry_t, entry)
465 list_remove(&prop->entry);
466 HeapFree(GetProcessHeap(), 0, (char *)prop->prop.name);
467 HeapFree(GetProcessHeap(), 0, prop);
471 static void release_data(REFIID riid, void *data)
475 if(IsEqualIID(riid, &IID_IStream))
476 IStream_Release((IStream *)data);
478 FIXME("Unhandled data format %s\n", debugstr_guid(riid));
481 static HRESULT find_prop(MimeBody *body, const char *name, header_t **prop)
487 LIST_FOR_EACH_ENTRY(header, &body->headers, header_t, entry)
489 if(!strcasecmp(name, header->prop->name))
496 return MIME_E_NOT_FOUND;
499 static HRESULT WINAPI MimeBody_QueryInterface(IMimeBody* iface,
503 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject);
507 if (IsEqualIID(riid, &IID_IUnknown) ||
508 IsEqualIID(riid, &IID_IPersist) ||
509 IsEqualIID(riid, &IID_IPersistStreamInit) ||
510 IsEqualIID(riid, &IID_IMimePropertySet) ||
511 IsEqualIID(riid, &IID_IMimeBody))
518 IUnknown_AddRef((IUnknown*)*ppvObject);
522 FIXME("no interface for %s\n", debugstr_guid(riid));
523 return E_NOINTERFACE;
526 static ULONG WINAPI MimeBody_AddRef(IMimeBody* iface)
528 MimeBody *This = impl_from_IMimeBody(iface);
529 TRACE("(%p)->()\n", iface);
530 return InterlockedIncrement(&This->refs);
533 static ULONG WINAPI MimeBody_Release(IMimeBody* iface)
535 MimeBody *This = impl_from_IMimeBody(iface);
538 TRACE("(%p)->()\n", iface);
540 refs = InterlockedDecrement(&This->refs);
543 empty_header_list(&This->headers);
544 empty_new_prop_list(&This->new_props);
546 HeapFree(GetProcessHeap(), 0, This->content_pri_type);
547 HeapFree(GetProcessHeap(), 0, This->content_sub_type);
549 release_data(&This->data_iid, This->data);
551 HeapFree(GetProcessHeap(), 0, This);
557 static HRESULT WINAPI MimeBody_GetClassID(
566 static HRESULT WINAPI MimeBody_IsDirty(
573 static HRESULT WINAPI MimeBody_Load(
577 MimeBody *This = impl_from_IMimeBody(iface);
578 TRACE("(%p)->(%p)\n", iface, pStm);
579 return parse_headers(This, pStm);
582 static HRESULT WINAPI MimeBody_Save(
591 static HRESULT WINAPI MimeBody_GetSizeMax(
593 ULARGE_INTEGER* pcbSize)
599 static HRESULT WINAPI MimeBody_InitNew(
602 TRACE("%p->()\n", iface);
606 static HRESULT WINAPI MimeBody_GetPropInfo(
609 LPMIMEPROPINFO pInfo)
615 static HRESULT WINAPI MimeBody_SetPropInfo(
618 LPCMIMEPROPINFO pInfo)
624 static HRESULT WINAPI MimeBody_GetProp(
628 LPPROPVARIANT pValue)
634 static HRESULT WINAPI MimeBody_SetProp(
638 LPCPROPVARIANT pValue)
644 static HRESULT WINAPI MimeBody_AppendProp(
648 LPPROPVARIANT pValue)
654 static HRESULT WINAPI MimeBody_DeleteProp(
662 static HRESULT WINAPI MimeBody_CopyProps(
666 IMimePropertySet* pPropertySet)
672 static HRESULT WINAPI MimeBody_MoveProps(
676 IMimePropertySet* pPropertySet)
682 static HRESULT WINAPI MimeBody_DeleteExcept(
691 static HRESULT WINAPI MimeBody_QueryProp(
696 boolean fCaseSensitive)
702 static HRESULT WINAPI MimeBody_GetCharset(
704 LPHCHARSET phCharset)
710 static HRESULT WINAPI MimeBody_SetCharset(
713 CSETAPPLYTYPE applytype)
719 static HRESULT WINAPI MimeBody_GetParameters(
723 LPMIMEPARAMINFO* pprgParam)
725 MimeBody *This = impl_from_IMimeBody(iface);
729 TRACE("(%p)->(%s, %p, %p)\n", iface, debugstr_a(pszName), pcParams, pprgParam);
734 hr = find_prop(This, pszName, &header);
735 if(hr != S_OK) return hr;
737 *pcParams = list_count(&header->params);
740 IMimeAllocator *alloc;
744 MimeOleGetAllocator(&alloc);
746 *pprgParam = info = IMimeAllocator_Alloc(alloc, *pcParams * sizeof(**pprgParam));
747 LIST_FOR_EACH_ENTRY(param, &header->params, param_t, entry)
751 len = strlen(param->name) + 1;
752 info->pszName = IMimeAllocator_Alloc(alloc, len);
753 memcpy(info->pszName, param->name, len);
754 len = strlen(param->value) + 1;
755 info->pszData = IMimeAllocator_Alloc(alloc, len);
756 memcpy(info->pszData, param->value, len);
759 IMimeAllocator_Release(alloc);
764 static HRESULT WINAPI MimeBody_IsContentType(
769 MimeBody *This = impl_from_IMimeBody(iface);
771 TRACE("(%p)->(%s, %s)\n", This, debugstr_a(pszPriType), debugstr_a(pszSubType));
774 const char *pri = This->content_pri_type;
775 if(!pri) pri = "text";
776 if(strcasecmp(pri, pszPriType)) return S_FALSE;
781 const char *sub = This->content_sub_type;
782 if(!sub) sub = "plain";
783 if(strcasecmp(sub, pszSubType)) return S_FALSE;
789 static HRESULT WINAPI MimeBody_BindToObject(
798 static HRESULT WINAPI MimeBody_Clone(
800 IMimePropertySet** ppPropertySet)
806 static HRESULT WINAPI MimeBody_SetOption(
809 LPCPROPVARIANT pValue)
815 static HRESULT WINAPI MimeBody_GetOption(
818 LPPROPVARIANT pValue)
824 static HRESULT WINAPI MimeBody_EnumProps(
827 IMimeEnumProperties** ppEnum)
833 static HRESULT WINAPI MimeBody_IsType(
835 IMSGBODYTYPE bodytype)
841 static HRESULT WINAPI MimeBody_SetDisplayName(
849 static HRESULT WINAPI MimeBody_GetDisplayName(
857 static HRESULT WINAPI MimeBody_GetOffsets(
859 LPBODYOFFSETS pOffsets)
861 MimeBody *This = impl_from_IMimeBody(iface);
862 TRACE("(%p)->(%p)\n", This, pOffsets);
864 *pOffsets = This->body_offsets;
866 if(This->body_offsets.cbBodyEnd == 0) return MIME_E_NO_DATA;
870 static HRESULT WINAPI MimeBody_GetCurrentEncoding(
872 ENCODINGTYPE* pietEncoding)
874 MimeBody *This = impl_from_IMimeBody(iface);
876 TRACE("(%p)->(%p)\n", This, pietEncoding);
878 *pietEncoding = This->encoding;
882 static HRESULT WINAPI MimeBody_SetCurrentEncoding(
884 ENCODINGTYPE ietEncoding)
886 MimeBody *This = impl_from_IMimeBody(iface);
888 TRACE("(%p)->(%d)\n", This, ietEncoding);
890 This->encoding = ietEncoding;
894 static HRESULT WINAPI MimeBody_GetEstimatedSize(
896 ENCODINGTYPE ietEncoding,
903 static HRESULT WINAPI MimeBody_GetDataHere(
905 ENCODINGTYPE ietEncoding,
912 static HRESULT WINAPI MimeBody_GetData(
914 ENCODINGTYPE ietEncoding,
921 static HRESULT WINAPI MimeBody_SetData(
923 ENCODINGTYPE ietEncoding,
929 MimeBody *This = impl_from_IMimeBody(iface);
930 TRACE("(%p)->(%d, %s, %s, %s %p)\n", This, ietEncoding, debugstr_a(pszPriType), debugstr_a(pszSubType),
931 debugstr_guid(riid), pvObject);
933 if(IsEqualIID(riid, &IID_IStream))
934 IStream_AddRef((IStream *)pvObject);
937 FIXME("Unhandled object type %s\n", debugstr_guid(riid));
942 FIXME("release old data\n");
944 This->data_iid = *riid;
945 This->data = pvObject;
947 IMimeBody_SetCurrentEncoding(iface, ietEncoding);
949 /* FIXME: Update the content type.
950 If pszPriType == NULL use 'application'
951 If pszSubType == NULL use 'octet-stream' */
956 static HRESULT WINAPI MimeBody_EmptyData(
963 static HRESULT WINAPI MimeBody_CopyTo(
971 static HRESULT WINAPI MimeBody_GetTransmitInfo(
973 LPTRANSMITINFO pTransmitInfo)
979 static HRESULT WINAPI MimeBody_SaveToFile(
981 ENCODINGTYPE ietEncoding,
988 static HRESULT WINAPI MimeBody_GetHandle(
992 MimeBody *This = impl_from_IMimeBody(iface);
993 TRACE("(%p)->(%p)\n", iface, phBody);
995 *phBody = This->handle;
996 return This->handle ? S_OK : MIME_E_NO_DATA;
999 static IMimeBodyVtbl body_vtbl =
1001 MimeBody_QueryInterface,
1004 MimeBody_GetClassID,
1008 MimeBody_GetSizeMax,
1010 MimeBody_GetPropInfo,
1011 MimeBody_SetPropInfo,
1014 MimeBody_AppendProp,
1015 MimeBody_DeleteProp,
1018 MimeBody_DeleteExcept,
1020 MimeBody_GetCharset,
1021 MimeBody_SetCharset,
1022 MimeBody_GetParameters,
1023 MimeBody_IsContentType,
1024 MimeBody_BindToObject,
1030 MimeBody_SetDisplayName,
1031 MimeBody_GetDisplayName,
1032 MimeBody_GetOffsets,
1033 MimeBody_GetCurrentEncoding,
1034 MimeBody_SetCurrentEncoding,
1035 MimeBody_GetEstimatedSize,
1036 MimeBody_GetDataHere,
1041 MimeBody_GetTransmitInfo,
1042 MimeBody_SaveToFile,
1046 static HRESULT MimeBody_set_offsets(MimeBody *body, const BODYOFFSETS *offsets)
1048 TRACE("setting offsets to %d, %d, %d, %d\n", offsets->cbBoundaryStart,
1049 offsets->cbHeaderStart, offsets->cbBodyStart, offsets->cbBodyEnd);
1051 body->body_offsets = *offsets;
1055 #define FIRST_CUSTOM_PROP_ID 0x100
1057 HRESULT MimeBody_create(IUnknown *outer, void **obj)
1060 BODYOFFSETS body_offsets;
1064 if(outer) return CLASS_E_NOAGGREGATION;
1066 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1067 if (!This) return E_OUTOFMEMORY;
1069 This->lpVtbl = &body_vtbl;
1071 This->handle = NULL;
1072 list_init(&This->headers);
1073 list_init(&This->new_props);
1074 This->next_prop_id = FIRST_CUSTOM_PROP_ID;
1075 This->content_pri_type = NULL;
1076 This->content_sub_type = NULL;
1077 This->encoding = IET_7BIT;
1079 This->data_iid = IID_NULL;
1081 body_offsets.cbBoundaryStart = body_offsets.cbHeaderStart = 0;
1082 body_offsets.cbBodyStart = body_offsets.cbBodyEnd = 0;
1083 MimeBody_set_offsets(This, &body_offsets);
1085 *obj = (IMimeBody *)&This->lpVtbl;
1089 typedef struct MimeMessage
1091 const IMimeMessageVtbl *lpVtbl;
1096 static HRESULT WINAPI MimeMessage_QueryInterface(IMimeMessage *iface, REFIID riid, void **ppv)
1098 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
1100 if (IsEqualIID(riid, &IID_IUnknown) ||
1101 IsEqualIID(riid, &IID_IPersist) ||
1102 IsEqualIID(riid, &IID_IPersistStreamInit) ||
1103 IsEqualIID(riid, &IID_IMimeMessageTree) ||
1104 IsEqualIID(riid, &IID_IMimeMessage))
1107 IUnknown_AddRef(iface);
1111 FIXME("no interface for %s\n", debugstr_guid(riid));
1113 return E_NOINTERFACE;
1116 static ULONG WINAPI MimeMessage_AddRef(IMimeMessage *iface)
1118 MimeMessage *This = (MimeMessage *)iface;
1119 TRACE("(%p)->()\n", iface);
1120 return InterlockedIncrement(&This->refs);
1123 static ULONG WINAPI MimeMessage_Release(IMimeMessage *iface)
1125 MimeMessage *This = (MimeMessage *)iface;
1128 TRACE("(%p)->()\n", iface);
1130 refs = InterlockedDecrement(&This->refs);
1133 HeapFree(GetProcessHeap(), 0, This);
1139 /*** IPersist methods ***/
1140 static HRESULT WINAPI MimeMessage_GetClassID(
1141 IMimeMessage *iface,
1144 FIXME("(%p)->(%p)\n", iface, pClassID);
1148 /*** IPersistStreamInit methods ***/
1149 static HRESULT WINAPI MimeMessage_IsDirty(
1150 IMimeMessage *iface)
1152 FIXME("(%p)->()\n", iface);
1156 static HRESULT WINAPI MimeMessage_Load(
1157 IMimeMessage *iface,
1159 FIXME("(%p)->(%p)\n", iface, pStm);
1163 static HRESULT WINAPI MimeMessage_Save(
1164 IMimeMessage *iface,
1168 FIXME("(%p)->(%p, %s)\n", iface, pStm, fClearDirty ? "TRUE" : "FALSE");
1172 static HRESULT WINAPI MimeMessage_GetSizeMax(
1173 IMimeMessage *iface,
1174 ULARGE_INTEGER *pcbSize)
1176 FIXME("(%p)->(%p)\n", iface, pcbSize);
1180 static HRESULT WINAPI MimeMessage_InitNew(
1181 IMimeMessage *iface)
1183 FIXME("(%p)->()\n", iface);
1187 /*** IMimeMessageTree methods ***/
1188 static HRESULT WINAPI MimeMessage_GetMessageSource(
1189 IMimeMessage *iface,
1193 FIXME("(%p)->(%p, 0x%x)\n", iface, ppStream, dwFlags);
1197 static HRESULT WINAPI MimeMessage_GetMessageSize(
1198 IMimeMessage *iface,
1202 FIXME("(%p)->(%p, 0x%x)\n", iface, pcbSize, dwFlags);
1206 static HRESULT WINAPI MimeMessage_LoadOffsetTable(
1207 IMimeMessage *iface,
1210 FIXME("(%p)->(%p)\n", iface, pStream);
1214 static HRESULT WINAPI MimeMessage_SaveOffsetTable(
1215 IMimeMessage *iface,
1219 FIXME("(%p)->(%p, 0x%x)\n", iface, pStream, dwFlags);
1224 static HRESULT WINAPI MimeMessage_GetFlags(
1225 IMimeMessage *iface,
1228 FIXME("(%p)->(%p)\n", iface, pdwFlags);
1232 static HRESULT WINAPI MimeMessage_Commit(
1233 IMimeMessage *iface,
1236 FIXME("(%p)->(0x%x)\n", iface, dwFlags);
1241 static HRESULT WINAPI MimeMessage_HandsOffStorage(
1242 IMimeMessage *iface)
1244 FIXME("(%p)->()\n", iface);
1248 static HRESULT WINAPI MimeMessage_BindToObject(
1249 IMimeMessage *iface,
1254 FIXME("(%p)->(%p, %s, %p)\n", iface, hBody, debugstr_guid(riid), ppvObject);
1258 static HRESULT WINAPI MimeMessage_SaveBody(
1259 IMimeMessage *iface,
1264 FIXME("(%p)->(%p, 0x%x, %p)\n", iface, hBody, dwFlags, pStream);
1268 static HRESULT WINAPI MimeMessage_InsertBody(
1269 IMimeMessage *iface,
1270 BODYLOCATION location,
1274 FIXME("(%p)->(%d, %p, %p)\n", iface, location, hPivot, phBody);
1278 static HRESULT WINAPI MimeMessage_GetBody(
1279 IMimeMessage *iface,
1280 BODYLOCATION location,
1284 FIXME("(%p)->(%d, %p, %p)\n", iface, location, hPivot, phBody);
1288 static HRESULT WINAPI MimeMessage_DeleteBody(
1289 IMimeMessage *iface,
1293 FIXME("(%p)->(%p, %08x)\n", iface, hBody, dwFlags);
1297 static HRESULT WINAPI MimeMessage_MoveBody(
1298 IMimeMessage *iface,
1300 BODYLOCATION location)
1302 FIXME("(%p)->(%d)\n", iface, location);
1306 static HRESULT WINAPI MimeMessage_CountBodies(
1307 IMimeMessage *iface,
1312 FIXME("(%p)->(%p, %s, %p)\n", iface, hParent, fRecurse ? "TRUE" : "FALSE", pcBodies);
1316 static HRESULT WINAPI MimeMessage_FindFirst(
1317 IMimeMessage *iface,
1318 LPFINDBODY pFindBody,
1321 FIXME("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
1325 static HRESULT WINAPI MimeMessage_FindNext(
1326 IMimeMessage *iface,
1327 LPFINDBODY pFindBody,
1330 FIXME("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
1334 static HRESULT WINAPI MimeMessage_ResolveURL(
1335 IMimeMessage *iface,
1342 FIXME("(%p)->(%p, %s, %s, 0x%x, %p)\n", iface, hRelated, pszBase, pszURL, dwFlags, phBody);
1346 static HRESULT WINAPI MimeMessage_ToMultipart(
1347 IMimeMessage *iface,
1350 LPHBODY phMultipart)
1352 FIXME("(%p)->(%p, %s, %p)\n", iface, hBody, pszSubType, phMultipart);
1356 static HRESULT WINAPI MimeMessage_GetBodyOffsets(
1357 IMimeMessage *iface,
1359 LPBODYOFFSETS pOffsets)
1361 FIXME("(%p)->(%p, %p)\n", iface, hBody, pOffsets);
1365 static HRESULT WINAPI MimeMessage_GetCharset(
1366 IMimeMessage *iface,
1367 LPHCHARSET phCharset)
1369 FIXME("(%p)->(%p)\n", iface, phCharset);
1373 static HRESULT WINAPI MimeMessage_SetCharset(
1374 IMimeMessage *iface,
1376 CSETAPPLYTYPE applytype)
1378 FIXME("(%p)->(%p, %d)\n", iface, hCharset, applytype);
1382 static HRESULT WINAPI MimeMessage_IsBodyType(
1383 IMimeMessage *iface,
1385 IMSGBODYTYPE bodytype)
1387 FIXME("(%p)->(%p, %d)\n", iface, hBody, bodytype);
1391 static HRESULT WINAPI MimeMessage_IsContentType(
1392 IMimeMessage *iface,
1397 FIXME("(%p)->(%p, %s, %s)\n", iface, hBody, pszPriType, pszSubType);
1401 static HRESULT WINAPI MimeMessage_QueryBodyProp(
1402 IMimeMessage *iface,
1407 boolean fCaseSensitive)
1409 FIXME("(%p)->(%p, %s, %s, %s, %s)\n", iface, hBody, pszName, pszCriteria, fSubString ? "TRUE" : "FALSE", fCaseSensitive ? "TRUE" : "FALSE");
1413 static HRESULT WINAPI MimeMessage_GetBodyProp(
1414 IMimeMessage *iface,
1418 LPPROPVARIANT pValue)
1420 FIXME("(%p)->(%p, %s, 0x%x, %p)\n", iface, hBody, pszName, dwFlags, pValue);
1424 static HRESULT WINAPI MimeMessage_SetBodyProp(
1425 IMimeMessage *iface,
1429 LPCPROPVARIANT pValue)
1431 FIXME("(%p)->(%p, %s, 0x%x, %p)\n", iface, hBody, pszName, dwFlags, pValue);
1435 static HRESULT WINAPI MimeMessage_DeleteBodyProp(
1436 IMimeMessage *iface,
1440 FIXME("(%p)->(%p, %s)\n", iface, hBody, pszName);
1444 static HRESULT WINAPI MimeMessage_SetOption(
1445 IMimeMessage *iface,
1447 LPCPROPVARIANT pValue)
1449 FIXME("(%p)->(%d, %p)\n", iface, oid, pValue);
1453 static HRESULT WINAPI MimeMessage_GetOption(
1454 IMimeMessage *iface,
1456 LPPROPVARIANT pValue)
1458 FIXME("(%p)->(%d, %p)\n", iface, oid, pValue);
1462 /*** IMimeMessage methods ***/
1463 static HRESULT WINAPI MimeMessage_CreateWebPage(
1464 IMimeMessage *iface,
1466 LPWEBPAGEOPTIONS pOptions,
1467 IMimeMessageCallback *pCallback,
1468 IMoniker **ppMoniker)
1470 FIXME("(%p)->(%p, %p, %p, %p)\n", iface, pRootStm, pOptions, pCallback, ppMoniker);
1475 static HRESULT WINAPI MimeMessage_GetProp(
1476 IMimeMessage *iface,
1479 LPPROPVARIANT pValue)
1481 FIXME("(%p)->(%s, 0x%x, %p)\n", iface, pszName, dwFlags, pValue);
1485 static HRESULT WINAPI MimeMessage_SetProp(
1486 IMimeMessage *iface,
1489 LPCPROPVARIANT pValue)
1491 FIXME("(%p)->(%s, 0x%x, %p)\n", iface, pszName, dwFlags, pValue);
1495 static HRESULT WINAPI MimeMessage_DeleteProp(
1496 IMimeMessage *iface,
1499 FIXME("(%p)->(%s)\n", iface, pszName);
1503 static HRESULT WINAPI MimeMessage_QueryProp(
1504 IMimeMessage *iface,
1508 boolean fCaseSensitive)
1510 FIXME("(%p)->(%s, %s, %s, %s)\n", iface, pszName, pszCriteria, fSubString ? "TRUE" : "FALSE", fCaseSensitive ? "TRUE" : "FALSE");
1514 static HRESULT WINAPI MimeMessage_GetTextBody(
1515 IMimeMessage *iface,
1517 ENCODINGTYPE ietEncoding,
1521 FIXME("(%p)->(%d, %d, %p, %p)\n", iface, dwTxtType, ietEncoding, pStream, phBody);
1525 static HRESULT WINAPI MimeMessage_SetTextBody(
1526 IMimeMessage *iface,
1528 ENCODINGTYPE ietEncoding,
1533 FIXME("(%p)->(%d, %d, %p, %p, %p)\n", iface, dwTxtType, ietEncoding, hAlternative, pStream, phBody);
1537 static HRESULT WINAPI MimeMessage_AttachObject(
1538 IMimeMessage *iface,
1543 FIXME("(%p)->(%s, %p, %p)\n", iface, debugstr_guid(riid), pvObject, phBody);
1547 static HRESULT WINAPI MimeMessage_AttachFile(
1548 IMimeMessage *iface,
1553 FIXME("(%p)->(%s, %p, %p)\n", iface, pszFilePath, pstmFile, phBody);
1557 static HRESULT WINAPI MimeMessage_AttachURL(
1558 IMimeMessage *iface,
1566 FIXME("(%p)->(%s, %s, 0x%x, %p, %p, %p)\n", iface, pszBase, pszURL, dwFlags, pstmURL, ppszCIDURL, phBody);
1570 static HRESULT WINAPI MimeMessage_GetAttachments(
1571 IMimeMessage *iface,
1573 LPHBODY *pprghAttach)
1575 FIXME("(%p)->(%p, %p)\n", iface, pcAttach, pprghAttach);
1579 static HRESULT WINAPI MimeMessage_GetAddressTable(
1580 IMimeMessage *iface,
1581 IMimeAddressTable **ppTable)
1583 FIXME("(%p)->(%p)\n", iface, ppTable);
1587 static HRESULT WINAPI MimeMessage_GetSender(
1588 IMimeMessage *iface,
1589 LPADDRESSPROPS pAddress)
1591 FIXME("(%p)->(%p)\n", iface, pAddress);
1595 static HRESULT WINAPI MimeMessage_GetAddressTypes(
1596 IMimeMessage *iface,
1599 LPADDRESSLIST pList)
1601 FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, dwProps, pList);
1605 static HRESULT WINAPI MimeMessage_GetAddressFormat(
1606 IMimeMessage *iface,
1608 ADDRESSFORMAT format,
1611 FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, format, ppszFormat);
1615 static HRESULT WINAPI MimeMessage_EnumAddressTypes(
1616 IMimeMessage *iface,
1619 IMimeEnumAddressTypes **ppEnum)
1621 FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, dwProps, ppEnum);
1625 static HRESULT WINAPI MimeMessage_SplitMessage(
1626 IMimeMessage *iface,
1628 IMimeMessageParts **ppParts)
1630 FIXME("(%p)->(%d, %p)\n", iface, cbMaxPart, ppParts);
1634 static HRESULT WINAPI MimeMessage_GetRootMoniker(
1635 IMimeMessage *iface,
1636 IMoniker **ppMoniker)
1638 FIXME("(%p)->(%p)\n", iface, ppMoniker);
1642 static const IMimeMessageVtbl MimeMessageVtbl =
1644 MimeMessage_QueryInterface,
1646 MimeMessage_Release,
1647 MimeMessage_GetClassID,
1648 MimeMessage_IsDirty,
1651 MimeMessage_GetSizeMax,
1652 MimeMessage_InitNew,
1653 MimeMessage_GetMessageSource,
1654 MimeMessage_GetMessageSize,
1655 MimeMessage_LoadOffsetTable,
1656 MimeMessage_SaveOffsetTable,
1657 MimeMessage_GetFlags,
1659 MimeMessage_HandsOffStorage,
1660 MimeMessage_BindToObject,
1661 MimeMessage_SaveBody,
1662 MimeMessage_InsertBody,
1663 MimeMessage_GetBody,
1664 MimeMessage_DeleteBody,
1665 MimeMessage_MoveBody,
1666 MimeMessage_CountBodies,
1667 MimeMessage_FindFirst,
1668 MimeMessage_FindNext,
1669 MimeMessage_ResolveURL,
1670 MimeMessage_ToMultipart,
1671 MimeMessage_GetBodyOffsets,
1672 MimeMessage_GetCharset,
1673 MimeMessage_SetCharset,
1674 MimeMessage_IsBodyType,
1675 MimeMessage_IsContentType,
1676 MimeMessage_QueryBodyProp,
1677 MimeMessage_GetBodyProp,
1678 MimeMessage_SetBodyProp,
1679 MimeMessage_DeleteBodyProp,
1680 MimeMessage_SetOption,
1681 MimeMessage_GetOption,
1682 MimeMessage_CreateWebPage,
1683 MimeMessage_GetProp,
1684 MimeMessage_SetProp,
1685 MimeMessage_DeleteProp,
1686 MimeMessage_QueryProp,
1687 MimeMessage_GetTextBody,
1688 MimeMessage_SetTextBody,
1689 MimeMessage_AttachObject,
1690 MimeMessage_AttachFile,
1691 MimeMessage_AttachURL,
1692 MimeMessage_GetAttachments,
1693 MimeMessage_GetAddressTable,
1694 MimeMessage_GetSender,
1695 MimeMessage_GetAddressTypes,
1696 MimeMessage_GetAddressFormat,
1697 MimeMessage_EnumAddressTypes,
1698 MimeMessage_SplitMessage,
1699 MimeMessage_GetRootMoniker,
1702 /***********************************************************************
1703 * MimeOleCreateMessage (INETCOMM.@)
1705 HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessage)
1709 TRACE("(%p, %p)\n", pUnkOuter, ppMessage);
1713 FIXME("outer unknown not supported yet\n");
1719 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1720 if (!This) return E_OUTOFMEMORY;
1722 This->lpVtbl = &MimeMessageVtbl;
1725 *ppMessage = (IMimeMessage *)&This->lpVtbl;
1729 /***********************************************************************
1730 * MimeOleSetCompatMode (INETCOMM.@)
1732 HRESULT WINAPI MimeOleSetCompatMode(DWORD dwMode)
1734 FIXME("(0x%x)\n", dwMode);
1738 /***********************************************************************
1739 * MimeOleCreateVirtualStream (INETCOMM.@)
1741 HRESULT WINAPI MimeOleCreateVirtualStream(IStream **ppStream)
1744 FIXME("(%p)\n", ppStream);
1746 hr = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
1750 typedef struct MimeSecurity
1752 const IMimeSecurityVtbl *lpVtbl;
1757 static HRESULT WINAPI MimeSecurity_QueryInterface(
1758 IMimeSecurity* iface,
1762 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), obj);
1764 if (IsEqualIID(riid, &IID_IUnknown) ||
1765 IsEqualIID(riid, &IID_IMimeSecurity))
1768 IUnknown_AddRef(iface);
1772 FIXME("no interface for %s\n", debugstr_guid(riid));
1774 return E_NOINTERFACE;
1777 static ULONG WINAPI MimeSecurity_AddRef(
1778 IMimeSecurity* iface)
1780 MimeSecurity *This = (MimeSecurity *)iface;
1781 TRACE("(%p)->()\n", iface);
1782 return InterlockedIncrement(&This->refs);
1785 static ULONG WINAPI MimeSecurity_Release(
1786 IMimeSecurity* iface)
1788 MimeSecurity *This = (MimeSecurity *)iface;
1791 TRACE("(%p)->()\n", iface);
1793 refs = InterlockedDecrement(&This->refs);
1796 HeapFree(GetProcessHeap(), 0, This);
1802 static HRESULT WINAPI MimeSecurity_InitNew(
1803 IMimeSecurity* iface)
1805 FIXME("(%p)->(): stub\n", iface);
1809 static HRESULT WINAPI MimeSecurity_CheckInit(
1810 IMimeSecurity* iface)
1812 FIXME("(%p)->(): stub\n", iface);
1816 static HRESULT WINAPI MimeSecurity_EncodeMessage(
1817 IMimeSecurity* iface,
1818 IMimeMessageTree* pTree,
1821 FIXME("(%p)->(%p, %08x): stub\n", iface, pTree, dwFlags);
1825 static HRESULT WINAPI MimeSecurity_EncodeBody(
1826 IMimeSecurity* iface,
1827 IMimeMessageTree* pTree,
1831 FIXME("(%p)->(%p, %p, %08x): stub\n", iface, pTree, hEncodeRoot, dwFlags);
1835 static HRESULT WINAPI MimeSecurity_DecodeMessage(
1836 IMimeSecurity* iface,
1837 IMimeMessageTree* pTree,
1840 FIXME("(%p)->(%p, %08x): stub\n", iface, pTree, dwFlags);
1844 static HRESULT WINAPI MimeSecurity_DecodeBody(
1845 IMimeSecurity* iface,
1846 IMimeMessageTree* pTree,
1850 FIXME("(%p)->(%p, %p, %08x): stub\n", iface, pTree, hDecodeRoot, dwFlags);
1854 static HRESULT WINAPI MimeSecurity_EnumCertificates(
1855 IMimeSecurity* iface,
1861 FIXME("(%p)->(%p, %08x, %p, %p): stub\n", iface, hc, dwUsage, pPrev, ppCert);
1865 static HRESULT WINAPI MimeSecurity_GetCertificateName(
1866 IMimeSecurity* iface,
1867 const PCX509CERT pX509Cert,
1868 const CERTNAMETYPE cn,
1871 FIXME("(%p)->(%p, %08x, %p): stub\n", iface, pX509Cert, cn, ppszName);
1875 static HRESULT WINAPI MimeSecurity_GetMessageType(
1876 IMimeSecurity* iface,
1877 const HWND hwndParent,
1881 FIXME("(%p)->(%p, %p, %p): stub\n", iface, hwndParent, pBody, pdwSecType);
1885 static HRESULT WINAPI MimeSecurity_GetCertData(
1886 IMimeSecurity* iface,
1887 const PCX509CERT pX509Cert,
1888 const CERTDATAID dataid,
1889 LPPROPVARIANT pValue)
1891 FIXME("(%p)->(%p, %x, %p): stub\n", iface, pX509Cert, dataid, pValue);
1896 static const IMimeSecurityVtbl MimeSecurityVtbl =
1898 MimeSecurity_QueryInterface,
1899 MimeSecurity_AddRef,
1900 MimeSecurity_Release,
1901 MimeSecurity_InitNew,
1902 MimeSecurity_CheckInit,
1903 MimeSecurity_EncodeMessage,
1904 MimeSecurity_EncodeBody,
1905 MimeSecurity_DecodeMessage,
1906 MimeSecurity_DecodeBody,
1907 MimeSecurity_EnumCertificates,
1908 MimeSecurity_GetCertificateName,
1909 MimeSecurity_GetMessageType,
1910 MimeSecurity_GetCertData
1913 /***********************************************************************
1914 * MimeOleCreateSecurity (INETCOMM.@)
1916 HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity)
1920 TRACE("(%p)\n", ppSecurity);
1924 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1925 if (!This) return E_OUTOFMEMORY;
1927 This->lpVtbl = &MimeSecurityVtbl;
1930 *ppSecurity = (IMimeSecurity *)&This->lpVtbl;
1937 IMimeAllocatorVtbl *lpVtbl;
1940 static HRESULT WINAPI MimeAlloc_QueryInterface(
1941 IMimeAllocator* iface,
1945 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), obj);
1947 if (IsEqualIID(riid, &IID_IUnknown) ||
1948 IsEqualIID(riid, &IID_IMalloc) ||
1949 IsEqualIID(riid, &IID_IMimeAllocator))
1952 IUnknown_AddRef(iface);
1956 FIXME("no interface for %s\n", debugstr_guid(riid));
1958 return E_NOINTERFACE;
1961 static ULONG WINAPI MimeAlloc_AddRef(
1962 IMimeAllocator* iface)
1967 static ULONG WINAPI MimeAlloc_Release(
1968 IMimeAllocator* iface)
1973 static LPVOID WINAPI MimeAlloc_Alloc(
1974 IMimeAllocator* iface,
1977 return CoTaskMemAlloc(cb);
1980 static LPVOID WINAPI MimeAlloc_Realloc(
1981 IMimeAllocator* iface,
1985 return CoTaskMemRealloc(pv, cb);
1988 static void WINAPI MimeAlloc_Free(
1989 IMimeAllocator* iface,
1992 return CoTaskMemFree(pv);
1995 static ULONG WINAPI MimeAlloc_GetSize(
1996 IMimeAllocator* iface,
2003 static int WINAPI MimeAlloc_DidAlloc(
2004 IMimeAllocator* iface,
2011 static void WINAPI MimeAlloc_HeapMinimize(
2012 IMimeAllocator* iface)
2018 static HRESULT WINAPI MimeAlloc_FreeParamInfoArray(
2019 IMimeAllocator* iface,
2021 LPMIMEPARAMINFO prgParam,
2025 TRACE("(%p)->(%d, %p, %d)\n", iface, cParams, prgParam, fFreeArray);
2027 for(i = 0; i < cParams; i++)
2029 IMimeAllocator_Free(iface, prgParam[i].pszName);
2030 IMimeAllocator_Free(iface, prgParam[i].pszData);
2032 if(fFreeArray) IMimeAllocator_Free(iface, prgParam);
2036 static HRESULT WINAPI MimeAlloc_FreeAddressList(
2037 IMimeAllocator* iface,
2038 LPADDRESSLIST pList)
2044 static HRESULT WINAPI MimeAlloc_FreeAddressProps(
2045 IMimeAllocator* iface,
2046 LPADDRESSPROPS pAddress)
2052 static HRESULT WINAPI MimeAlloc_ReleaseObjects(
2053 IMimeAllocator* iface,
2055 IUnknown **prgpUnknown,
2063 static HRESULT WINAPI MimeAlloc_FreeEnumHeaderRowArray(
2064 IMimeAllocator* iface,
2066 LPENUMHEADERROW prgRow,
2073 static HRESULT WINAPI MimeAlloc_FreeEnumPropertyArray(
2074 IMimeAllocator* iface,
2076 LPENUMPROPERTY prgProp,
2083 static HRESULT WINAPI MimeAlloc_FreeThumbprint(
2084 IMimeAllocator* iface,
2085 THUMBBLOB *pthumbprint)
2092 static HRESULT WINAPI MimeAlloc_PropVariantClear(
2093 IMimeAllocator* iface,
2094 LPPROPVARIANT pProp)
2100 static IMimeAllocatorVtbl mime_alloc_vtbl =
2102 MimeAlloc_QueryInterface,
2110 MimeAlloc_HeapMinimize,
2111 MimeAlloc_FreeParamInfoArray,
2112 MimeAlloc_FreeAddressList,
2113 MimeAlloc_FreeAddressProps,
2114 MimeAlloc_ReleaseObjects,
2115 MimeAlloc_FreeEnumHeaderRowArray,
2116 MimeAlloc_FreeEnumPropertyArray,
2117 MimeAlloc_FreeThumbprint,
2118 MimeAlloc_PropVariantClear
2121 static MimeAllocator mime_allocator =
2126 HRESULT MimeAllocator_create(IUnknown *outer, void **obj)
2128 if(outer) return CLASS_E_NOAGGREGATION;
2130 *obj = &mime_allocator;
2134 HRESULT WINAPI MimeOleGetAllocator(IMimeAllocator **alloc)
2136 return MimeAllocator_create(NULL, (void**)alloc);