ReactOS 0.4.15-dev-7788-g1ad9096
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
67DEFINE_EXPECT(Stream_Seek_END);
68DEFINE_EXPECT(GetBindInfo);
69DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
70DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
71DEFINE_EXPECT(ReportData);
72DEFINE_EXPECT(ReportResult);
73
74static 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
102static 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
118static 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));
129 return ret;
130}
131
132static int strcmp_wa(const WCHAR *strw, const char *stra)
133{
134 WCHAR buf[512];
136 return lstrcmpW(strw, buf);
137}
138
140{
141 HRESULT hr;
142 IStream *pstm;
143
145 ok(hr == S_OK, "ret %08x\n", hr);
146
147 IStream_Release(pstm);
148}
149
150static void test_CreateSecurity(void)
151{
152 HRESULT hr;
153 IMimeSecurity *sec;
154
156 ok(hr == S_OK, "ret %08x\n", hr);
157
158 IMimeSecurity_Release(sec);
159}
160
162{
163 LARGE_INTEGER off;
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)
181static void _test_current_encoding(unsigned line, IMimeBody *mime_body, ENCODINGTYPE encoding)
182{
183 ENCODINGTYPE current_encoding;
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
191static void test_CreateBody(void)
192{
193 HRESULT hr;
195 HBODY handle = (void *)0xdeadbeef;
196 IStream *in;
197 LARGE_INTEGER off;
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
225 test_current_encoding(body, IET_7BIT);
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");
246 ok(hr == S_OK, "ret %08x\n", hr);
247 test_current_encoding(body, IET_8BIT);
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
305typedef struct {
308 unsigned pos;
309} TestStream;
310
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
345static 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
359static 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
367static 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
403static 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
429static 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
437{
438 ok(0, "unexpected call\n");
439 return E_NOTIMPL;
440}
441
442static const IStreamVtbl StreamVtbl = {
457};
458
460{
462 stream = HeapAlloc(GetProcessHeap(), 0, sizeof(*stream));
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)
470static 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];
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
486static void test_SetData(void)
487{
488 IStream *stream, *stream2, *test_stream;
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");
510 ok(hr == S_OK, "ret %08x\n", hr);
511
512 test_current_encoding(body, IET_BINARY);
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
558 test_current_encoding(body, IET_BASE64);
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
591static 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
601static void test_CreateMessage(void)
602{
603 HRESULT hr;
606 LONG ref;
607 HBODY hbody, hbody2;
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);
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);
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
796static void test_mhtml_message(void)
797{
798 IMimeMessage *mime_message;
799 IMimeBody *mime_body;
800 HBODY *body_list;
802 ULONG count;
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
850static 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;
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
956static void test_MessageGetPropInfo(void)
957{
958 static const char topic[] = "wine topic";
959 static const char subject[] = "wine testing";
960 HRESULT hr;
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
1046static void test_MessageOptions(void)
1047{
1048 static const char string[] = "XXXXX";
1049 static const char zero[] = "0";
1050 HRESULT hr;
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
1115static void test_BindToObject(void)
1116{
1117 HRESULT hr;
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
1136static void test_BodyDeleteProp(void)
1137{
1138 static const char topic[] = "wine topic";
1139 HRESULT hr;
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
1199typedef struct {
1200 const char *url;
1201 const char *content;
1202 const char *mime;
1203 const char *data;
1205
1207 {
1208 "mhtml:file://%s",
1210 "text/html",
1211 "<HTML></HTML>"
1212 },
1213 {
1214 "mhtml:file://%s!http://winehq.org/mhtmltest.html",
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
1246static 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
1265static 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
1306static 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)) {
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
1342static 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
1401static 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);
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
1465static 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 }
1505
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
1569static const IUnknownVtbl outer_vtbl = {
1573};
1574
1576
1577static void test_mhtml_protocol(void)
1578{
1579 IUnknown outer = { &outer_vtbl };
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);
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
1664{
1669 test_SetData();
1682}
#define broken(x)
Definition: _sntprintf.h:21
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define read
Definition: acwin.h:96
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define msg(x)
Definition: auth_time.c:54
#define ARRAY_SIZE(A)
Definition: main.h:33
const GUID IID_IUnknown
const GUID IID_IClassFactory
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define MultiByteToWideChar
Definition: compat.h:110
@ VT_LPSTR
Definition: compat.h:2324
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_I4
Definition: compat.h:2298
@ VT_BOOL
Definition: compat.h:2306
HRESULT WINAPI MimeOleGetPropertySchema(IMimePropertySchema **schema)
Definition: mimeole.c:3643
static sub_stream_t * impl_from_IStream(IStream *iface)
Definition: mimeole.c:182
HRESULT WINAPI MimeOleObjectFromMoniker(BINDF bindf, IMoniker *moniker, IBindCtx *binding, REFIID riid, void **out, IMoniker **moniker_new)
Definition: mimeole.c:3696
HRESULT WINAPI MimeOleGetAllocator(IMimeAllocator **alloc)
Definition: mimeole.c:3530
HRESULT WINAPI MimeOleCreateVirtualStream(IStream **ppStream)
Definition: mimeole.c:3139
HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity)
Definition: mimeole.c:3331
HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessage)
Definition: mimeole.c:3121
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
const WCHAR * text
Definition: package.c:1799
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3103
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:169
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2968
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:230
#define INTERNET_MAX_URL_LENGTH
Definition: session.c:1418
#define strcasecmp
Definition: fake.h:9
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static const FxOffsetAndName offsets[]
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLenum attachment
Definition: glext.h:6295
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
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
const WCHAR * schema
@ PID_HDR_SUBJECT
Definition: mimeole.idl:81
@ PID_HDR_TO
Definition: mimeole.idl:101
#define CREATE_ALWAYS
Definition: disk.h:72
static struct test_info tests[]
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const WCHAR url[]
Definition: encode.c:1432
static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
Definition: mimeole.c:1294
#define SET_EXPECT(func)
Definition: mimeole.c:42
const char * expected_result
Definition: mimeole.c:1468
static ULONG WINAPI Stream_AddRef(IStream *iface)
Definition: mimeole.c:328
static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
Definition: mimeole.c:1342
static void test_MimeOleObjectFromMoniker(void)
Definition: mimeole.c:1615
static const IUnknownVtbl outer_vtbl
Definition: mimeole.c:1569
static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
Definition: mimeole.c:1289
static void test_mhtml_protocol_info(void)
Definition: mimeole.c:1506
static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
Definition: mimeole.c:1241
static HRESULT WINAPI Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
Definition: mimeole.c:390
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: mimeole.c:1559
static HRESULT WINAPI Stream_Revert(IStream *iface)
Definition: mimeole.c:409
static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg, DWORD dwStatFlag)
Definition: mimeole.c:429
#define test_stream_read(a, b, c, d)
Definition: mimeole.c:469
static IInternetProtocolSinkVtbl InternetProtocolSinkVtbl
Definition: mimeole.c:1401
static void test_mhtml_message(void)
Definition: mimeole.c:796
static HRESULT WINAPI Stream_CopyTo(IStream *iface, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
Definition: mimeole.c:396
static void test_CreateSecurity(void)
Definition: mimeole.c:150
static IInternetProtocol * current_binding_protocol
Definition: mimeole.c:1222
#define CHECK_EXPECT(func)
Definition: mimeole.c:45
static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
Definition: mimeole.c:1337
static const struct @1658 combine_tests[]
static BOOL broken_mhtml_resolver
Definition: mimeole.c:1575
#define DEFINE_EXPECT(func)
Definition: mimeole.c:39
static void test_MessageGetPropInfo(void)
Definition: mimeole.c:956
static HRESULT WINAPI Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: mimeole.c:415
static IServiceProvider service_provider
Definition: mimeole.c:1313
static HRESULT WINAPI Stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
Definition: mimeole.c:316
const char * relative_url
Definition: mimeole.c:1467
static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1224
static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
Definition: mimeole.c:436
static int strcmp_wa(const WCHAR *strw, const char *stra)
Definition: mimeole.c:132
static const char mhtml_page1[]
Definition: mimeole.c:102
static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
Definition: mimeole.c:1246
const char * base_url
Definition: mimeole.c:1466
static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1315
static IStream * create_stream_from_string(const char *data)
Definition: mimeole.c:161
static void test_MessageSetProp(void)
Definition: mimeole.c:850
static void test_MessageOptions(void)
Definition: mimeole.c:1046
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1553
static HRESULT WINAPI Stream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: mimeole.c:422
static void test_CreateVirtualStream(void)
Definition: mimeole.c:139
static const mhtml_binding_test_t * current_binding_test
Definition: mimeole.c:1221
static void test_mhtml_protocol(void)
Definition: mimeole.c:1577
static IInternetProtocolSink protocol_sink
Definition: mimeole.c:1411
static DWORD expect_seek_pos
Definition: mimeole.c:365
static const mhtml_binding_test_t binding_tests[]
Definition: mimeole.c:1206
static IStream * create_test_stream(void)
Definition: mimeole.c:459
BOOL todo
Definition: mimeole.c:1469
#define CHECK_CALLED(func)
Definition: mimeole.c:58
static const char msg1[]
Definition: mimeole.c:74
static WCHAR * a2w(const char *str)
Definition: mimeole.c:118
static void test_MimeOleGetPropertySchema(void)
Definition: mimeole.c:1188
static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
Definition: mimeole.c:1391
static ULONG WINAPI Stream_Release(IStream *iface)
Definition: mimeole.c:334
static const IStreamVtbl StreamVtbl
Definition: mimeole.c:442
static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
Definition: mimeole.c:403
static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: mimeole.c:367
static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: mimeole.c:359
static void test_mhtml_protocol_binding(const mhtml_binding_test_t *test)
Definition: mimeole.c:1413
static void test_BodyDeleteProp(void)
Definition: mimeole.c:1136
static void test_BindToObject(void)
Definition: mimeole.c:1115
static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
Definition: mimeole.c:1366
static HRESULT WINAPI Stream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: mimeole.c:345
static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1277
#define test_current_encoding(a, b)
Definition: mimeole.c:180
static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode, const WCHAR *szStatusText)
Definition: mimeole.c:1348
static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
Definition: mimeole.c:1284
static const IServiceProviderVtbl ServiceProviderVtbl
Definition: mimeole.c:1306
static IInternetBindInfoVtbl InternetBindInfoVtbl
Definition: mimeole.c:1265
static void test_CreateBody(void)
Definition: mimeole.c:191
static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
Definition: mimeole.c:1258
static void _test_current_encoding(unsigned line, IMimeBody *mime_body, ENCODINGTYPE encoding)
Definition: mimeole.c:181
static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
Definition: mimeole.c:1236
static IInternetBindInfo bind_info
Definition: mimeole.c:1273
static void test_CreateMessage(void)
Definition: mimeole.c:601
static void _test_stream_read(unsigned line, IStream *stream, HRESULT exhres, const char *exdata, unsigned read_size)
Definition: mimeole.c:470
static void test_Allocator(void)
Definition: mimeole.c:591
static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
Definition: mimeole.c:1332
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: mimeole.c:1564
static void test_SetData(void)
Definition: mimeole.c:486
HRESULT hres
Definition: protocol.c:465
const char * combined_url
Definition: protocol.c:466
static const char * strw(LPCWSTR x)
Definition: actctx.c:49
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define todo_wine
Definition: custom.c:79
static LPOLESTR
Definition: stg_prop.c:27
static IInternetProtocolInfo protocol_info
Definition: misc.c:947
static LPCWSTR file_name
Definition: protocol.c:147
static LPCWSTR http_url
Definition: protocol.c:147
static const char test_url[]
Definition: urlcache.c:37
REFCLSID clsid
Definition: msctf.c:82
#define GENERIC_WRITE
Definition: nt_native.h:90
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
long LONG
Definition: pedump.c:60
static const WCHAR topicW[]
Definition: propsys.c:45
static const char topic[]
Definition: propsys.c:44
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define alloc
Definition: rosglue.h:13
#define test
Definition: rosglue.h:37
const WCHAR * str
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define win_skip
Definition: test.h:160
static const void * body(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:100
#define memset(x, y, z)
Definition: compat.h:39
int zero
Definition: sehframes.cpp:29
HRESULT hr
Definition: shlfolder.c:183
LONG ref
Definition: mimeole.c:307
unsigned pos
Definition: mimeole.c:308
IStream IStream_iface
Definition: mimeole.c:306
Definition: scsiwmi.h:51
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: fci.c:127
Definition: parser.c:49
const char * mime
Definition: mimeole.c:1202
const char * url
Definition: mimeole.c:1200
const char * data
Definition: mimeole.c:1203
const char * content
Definition: mimeole.c:1201
Definition: send.c:48
Definition: parse.h:23
ULARGE_INTEGER pos
Definition: request.c:4380
IStream IStream_iface
Definition: request.c:4377
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
HRESULT WINAPI CreateURLMoniker(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk)
Definition: umon.c:732
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2290 u
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define ICU_BROWSER_MODE
Definition: winhttp.h:294
static char * encoding
Definition: xmllint.c:155
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193