ReactOS  0.4.13-dev-551-gf37fb1f
mimeole.c
Go to the documentation of this file.
1 /*
2  * MimeOle tests
3  *
4  * Copyright 2007 Huw Davies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #define COBJMACROS
22 #define NONAMELESSUNION
23 #ifdef __REACTOS__
24 #define CONST_VTABLE
25 #endif
26 
27 #include "initguid.h"
28 #include "windows.h"
29 #include "ole2.h"
30 #include "ocidl.h"
31 
32 #include "mimeole.h"
33 #include "wininet.h"
34 
35 #include <stdio.h>
36 
37 #include "wine/test.h"
38 
39 #define DEFINE_EXPECT(func) \
40  static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
41 
42 #define SET_EXPECT(func) \
43  expect_ ## func = TRUE
44 
45 #define CHECK_EXPECT(func) \
46  do { \
47  ok(expect_ ##func, "unexpected call " #func "\n"); \
48  expect_ ## func = FALSE; \
49  called_ ## func = TRUE; \
50  }while(0)
51 
52 #define CHECK_EXPECT2(func) \
53  do { \
54  ok(expect_ ##func, "unexpected call " #func "\n"); \
55  called_ ## func = TRUE; \
56  }while(0)
57 
58 #define CHECK_CALLED(func) \
59  do { \
60  ok(called_ ## func, "expected " #func "\n"); \
61  expect_ ## func = called_ ## func = FALSE; \
62  }while(0)
63 
67 DEFINE_EXPECT(Stream_Seek_END);
68 DEFINE_EXPECT(GetBindInfo);
69 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
70 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
71 DEFINE_EXPECT(ReportData);
72 DEFINE_EXPECT(ReportResult);
73 
74 static const char msg1[] =
75  "MIME-Version: 1.0\r\n"
76  "Content-Type: multipart/mixed;\r\n"
77  " boundary=\"------------1.5.0.6\";\r\n"
78  " stuff=\"du;nno\";\r\n"
79  " morestuff=\"so\\\\me\\\"thing\\\"\"\r\n"
80  "foo: bar\r\n"
81  "From: Huw Davies <huw@codeweavers.com>\r\n"
82  "From: Me <xxx@codeweavers.com>\r\n"
83  "To: wine-patches <wine-patches@winehq.org>\r\n"
84  "Cc: Huw Davies <huw@codeweavers.com>,\r\n"
85  " \"Fred Bloggs\" <fred@bloggs.com>\r\n"
86  "foo: baz\r\n"
87  "bar: fum\r\n"
88  "\r\n"
89  "This is a multi-part message in MIME format.\r\n"
90  "--------------1.5.0.6\r\n"
91  "Content-Type: text/plain; format=fixed; charset=UTF-8\r\n"
92  "Content-Transfer-Encoding: 8bit\r\n"
93  "\r\n"
94  "Stuff\r\n"
95  "--------------1.5.0.6\r\n"
96  "Content-Type: text/plain; charset=\"us-ascii\"\r\n"
97  "Content-Transfer-Encoding: 7bit\r\n"
98  "\r\n"
99  "More stuff\r\n"
100  "--------------1.5.0.6--\r\n";
101 
102 static const char mhtml_page1[] =
103  "MIME-Version: 1.0\r\n"
104  "Content-Type: multipart/related; type:=\"text/html\"; boundary=\"----=_NextPart_000_00\"\r\n"
105  "\r\n"
106  "------=_NextPart_000_00\r\n"
107  "Content-Type: text/html; charset=\"Windows-1252\"\r\n"
108  "Content-Transfer-Encoding: quoted-printable\r\n"
109  "\r\n"
110  "<HTML></HTML>\r\n"
111  "------=_NextPart_000_00\r\n"
112  "Content-Type: Image/Jpeg\r\n"
113  "Content-Transfer-Encoding: base64\r\n"
114  "Content-Location: http://winehq.org/mhtmltest.html\r\n"
115  "\r\n\t\t\t\tVGVzdA==\r\n\r\n"
116  "------=_NextPart_000_00--";
117 
118 static WCHAR *a2w(const char *str)
119 {
120  WCHAR *ret;
121  int len;
122 
123  if(!str)
124  return NULL;
125 
126  len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
127  ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
128  MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
129  return ret;
130 }
131 
132 static int strcmp_wa(const WCHAR *strw, const char *stra)
133 {
134  WCHAR buf[512];
135  MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
136  return lstrcmpW(strw, buf);
137 }
138 
139 static void test_CreateVirtualStream(void)
140 {
141  HRESULT hr;
142  IStream *pstm;
143 
145  ok(hr == S_OK, "ret %08x\n", hr);
146 
147  IStream_Release(pstm);
148 }
149 
150 static void test_CreateSecurity(void)
151 {
152  HRESULT hr;
153  IMimeSecurity *sec;
154 
155  hr = MimeOleCreateSecurity(&sec);
156  ok(hr == S_OK, "ret %08x\n", hr);
157 
158  IMimeSecurity_Release(sec);
159 }
160 
162 {
164  IStream *stream;
165  HRESULT hr;
166 
168  ok(hr == S_OK, "ret %08x\n", hr);
169 
170  hr = IStream_Write(stream, data, strlen(data), NULL);
171  ok(hr == S_OK, "Write failed: %08x\n", hr);
172 
173  off.QuadPart = 0;
174  hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL);
175  ok(hr == S_OK, "Seek failed: %08x\n", hr);
176 
177  return stream;
178 }
179 
180 #define test_current_encoding(a,b) _test_current_encoding(__LINE__,a,b)
181 static void _test_current_encoding(unsigned line, IMimeBody *mime_body, ENCODINGTYPE encoding)
182 {
183  ENCODINGTYPE current_encoding;
184  HRESULT hres;
185 
186  hres = IMimeBody_GetCurrentEncoding(mime_body, &current_encoding);
187  ok_(__FILE__,line)(hres == S_OK, "GetCurrentEncoding failed: %08x\n", hres);
188  ok_(__FILE__,line)(current_encoding == encoding, "encoding = %d, expected %d\n", current_encoding, encoding);
189 }
190 
191 static void test_CreateBody(void)
192 {
193  HRESULT hr;
194  IMimeBody *body;
195  HBODY handle = (void *)0xdeadbeef;
196  IStream *in;
199  ULONG count, found_param, i;
200  MIMEPARAMINFO *param_info;
201  IMimeAllocator *alloc;
202  BODYOFFSETS offsets;
203  CLSID clsid;
204 
205  hr = CoCreateInstance(&CLSID_IMimeBody, NULL, CLSCTX_INPROC_SERVER, &IID_IMimeBody, (void**)&body);
206  ok(hr == S_OK, "ret %08x\n", hr);
207 
208  hr = IMimeBody_GetClassID(body, NULL);
209  ok(hr == E_INVALIDARG, "ret %08x\n", hr);
210 
211  hr = IMimeBody_GetClassID(body, &clsid);
212  ok(hr == S_OK, "ret %08x\n", hr);
213  ok(IsEqualGUID(&clsid, &IID_IMimeBody), "got %s\n", wine_dbgstr_guid(&clsid));
214 
215  hr = IMimeBody_GetHandle(body, &handle);
216  ok(hr == MIME_E_NO_DATA, "ret %08x\n", hr);
217  ok(handle == NULL, "handle %p\n", handle);
218 
220 
221  /* Need to call InitNew before Load otherwise Load crashes with native inetcomm */
222  hr = IMimeBody_InitNew(body);
223  ok(hr == S_OK, "ret %08x\n", hr);
224 
226 
227  hr = IMimeBody_Load(body, in);
228  ok(hr == S_OK, "ret %08x\n", hr);
229  off.QuadPart = 0;
230  IStream_Seek(in, off, STREAM_SEEK_CUR, &pos);
231  ok(pos.u.LowPart == 359, "pos %u\n", pos.u.LowPart);
232 
233  hr = IMimeBody_IsContentType(body, "multipart", "mixed");
234  ok(hr == S_OK, "ret %08x\n", hr);
235  hr = IMimeBody_IsContentType(body, "text", "plain");
236  ok(hr == S_FALSE, "ret %08x\n", hr);
237  hr = IMimeBody_IsContentType(body, NULL, "mixed");
238  ok(hr == S_OK, "ret %08x\n", hr);
239  hr = IMimeBody_IsType(body, IBT_EMPTY);
240  ok(hr == S_OK, "got %08x\n", hr);
241 
242  hr = IMimeBody_SetData(body, IET_8BIT, "text", "plain", &IID_IStream, in);
243  ok(hr == S_OK, "ret %08x\n", hr);
244  hr = IMimeBody_IsContentType(body, "text", "plain");
245  todo_wine
246  ok(hr == S_OK, "ret %08x\n", hr);
248 
249  memset(&offsets, 0xcc, sizeof(offsets));
250  hr = IMimeBody_GetOffsets(body, &offsets);
251  ok(hr == MIME_E_NO_DATA, "ret %08x\n", hr);
252  ok(offsets.cbBoundaryStart == 0, "got %d\n", offsets.cbBoundaryStart);
253  ok(offsets.cbHeaderStart == 0, "got %d\n", offsets.cbHeaderStart);
254  ok(offsets.cbBodyStart == 0, "got %d\n", offsets.cbBodyStart);
255  ok(offsets.cbBodyEnd == 0, "got %d\n", offsets.cbBodyEnd);
256 
257  hr = IMimeBody_IsType(body, IBT_EMPTY);
258  ok(hr == S_FALSE, "got %08x\n", hr);
259 
261  ok(hr == S_OK, "ret %08x\n", hr);
262 
263  hr = IMimeBody_GetParameters(body, "nothere", &count, &param_info);
264  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
265  ok(count == 0, "got %d\n", count);
266  ok(!param_info, "got %p\n", param_info);
267 
268  hr = IMimeBody_GetParameters(body, "bar", &count, &param_info);
269  ok(hr == S_OK, "ret %08x\n", hr);
270  ok(count == 0, "got %d\n", count);
271  ok(!param_info, "got %p\n", param_info);
272 
273  hr = IMimeBody_GetParameters(body, "Content-Type", &count, &param_info);
274  ok(hr == S_OK, "ret %08x\n", hr);
275  todo_wine /* native adds a charset parameter */
276  ok(count == 4, "got %d\n", count);
277  ok(param_info != NULL, "got %p\n", param_info);
278 
279  found_param = 0;
280  for(i = 0; i < count; i++)
281  {
282  if(!strcmp(param_info[i].pszName, "morestuff"))
283  {
284  found_param++;
285  ok(!strcmp(param_info[i].pszData, "so\\me\"thing\""),
286  "got %s\n", param_info[i].pszData);
287  }
288  else if(!strcmp(param_info[i].pszName, "stuff"))
289  {
290  found_param++;
291  ok(!strcmp(param_info[i].pszData, "du;nno"),
292  "got %s\n", param_info[i].pszData);
293  }
294  }
295  ok(found_param == 2, "matched %d params\n", found_param);
296 
297  hr = IMimeAllocator_FreeParamInfoArray(alloc, count, param_info, TRUE);
298  ok(hr == S_OK, "ret %08x\n", hr);
299  IMimeAllocator_Release(alloc);
300 
301  IStream_Release(in);
302  IMimeBody_Release(body);
303 }
304 
305 typedef struct {
308  unsigned pos;
309 } TestStream;
310 
311 static inline TestStream *impl_from_IStream(IStream *iface)
312 {
313  return CONTAINING_RECORD(iface, TestStream, IStream_iface);
314 }
315 
317 {
318  if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ISequentialStream, riid) || IsEqualGUID(&IID_IStream, riid)) {
319  *ppv = iface;
320  return S_OK;
321  }
322 
323  ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
324  *ppv = NULL;
325  return E_NOINTERFACE;
326 }
327 
329 {
331  return InterlockedIncrement(&This->ref);
332 }
333 
335 {
338 
339  if (!ref)
341 
342  return ref;
343 }
344 
345 static HRESULT WINAPI Stream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
346 {
348  BYTE *output = pv;
349  unsigned i;
350 
352 
353  for(i = 0; i < cb; i++)
354  output[i] = '0' + This->pos++;
355  *pcbRead = i;
356  return S_OK;
357 }
358 
359 static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
360 {
361  ok(0, "unexpected call\n");
362  return E_NOTIMPL;
363 }
364 
366 
367 static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin,
368  ULARGE_INTEGER *plibNewPosition)
369 {
371 
372  if(dwOrigin == STREAM_SEEK_END) {
373  CHECK_EXPECT(Stream_Seek_END);
374  ok(dlibMove.QuadPart == expect_seek_pos, "unexpected seek pos %u\n", dlibMove.u.LowPart);
375  if(plibNewPosition)
376  plibNewPosition->QuadPart = 10;
377  return S_OK;
378  }
379 
381 
382  ok(dlibMove.QuadPart == expect_seek_pos, "unexpected seek pos %u\n", dlibMove.u.LowPart);
383  ok(dwOrigin == STREAM_SEEK_SET, "dwOrigin = %d\n", dwOrigin);
384  This->pos = dlibMove.QuadPart;
385  if(plibNewPosition)
386  plibNewPosition->QuadPart = This->pos;
387  return S_OK;
388 }
389 
391 {
392  ok(0, "unexpected call\n");
393  return E_NOTIMPL;
394 }
395 
397  ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
398 {
399  ok(0, "unexpected call\n");
400  return E_NOTIMPL;
401 }
402 
403 static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
404 {
405  ok(0, "unexpected call\n");
406  return E_NOTIMPL;
407 }
408 
410 {
411  ok(0, "unexpected call\n");
412  return E_NOTIMPL;
413 }
414 
416  ULARGE_INTEGER cb, DWORD dwLockType)
417 {
418  ok(0, "unexpected call\n");
419  return E_NOTIMPL;
420 }
421 
423  ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
424 {
425  ok(0, "unexpected call\n");
426  return E_NOTIMPL;
427 }
428 
429 static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg, DWORD dwStatFlag)
430 {
432  ok(dwStatFlag == STATFLAG_NONAME, "dwStatFlag = %x\n", dwStatFlag);
433  return E_NOTIMPL;
434 }
435 
436 static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
437 {
438  ok(0, "unexpected call\n");
439  return E_NOTIMPL;
440 }
441 
442 static const IStreamVtbl StreamVtbl = {
446  Stream_Read,
447  Stream_Write,
448  Stream_Seek,
455  Stream_Stat,
457 };
458 
460 {
462  stream = HeapAlloc(GetProcessHeap(), 0, sizeof(*stream));
463  stream->IStream_iface.lpVtbl = &StreamVtbl;
464  stream->ref = 1;
465  stream->pos = 0;
466  return &stream->IStream_iface;
467 }
468 
469 #define test_stream_read(a,b,c,d) _test_stream_read(__LINE__,a,b,c,d)
470 static void _test_stream_read(unsigned line, IStream *stream, HRESULT exhres, const char *exdata, unsigned read_size)
471 {
472  ULONG read = 0xdeadbeed, exread = strlen(exdata);
473  char buf[1024];
474  HRESULT hres;
475 
476  if(read_size == -1)
477  read_size = sizeof(buf)-1;
478 
479  hres = IStream_Read(stream, buf, read_size, &read);
480  ok_(__FILE__,line)(hres == exhres, "Read returned %08x, expected %08x\n", hres, exhres);
481  ok_(__FILE__,line)(read == exread, "unexpected read size %u, expected %u\n", read, exread);
482  buf[read] = 0;
483  ok_(__FILE__,line)(read == exread && !memcmp(buf, exdata, read), "unexpected data %s\n", buf);
484 }
485 
486 static void test_SetData(void)
487 {
488  IStream *stream, *stream2, *test_stream;
489  IMimeBody *body;
490  HRESULT hr;
491 
492  hr = CoCreateInstance(&CLSID_IMimeBody, NULL, CLSCTX_INPROC_SERVER, &IID_IMimeBody, (void**)&body);
493  ok(hr == S_OK, "ret %08x\n", hr);
494 
495  /* Need to call InitNew before Load otherwise Load crashes with native inetcomm */
496  hr = IMimeBody_InitNew(body);
497  ok(hr == S_OK, "ret %08x\n", hr);
498 
500  hr = IMimeBody_Load(body, stream);
501  ok(hr == S_OK, "ret %08x\n", hr);
502  IStream_Release(stream);
503 
505  hr = IMimeBody_SetData(body, IET_BINARY, "text", "plain", &IID_IStream, test_stream);
506 
507  ok(hr == S_OK, "ret %08x\n", hr);
508  hr = IMimeBody_IsContentType(body, "text", "plain");
509  todo_wine
510  ok(hr == S_OK, "ret %08x\n", hr);
511 
513 
515  SET_EXPECT(Stream_Seek_END);
516  hr = IMimeBody_GetData(body, IET_BINARY, &stream);
518  CHECK_CALLED(Stream_Seek_END);
519  ok(hr == S_OK, "GetData failed %08x\n", hr);
520  ok(stream != test_stream, "unexpected stream\n");
521 
524  test_stream_read(stream, S_OK, "012", 3);
527 
529  SET_EXPECT(Stream_Seek_END);
530  hr = IMimeBody_GetData(body, IET_BINARY, &stream2);
532  CHECK_CALLED(Stream_Seek_END);
533  ok(hr == S_OK, "GetData failed %08x\n", hr);
534  ok(stream2 != stream, "unexpected stream\n");
535 
538  test_stream_read(stream2, S_OK, "01", 2);
541 
542  expect_seek_pos = 3;
545  test_stream_read(stream, S_OK, "345", 3);
548 
549  IStream_Release(stream);
550  IStream_Release(stream2);
551  IStream_Release(test_stream);
552 
553  stream = create_stream_from_string(" \t\r\n|}~YWJj ZGV|}~mZw== \t"); /* "abcdefg" in base64 obscured by invalid chars */
554  hr = IMimeBody_SetData(body, IET_BASE64, "text", "plain", &IID_IStream, stream);
555  IStream_Release(stream);
556  ok(hr == S_OK, "SetData failed: %08x\n", hr);
557 
559 
560  hr = IMimeBody_GetData(body, IET_BINARY, &stream);
561  ok(hr == S_OK, "GetData failed %08x\n", hr);
562 
563  test_stream_read(stream, S_OK, "abc", 3);
564  test_stream_read(stream, S_OK, "defg", -1);
565 
566  IStream_Release(stream);
567 
568  hr = IMimeBody_GetData(body, IET_BASE64, &stream);
569  ok(hr == S_OK, "GetData failed %08x\n", hr);
570 
571  test_stream_read(stream, S_OK, " \t\r", 3);
572  IStream_Release(stream);
573 
574  stream = create_stream_from_string(" =3d=3D\"one\" \t=\r\ntw= o=\nx3\n=34\r\n5");
575  hr = IMimeBody_SetData(body, IET_QP, "text", "plain", &IID_IStream, stream);
576  IStream_Release(stream);
577  ok(hr == S_OK, "SetData failed: %08x\n", hr);
578 
580 
581  hr = IMimeBody_GetData(body, IET_BINARY, &stream);
582  ok(hr == S_OK, "GetData failed %08x\n", hr);
583 
584  test_stream_read(stream, S_OK, " ==\"one\" \ttw=o=3\n4\r\n5", -1);
585 
586  IStream_Release(stream);
587 
588  IMimeBody_Release(body);
589 }
590 
591 static void test_Allocator(void)
592 {
593  HRESULT hr;
594  IMimeAllocator *alloc;
595 
597  ok(hr == S_OK, "ret %08x\n", hr);
598  IMimeAllocator_Release(alloc);
599 }
600 
601 static void test_CreateMessage(void)
602 {
603  HRESULT hr;
604  IMimeMessage *msg;
605  IStream *stream;
606  LONG ref;
607  HBODY hbody, hbody2;
608  IMimeBody *body;
609  BODYOFFSETS offsets;
610  ULONG count;
611  FINDBODY find_struct;
612  HCHARSET hcs;
613  HBODY handle = NULL;
614 
615  char text[] = "text";
616  HBODY *body_list;
617  PROPVARIANT prop;
618  static const char att_pritype[] = "att:pri-content-type";
619 
621  ok(hr == S_OK, "ret %08x\n", hr);
622 
624 
625  hr = IMimeMessage_Load(msg, stream);
626  ok(hr == S_OK, "ret %08x\n", hr);
627 
628  hr = IMimeMessage_CountBodies(msg, HBODY_ROOT, TRUE, &count);
629  ok(hr == S_OK, "ret %08x\n", hr);
630  ok(count == 3, "got %d\n", count);
631 
632  hr = IMimeMessage_CountBodies(msg, HBODY_ROOT, FALSE, &count);
633  ok(hr == S_OK, "ret %08x\n", hr);
634  ok(count == 3, "got %d\n", count);
635 
636  hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
637  ok(hr == S_OK, "ret %08x\n", hr);
638  hr = IMimeBody_GetOffsets(body, &offsets);
639  ok(hr == S_OK, "ret %08x\n", hr);
640  ok(offsets.cbBoundaryStart == 0, "got %d\n", offsets.cbBoundaryStart);
641  ok(offsets.cbHeaderStart == 0, "got %d\n", offsets.cbHeaderStart);
642  ok(offsets.cbBodyStart == 359, "got %d\n", offsets.cbBodyStart);
643  ok(offsets.cbBodyEnd == 666, "got %d\n", offsets.cbBodyEnd);
644  IMimeBody_Release(body);
645 
646  hr = IMimeMessage_GetBody(msg, IBL_ROOT, NULL, &hbody);
647  ok(hr == S_OK, "ret %08x\n", hr);
648 
649  hr = IMimeBody_GetHandle(body, NULL);
650  ok(hr == E_INVALIDARG, "ret %08x\n", hr);
651 
652  hr = IMimeBody_GetHandle(body, &handle);
653  ok(hr == S_OK, "ret %08x\n", hr);
654  ok(handle != NULL, "handle %p\n", handle);
655 
656  hr = IMimeMessage_GetBody(msg, IBL_PARENT, hbody, NULL);
657  ok(hr == E_INVALIDARG, "ret %08x\n", hr);
658 
659  hbody2 = (HBODY)0xdeadbeef;
660  hr = IMimeMessage_GetBody(msg, IBL_PARENT, hbody, &hbody2);
661  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
662  ok(hbody2 == NULL, "hbody2 %p\n", hbody2);
663 
664  PropVariantInit(&prop);
665  hr = IMimeMessage_GetBodyProp(msg, hbody, att_pritype, 0, &prop);
666  ok(hr == S_OK, "ret %08x\n", hr);
667  ok(prop.vt == VT_LPSTR, "vt %08x\n", prop.vt);
668  ok(!strcasecmp(prop.u.pszVal, "multipart"), "got %s\n", prop.u.pszVal);
669  PropVariantClear(&prop);
670 
671  hr = IMimeMessage_GetBody(msg, IBL_FIRST, hbody, &hbody);
672  ok(hr == S_OK, "ret %08x\n", hr);
673  hr = IMimeMessage_BindToObject(msg, hbody, &IID_IMimeBody, (void**)&body);
674  ok(hr == S_OK, "ret %08x\n", hr);
675 
676  hr = IMimeBody_GetHandle(body, &handle);
677  ok(hr == S_OK, "ret %08x\n", hr);
678  ok(handle == hbody, "handle %p\n", handle);
679 
680  hr = IMimeBody_GetOffsets(body, &offsets);
681  ok(hr == S_OK, "ret %08x\n", hr);
682  ok(offsets.cbBoundaryStart == 405, "got %d\n", offsets.cbBoundaryStart);
683  ok(offsets.cbHeaderStart == 428, "got %d\n", offsets.cbHeaderStart);
684  ok(offsets.cbBodyStart == 518, "got %d\n", offsets.cbBodyStart);
685  ok(offsets.cbBodyEnd == 523, "got %d\n", offsets.cbBodyEnd);
686 
687  hr = IMimeBody_GetCharset(body, &hcs);
688  ok(hr == S_OK, "ret %08x\n", hr);
689  todo_wine
690  {
691  ok(hcs != NULL, "Expected non-NULL charset\n");
692  }
693 
694  IMimeBody_Release(body);
695 
696  hr = IMimeMessage_GetBody(msg, IBL_NEXT, hbody, &hbody);
697  ok(hr == S_OK, "ret %08x\n", hr);
698  hr = IMimeMessage_BindToObject(msg, hbody, &IID_IMimeBody, (void**)&body);
699  ok(hr == S_OK, "ret %08x\n", hr);
700 
701  hr = IMimeBody_GetHandle(body, &handle);
702  ok(hr == S_OK, "ret %08x\n", hr);
703  ok(handle == hbody, "handle %p\n", handle);
704 
705  hr = IMimeBody_GetOffsets(body, &offsets);
706  ok(hr == S_OK, "ret %08x\n", hr);
707  ok(offsets.cbBoundaryStart == 525, "got %d\n", offsets.cbBoundaryStart);
708  ok(offsets.cbHeaderStart == 548, "got %d\n", offsets.cbHeaderStart);
709  ok(offsets.cbBodyStart == 629, "got %d\n", offsets.cbBodyStart);
710  ok(offsets.cbBodyEnd == 639, "got %d\n", offsets.cbBodyEnd);
711  IMimeBody_Release(body);
712 
713  find_struct.pszPriType = text;
714  find_struct.pszSubType = NULL;
715 
716  hr = IMimeMessage_FindFirst(msg, &find_struct, &hbody);
717  ok(hr == S_OK, "ret %08x\n", hr);
718 
719  hr = IMimeMessage_FindNext(msg, &find_struct, &hbody);
720  ok(hr == S_OK, "ret %08x\n", hr);
721 
722  hr = IMimeMessage_FindNext(msg, &find_struct, &hbody);
723  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
724 
725  hr = IMimeMessage_GetAttachments(msg, &count, &body_list);
726  ok(hr == S_OK, "ret %08x\n", hr);
727  ok(count == 2, "got %d\n", count);
728  if(count == 2)
729  {
731  PROPVARIANT prop;
732 
733  PropVariantInit(&prop);
734 
735  hr = IMimeMessage_BindToObject(msg, body_list[0], &IID_IMimeBody, (void**)&attachment);
736  ok(hr == S_OK, "ret %08x\n", hr);
737 
738  hr = IMimeBody_IsContentType(attachment, "multipart", NULL);
739  ok(hr == S_FALSE, "ret %08x\n", hr);
740 
742 
743  prop.vt = VT_LPSTR;
744  hr = IMimeBody_GetProp(attachment, "Content-Transfer-Encoding", 0, &prop);
745  ok(hr == S_OK, "ret %08x\n", hr);
746 
747  ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
748  ok(!strcmp(prop.u.pszVal, "8bit"), "got %s\n", prop.u.pszVal);
749  PropVariantClear(&prop);
750 
751  hr = IMimeBody_IsType(attachment, IBT_ATTACHMENT);
752  todo_wine ok(hr == S_FALSE, "ret %08x\n", hr);
753 
754  IMimeBody_Release(attachment);
755 
756  hr = IMimeMessage_BindToObject(msg, body_list[1], &IID_IMimeBody, (void**)&attachment);
757  ok(hr == S_OK, "ret %08x\n", hr);
758 
759  hr = IMimeBody_IsContentType(attachment, "multipart", NULL);
760  ok(hr == S_FALSE, "ret %08x\n", hr);
761 
763 
764  prop.vt = VT_LPSTR;
765  hr = IMimeBody_GetProp(attachment, "Content-Transfer-Encoding", 0, &prop);
766  ok(hr == S_OK, "ret %08x\n", hr);
767  ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
768  ok(!strcmp(prop.u.pszVal, "7bit"), "got %s\n", prop.u.pszVal);
769  PropVariantClear(&prop);
770 
771  hr = IMimeBody_IsType(attachment, IBT_ATTACHMENT);
772  ok(hr == S_OK, "ret %08x\n", hr);
773 
774  IMimeBody_Release(attachment);
775  }
776  CoTaskMemFree(body_list);
777 
778  hr = IMimeBody_GetCharset(body, &hcs);
779  ok(hr == S_OK, "ret %08x\n", hr);
780  todo_wine
781  {
782  ok(hcs != NULL, "Expected non-NULL charset\n");
783  }
784 
785  IMimeMessage_Release(msg);
786 
787  ref = IStream_AddRef(stream);
788  ok(ref == 2 ||
789  broken(ref == 1), /* win95 */
790  "ref %d\n", ref);
791  IStream_Release(stream);
792 
793  IStream_Release(stream);
794 }
795 
796 static void test_mhtml_message(void)
797 {
798  IMimeMessage *mime_message;
799  IMimeBody *mime_body;
800  HBODY *body_list;
801  IStream *stream;
802  ULONG count;
803  HRESULT hres;
804 
805  hres = MimeOleCreateMessage(NULL, &mime_message);
806  ok(hres == S_OK, "MimeOleCreateMessage failed: %08x\n", hres);
807 
809  hres = IMimeMessage_Load(mime_message, stream);
810  IStream_Release(stream);
811  ok(hres == S_OK, "Load failed: %08x\n", hres);
812 
813  hres = IMimeMessage_CountBodies(mime_message, HBODY_ROOT, TRUE, &count);
814  ok(hres == S_OK, "CountBodies failed: %08x\n", hres);
815  ok(count == 3, "got %d\n", count);
816 
817  hres = IMimeMessage_GetAttachments(mime_message, &count, &body_list);
818  ok(hres == S_OK, "GetAttachments failed: %08x\n", hres);
819  ok(count == 2, "count = %u\n", count);
820 
821  hres = IMimeMessage_BindToObject(mime_message, body_list[0], &IID_IMimeBody, (void**)&mime_body);
822  ok(hres == S_OK, "BindToObject failed: %08x\n", hres);
823 
824  hres = IMimeBody_GetData(mime_body, IET_BINARY, &stream);
825  ok(hres == S_OK, "GetData failed: %08x\n", hres);
826  test_stream_read(stream, S_OK, "<HTML></HTML>", -1);
827  IStream_Release(stream);
828 
829  test_current_encoding(mime_body, IET_QP);
830 
831  IMimeBody_Release(mime_body);
832 
833  hres = IMimeMessage_BindToObject(mime_message, body_list[1], &IID_IMimeBody, (void**)&mime_body);
834  ok(hres == S_OK, "BindToObject failed: %08x\n", hres);
835 
836  test_current_encoding(mime_body, IET_BASE64);
837 
838  hres = IMimeBody_GetData(mime_body, IET_BINARY, &stream);
839  ok(hres == S_OK, "GetData failed: %08x\n", hres);
840  test_stream_read(stream, S_OK, "Test", -1);
841  IStream_Release(stream);
842 
843  IMimeBody_Release(mime_body);
844 
845  CoTaskMemFree(body_list);
846 
847  IMimeMessage_Release(mime_message);
848 }
849 
850 static void test_MessageSetProp(void)
851 {
852  static const char topic[] = "wine topic";
853  static const WCHAR topicW[] = {'w','i','n','e',' ','t','o','p','i','c',0};
854  HRESULT hr;
855  IMimeMessage *msg;
856  IMimeBody *body;
857  PROPVARIANT prop;
858 
860  ok(hr == S_OK, "ret %08x\n", hr);
861 
862  PropVariantInit(&prop);
863 
864  hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
865  ok(hr == S_OK, "ret %08x\n", hr);
866 
867  hr = IMimeBody_SetProp(body, NULL, 0, &prop);
868  ok(hr == E_INVALIDARG, "ret %08x\n", hr);
869 
870  hr = IMimeBody_SetProp(body, "Thread-Topic", 0, NULL);
871  ok(hr == E_INVALIDARG, "ret %08x\n", hr);
872 
873  prop.vt = VT_LPSTR;
874  prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
875  strcpy(prop.u.pszVal, topic);
876  hr = IMimeBody_SetProp(body, "Thread-Topic", 0, &prop);
877  ok(hr == S_OK, "ret %08x\n", hr);
878  PropVariantClear(&prop);
879 
880  hr = IMimeBody_GetProp(body, NULL, 0, &prop);
881  ok(hr == E_INVALIDARG, "ret %08x\n", hr);
882 
883  hr = IMimeBody_GetProp(body, "Thread-Topic", 0, NULL);
884  ok(hr == E_INVALIDARG, "ret %08x\n", hr);
885 
886  hr = IMimeBody_GetProp(body, "Wine-Topic", 0, &prop);
887  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
888 
889  prop.vt = VT_LPSTR;
890  hr = IMimeBody_GetProp(body, "Thread-Topic", 0, &prop);
891  ok(hr == S_OK, "ret %08x\n", hr);
892  if(hr == S_OK)
893  {
894  ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
895  ok(!strcmp(prop.u.pszVal, topic), "got %s\n", prop.u.pszVal);
896  PropVariantClear(&prop);
897  }
898 
899  prop.vt = VT_LPSTR;
900  prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
901  strcpy(prop.u.pszVal, topic);
902  hr = IMimeBody_SetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
903  ok(hr == S_OK, "ret %08x\n", hr);
904  PropVariantClear(&prop);
905 
906  prop.vt = VT_LPSTR;
907  hr = IMimeBody_GetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
908  ok(hr == S_OK, "ret %08x\n", hr);
909  if(hr == S_OK)
910  {
911  ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
912  ok(!strcmp(prop.u.pszVal, topic), "got %s\n", prop.u.pszVal);
913  PropVariantClear(&prop);
914  }
915 
916  /* Using the name or PID returns the same result. */
917  prop.vt = VT_LPSTR;
918  hr = IMimeBody_GetProp(body, "Subject", 0, &prop);
919  ok(hr == S_OK, "ret %08x\n", hr);
920  if(hr == S_OK)
921  {
922  ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
923  ok(!strcmp(prop.u.pszVal, topic), "got %s\n", prop.u.pszVal);
924  PropVariantClear(&prop);
925  }
926 
927  prop.vt = VT_LPWSTR;
928  hr = IMimeBody_GetProp(body, "Subject", 0, &prop);
929  ok(hr == S_OK, "ret %08x\n", hr);
930  if(hr == S_OK)
931  {
932  ok(prop.vt == VT_LPWSTR, "type %d\n", prop.vt);
933  ok(!lstrcmpW(prop.u.pwszVal, topicW), "got %s\n", wine_dbgstr_w(prop.u.pwszVal));
934  PropVariantClear(&prop);
935  }
936 
937  prop.vt = VT_LPSTR;
938  prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
939  strcpy(prop.u.pszVal, topic);
940  hr = IMimeBody_SetProp(body, PIDTOSTR(PID_HDR_TO), 0, &prop);
941  ok(hr == S_OK, "ret %08x\n", hr);
942  PropVariantClear(&prop);
943 
944  /* Out of Range PID */
945  prop.vt = VT_LPSTR;
946  prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
947  strcpy(prop.u.pszVal, topic);
948  hr = IMimeBody_SetProp(body, PIDTOSTR(124), 0, &prop);
949  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
950  PropVariantClear(&prop);
951 
952  IMimeBody_Release(body);
953  IMimeMessage_Release(msg);
954 }
955 
956 static void test_MessageGetPropInfo(void)
957 {
958  static const char topic[] = "wine topic";
959  static const char subject[] = "wine testing";
960  HRESULT hr;
961  IMimeMessage *msg;
962  IMimeBody *body;
963  PROPVARIANT prop;
964  MIMEPROPINFO info;
965 
967  ok(hr == S_OK, "ret %08x\n", hr);
968 
969  PropVariantInit(&prop);
970 
971  hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
972  ok(hr == S_OK, "ret %08x\n", hr);
973 
974  prop.vt = VT_LPSTR;
975  prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
976  strcpy(prop.u.pszVal, topic);
977  hr = IMimeBody_SetProp(body, "Thread-Topic", 0, &prop);
978  ok(hr == S_OK, "ret %08x\n", hr);
979  PropVariantClear(&prop);
980 
981  prop.vt = VT_LPSTR;
982  prop.u.pszVal = CoTaskMemAlloc(strlen(subject)+1);
983  strcpy(prop.u.pszVal, subject);
984  hr = IMimeBody_SetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
985  ok(hr == S_OK, "ret %08x\n", hr);
986  PropVariantClear(&prop);
987 
988  memset(&info, 0, sizeof(info));
989  info.dwMask = PIM_ENCODINGTYPE | PIM_FLAGS | PIM_PROPID;
990  hr = IMimeBody_GetPropInfo(body, NULL, &info);
991  ok(hr == E_INVALIDARG, "ret %08x\n", hr);
992 
993  memset(&info, 0, sizeof(info));
994  info.dwMask = PIM_ENCODINGTYPE | PIM_FLAGS | PIM_PROPID;
995  hr = IMimeBody_GetPropInfo(body, "Subject", NULL);
996  ok(hr == E_INVALIDARG, "ret %08x\n", hr);
997 
998  memset(&info, 0xfe, sizeof(info));
999  info.dwMask = PIM_ENCODINGTYPE | PIM_FLAGS | PIM_PROPID;
1000  hr = IMimeBody_GetPropInfo(body, "Subject", &info);
1001  ok(hr == S_OK, "ret %08x\n", hr);
1002  if(hr == S_OK)
1003  {
1004  ok(info.dwMask & (PIM_ENCODINGTYPE | PIM_FLAGS| PIM_PROPID), "Invalid mask 0x%08x\n", info.dwFlags);
1005  todo_wine ok(info.dwFlags & 0x10000000, "Invalid flags 0x%08x\n", info.dwFlags);
1006  ok(info.ietEncoding == 0, "Invalid encoding %d\n", info.ietEncoding);
1007  ok(info.dwPropId == PID_HDR_SUBJECT, "Invalid propid %d\n", info.dwPropId);
1008  ok(info.cValues == 0xfefefefe, "Invalid cValues %d\n", info.cValues);
1009  }
1010 
1011  memset(&info, 0xfe, sizeof(info));
1012  info.dwMask = 0;
1013  hr = IMimeBody_GetPropInfo(body, "Subject", &info);
1014  ok(hr == S_OK, "ret %08x\n", hr);
1015  if(hr == S_OK)
1016  {
1017  ok(info.dwMask == 0, "Invalid mask 0x%08x\n", info.dwFlags);
1018  ok(info.dwFlags == 0xfefefefe, "Invalid flags 0x%08x\n", info.dwFlags);
1019  ok(info.ietEncoding == -16843010, "Invalid encoding %d\n", info.ietEncoding);
1020  ok(info.dwPropId == -16843010, "Invalid propid %d\n", info.dwPropId);
1021  }
1022 
1023  memset(&info, 0xfe, sizeof(info));
1024  info.dwMask = 0;
1025  info.dwPropId = 1024;
1026  info.ietEncoding = 99;
1027  hr = IMimeBody_GetPropInfo(body, "Subject", &info);
1028  ok(hr == S_OK, "ret %08x\n", hr);
1029  if(hr == S_OK)
1030  {
1031  ok(info.dwMask == 0, "Invalid mask 0x%08x\n", info.dwFlags);
1032  ok(info.dwFlags == 0xfefefefe, "Invalid flags 0x%08x\n", info.dwFlags);
1033  ok(info.ietEncoding == 99, "Invalid encoding %d\n", info.ietEncoding);
1034  ok(info.dwPropId == 1024, "Invalid propid %d\n", info.dwPropId);
1035  }
1036 
1037  memset(&info, 0, sizeof(info));
1038  info.dwMask = PIM_ENCODINGTYPE | PIM_FLAGS | PIM_PROPID;
1039  hr = IMimeBody_GetPropInfo(body, "Invalid Property", &info);
1040  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
1041 
1042  IMimeBody_Release(body);
1043  IMimeMessage_Release(msg);
1044 }
1045 
1046 static void test_MessageOptions(void)
1047 {
1048  static const char string[] = "XXXXX";
1049  static const char zero[] = "0";
1050  HRESULT hr;
1051  IMimeMessage *msg;
1052  PROPVARIANT prop;
1053 
1055  ok(hr == S_OK, "ret %08x\n", hr);
1056 
1057  PropVariantInit(&prop);
1058 
1059  prop.vt = VT_BOOL;
1060  prop.u.boolVal = TRUE;
1061  hr = IMimeMessage_SetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1062  ok(hr == S_OK, "ret %08x\n", hr);
1063  PropVariantClear(&prop);
1064 
1065  hr = IMimeMessage_GetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1066  todo_wine ok(hr == S_OK, "ret %08x\n", hr);
1067  todo_wine ok(prop.vt == VT_BOOL, "vt %08x\n", prop.vt);
1068  todo_wine ok(prop.u.boolVal == TRUE, "Hide Attachments got %d\n", prop.u.boolVal);
1069  PropVariantClear(&prop);
1070 
1071  prop.vt = VT_LPSTR;
1072  prop.u.pszVal = CoTaskMemAlloc(strlen(string)+1);
1073  strcpy(prop.u.pszVal, string);
1074  hr = IMimeMessage_SetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1075  ok(hr == S_OK, "ret %08x\n", hr);
1076  PropVariantClear(&prop);
1077 
1078  hr = IMimeMessage_GetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1079  todo_wine ok(hr == S_OK, "ret %08x\n", hr);
1080  todo_wine ok(prop.vt == VT_BOOL, "vt %08x\n", prop.vt);
1081  todo_wine ok(prop.u.boolVal == TRUE, "Hide Attachments got %d\n", prop.u.boolVal);
1082  PropVariantClear(&prop);
1083 
1084  /* Invalid property type doesn't change the value */
1085  prop.vt = VT_LPSTR;
1086  prop.u.pszVal = CoTaskMemAlloc(strlen(zero)+1);
1087  strcpy(prop.u.pszVal, zero);
1088  hr = IMimeMessage_SetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1089  ok(hr == S_OK, "ret %08x\n", hr);
1090  PropVariantClear(&prop);
1091 
1092  hr = IMimeMessage_GetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1093  todo_wine ok(hr == S_OK, "ret %08x\n", hr);
1094  todo_wine ok(prop.vt == VT_BOOL, "vt %08x\n", prop.vt);
1095  todo_wine ok(prop.u.boolVal == TRUE, "Hide Attachments got %d\n", prop.u.boolVal);
1096  PropVariantClear(&prop);
1097 
1098  /* Invalid OID */
1099  prop.vt = VT_BOOL;
1100  prop.u.boolVal = TRUE;
1101  hr = IMimeMessage_SetOption(msg, 0xff00000a, &prop);
1102  ok(hr == MIME_E_INVALID_OPTION_ID, "ret %08x\n", hr);
1103  PropVariantClear(&prop);
1104 
1105  /* Out of range before type. */
1106  prop.vt = VT_I4;
1107  prop.u.lVal = 1;
1108  hr = IMimeMessage_SetOption(msg, 0xff00000a, &prop);
1109  ok(hr == MIME_E_INVALID_OPTION_ID, "ret %08x\n", hr);
1110  PropVariantClear(&prop);
1111 
1112  IMimeMessage_Release(msg);
1113 }
1114 
1115 static void test_BindToObject(void)
1116 {
1117  HRESULT hr;
1118  IMimeMessage *msg;
1119  IMimeBody *body;
1120  ULONG count;
1121 
1123  ok(hr == S_OK, "ret %08x\n", hr);
1124 
1125  hr = IMimeMessage_CountBodies(msg, HBODY_ROOT, TRUE, &count);
1126  ok(hr == S_OK, "ret %08x\n", hr);
1127  ok(count == 1, "got %d\n", count);
1128 
1129  hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
1130  ok(hr == S_OK, "ret %08x\n", hr);
1131  IMimeBody_Release(body);
1132 
1133  IMimeMessage_Release(msg);
1134 }
1135 
1136 static void test_BodyDeleteProp(void)
1137 {
1138  static const char topic[] = "wine topic";
1139  HRESULT hr;
1140  IMimeMessage *msg;
1141  IMimeBody *body;
1142  PROPVARIANT prop;
1143 
1145  ok(hr == S_OK, "ret %08x\n", hr);
1146 
1147  PropVariantInit(&prop);
1148 
1149  hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
1150  ok(hr == S_OK, "ret %08x\n", hr);
1151 
1152  hr = IMimeBody_DeleteProp(body, "Subject");
1153  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
1154 
1155  hr = IMimeBody_DeleteProp(body, PIDTOSTR(PID_HDR_SUBJECT));
1156  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
1157 
1158  prop.vt = VT_LPSTR;
1159  prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
1160  strcpy(prop.u.pszVal, topic);
1161  hr = IMimeBody_SetProp(body, "Subject", 0, &prop);
1162  ok(hr == S_OK, "ret %08x\n", hr);
1163  PropVariantClear(&prop);
1164 
1165  hr = IMimeBody_DeleteProp(body, "Subject");
1166  ok(hr == S_OK, "ret %08x\n", hr);
1167 
1168  hr = IMimeBody_GetProp(body, "Subject", 0, &prop);
1169  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
1170 
1171  prop.vt = VT_LPSTR;
1172  prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
1173  strcpy(prop.u.pszVal, topic);
1174  hr = IMimeBody_SetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
1175  ok(hr == S_OK, "ret %08x\n", hr);
1176  PropVariantClear(&prop);
1177 
1178  hr = IMimeBody_DeleteProp(body, PIDTOSTR(PID_HDR_SUBJECT));
1179  ok(hr == S_OK, "ret %08x\n", hr);
1180 
1181  hr = IMimeBody_GetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
1182  ok(hr == MIME_E_NOT_FOUND, "ret %08x\n", hr);
1183 
1184  IMimeBody_Release(body);
1185  IMimeMessage_Release(msg);
1186 }
1187 
1189 {
1190  HRESULT hr;
1191  IMimePropertySchema *schema = NULL;
1192 
1194  ok(hr == S_OK, "ret %08x\n", hr);
1195 
1196  IMimePropertySchema_Release(schema);
1197 }
1198 
1199 typedef struct {
1200  const char *url;
1201  const char *content;
1202  const char *mime;
1203  const char *data;
1205 
1207  {
1208  "mhtml:file://%s",
1209  mhtml_page1,
1210  "text/html",
1211  "<HTML></HTML>"
1212  },
1213  {
1214  "mhtml:file://%s!http://winehq.org/mhtmltest.html",
1215  mhtml_page1,
1216  "Image/Jpeg",
1217  "Test"
1218  }
1219 };
1220 
1223 
1225 {
1226  if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1227  *ppv = iface;
1228  return S_OK;
1229  }
1230 
1231  *ppv = NULL;
1232  ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1233  return E_NOINTERFACE;
1234 }
1235 
1237 {
1238  return 2;
1239 }
1240 
1242 {
1243  return 1;
1244 }
1245 
1246 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1247 {
1248  CHECK_EXPECT(GetBindInfo);
1249 
1250  ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1251  ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1252  ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1253 
1254  *grfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
1255  return S_OK;
1256 }
1257 
1259  ULONG cEl, ULONG *pcElFetched)
1260 {
1261  ok(0, "unexpected call\n");
1262  return E_NOTIMPL;
1263 }
1264 
1265 static IInternetBindInfoVtbl InternetBindInfoVtbl = {
1271 };
1272 
1275 };
1276 
1278 {
1279  ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1280  *ppv = NULL;
1281  return E_NOINTERFACE;
1282 }
1283 
1285 {
1286  return 2;
1287 }
1288 
1290 {
1291  return 1;
1292 }
1293 
1295  REFIID riid, void **ppv)
1296 {
1297  if(IsEqualGUID(&CLSID_MimeEdit, guidService)) {
1298  *ppv = NULL;
1299  return E_NOINTERFACE;
1300  }
1301 
1302  ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
1303  return E_FAIL;
1304 }
1305 
1306 static const IServiceProviderVtbl ServiceProviderVtbl = {
1311 };
1312 
1314 
1316 {
1317  if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
1318  *ppv = iface;
1319  return S_OK;
1320  }
1321 
1322  if(IsEqualGUID(&IID_IServiceProvider, riid)) {
1323  *ppv = &service_provider;
1324  return S_OK;
1325  }
1326 
1327  *ppv = NULL;
1328  ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1329  return E_NOINTERFACE;
1330 }
1331 
1333 {
1334  return 2;
1335 }
1336 
1338 {
1339  return 1;
1340 }
1341 
1342 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1343 {
1344  ok(0, "unexpected call\n");
1345  return E_NOTIMPL;
1346 }
1347 
1349  const WCHAR *szStatusText)
1350 {
1351  switch(ulStatusCode) {
1352  case BINDSTATUS_MIMETYPEAVAILABLE:
1353  CHECK_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1354  ok(!strcmp_wa(szStatusText, current_binding_test->mime), "status text %s\n", wine_dbgstr_w(szStatusText));
1355  return S_OK;
1356  case BINDSTATUS_CACHEFILENAMEAVAILABLE:
1357  CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1358  return S_OK;
1359  default:
1360  ok(0, "unexpected call %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText));
1361  }
1362 
1363  return E_NOTIMPL;
1364 }
1365 
1367  ULONG ulProgressMax)
1368 {
1369  char buf[1024];
1370  DWORD read;
1371  HRESULT hres;
1372 
1373  CHECK_EXPECT(ReportData);
1374 
1375  ok(!ulProgress, "ulProgress = %u\n", ulProgress);
1376  ok(ulProgress == ulProgressMax, "ulProgress != ulProgressMax\n");
1377  ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_INTERMEDIATEDATANOTIFICATION
1378  | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE | BSCF_AVAILABLEDATASIZEUNKNOWN),
1379  "grcf = %08x\n", grfBSCF);
1380 
1381  hres = IInternetProtocol_Read(current_binding_protocol, buf, sizeof(buf), &read);
1382  ok(hres == S_OK, "Read failed: %08x\n", hres);
1383  buf[read] = 0;
1384  ok(!strcmp(buf, current_binding_test->data), "unexpected data: %s\n", buf);
1385 
1386  hres = IInternetProtocol_Read(current_binding_protocol, buf, sizeof(buf), &read);
1387  ok(hres == S_FALSE, "Read failed: %08x\n", hres);
1388  return S_OK;
1389 }
1390 
1392  LPCWSTR szResult)
1393 {
1394  CHECK_EXPECT(ReportResult);
1395  ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1396  ok(!dwError, "dwError = %u\n", dwError);
1397  ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1398  return S_OK;
1399 }
1400 
1401 static IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
1409 };
1410 
1412 
1414 {
1415  char file_name[MAX_PATH+32], *p, urla[INTERNET_MAX_URL_LENGTH];
1418  IUnknown *unk;
1419  HRESULT hres;
1420  HANDLE file;
1421  DWORD size;
1422  BOOL ret;
1423 
1425  *p++ = '\\';
1426  strcpy(p, "winetest.mht");
1427 
1430  ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
1431 
1432  WriteFile(file, test->content, strlen(test->content), &size, NULL);
1433  CloseHandle(file);
1434 
1435  sprintf(urla, test->url, file_name);
1437 
1438  hres = CoCreateInstance(&CLSID_IMimeHtmlProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void**)&protocol);
1439  ok(hres == S_OK, "Could not create protocol handler: %08x\n", hres);
1440 
1441  hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&unk);
1442  ok(hres == E_NOINTERFACE, "Could get IInternetProtocolEx\n");
1443 
1446 
1447  SET_EXPECT(GetBindInfo);
1448  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1449  SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1450  SET_EXPECT(ReportData);
1451  SET_EXPECT(ReportResult);
1452  hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
1453  ok(hres == S_OK, "Start failed: %08x\n", hres);
1454  CHECK_CALLED(GetBindInfo);
1455  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1456  todo_wine CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1457  CHECK_CALLED(ReportData);
1458  CHECK_CALLED(ReportResult);
1459 
1460  IInternetProtocol_Release(protocol);
1461  ret = DeleteFileA("winetest.mht");
1462  ok(ret, "DeleteFile failed: %u\n", GetLastError());
1463 }
1464 
1465 static const struct {
1466  const char *base_url;
1467  const char *relative_url;
1468  const char *expected_result;
1470 } combine_tests[] = {
1471  {
1472  "mhtml:file:///c:/dir/test.mht", "http://test.org",
1473  "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org"
1474  }, {
1475  "mhtml:file:///c:/dir/test.mht", "3D\"http://test.org\"",
1476  "mhtml:file:///c:/dir/test.mht!x-usc:3D\"http://test.org\""
1477  }, {
1478  "mhtml:file:///c:/dir/test.mht", "123abc",
1479  "mhtml:file:///c:/dir/test.mht!x-usc:123abc"
1480  }, {
1481  "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", "123abc",
1482  "mhtml:file:///c:/dir/test.mht!x-usc:123abc"
1483  }, {
1484  "MhtMl:file:///c:/dir/test.mht!x-usc:http://test.org/dir/dir2/file.html", "../..",
1485  "mhtml:file:///c:/dir/test.mht!x-usc:../.."
1486  }, {"mhtml:file:///c:/dir/test.mht!x-usc:file:///c:/dir/dir2/file.html", "../..",
1487  "mhtml:file:///c:/dir/test.mht!x-usc:../.."
1488  }, {
1489  "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", "",
1490  "mhtml:file:///c:/dir/test.mht"
1491  }, {
1492  "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", "mhtml:file:///d:/file.html",
1493  "file:///d:/file.html", TRUE
1494  }, {
1495  "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", "mhtml:file:///c:/dir2/test.mht!x-usc:http://test.org",
1496  "mhtml:file:///c:/dir2/test.mht!x-usc:http://test.org", TRUE
1497  }, {
1498  "mhtml:file:///c:/dir/test.mht!http://test.org", "123abc",
1499  "mhtml:file:///c:/dir/test.mht!x-usc:123abc"
1500  }, {
1501  "mhtml:file:///c:/dir/test.mht!http://test.org", "",
1502  "mhtml:file:///c:/dir/test.mht"
1503  }
1504 };
1505 
1506 static void test_mhtml_protocol_info(void)
1507 {
1510  DWORD combined_len;
1511  unsigned i, exlen;
1512  HRESULT hres;
1513 
1514  static const WCHAR http_url[] = {'h','t','t','p',':','/','/','t','e','s','t','.','o','r','g',0};
1515 
1516  hres = CoCreateInstance(&CLSID_IMimeHtmlProtocol, NULL, CLSCTX_INPROC_SERVER,
1517  &IID_IInternetProtocolInfo, (void**)&protocol_info);
1518  ok(hres == S_OK, "Could not create protocol info: %08x\n", hres);
1519 
1520  for(i = 0; i < ARRAY_SIZE(combine_tests); i++) {
1523 
1524  combined_len = 0xdeadbeef;
1525  hres = IInternetProtocolInfo_CombineUrl(protocol_info, base_url, relative_url, ICU_BROWSER_MODE,
1526  combined_url, ARRAY_SIZE(combined_url), &combined_len, 0);
1528  ok(hres == S_OK, "[%u] CombineUrl failed: %08x\n", i, hres);
1529  if(SUCCEEDED(hres)) {
1531  ok(combined_len == exlen, "[%u] combined len is %u, expected %u\n", i, combined_len, exlen);
1532  ok(!strcmp_wa(combined_url, combine_tests[i].expected_result), "[%u] combined URL is %s, expected %s\n",
1534 
1535  combined_len = 0xdeadbeef;
1536  hres = IInternetProtocolInfo_CombineUrl(protocol_info, base_url, relative_url, ICU_BROWSER_MODE,
1537  combined_url, exlen, &combined_len, 0);
1538  ok(hres == E_FAIL, "[%u] CombineUrl returned: %08x\n", i, hres);
1539  ok(!combined_len, "[%u] combined_len = %u\n", i, combined_len);
1540  }
1541 
1544  }
1545 
1546  hres = IInternetProtocolInfo_CombineUrl(protocol_info, http_url, http_url, ICU_BROWSER_MODE,
1547  combined_url, ARRAY_SIZE(combined_url), &combined_len, 0);
1548  ok(hres == E_FAIL, "CombineUrl failed: %08x\n", hres);
1549 
1550  IInternetProtocolInfo_Release(protocol_info);
1551 }
1552 
1554 {
1555  ok(0, "unexpected call\n");
1556  return E_NOINTERFACE;
1557 }
1558 
1560 {
1561  return 2;
1562 }
1563 
1565 {
1566  return 1;
1567 }
1568 
1569 static const IUnknownVtbl outer_vtbl = {
1571  outer_AddRef,
1573 };
1574 
1576 
1577 static void test_mhtml_protocol(void)
1578 {
1579  IUnknown outer = { &outer_vtbl };
1580  IClassFactory *class_factory;
1581  IUnknown *unk, *unk2;
1582  unsigned i;
1583  HRESULT hres;
1584 
1585  /* test class factory */
1586  hres = CoGetClassObject(&CLSID_IMimeHtmlProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
1587  ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
1588 
1589  hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&unk2);
1590  ok(hres == E_NOINTERFACE, "IInternetProtocolInfo supported\n");
1591 
1592  hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&class_factory);
1593  ok(hres == S_OK, "Could not get IClassFactory iface: %08x\n", hres);
1594  IUnknown_Release(unk);
1595 
1596  hres = IClassFactory_CreateInstance(class_factory, &outer, &IID_IUnknown, (void**)&unk);
1597  ok(hres == S_OK, "CreateInstance returned: %08x\n", hres);
1598  hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&unk2);
1599  ok(hres == S_OK, "Could not get IInternetProtocol iface: %08x\n", hres);
1600  IUnknown_Release(unk2);
1601  IUnknown_Release(unk);
1602 
1603  hres = IClassFactory_CreateInstance(class_factory, (IUnknown*)0xdeadbeef, &IID_IInternetProtocol, (void**)&unk2);
1604  ok(hres == CLASS_E_NOAGGREGATION, "CreateInstance returned: %08x\n", hres);
1605 
1606  IClassFactory_Release(class_factory);
1607 
1610 
1611  for(i = 0; i < ARRAY_SIZE(binding_tests); i++)
1613 }
1614 
1616 {
1617  IMoniker *mon, *new_mon;
1618  WCHAR *mhtml_url, *url;
1619  IBindCtx *bind_ctx;
1620  IUnknown *unk;
1621  unsigned i;
1622  HRESULT hres;
1623 
1624  static const struct {
1625  const char *url;
1626  const char *mhtml_url;
1627  } tests[] = {
1628  {"file:///x:\\dir\\file.mht", "mhtml:file://x:\\dir\\file.mht"},
1629  {"file:///x:/dir/file.mht", "mhtml:file://x:\\dir\\file.mht"},
1630  {"http://www.winehq.org/index.html?query#hash", "mhtml:http://www.winehq.org/index.html?query#hash"},
1631  {"../test.mht", "mhtml:../test.mht"}
1632  };
1633 
1634  for(i = 0; i < ARRAY_SIZE(tests); i++) {
1635  url = a2w(tests[i].url);
1636  hres = CreateURLMoniker(NULL, url, &mon);
1637  ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
1638  HeapFree(GetProcessHeap(), 0, url);
1639 
1640  hres = CreateBindCtx(0, &bind_ctx);
1641  ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
1642 
1643  hres = MimeOleObjectFromMoniker(0, mon, bind_ctx, &IID_IUnknown, (void**)&unk, &new_mon);
1644  ok(hres == S_OK || broken(!i && hres == INET_E_RESOURCE_NOT_FOUND), "MimeOleObjectFromMoniker failed: %08x\n", hres);
1645  IBindCtx_Release(bind_ctx);
1646  if(hres == INET_E_RESOURCE_NOT_FOUND) { /* winxp */
1647  win_skip("Broken MHTML behaviour found. Skipping some tests.\n");
1649  return;
1650  }
1651 
1652  hres = IMoniker_GetDisplayName(new_mon, NULL, NULL, &mhtml_url);
1653  ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1654  ok(!strcmp_wa(mhtml_url, tests[i].mhtml_url), "[%d] unexpected mhtml URL: %s\n", i, wine_dbgstr_w(mhtml_url));
1655  CoTaskMemFree(mhtml_url);
1656 
1657  IUnknown_Release(unk);
1658  IMoniker_Release(new_mon);
1659  IMoniker_Release(mon);
1660  }
1661 }
1662 
1663 START_TEST(mimeole)
1664 {
1668  test_CreateBody();
1669  test_SetData();
1670  test_Allocator();
1681  OleUninitialize();
1682 }
GLenum attachment
Definition: glext.h:6295
HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity)
Definition: mimeole.c:3331
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
struct param_test tests[]
#define test_stream_read(a, b, c, d)
Definition: mimeole.c:469
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: mimeole.c:1559
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
#define CloseHandle
Definition: compat.h:398
#define E_NOINTERFACE
Definition: winerror.h:2364
Definition: compat.h:1939
static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
Definition: mimeole.c:1284
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1553
static void test_MessageOptions(void)
Definition: mimeole.c:1046
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
static HRESULT WINAPI Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
Definition: mimeole.c:390
static const IStreamVtbl StreamVtbl
Definition: mimeole.c:442
static void _test_current_encoding(unsigned line, IMimeBody *mime_body, ENCODINGTYPE encoding)
Definition: mimeole.c:181
HRESULT hr
Definition: shlfolder.c:183
Definition: scsiwmi.h:51
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define strcasecmp
Definition: fake.h:9
static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1277
#define ok_(x1, x2)
static IInternetProtocolInfo protocol_info
Definition: misc.c:927
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void test_mhtml_protocol(void)
Definition: mimeole.c:1577
static HRESULT WINAPI Stream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: mimeole.c:345
REFIID riid
Definition: precomp.h:44
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2952
HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessage)
Definition: mimeole.c:3121
const WCHAR * text
Definition: package.c:1827
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static void _test_stream_read(unsigned line, IStream *stream, HRESULT exhres, const char *exdata, unsigned read_size)
Definition: mimeole.c:470
GLuint GLuint GLsizei count
Definition: gl.h:1545
static void test_CreateBody(void)
Definition: mimeole.c:191
static const IUnknownVtbl outer_vtbl
Definition: mimeole.c:1569
static TestStream * impl_from_IStream(IStream *iface)
Definition: mimeole.c:311
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define wine_dbgstr_w
Definition: kernel32.h:34
const char * mime
Definition: mimeole.c:1202
static const char mhtml_page1[]
Definition: mimeole.c:102
const char * wine_dbgstr_guid(const GUID *guid)
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static DWORD expect_seek_pos
Definition: mimeole.c:365
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
static ULONG WINAPI Stream_Release(IStream *iface)
Definition: mimeole.c:334
static int strcmp_wa(const WCHAR *strw, const char *stra)
Definition: mimeole.c:132
#define test
Definition: rosglue.h:37
static IStream * create_test_stream(void)
Definition: mimeole.c:459
static LPOLESTR
Definition: stg_prop.c:27
static void test_CreateVirtualStream(void)
Definition: mimeole.c:139
static IInternetProtocolSink protocol_sink
Definition: mimeole.c:1411
#define E_FAIL
Definition: ddrawi.h:102
static void test_CreateSecurity(void)
Definition: mimeole.c:150
static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1315
Definition: send.c:47
static void test_MessageSetProp(void)
Definition: mimeole.c:850
static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
Definition: mimeole.c:1289
static WCHAR * a2w(const char *str)
Definition: mimeole.c:118
static const struct @1597 combine_tests[]
static HRESULT WINAPI Stream_CopyTo(IStream *iface, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
Definition: mimeole.c:396
struct _test_info info[]
Definition: SetCursorPos.c:19
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define ICU_BROWSER_MODE
Definition: winhttp.h:294
static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
Definition: mimeole.c:1294
static const char msg1[]
Definition: mimeole.c:74
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
START_TEST(mimeole)
Definition: mimeole.c:1663
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
Definition: mimeole.c:1241
const char * relative_url
Definition: mimeole.c:1467
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
BOOL todo
Definition: mimeole.c:1469
#define GENERIC_WRITE
Definition: nt_native.h:90
static void test_BindToObject(void)
Definition: mimeole.c:1115
GLenum GLint ref
Definition: glext.h:6028
static const WCHAR topicW[]
Definition: propsys.c:44
static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
Definition: mimeole.c:1236
#define ok(value,...)
static LPCWSTR http_url
Definition: protocol.c:146
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
IStream IStream_iface
Definition: mimeole.c:306
#define INTERNET_MAX_URL_LENGTH
Definition: session.c:1380
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
Definition: parser.c:48
static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode, const WCHAR *szStatusText)
Definition: mimeole.c:1348
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3012
static const IServiceProviderVtbl ServiceProviderVtbl
Definition: mimeole.c:1306
static void test_mhtml_message(void)
Definition: mimeole.c:796
static HRESULT WINAPI Stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
Definition: mimeole.c:316
static const mhtml_binding_test_t binding_tests[]
Definition: mimeole.c:1206
static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
Definition: mimeole.c:1246
static IInternetProtocol * current_binding_protocol
Definition: mimeole.c:1222
enum MIMEOLE::tagENCODINGTYPE ENCODINGTYPE
static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: mimeole.c:367
static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
Definition: mimeole.c:403
#define todo_wine_if(is_todo)
Definition: test.h:155
#define CHECK_EXPECT(func)
Definition: mimeole.c:45
static IServiceProvider service_provider
Definition: mimeole.c:1313
static void test_MimeOleGetPropertySchema(void)
Definition: mimeole.c:1188
#define test_current_encoding(a, b)
Definition: mimeole.c:180
static void test_Allocator(void)
Definition: mimeole.c:591
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static IStream test_stream
Definition: mlang.c:2453
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
__wchar_t WCHAR
Definition: xmlstorage.h:180
HRESULT WINAPI MimeOleGetAllocator(IMimeAllocator **alloc)
Definition: mimeole.c:3530
LONG HRESULT
Definition: typedefs.h:77
static const WCHAR url[]
Definition: encode.c:1432
const GUID IID_IUnknown
static HRESULT WINAPI Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: mimeole.c:415
HRESULT WINAPI MimeOleObjectFromMoniker(BINDF bindf, IMoniker *moniker, IBindCtx *binding, REFIID riid, void **out, IMoniker **moniker_new)
Definition: mimeole.c:3696
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
const char file[]
Definition: icontest.c:11
static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
Definition: mimeole.c:1332
unsigned long DWORD
Definition: ntddk_ex.h:95
static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
Definition: mimeole.c:1337
static IStream * create_stream_from_string(const char *data)
Definition: mimeole.c:161
static IInternetProtocolSinkVtbl InternetProtocolSinkVtbl
Definition: mimeole.c:1401
static DWORD cb
Definition: integrity.c:41
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
unsigned pos
Definition: mimeole.c:308
LONG ref
Definition: mimeole.c:307
static BOOL broken_mhtml_resolver
Definition: mimeole.c:1575
static double zero
Definition: j0_y0.c:96
int ret
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
REFCLSID clsid
Definition: msctf.c:84
#define todo_wine
Definition: test.h:154
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: mimeole.c:1564
GLuint GLuint stream
Definition: glext.h:7522
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
Definition: mimeole.c:1366
static void test_MessageGetPropInfo(void)
Definition: mimeole.c:956
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
struct _LARGE_INTEGER::@2199 u
static void test_BodyDeleteProp(void)
Definition: mimeole.c:1136
#define broken(x)
Definition: _sntprintf.h:21
ed encoding
Definition: write.c:2847
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3234
static void test_CreateMessage(void)
Definition: mimeole.c:601
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:172
const char * content
Definition: mimeole.c:1201
ULARGE_INTEGER pos
Definition: request.c:4080
#define S_OK
Definition: intsafe.h:59
#define CREATE_ALWAYS
Definition: disk.h:72
static void test_SetData(void)
Definition: mimeole.c:486
#define InterlockedIncrement
Definition: armddk.h:53
GLuint in
Definition: glext.h:9616
#define ARRAY_SIZE(a)
Definition: main.h:24
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
#define E_NOTIMPL
Definition: ddrawi.h:99
static const char topic[]
Definition: propsys.c:43
static const void * body(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:100
const char * base_url
Definition: mimeole.c:1466
static void test_MimeOleObjectFromMoniker(void)
Definition: mimeole.c:1615
#define alloc
Definition: rosglue.h:13
static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
Definition: mimeole.c:1391
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
const WCHAR * schema
const char * combined_url
Definition: protocol.c:466
static HRESULT WINAPI Stream_Revert(IStream *iface)
Definition: mimeole.c:409
#define SET_EXPECT(func)
Definition: mimeole.c:42
#define MultiByteToWideChar
Definition: compat.h:100
static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1224
const char * url
Definition: mimeole.c:1200
static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg, DWORD dwStatFlag)
Definition: mimeole.c:429
static LPCWSTR file_name
Definition: protocol.c:146
static HRESULT WINAPI Stream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: mimeole.c:422
const char * expected_result
Definition: mimeole.c:1468
static void test_mhtml_protocol_binding(const mhtml_binding_test_t *test)
Definition: mimeole.c:1413
static IInternetBindInfo bind_info
Definition: mimeole.c:1273
#define msg(x)
Definition: auth_time.c:54
IStream IStream_iface
Definition: request.c:4077
#define CHECK_CALLED(func)
Definition: mimeole.c:58
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
HRESULT WINAPI CreateURLMoniker(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk)
Definition: umon.c:732
static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: mimeole.c:359
HRESULT WINAPI MimeOleCreateVirtualStream(IStream **ppStream)
Definition: mimeole.c:3139
static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
Definition: mimeole.c:1342
static IInternetBindInfoVtbl InternetBindInfoVtbl
Definition: mimeole.c:1265
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:399
GLfloat GLfloat p
Definition: glext.h:8902
static void test_mhtml_protocol_info(void)
Definition: mimeole.c:1506
const GUID IID_IClassFactory
static const mhtml_binding_test_t * current_binding_test
Definition: mimeole.c:1221
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:233
#define memset(x, y, z)
Definition: compat.h:39
static const char * strw(LPCWSTR x)
Definition: actctx.c:49
static ULONG WINAPI Stream_AddRef(IStream *iface)
Definition: mimeole.c:328
static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
Definition: mimeole.c:1258
#define win_skip
Definition: test.h:141
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
#define HeapFree(x, y, z)
Definition: compat.h:394
static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
Definition: mimeole.c:436
const char * data
Definition: mimeole.c:1203
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define DEFINE_EXPECT(func)
Definition: mimeole.c:39
#define SUCCEEDED(hr)
Definition: intsafe.h:57
LONGLONG QuadPart
Definition: typedefs.h:112
HRESULT WINAPI MimeOleGetPropertySchema(IMimePropertySchema **schema)
Definition: mimeole.c:3643
static const char test_url[]
Definition: urlcache.c:33
off
Definition: i386-dis.c:3909
Definition: fci.c:126