inetcomm: Copy RFC822 headers into a memory block for later parsing.
[wine] / dlls / inetcomm / mimeole.c
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
24 #include <stdarg.h>
25 #include <stdio.h>
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "objbase.h"
31 #include "ole2.h"
32 #include "mimeole.h"
33
34 #include "wine/debug.h"
35
36 #include "inetcomm_private.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);
39
40 typedef struct MimeBody
41 {
42     const IMimeBodyVtbl *lpVtbl;
43     LONG refs;
44
45     HBODY handle;
46 } MimeBody;
47
48 static inline MimeBody *impl_from_IMimeBody( IMimeBody *iface )
49 {
50     return (MimeBody *)((char*)iface - FIELD_OFFSET(MimeBody, lpVtbl));
51 }
52
53 #define PARSER_BUF_SIZE 1024
54
55 /*****************************************************
56  *        copy_headers_to_buf [internal]
57  *
58  * Copies the headers into a '\0' terminated memory block and leave
59  * the stream's current position set to after the blank line.
60  */
61 static HRESULT copy_headers_to_buf(IStream *stm, char **ptr)
62 {
63     char *buf = NULL;
64     DWORD size = PARSER_BUF_SIZE, offset = 0, last_end = 0;
65     HRESULT hr;
66     int done = 0;
67
68     *ptr = NULL;
69
70     do
71     {
72         char *end;
73         DWORD read;
74
75         if(!buf)
76             buf = HeapAlloc(GetProcessHeap(), 0, size + 1);
77         else
78         {
79             size *= 2;
80             buf = HeapReAlloc(GetProcessHeap(), 0, buf, size + 1);
81         }
82         if(!buf)
83         {
84             hr = E_OUTOFMEMORY;
85             goto fail;
86         }
87
88         hr = IStream_Read(stm, buf + offset, size - offset, &read);
89         if(FAILED(hr)) goto fail;
90
91         offset += read;
92         buf[offset] = '\0';
93
94         if(read == 0) done = 1;
95
96         while(!done && (end = strstr(buf + last_end, "\r\n")))
97         {
98             DWORD new_end = end - buf + 2;
99             if(new_end - last_end == 2)
100             {
101                 LARGE_INTEGER off;
102                 off.QuadPart = new_end;
103                 IStream_Seek(stm, off, STREAM_SEEK_SET, NULL);
104                 buf[new_end] = '\0';
105                 done = 1;
106             }
107             else
108                 last_end = new_end;
109         }
110     } while(!done);
111
112     *ptr = buf;
113     return S_OK;
114
115 fail:
116     HeapFree(GetProcessHeap(), 0, buf);
117     return hr;
118 }
119
120 static HRESULT parse_headers(MimeBody *body, IStream *stm)
121 {
122     char *header_buf;
123     HRESULT hr;
124
125     hr = copy_headers_to_buf(stm, &header_buf);
126     if(FAILED(hr)) return hr;
127
128     HeapFree(GetProcessHeap(), 0, header_buf);
129     return hr;
130 }
131
132
133 static HRESULT WINAPI MimeBody_QueryInterface(IMimeBody* iface,
134                                      REFIID riid,
135                                      void** ppvObject)
136 {
137     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject);
138
139     *ppvObject = NULL;
140
141     if (IsEqualIID(riid, &IID_IUnknown) ||
142         IsEqualIID(riid, &IID_IPersist) ||
143         IsEqualIID(riid, &IID_IPersistStreamInit) ||
144         IsEqualIID(riid, &IID_IMimePropertySet) ||
145         IsEqualIID(riid, &IID_IMimeBody))
146     {
147         *ppvObject = iface;
148     }
149
150     if(*ppvObject)
151     {
152         IUnknown_AddRef((IUnknown*)*ppvObject);
153         return S_OK;
154     }
155
156     FIXME("no interface for %s\n", debugstr_guid(riid));
157     return E_NOINTERFACE;
158 }
159
160 static ULONG WINAPI MimeBody_AddRef(IMimeBody* iface)
161 {
162     MimeBody *This = impl_from_IMimeBody(iface);
163     TRACE("(%p)->()\n", iface);
164     return InterlockedIncrement(&This->refs);
165 }
166
167 static ULONG WINAPI MimeBody_Release(IMimeBody* iface)
168 {
169     MimeBody *This = impl_from_IMimeBody(iface);
170     ULONG refs;
171
172     TRACE("(%p)->()\n", iface);
173
174     refs = InterlockedDecrement(&This->refs);
175     if (!refs)
176     {
177         HeapFree(GetProcessHeap(), 0, This);
178     }
179
180     return refs;
181 }
182
183 static HRESULT WINAPI MimeBody_GetClassID(
184                                  IMimeBody* iface,
185                                  CLSID* pClassID)
186 {
187     FIXME("stub\n");
188     return E_NOTIMPL;
189 }
190
191
192 static HRESULT WINAPI MimeBody_IsDirty(
193                               IMimeBody* iface)
194 {
195     FIXME("stub\n");
196     return E_NOTIMPL;
197 }
198
199 static HRESULT WINAPI MimeBody_Load(
200                            IMimeBody* iface,
201                            LPSTREAM pStm)
202 {
203     MimeBody *This = impl_from_IMimeBody(iface);
204     TRACE("(%p)->(%p)\n", iface, pStm);
205     return parse_headers(This, pStm);
206 }
207
208 static HRESULT WINAPI MimeBody_Save(
209                            IMimeBody* iface,
210                            LPSTREAM pStm,
211                            BOOL fClearDirty)
212 {
213     FIXME("stub\n");
214     return E_NOTIMPL;
215 }
216
217 static HRESULT WINAPI MimeBody_GetSizeMax(
218                                  IMimeBody* iface,
219                                  ULARGE_INTEGER* pcbSize)
220 {
221     FIXME("stub\n");
222     return E_NOTIMPL;
223 }
224
225 static HRESULT WINAPI MimeBody_InitNew(
226                               IMimeBody* iface)
227 {
228     TRACE("%p->()\n", iface);
229     return S_OK;
230 }
231
232 static HRESULT WINAPI MimeBody_GetPropInfo(
233                                   IMimeBody* iface,
234                                   LPCSTR pszName,
235                                   LPMIMEPROPINFO pInfo)
236 {
237     FIXME("stub\n");
238     return E_NOTIMPL;
239 }
240
241 static HRESULT WINAPI MimeBody_SetPropInfo(
242                                   IMimeBody* iface,
243                                   LPCSTR pszName,
244                                   LPCMIMEPROPINFO pInfo)
245 {
246     FIXME("stub\n");
247     return E_NOTIMPL;
248 }
249
250 static HRESULT WINAPI MimeBody_GetProp(
251                               IMimeBody* iface,
252                               LPCSTR pszName,
253                               DWORD dwFlags,
254                               LPPROPVARIANT pValue)
255 {
256     FIXME("stub\n");
257     return E_NOTIMPL;
258 }
259
260 static HRESULT WINAPI MimeBody_SetProp(
261                               IMimeBody* iface,
262                               LPCSTR pszName,
263                               DWORD dwFlags,
264                               LPCPROPVARIANT pValue)
265 {
266     FIXME("stub\n");
267     return E_NOTIMPL;
268 }
269
270 static HRESULT WINAPI MimeBody_AppendProp(
271                                  IMimeBody* iface,
272                                  LPCSTR pszName,
273                                  DWORD dwFlags,
274                                  LPPROPVARIANT pValue)
275 {
276     FIXME("stub\n");
277     return E_NOTIMPL;
278 }
279
280 static HRESULT WINAPI MimeBody_DeleteProp(
281                                  IMimeBody* iface,
282                                  LPCSTR pszName)
283 {
284     FIXME("stub\n");
285     return E_NOTIMPL;
286 }
287
288 static HRESULT WINAPI MimeBody_CopyProps(
289                                 IMimeBody* iface,
290                                 ULONG cNames,
291                                 LPCSTR* prgszName,
292                                 IMimePropertySet* pPropertySet)
293 {
294     FIXME("stub\n");
295     return E_NOTIMPL;
296 }
297
298 static HRESULT WINAPI MimeBody_MoveProps(
299                                 IMimeBody* iface,
300                                 ULONG cNames,
301                                 LPCSTR* prgszName,
302                                 IMimePropertySet* pPropertySet)
303 {
304     FIXME("stub\n");
305     return E_NOTIMPL;
306 }
307
308 static HRESULT WINAPI MimeBody_DeleteExcept(
309                                    IMimeBody* iface,
310                                    ULONG cNames,
311                                    LPCSTR* prgszName)
312 {
313     FIXME("stub\n");
314     return E_NOTIMPL;
315 }
316
317 static HRESULT WINAPI MimeBody_QueryProp(
318                                 IMimeBody* iface,
319                                 LPCSTR pszName,
320                                 LPCSTR pszCriteria,
321                                 boolean fSubString,
322                                 boolean fCaseSensitive)
323 {
324     FIXME("stub\n");
325     return E_NOTIMPL;
326 }
327
328 static HRESULT WINAPI MimeBody_GetCharset(
329                                  IMimeBody* iface,
330                                  LPHCHARSET phCharset)
331 {
332     FIXME("stub\n");
333     return E_NOTIMPL;
334 }
335
336 static HRESULT WINAPI MimeBody_SetCharset(
337                                  IMimeBody* iface,
338                                  HCHARSET hCharset,
339                                  CSETAPPLYTYPE applytype)
340 {
341     FIXME("stub\n");
342     return E_NOTIMPL;
343 }
344
345 static HRESULT WINAPI MimeBody_GetParameters(
346                                     IMimeBody* iface,
347                                     LPCSTR pszName,
348                                     ULONG* pcParams,
349                                     LPMIMEPARAMINFO* pprgParam)
350 {
351     FIXME("stub\n");
352     return E_NOTIMPL;
353 }
354
355 static HRESULT WINAPI MimeBody_IsContentType(
356                                     IMimeBody* iface,
357                                     LPCSTR pszPriType,
358                                     LPCSTR pszSubType)
359 {
360     FIXME("stub\n");
361     return E_NOTIMPL;
362 }
363
364 static HRESULT WINAPI MimeBody_BindToObject(
365                                    IMimeBody* iface,
366                                    REFIID riid,
367                                    void** ppvObject)
368 {
369     FIXME("stub\n");
370     return E_NOTIMPL;
371 }
372
373 static HRESULT WINAPI MimeBody_Clone(
374                             IMimeBody* iface,
375                             IMimePropertySet** ppPropertySet)
376 {
377     FIXME("stub\n");
378     return E_NOTIMPL;
379 }
380
381 static HRESULT WINAPI MimeBody_SetOption(
382                                 IMimeBody* iface,
383                                 const TYPEDID oid,
384                                 LPCPROPVARIANT pValue)
385 {
386     FIXME("stub\n");
387     return E_NOTIMPL;
388 }
389
390 static HRESULT WINAPI MimeBody_GetOption(
391                                 IMimeBody* iface,
392                                 const TYPEDID oid,
393                                 LPPROPVARIANT pValue)
394 {
395     FIXME("stub\n");
396     return E_NOTIMPL;
397 }
398
399 static HRESULT WINAPI MimeBody_EnumProps(
400                                 IMimeBody* iface,
401                                 DWORD dwFlags,
402                                 IMimeEnumProperties** ppEnum)
403 {
404     FIXME("stub\n");
405     return E_NOTIMPL;
406 }
407
408 static HRESULT WINAPI MimeBody_IsType(
409                              IMimeBody* iface,
410                              IMSGBODYTYPE bodytype)
411 {
412     FIXME("stub\n");
413     return E_NOTIMPL;
414 }
415
416 static HRESULT WINAPI MimeBody_SetDisplayName(
417                                      IMimeBody* iface,
418                                      LPCSTR pszDisplay)
419 {
420     FIXME("stub\n");
421     return E_NOTIMPL;
422 }
423
424 static HRESULT WINAPI MimeBody_GetDisplayName(
425                                      IMimeBody* iface,
426                                      LPSTR* ppszDisplay)
427 {
428     FIXME("stub\n");
429     return E_NOTIMPL;
430 }
431
432 static HRESULT WINAPI MimeBody_GetOffsets(
433                                  IMimeBody* iface,
434                                  LPBODYOFFSETS pOffsets)
435 {
436     FIXME("stub\n");
437     return E_NOTIMPL;
438 }
439
440 static HRESULT WINAPI MimeBody_GetCurrentEncoding(
441                                          IMimeBody* iface,
442                                          ENCODINGTYPE* pietEncoding)
443 {
444     FIXME("stub\n");
445     return E_NOTIMPL;
446 }
447
448 static HRESULT WINAPI MimeBody_SetCurrentEncoding(
449                                          IMimeBody* iface,
450                                          ENCODINGTYPE ietEncoding)
451 {
452     FIXME("stub\n");
453     return E_NOTIMPL;
454 }
455
456 static HRESULT WINAPI MimeBody_GetEstimatedSize(
457                                        IMimeBody* iface,
458                                        ENCODINGTYPE ietEncoding,
459                                        ULONG* pcbSize)
460 {
461     FIXME("stub\n");
462     return E_NOTIMPL;
463 }
464
465 static HRESULT WINAPI MimeBody_GetDataHere(
466                                   IMimeBody* iface,
467                                   ENCODINGTYPE ietEncoding,
468                                   IStream* pStream)
469 {
470     FIXME("stub\n");
471     return E_NOTIMPL;
472 }
473
474 static HRESULT WINAPI MimeBody_GetData(
475                               IMimeBody* iface,
476                               ENCODINGTYPE ietEncoding,
477                               IStream** ppStream)
478 {
479     FIXME("stub\n");
480     return E_NOTIMPL;
481 }
482
483 static HRESULT WINAPI MimeBody_SetData(
484                               IMimeBody* iface,
485                               ENCODINGTYPE ietEncoding,
486                               LPCSTR pszPriType,
487                               LPCSTR pszSubType,
488                               REFIID riid,
489                               LPVOID pvObject)
490 {
491     FIXME("stub\n");
492     return E_NOTIMPL;
493 }
494
495 static HRESULT WINAPI MimeBody_EmptyData(
496                                 IMimeBody* iface)
497 {
498     FIXME("stub\n");
499     return E_NOTIMPL;
500 }
501
502 static HRESULT WINAPI MimeBody_CopyTo(
503                              IMimeBody* iface,
504                              IMimeBody* pBody)
505 {
506     FIXME("stub\n");
507     return E_NOTIMPL;
508 }
509
510 static HRESULT WINAPI MimeBody_GetTransmitInfo(
511                                       IMimeBody* iface,
512                                       LPTRANSMITINFO pTransmitInfo)
513 {
514     FIXME("stub\n");
515     return E_NOTIMPL;
516 }
517
518 static HRESULT WINAPI MimeBody_SaveToFile(
519                                  IMimeBody* iface,
520                                  ENCODINGTYPE ietEncoding,
521                                  LPCSTR pszFilePath)
522 {
523     FIXME("stub\n");
524     return E_NOTIMPL;
525 }
526
527 static HRESULT WINAPI MimeBody_GetHandle(
528                                 IMimeBody* iface,
529                                 LPHBODY phBody)
530 {
531     MimeBody *This = impl_from_IMimeBody(iface);
532     TRACE("(%p)->(%p)\n", iface, phBody);
533
534     *phBody = This->handle;
535     return This->handle ? S_OK : MIME_E_NO_DATA;
536 }
537
538 static IMimeBodyVtbl body_vtbl =
539 {
540     MimeBody_QueryInterface,
541     MimeBody_AddRef,
542     MimeBody_Release,
543     MimeBody_GetClassID,
544     MimeBody_IsDirty,
545     MimeBody_Load,
546     MimeBody_Save,
547     MimeBody_GetSizeMax,
548     MimeBody_InitNew,
549     MimeBody_GetPropInfo,
550     MimeBody_SetPropInfo,
551     MimeBody_GetProp,
552     MimeBody_SetProp,
553     MimeBody_AppendProp,
554     MimeBody_DeleteProp,
555     MimeBody_CopyProps,
556     MimeBody_MoveProps,
557     MimeBody_DeleteExcept,
558     MimeBody_QueryProp,
559     MimeBody_GetCharset,
560     MimeBody_SetCharset,
561     MimeBody_GetParameters,
562     MimeBody_IsContentType,
563     MimeBody_BindToObject,
564     MimeBody_Clone,
565     MimeBody_SetOption,
566     MimeBody_GetOption,
567     MimeBody_EnumProps,
568     MimeBody_IsType,
569     MimeBody_SetDisplayName,
570     MimeBody_GetDisplayName,
571     MimeBody_GetOffsets,
572     MimeBody_GetCurrentEncoding,
573     MimeBody_SetCurrentEncoding,
574     MimeBody_GetEstimatedSize,
575     MimeBody_GetDataHere,
576     MimeBody_GetData,
577     MimeBody_SetData,
578     MimeBody_EmptyData,
579     MimeBody_CopyTo,
580     MimeBody_GetTransmitInfo,
581     MimeBody_SaveToFile,
582     MimeBody_GetHandle
583 };
584
585 HRESULT MimeBody_create(IUnknown *outer, void **obj)
586 {
587     MimeBody *This;
588
589     *obj = NULL;
590
591     if(outer) return CLASS_E_NOAGGREGATION;
592
593     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
594     if (!This) return E_OUTOFMEMORY;
595
596     This->lpVtbl = &body_vtbl;
597     This->refs = 1;
598     This->handle = NULL;
599
600     *obj = (IMimeBody *)&This->lpVtbl;
601     return S_OK;
602 }
603
604 typedef struct MimeMessage
605 {
606     const IMimeMessageVtbl *lpVtbl;
607
608     LONG refs;
609 } MimeMessage;
610
611 static HRESULT WINAPI MimeMessage_QueryInterface(IMimeMessage *iface, REFIID riid, void **ppv)
612 {
613     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
614
615     if (IsEqualIID(riid, &IID_IUnknown) ||
616         IsEqualIID(riid, &IID_IPersist) ||
617         IsEqualIID(riid, &IID_IPersistStreamInit) ||
618         IsEqualIID(riid, &IID_IMimeMessageTree) ||
619         IsEqualIID(riid, &IID_IMimeMessage))
620     {
621         *ppv = iface;
622         IUnknown_AddRef(iface);
623         return S_OK;
624     }
625
626     FIXME("no interface for %s\n", debugstr_guid(riid));
627     *ppv = NULL;
628     return E_NOINTERFACE;
629 }
630
631 static ULONG WINAPI MimeMessage_AddRef(IMimeMessage *iface)
632 {
633     MimeMessage *This = (MimeMessage *)iface;
634     TRACE("(%p)->()\n", iface);
635     return InterlockedIncrement(&This->refs);
636 }
637
638 static ULONG WINAPI MimeMessage_Release(IMimeMessage *iface)
639 {
640     MimeMessage *This = (MimeMessage *)iface;
641     ULONG refs;
642
643     TRACE("(%p)->()\n", iface);
644
645     refs = InterlockedDecrement(&This->refs);
646     if (!refs)
647     {
648         HeapFree(GetProcessHeap(), 0, This);
649     }
650
651     return refs;
652 }
653
654 /*** IPersist methods ***/
655 static HRESULT WINAPI MimeMessage_GetClassID(
656     IMimeMessage *iface,
657     CLSID *pClassID)
658 {
659     FIXME("(%p)->(%p)\n", iface, pClassID);
660     return E_NOTIMPL;
661 }
662
663 /*** IPersistStreamInit methods ***/
664 static HRESULT WINAPI MimeMessage_IsDirty(
665     IMimeMessage *iface)
666 {
667     FIXME("(%p)->()\n", iface);
668     return E_NOTIMPL;
669 }
670
671 static HRESULT WINAPI MimeMessage_Load(
672     IMimeMessage *iface,
673     LPSTREAM pStm){
674     FIXME("(%p)->(%p)\n", iface, pStm);
675     return E_NOTIMPL;
676 }
677
678 static HRESULT WINAPI MimeMessage_Save(
679     IMimeMessage *iface,
680     LPSTREAM pStm,
681     BOOL fClearDirty)
682 {
683     FIXME("(%p)->(%p, %s)\n", iface, pStm, fClearDirty ? "TRUE" : "FALSE");
684     return E_NOTIMPL;
685 }
686
687 static HRESULT WINAPI MimeMessage_GetSizeMax(
688     IMimeMessage *iface,
689     ULARGE_INTEGER *pcbSize)
690 {
691     FIXME("(%p)->(%p)\n", iface, pcbSize);
692     return E_NOTIMPL;
693 }
694
695 static HRESULT WINAPI MimeMessage_InitNew(
696     IMimeMessage *iface)
697 {
698     FIXME("(%p)->()\n", iface);
699     return E_NOTIMPL;
700 }
701
702 /*** IMimeMessageTree methods ***/
703 static HRESULT WINAPI MimeMessage_GetMessageSource(
704     IMimeMessage *iface,
705     IStream **ppStream,
706     DWORD dwFlags)
707 {
708     FIXME("(%p)->(%p, 0x%x)\n", iface, ppStream, dwFlags);
709     return E_NOTIMPL;
710 }
711
712 static HRESULT WINAPI MimeMessage_GetMessageSize(
713     IMimeMessage *iface,
714     ULONG *pcbSize,
715     DWORD dwFlags)
716 {
717     FIXME("(%p)->(%p, 0x%x)\n", iface, pcbSize, dwFlags);
718     return E_NOTIMPL;
719 }
720
721 static HRESULT WINAPI MimeMessage_LoadOffsetTable(
722     IMimeMessage *iface,
723     IStream *pStream)
724 {
725     FIXME("(%p)->(%p)\n", iface, pStream);
726     return E_NOTIMPL;
727 }
728
729 static HRESULT WINAPI MimeMessage_SaveOffsetTable(
730     IMimeMessage *iface,
731     IStream *pStream,
732     DWORD dwFlags)
733 {
734     FIXME("(%p)->(%p, 0x%x)\n", iface, pStream, dwFlags);
735     return E_NOTIMPL;
736 }
737
738
739 static HRESULT WINAPI MimeMessage_GetFlags(
740     IMimeMessage *iface,
741     DWORD *pdwFlags)
742 {
743     FIXME("(%p)->(%p)\n", iface, pdwFlags);
744     return E_NOTIMPL;
745 }
746
747 static HRESULT WINAPI MimeMessage_Commit(
748     IMimeMessage *iface,
749     DWORD dwFlags)
750 {
751     FIXME("(%p)->(0x%x)\n", iface, dwFlags);
752     return E_NOTIMPL;
753 }
754
755
756 static HRESULT WINAPI MimeMessage_HandsOffStorage(
757     IMimeMessage *iface)
758 {
759     FIXME("(%p)->()\n", iface);
760     return E_NOTIMPL;
761 }
762
763 static HRESULT WINAPI MimeMessage_BindToObject(
764     IMimeMessage *iface,
765     const HBODY hBody,
766     REFIID riid,
767     void **ppvObject)
768 {
769     FIXME("(%p)->(%p, %s, %p)\n", iface, hBody, debugstr_guid(riid), ppvObject);
770     return E_NOTIMPL;
771 }
772
773 static HRESULT WINAPI MimeMessage_SaveBody(
774     IMimeMessage *iface,
775     HBODY hBody,
776     DWORD dwFlags,
777     IStream *pStream)
778 {
779     FIXME("(%p)->(%p, 0x%x, %p)\n", iface, hBody, dwFlags, pStream);
780     return E_NOTIMPL;
781 }
782
783 static HRESULT WINAPI MimeMessage_InsertBody(
784     IMimeMessage *iface,
785     BODYLOCATION location,
786     HBODY hPivot,
787     LPHBODY phBody)
788 {
789     FIXME("(%p)->(%d, %p, %p)\n", iface, location, hPivot, phBody);
790     return E_NOTIMPL;
791 }
792
793 static HRESULT WINAPI MimeMessage_GetBody(
794     IMimeMessage *iface,
795     BODYLOCATION location,
796     HBODY hPivot,
797     LPHBODY phBody)
798 {
799     FIXME("(%p)->(%d, %p, %p)\n", iface, location, hPivot, phBody);
800     return E_NOTIMPL;
801 }
802
803 static HRESULT WINAPI MimeMessage_DeleteBody(
804     IMimeMessage *iface,
805     HBODY hBody,
806     DWORD dwFlags)
807 {
808     FIXME("(%p)->(%p, %08x)\n", iface, hBody, dwFlags);
809     return E_NOTIMPL;
810 }
811
812 static HRESULT WINAPI MimeMessage_MoveBody(
813     IMimeMessage *iface,
814     HBODY hBody,
815     BODYLOCATION location)
816 {
817     FIXME("(%p)->(%d)\n", iface, location);
818     return E_NOTIMPL;
819 }
820
821 static HRESULT WINAPI MimeMessage_CountBodies(
822     IMimeMessage *iface,
823     HBODY hParent,
824     boolean fRecurse,
825     ULONG *pcBodies)
826 {
827     FIXME("(%p)->(%p, %s, %p)\n", iface, hParent, fRecurse ? "TRUE" : "FALSE", pcBodies);
828     return E_NOTIMPL;
829 }
830
831 static HRESULT WINAPI MimeMessage_FindFirst(
832     IMimeMessage *iface,
833     LPFINDBODY pFindBody,
834     LPHBODY phBody)
835 {
836     FIXME("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
837     return E_NOTIMPL;
838 }
839
840 static HRESULT WINAPI MimeMessage_FindNext(
841     IMimeMessage *iface,
842     LPFINDBODY pFindBody,
843     LPHBODY phBody)
844 {
845     FIXME("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
846     return E_NOTIMPL;
847 }
848
849 static HRESULT WINAPI MimeMessage_ResolveURL(
850     IMimeMessage *iface,
851     HBODY hRelated,
852     LPCSTR pszBase,
853     LPCSTR pszURL,
854     DWORD dwFlags,
855     LPHBODY phBody)
856 {
857     FIXME("(%p)->(%p, %s, %s, 0x%x, %p)\n", iface, hRelated, pszBase, pszURL, dwFlags, phBody);
858     return E_NOTIMPL;
859 }
860
861 static HRESULT WINAPI MimeMessage_ToMultipart(
862     IMimeMessage *iface,
863     HBODY hBody,
864     LPCSTR pszSubType,
865     LPHBODY phMultipart)
866 {
867     FIXME("(%p)->(%p, %s, %p)\n", iface, hBody, pszSubType, phMultipart);
868     return E_NOTIMPL;
869 }
870
871 static HRESULT WINAPI MimeMessage_GetBodyOffsets(
872     IMimeMessage *iface,
873     HBODY hBody,
874     LPBODYOFFSETS pOffsets)
875 {
876     FIXME("(%p)->(%p, %p)\n", iface, hBody, pOffsets);
877     return E_NOTIMPL;
878 }
879
880 static HRESULT WINAPI MimeMessage_GetCharset(
881     IMimeMessage *iface,
882     LPHCHARSET phCharset)
883 {
884     FIXME("(%p)->(%p)\n", iface, phCharset);
885     return E_NOTIMPL;
886 }
887
888 static HRESULT WINAPI MimeMessage_SetCharset(
889     IMimeMessage *iface,
890     HCHARSET hCharset,
891     CSETAPPLYTYPE applytype)
892 {
893     FIXME("(%p)->(%p, %d)\n", iface, hCharset, applytype);
894     return E_NOTIMPL;
895 }
896
897 static HRESULT WINAPI MimeMessage_IsBodyType(
898     IMimeMessage *iface,
899     HBODY hBody,
900     IMSGBODYTYPE bodytype)
901 {
902     FIXME("(%p)->(%p, %d)\n", iface, hBody, bodytype);
903     return E_NOTIMPL;
904 }
905
906 static HRESULT WINAPI MimeMessage_IsContentType(
907     IMimeMessage *iface,
908     HBODY hBody,
909     LPCSTR pszPriType,
910     LPCSTR pszSubType)
911 {
912     FIXME("(%p)->(%p, %s, %s)\n", iface, hBody, pszPriType, pszSubType);
913     return E_NOTIMPL;
914 }
915
916 static HRESULT WINAPI MimeMessage_QueryBodyProp(
917     IMimeMessage *iface,
918     HBODY hBody,
919     LPCSTR pszName,
920     LPCSTR pszCriteria,
921     boolean fSubString,
922     boolean fCaseSensitive)
923 {
924     FIXME("(%p)->(%p, %s, %s, %s, %s)\n", iface, hBody, pszName, pszCriteria, fSubString ? "TRUE" : "FALSE", fCaseSensitive ? "TRUE" : "FALSE");
925     return E_NOTIMPL;
926 }
927
928 static HRESULT WINAPI MimeMessage_GetBodyProp(
929     IMimeMessage *iface,
930     HBODY hBody,
931     LPCSTR pszName,
932     DWORD dwFlags,
933     LPPROPVARIANT pValue)
934 {
935     FIXME("(%p)->(%p, %s, 0x%x, %p)\n", iface, hBody, pszName, dwFlags, pValue);
936     return E_NOTIMPL;
937 }
938
939 static HRESULT WINAPI MimeMessage_SetBodyProp(
940     IMimeMessage *iface,
941     HBODY hBody,
942     LPCSTR pszName,
943     DWORD dwFlags,
944     LPCPROPVARIANT pValue)
945 {
946     FIXME("(%p)->(%p, %s, 0x%x, %p)\n", iface, hBody, pszName, dwFlags, pValue);
947     return E_NOTIMPL;
948 }
949
950 static HRESULT WINAPI MimeMessage_DeleteBodyProp(
951     IMimeMessage *iface,
952     HBODY hBody,
953     LPCSTR pszName)
954 {
955     FIXME("(%p)->(%p, %s)\n", iface, hBody, pszName);
956     return E_NOTIMPL;
957 }
958
959 static HRESULT WINAPI MimeMessage_SetOption(
960     IMimeMessage *iface,
961     const TYPEDID oid,
962     LPCPROPVARIANT pValue)
963 {
964     FIXME("(%p)->(%d, %p)\n", iface, oid, pValue);
965     return E_NOTIMPL;
966 }
967
968 static HRESULT WINAPI MimeMessage_GetOption(
969     IMimeMessage *iface,
970     const TYPEDID oid,
971     LPPROPVARIANT pValue)
972 {
973     FIXME("(%p)->(%d, %p)\n", iface, oid, pValue);
974     return E_NOTIMPL;
975 }
976
977 /*** IMimeMessage methods ***/
978 static HRESULT WINAPI MimeMessage_CreateWebPage(
979     IMimeMessage *iface,
980     IStream *pRootStm,
981     LPWEBPAGEOPTIONS pOptions,
982     IMimeMessageCallback *pCallback,
983     IMoniker **ppMoniker)
984 {
985     FIXME("(%p)->(%p, %p, %p, %p)\n", iface, pRootStm, pOptions, pCallback, ppMoniker);
986     *ppMoniker = NULL;
987     return E_NOTIMPL;
988 }
989
990 static HRESULT WINAPI MimeMessage_GetProp(
991     IMimeMessage *iface,
992     LPCSTR pszName,
993     DWORD dwFlags,
994     LPPROPVARIANT pValue)
995 {
996     FIXME("(%p)->(%s, 0x%x, %p)\n", iface, pszName, dwFlags, pValue);
997     return E_NOTIMPL;
998 }
999
1000 static HRESULT WINAPI MimeMessage_SetProp(
1001     IMimeMessage *iface,
1002     LPCSTR pszName,
1003     DWORD dwFlags,
1004     LPCPROPVARIANT pValue)
1005 {
1006     FIXME("(%p)->(%s, 0x%x, %p)\n", iface, pszName, dwFlags, pValue);
1007     return E_NOTIMPL;
1008 }
1009
1010 static HRESULT WINAPI MimeMessage_DeleteProp(
1011     IMimeMessage *iface,
1012     LPCSTR pszName)
1013 {
1014     FIXME("(%p)->(%s)\n", iface, pszName);
1015     return E_NOTIMPL;
1016 }
1017
1018 static HRESULT WINAPI MimeMessage_QueryProp(
1019     IMimeMessage *iface,
1020     LPCSTR pszName,
1021     LPCSTR pszCriteria,
1022     boolean fSubString,
1023     boolean fCaseSensitive)
1024 {
1025     FIXME("(%p)->(%s, %s, %s, %s)\n", iface, pszName, pszCriteria, fSubString ? "TRUE" : "FALSE", fCaseSensitive ? "TRUE" : "FALSE");
1026     return E_NOTIMPL;
1027 }
1028
1029 static HRESULT WINAPI MimeMessage_GetTextBody(
1030     IMimeMessage *iface,
1031     DWORD dwTxtType,
1032     ENCODINGTYPE ietEncoding,
1033     IStream **pStream,
1034     LPHBODY phBody)
1035 {
1036     FIXME("(%p)->(%d, %d, %p, %p)\n", iface, dwTxtType, ietEncoding, pStream, phBody);
1037     return E_NOTIMPL;
1038 }
1039
1040 static HRESULT WINAPI MimeMessage_SetTextBody(
1041     IMimeMessage *iface,
1042     DWORD dwTxtType,
1043     ENCODINGTYPE ietEncoding,
1044     HBODY hAlternative,
1045     IStream *pStream,
1046     LPHBODY phBody)
1047 {
1048     FIXME("(%p)->(%d, %d, %p, %p, %p)\n", iface, dwTxtType, ietEncoding, hAlternative, pStream, phBody);
1049     return E_NOTIMPL;
1050 }
1051
1052 static HRESULT WINAPI MimeMessage_AttachObject(
1053     IMimeMessage *iface,
1054     REFIID riid,
1055     void *pvObject,
1056     LPHBODY phBody)
1057 {
1058     FIXME("(%p)->(%s, %p, %p)\n", iface, debugstr_guid(riid), pvObject, phBody);
1059     return E_NOTIMPL;
1060 }
1061
1062 static HRESULT WINAPI MimeMessage_AttachFile(
1063     IMimeMessage *iface,
1064     LPCSTR pszFilePath,
1065     IStream *pstmFile,
1066     LPHBODY phBody)
1067 {
1068     FIXME("(%p)->(%s, %p, %p)\n", iface, pszFilePath, pstmFile, phBody);
1069     return E_NOTIMPL;
1070 }
1071
1072 static HRESULT WINAPI MimeMessage_AttachURL(
1073     IMimeMessage *iface,
1074     LPCSTR pszBase,
1075     LPCSTR pszURL,
1076     DWORD dwFlags,
1077     IStream *pstmURL,
1078     LPSTR *ppszCIDURL,
1079     LPHBODY phBody)
1080 {
1081     FIXME("(%p)->(%s, %s, 0x%x, %p, %p, %p)\n", iface, pszBase, pszURL, dwFlags, pstmURL, ppszCIDURL, phBody);
1082     return E_NOTIMPL;
1083 }
1084
1085 static HRESULT WINAPI MimeMessage_GetAttachments(
1086     IMimeMessage *iface,
1087     ULONG *pcAttach,
1088     LPHBODY *pprghAttach)
1089 {
1090     FIXME("(%p)->(%p, %p)\n", iface, pcAttach, pprghAttach);
1091     return E_NOTIMPL;
1092 }
1093
1094 static HRESULT WINAPI MimeMessage_GetAddressTable(
1095     IMimeMessage *iface,
1096     IMimeAddressTable **ppTable)
1097 {
1098     FIXME("(%p)->(%p)\n", iface, ppTable);
1099     return E_NOTIMPL;
1100 }
1101
1102 static HRESULT WINAPI MimeMessage_GetSender(
1103     IMimeMessage *iface,
1104     LPADDRESSPROPS pAddress)
1105 {
1106     FIXME("(%p)->(%p)\n", iface, pAddress);
1107     return E_NOTIMPL;
1108 }
1109
1110 static HRESULT WINAPI MimeMessage_GetAddressTypes(
1111     IMimeMessage *iface,
1112     DWORD dwAdrTypes,
1113     DWORD dwProps,
1114     LPADDRESSLIST pList)
1115 {
1116     FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, dwProps, pList);
1117     return E_NOTIMPL;
1118 }
1119
1120 static HRESULT WINAPI MimeMessage_GetAddressFormat(
1121     IMimeMessage *iface,
1122     DWORD dwAdrTypes,
1123     ADDRESSFORMAT format,
1124     LPSTR *ppszFormat)
1125 {
1126     FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, format, ppszFormat);
1127     return E_NOTIMPL;
1128 }
1129
1130 static HRESULT WINAPI MimeMessage_EnumAddressTypes(
1131     IMimeMessage *iface,
1132     DWORD dwAdrTypes,
1133     DWORD dwProps,
1134     IMimeEnumAddressTypes **ppEnum)
1135 {
1136     FIXME("(%p)->(%d, %d, %p)\n", iface, dwAdrTypes, dwProps, ppEnum);
1137     return E_NOTIMPL;
1138 }
1139
1140 static HRESULT WINAPI MimeMessage_SplitMessage(
1141     IMimeMessage *iface,
1142     ULONG cbMaxPart,
1143     IMimeMessageParts **ppParts)
1144 {
1145     FIXME("(%p)->(%d, %p)\n", iface, cbMaxPart, ppParts);
1146     return E_NOTIMPL;
1147 }
1148
1149 static HRESULT WINAPI MimeMessage_GetRootMoniker(
1150     IMimeMessage *iface,
1151     IMoniker **ppMoniker)
1152 {
1153     FIXME("(%p)->(%p)\n", iface, ppMoniker);
1154     return E_NOTIMPL;
1155 }
1156
1157 static const IMimeMessageVtbl MimeMessageVtbl =
1158 {
1159     MimeMessage_QueryInterface,
1160     MimeMessage_AddRef,
1161     MimeMessage_Release,
1162     MimeMessage_GetClassID,
1163     MimeMessage_IsDirty,
1164     MimeMessage_Load,
1165     MimeMessage_Save,
1166     MimeMessage_GetSizeMax,
1167     MimeMessage_InitNew,
1168     MimeMessage_GetMessageSource,
1169     MimeMessage_GetMessageSize,
1170     MimeMessage_LoadOffsetTable,
1171     MimeMessage_SaveOffsetTable,
1172     MimeMessage_GetFlags,
1173     MimeMessage_Commit,
1174     MimeMessage_HandsOffStorage,
1175     MimeMessage_BindToObject,
1176     MimeMessage_SaveBody,
1177     MimeMessage_InsertBody,
1178     MimeMessage_GetBody,
1179     MimeMessage_DeleteBody,
1180     MimeMessage_MoveBody,
1181     MimeMessage_CountBodies,
1182     MimeMessage_FindFirst,
1183     MimeMessage_FindNext,
1184     MimeMessage_ResolveURL,
1185     MimeMessage_ToMultipart,
1186     MimeMessage_GetBodyOffsets,
1187     MimeMessage_GetCharset,
1188     MimeMessage_SetCharset,
1189     MimeMessage_IsBodyType,
1190     MimeMessage_IsContentType,
1191     MimeMessage_QueryBodyProp,
1192     MimeMessage_GetBodyProp,
1193     MimeMessage_SetBodyProp,
1194     MimeMessage_DeleteBodyProp,
1195     MimeMessage_SetOption,
1196     MimeMessage_GetOption,
1197     MimeMessage_CreateWebPage,
1198     MimeMessage_GetProp,
1199     MimeMessage_SetProp,
1200     MimeMessage_DeleteProp,
1201     MimeMessage_QueryProp,
1202     MimeMessage_GetTextBody,
1203     MimeMessage_SetTextBody,
1204     MimeMessage_AttachObject,
1205     MimeMessage_AttachFile,
1206     MimeMessage_AttachURL,
1207     MimeMessage_GetAttachments,
1208     MimeMessage_GetAddressTable,
1209     MimeMessage_GetSender,
1210     MimeMessage_GetAddressTypes,
1211     MimeMessage_GetAddressFormat,
1212     MimeMessage_EnumAddressTypes,
1213     MimeMessage_SplitMessage,
1214     MimeMessage_GetRootMoniker,
1215 };
1216
1217 /***********************************************************************
1218  *              MimeOleCreateMessage (INETCOMM.@)
1219  */
1220 HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessage)
1221 {
1222     MimeMessage *This;
1223
1224     TRACE("(%p, %p)\n", pUnkOuter, ppMessage);
1225
1226     if (pUnkOuter)
1227     {
1228         FIXME("outer unknown not supported yet\n");
1229         return E_NOTIMPL;
1230     }
1231
1232     *ppMessage = NULL;
1233
1234     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1235     if (!This) return E_OUTOFMEMORY;
1236
1237     This->lpVtbl = &MimeMessageVtbl;
1238     This->refs = 1;
1239
1240     *ppMessage = (IMimeMessage *)&This->lpVtbl;
1241     return S_OK;
1242 }
1243
1244 /***********************************************************************
1245  *              MimeOleSetCompatMode (INETCOMM.@)
1246  */
1247 HRESULT WINAPI MimeOleSetCompatMode(DWORD dwMode)
1248 {
1249     FIXME("(0x%x)\n", dwMode);
1250     return S_OK;
1251 }
1252
1253 /***********************************************************************
1254  *              MimeOleCreateVirtualStream (INETCOMM.@)
1255  */
1256 HRESULT WINAPI MimeOleCreateVirtualStream(IStream **ppStream)
1257 {
1258     HRESULT hr;
1259     FIXME("(%p)\n", ppStream);
1260
1261     hr = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
1262     return hr;
1263 }
1264
1265 typedef struct MimeSecurity
1266 {
1267     const IMimeSecurityVtbl *lpVtbl;
1268
1269     LONG refs;
1270 } MimeSecurity;
1271
1272 static HRESULT WINAPI MimeSecurity_QueryInterface(
1273         IMimeSecurity* iface,
1274         REFIID riid,
1275         void** obj)
1276 {
1277     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), obj);
1278
1279     if (IsEqualIID(riid, &IID_IUnknown) ||
1280         IsEqualIID(riid, &IID_IMimeSecurity))
1281     {
1282         *obj = iface;
1283         IUnknown_AddRef(iface);
1284         return S_OK;
1285     }
1286
1287     FIXME("no interface for %s\n", debugstr_guid(riid));
1288     *obj = NULL;
1289     return E_NOINTERFACE;
1290 }
1291
1292 static ULONG WINAPI MimeSecurity_AddRef(
1293         IMimeSecurity* iface)
1294 {
1295     MimeSecurity *This = (MimeSecurity *)iface;
1296     TRACE("(%p)->()\n", iface);
1297     return InterlockedIncrement(&This->refs);
1298 }
1299
1300 static ULONG WINAPI MimeSecurity_Release(
1301         IMimeSecurity* iface)
1302 {
1303     MimeSecurity *This = (MimeSecurity *)iface;
1304     ULONG refs;
1305
1306     TRACE("(%p)->()\n", iface);
1307
1308     refs = InterlockedDecrement(&This->refs);
1309     if (!refs)
1310     {
1311         HeapFree(GetProcessHeap(), 0, This);
1312     }
1313
1314     return refs;
1315 }
1316
1317 static HRESULT WINAPI MimeSecurity_InitNew(
1318         IMimeSecurity* iface)
1319 {
1320     FIXME("(%p)->(): stub\n", iface);
1321     return S_OK;
1322 }
1323
1324 static HRESULT WINAPI MimeSecurity_CheckInit(
1325         IMimeSecurity* iface)
1326 {
1327     FIXME("(%p)->(): stub\n", iface);
1328     return E_NOTIMPL;
1329 }
1330
1331 static HRESULT WINAPI MimeSecurity_EncodeMessage(
1332         IMimeSecurity* iface,
1333         IMimeMessageTree* pTree,
1334         DWORD dwFlags)
1335 {
1336     FIXME("(%p)->(%p, %08x): stub\n", iface, pTree, dwFlags);
1337     return E_NOTIMPL;
1338 }
1339
1340 static HRESULT WINAPI MimeSecurity_EncodeBody(
1341         IMimeSecurity* iface,
1342         IMimeMessageTree* pTree,
1343         HBODY hEncodeRoot,
1344         DWORD dwFlags)
1345 {
1346     FIXME("(%p)->(%p, %p, %08x): stub\n", iface, pTree, hEncodeRoot, dwFlags);
1347     return E_NOTIMPL;
1348 }
1349
1350 static HRESULT WINAPI MimeSecurity_DecodeMessage(
1351         IMimeSecurity* iface,
1352         IMimeMessageTree* pTree,
1353         DWORD dwFlags)
1354 {
1355     FIXME("(%p)->(%p, %08x): stub\n", iface, pTree, dwFlags);
1356     return E_NOTIMPL;
1357 }
1358
1359 static HRESULT WINAPI MimeSecurity_DecodeBody(
1360         IMimeSecurity* iface,
1361         IMimeMessageTree* pTree,
1362         HBODY hDecodeRoot,
1363         DWORD dwFlags)
1364 {
1365     FIXME("(%p)->(%p, %p, %08x): stub\n", iface, pTree, hDecodeRoot, dwFlags);
1366     return E_NOTIMPL;
1367 }
1368
1369 static HRESULT WINAPI MimeSecurity_EnumCertificates(
1370         IMimeSecurity* iface,
1371         HCAPICERTSTORE hc,
1372         DWORD dwUsage,
1373         PCX509CERT pPrev,
1374         PCX509CERT* ppCert)
1375 {
1376     FIXME("(%p)->(%p, %08x, %p, %p): stub\n", iface, hc, dwUsage, pPrev, ppCert);
1377     return E_NOTIMPL;
1378 }
1379
1380 static HRESULT WINAPI MimeSecurity_GetCertificateName(
1381         IMimeSecurity* iface,
1382         const PCX509CERT pX509Cert,
1383         const CERTNAMETYPE cn,
1384         LPSTR* ppszName)
1385 {
1386     FIXME("(%p)->(%p, %08x, %p): stub\n", iface, pX509Cert, cn, ppszName);
1387     return E_NOTIMPL;
1388 }
1389
1390 static HRESULT WINAPI MimeSecurity_GetMessageType(
1391         IMimeSecurity* iface,
1392         const HWND hwndParent,
1393         IMimeBody* pBody,
1394         DWORD* pdwSecType)
1395 {
1396     FIXME("(%p)->(%p, %p, %p): stub\n", iface, hwndParent, pBody, pdwSecType);
1397     return E_NOTIMPL;
1398 }
1399
1400 static HRESULT WINAPI MimeSecurity_GetCertData(
1401         IMimeSecurity* iface,
1402         const PCX509CERT pX509Cert,
1403         const CERTDATAID dataid,
1404         LPPROPVARIANT pValue)
1405 {
1406     FIXME("(%p)->(%p, %x, %p): stub\n", iface, pX509Cert, dataid, pValue);
1407     return E_NOTIMPL;
1408 }
1409
1410
1411 static const IMimeSecurityVtbl MimeSecurityVtbl =
1412 {
1413     MimeSecurity_QueryInterface,
1414     MimeSecurity_AddRef,
1415     MimeSecurity_Release,
1416     MimeSecurity_InitNew,
1417     MimeSecurity_CheckInit,
1418     MimeSecurity_EncodeMessage,
1419     MimeSecurity_EncodeBody,
1420     MimeSecurity_DecodeMessage,
1421     MimeSecurity_DecodeBody,
1422     MimeSecurity_EnumCertificates,
1423     MimeSecurity_GetCertificateName,
1424     MimeSecurity_GetMessageType,
1425     MimeSecurity_GetCertData
1426 };
1427
1428 /***********************************************************************
1429  *              MimeOleCreateSecurity (INETCOMM.@)
1430  */
1431 HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity)
1432 {
1433     MimeSecurity *This;
1434
1435     TRACE("(%p)\n", ppSecurity);
1436
1437     *ppSecurity = NULL;
1438
1439     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1440     if (!This) return E_OUTOFMEMORY;
1441
1442     This->lpVtbl = &MimeSecurityVtbl;
1443     This->refs = 1;
1444
1445     *ppSecurity = (IMimeSecurity *)&This->lpVtbl;
1446     return S_OK;
1447 }