ReactOS 0.4.17-dev-357-ga8f14ff
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#include "initguid.h"
23#include "windows.h"
24#include "ole2.h"
25#include "ocidl.h"
26
27#include "mimeole.h"
28#include "wininet.h"
29
30#include <stdio.h>
31
32#include "wine/test.h"
33
34#define DEFINE_EXPECT(func) \
35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
36
37#define SET_EXPECT(func) \
38 expect_ ## func = TRUE
39
40#define CHECK_EXPECT(func) \
41 do { \
42 ok(expect_ ##func, "unexpected call " #func "\n"); \
43 expect_ ## func = FALSE; \
44 called_ ## func = TRUE; \
45 }while(0)
46
47#define CHECK_EXPECT2(func) \
48 do { \
49 ok(expect_ ##func, "unexpected call " #func "\n"); \
50 called_ ## func = TRUE; \
51 }while(0)
52
53#define CHECK_CALLED(func) \
54 do { \
55 ok(called_ ## func, "expected " #func "\n"); \
56 expect_ ## func = called_ ## func = FALSE; \
57 }while(0)
58
62DEFINE_EXPECT(Stream_Seek_END);
63DEFINE_EXPECT(GetBindInfo);
64DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
65DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
66DEFINE_EXPECT(ReportData);
67DEFINE_EXPECT(ReportResult);
68
69static const char msg1[] =
70 "MIME-Version: 1.0\r\n"
71 "Content-Type: multipart/mixed;\r\n"
72 " boundary=\"------------1.5.0.6\";\r\n"
73 " stuff=\"du;nno\";\r\n"
74 " morestuff=\"so\\\\me\\\"thing\\\"\"\r\n"
75 "foo: bar\r\n"
76 "From: Huw Davies <huw@codeweavers.com>\r\n"
77 "From: Me <xxx@codeweavers.com>\r\n"
78 "To: wine-patches <wine-patches@winehq.org>\r\n"
79 "Cc: Huw Davies <huw@codeweavers.com>,\r\n"
80 " \"Fred Bloggs\" <fred@bloggs.com>\r\n"
81 "foo: baz\r\n"
82 "bar: fum\r\n"
83 "\r\n"
84 "This is a multi-part message in MIME format.\r\n"
85 "--------------1.5.0.6\r\n"
86 "Content-Type: text/plain; format=fixed; charset=UTF-8\r\n"
87 "Content-Transfer-Encoding: 8bit\r\n"
88 "\r\n"
89 "Stuff\r\n"
90 "--------------1.5.0.6\r\n"
91 "Content-Type: text/plain; charset=\"us-ascii\"\r\n"
92 "Content-Transfer-Encoding: 7bit\r\n"
93 "\r\n"
94 "More stuff\r\n"
95 "--------------1.5.0.6--\r\n";
96
97static const char mhtml_page1[] =
98 "MIME-Version: 1.0\r\n"
99 "Content-Type: multipart/related; type:=\"text/html\"; boundary=\"----=_NextPart_000_00\"\r\n"
100 "\r\n"
101 "------=_NextPart_000_00\r\n"
102 "Content-Type: text/html; charset=\"Windows-1252\"\r\n"
103 "Content-Transfer-Encoding: quoted-printable\r\n"
104 "\r\n"
105 "<HTML></HTML>\r\n"
106 "------=_NextPart_000_00\r\n"
107 "Content-Type: Image/Jpeg\r\n"
108 "Content-Transfer-Encoding: base64\r\n"
109 "Content-Location: http://winehq.org/mhtmltest.html\r\n"
110 "\r\n\t\t\t\tVGVzdA==\r\n\r\n"
111 "------=_NextPart_000_00--";
112
114{
115 HRESULT hr;
116 IStream *pstm;
117
119 ok(hr == S_OK, "ret %08lx\n", hr);
120
121 IStream_Release(pstm);
122}
123
124static void test_CreateSecurity(void)
125{
126 HRESULT hr;
127 IMimeSecurity *sec;
128
130 ok(hr == S_OK, "ret %08lx\n", hr);
131
132 IMimeSecurity_Release(sec);
133}
134
136{
137 LARGE_INTEGER off;
139 HRESULT hr;
140
142 ok(hr == S_OK, "ret %08lx\n", hr);
143
144 hr = IStream_Write(stream, data, strlen(data), NULL);
145 ok(hr == S_OK, "Write failed: %08lx\n", hr);
146
147 off.QuadPart = 0;
148 hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL);
149 ok(hr == S_OK, "Seek failed: %08lx\n", hr);
150
151 return stream;
152}
153
154#define test_current_encoding(a,b) _test_current_encoding(__LINE__,a,b)
155static void _test_current_encoding(unsigned line, IMimeBody *mime_body, ENCODINGTYPE encoding)
156{
157 ENCODINGTYPE current_encoding;
159
160 hres = IMimeBody_GetCurrentEncoding(mime_body, &current_encoding);
161 ok_(__FILE__,line)(hres == S_OK, "GetCurrentEncoding failed: %08lx\n", hres);
162 ok_(__FILE__,line)(current_encoding == encoding, "encoding = %d, expected %d\n", current_encoding, encoding);
163}
164
165static void test_CreateBody(void)
166{
167 HRESULT hr;
169 HBODY handle = (void *)0xdeadbeef;
170 IStream *in;
171 LARGE_INTEGER off;
173 ULONG count, found_param, i;
174 MIMEPARAMINFO *param_info;
175 IMimeAllocator *alloc;
176 BODYOFFSETS offsets;
177 CLSID clsid;
178
179 hr = CoCreateInstance(&CLSID_IMimeBody, NULL, CLSCTX_INPROC_SERVER, &IID_IMimeBody, (void**)&body);
180 ok(hr == S_OK, "ret %08lx\n", hr);
181
182 hr = IMimeBody_GetClassID(body, NULL);
183 ok(hr == E_INVALIDARG, "ret %08lx\n", hr);
184
185 hr = IMimeBody_GetClassID(body, &clsid);
186 ok(hr == S_OK, "ret %08lx\n", hr);
187 ok(IsEqualGUID(&clsid, &IID_IMimeBody), "got %s\n", wine_dbgstr_guid(&clsid));
188
189 hr = IMimeBody_GetHandle(body, &handle);
190 ok(hr == MIME_E_NO_DATA, "ret %08lx\n", hr);
191 ok(handle == NULL, "handle %p\n", handle);
192
194
195 /* Need to call InitNew before Load otherwise Load crashes with native inetcomm */
196 hr = IMimeBody_InitNew(body);
197 ok(hr == S_OK, "ret %08lx\n", hr);
198
199 test_current_encoding(body, IET_7BIT);
200
201 hr = IMimeBody_Load(body, in);
202 ok(hr == S_OK, "ret %08lx\n", hr);
203 off.QuadPart = 0;
204 IStream_Seek(in, off, STREAM_SEEK_CUR, &pos);
205 ok(pos.LowPart == 359, "pos %lu\n", pos.LowPart);
206
207 hr = IMimeBody_IsContentType(body, "multipart", "mixed");
208 ok(hr == S_OK, "ret %08lx\n", hr);
209 hr = IMimeBody_IsContentType(body, "text", "plain");
210 ok(hr == S_FALSE, "ret %08lx\n", hr);
211 hr = IMimeBody_IsContentType(body, NULL, "mixed");
212 ok(hr == S_OK, "ret %08lx\n", hr);
213 hr = IMimeBody_IsType(body, IBT_EMPTY);
214 ok(hr == S_OK, "got %08lx\n", hr);
215
216 hr = IMimeBody_SetData(body, IET_8BIT, "text", "plain", &IID_IStream, in);
217 ok(hr == S_OK, "ret %08lx\n", hr);
218 hr = IMimeBody_IsContentType(body, "text", "plain");
220 ok(hr == S_OK, "ret %08lx\n", hr);
221 test_current_encoding(body, IET_8BIT);
222
223 memset(&offsets, 0xcc, sizeof(offsets));
224 hr = IMimeBody_GetOffsets(body, &offsets);
225 ok(hr == MIME_E_NO_DATA, "ret %08lx\n", hr);
226 ok(offsets.cbBoundaryStart == 0, "got %ld\n", offsets.cbBoundaryStart);
227 ok(offsets.cbHeaderStart == 0, "got %ld\n", offsets.cbHeaderStart);
228 ok(offsets.cbBodyStart == 0, "got %ld\n", offsets.cbBodyStart);
229 ok(offsets.cbBodyEnd == 0, "got %ld\n", offsets.cbBodyEnd);
230
231 hr = IMimeBody_IsType(body, IBT_EMPTY);
232 ok(hr == S_FALSE, "got %08lx\n", hr);
233
235 ok(hr == S_OK, "ret %08lx\n", hr);
236
237 hr = IMimeBody_GetParameters(body, "nothere", &count, &param_info);
238 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
239 ok(count == 0, "got %ld\n", count);
240 ok(!param_info, "got %p\n", param_info);
241
242 hr = IMimeBody_GetParameters(body, "bar", &count, &param_info);
243 ok(hr == S_OK, "ret %08lx\n", hr);
244 ok(count == 0, "got %ld\n", count);
245 ok(!param_info, "got %p\n", param_info);
246
247 hr = IMimeBody_GetParameters(body, "Content-Type", &count, &param_info);
248 ok(hr == S_OK, "ret %08lx\n", hr);
249 todo_wine /* native adds a charset parameter */
250 ok(count == 4, "got %ld\n", count);
251 ok(param_info != NULL, "got %p\n", param_info);
252
253 found_param = 0;
254 for(i = 0; i < count; i++)
255 {
256 if(!strcmp(param_info[i].pszName, "morestuff"))
257 {
258 found_param++;
259 ok(!strcmp(param_info[i].pszData, "so\\me\"thing\""),
260 "got %s\n", param_info[i].pszData);
261 }
262 else if(!strcmp(param_info[i].pszName, "stuff"))
263 {
264 found_param++;
265 ok(!strcmp(param_info[i].pszData, "du;nno"),
266 "got %s\n", param_info[i].pszData);
267 }
268 }
269 ok(found_param == 2, "matched %ld params\n", found_param);
270
271 hr = IMimeAllocator_FreeParamInfoArray(alloc, count, param_info, TRUE);
272 ok(hr == S_OK, "ret %08lx\n", hr);
273 IMimeAllocator_Release(alloc);
274
275 IStream_Release(in);
276 IMimeBody_Release(body);
277}
278
279typedef struct {
282 unsigned pos;
283} TestStream;
284
286{
287 return CONTAINING_RECORD(iface, TestStream, IStream_iface);
288}
289
291{
292 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ISequentialStream, riid) || IsEqualGUID(&IID_IStream, riid)) {
293 *ppv = iface;
294 return S_OK;
295 }
296
297 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
298 *ppv = NULL;
299 return E_NOINTERFACE;
300}
301
303{
305 return InterlockedIncrement(&This->ref);
306}
307
309{
312
313 if (!ref)
315
316 return ref;
317}
318
319static HRESULT WINAPI Stream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
320{
322 BYTE *output = pv;
323 unsigned i;
324
326
327 for(i = 0; i < cb; i++)
328 output[i] = '0' + This->pos++;
329 *pcbRead = i;
330 return S_OK;
331}
332
333static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
334{
335 ok(0, "unexpected call\n");
336 return E_NOTIMPL;
337}
338
340
341static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin,
342 ULARGE_INTEGER *plibNewPosition)
343{
345
346 if(dwOrigin == STREAM_SEEK_END) {
347 CHECK_EXPECT(Stream_Seek_END);
348 ok(dlibMove.QuadPart == expect_seek_pos, "unexpected seek pos %lu\n", dlibMove.LowPart);
349 if(plibNewPosition)
350 plibNewPosition->QuadPart = 10;
351 return S_OK;
352 }
353
355
356 ok(dlibMove.QuadPart == expect_seek_pos, "unexpected seek pos %lu\n", dlibMove.LowPart);
357 ok(dwOrigin == STREAM_SEEK_SET, "dwOrigin = %ld\n", dwOrigin);
358 This->pos = dlibMove.QuadPart;
359 if(plibNewPosition)
360 plibNewPosition->QuadPart = This->pos;
361 return S_OK;
362}
363
365{
366 ok(0, "unexpected call\n");
367 return E_NOTIMPL;
368}
369
371 ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
372{
373 ok(0, "unexpected call\n");
374 return E_NOTIMPL;
375}
376
377static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
378{
379 ok(0, "unexpected call\n");
380 return E_NOTIMPL;
381}
382
384{
385 ok(0, "unexpected call\n");
386 return E_NOTIMPL;
387}
388
390 ULARGE_INTEGER cb, DWORD dwLockType)
391{
392 ok(0, "unexpected call\n");
393 return E_NOTIMPL;
394}
395
397 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
398{
399 ok(0, "unexpected call\n");
400 return E_NOTIMPL;
401}
402
403static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg, DWORD dwStatFlag)
404{
406 ok(dwStatFlag == STATFLAG_NONAME, "dwStatFlag = %lx\n", dwStatFlag);
407 return E_NOTIMPL;
408}
409
411{
412 ok(0, "unexpected call\n");
413 return E_NOTIMPL;
414}
415
416static const IStreamVtbl StreamVtbl = {
431};
432
434{
436 stream = HeapAlloc(GetProcessHeap(), 0, sizeof(*stream));
438 stream->ref = 1;
439 stream->pos = 0;
440 return &stream->IStream_iface;
441}
442
443#define test_stream_read(a,b,c,d) _test_stream_read(__LINE__,a,b,c,d)
444static void _test_stream_read(unsigned line, IStream *stream, HRESULT exhres, const char *exdata, unsigned read_size)
445{
446 ULONG read = 0xdeadbeed, exread = strlen(exdata);
447 char buf[1024];
449
450 if(read_size == -1)
451 read_size = sizeof(buf)-1;
452
453 hres = IStream_Read(stream, buf, read_size, &read);
454 ok_(__FILE__,line)(hres == exhres, "Read returned %08lx, expected %08lx\n", hres, exhres);
455 ok_(__FILE__,line)(read == exread, "unexpected read size %lu, expected %lu\n", read, exread);
456 buf[read] = 0;
457 ok_(__FILE__,line)(read == exread && !memcmp(buf, exdata, read), "unexpected data %s\n", buf);
458}
459
460static void test_SetData(void)
461{
462 IStream *stream, *stream2, *test_stream;
464 HRESULT hr;
465
466 hr = CoCreateInstance(&CLSID_IMimeBody, NULL, CLSCTX_INPROC_SERVER, &IID_IMimeBody, (void**)&body);
467 ok(hr == S_OK, "ret %08lx\n", hr);
468
469 /* Need to call InitNew before Load otherwise Load crashes with native inetcomm */
470 hr = IMimeBody_InitNew(body);
471 ok(hr == S_OK, "ret %08lx\n", hr);
472
474 hr = IMimeBody_Load(body, stream);
475 ok(hr == S_OK, "ret %08lx\n", hr);
476 IStream_Release(stream);
477
479 hr = IMimeBody_SetData(body, IET_BINARY, "text", "plain", &IID_IStream, test_stream);
480
481 ok(hr == S_OK, "ret %08lx\n", hr);
482 hr = IMimeBody_IsContentType(body, "text", "plain");
484 ok(hr == S_OK, "ret %08lx\n", hr);
485
486 test_current_encoding(body, IET_BINARY);
487
489 SET_EXPECT(Stream_Seek_END);
490 hr = IMimeBody_GetData(body, IET_BINARY, &stream);
492 CHECK_CALLED(Stream_Seek_END);
493 ok(hr == S_OK, "GetData failed %08lx\n", hr);
494 ok(stream != test_stream, "unexpected stream\n");
495
498 test_stream_read(stream, S_OK, "012", 3);
501
503 SET_EXPECT(Stream_Seek_END);
504 hr = IMimeBody_GetData(body, IET_BINARY, &stream2);
506 CHECK_CALLED(Stream_Seek_END);
507 ok(hr == S_OK, "GetData failed %08lx\n", hr);
508 ok(stream2 != stream, "unexpected stream\n");
509
512 test_stream_read(stream2, S_OK, "01", 2);
515
516 expect_seek_pos = 3;
519 test_stream_read(stream, S_OK, "345", 3);
522
523 IStream_Release(stream);
524 IStream_Release(stream2);
525 IStream_Release(test_stream);
526
527 stream = create_stream_from_string(" \t\r\n|}~YWJj ZGV|}~mZw== \t"); /* "abcdefg" in base64 obscured by invalid chars */
528 hr = IMimeBody_SetData(body, IET_BASE64, "text", "plain", &IID_IStream, stream);
529 IStream_Release(stream);
530 ok(hr == S_OK, "SetData failed: %08lx\n", hr);
531
532 test_current_encoding(body, IET_BASE64);
533
534 hr = IMimeBody_GetData(body, IET_BINARY, &stream);
535 ok(hr == S_OK, "GetData failed %08lx\n", hr);
536
537 test_stream_read(stream, S_OK, "abc", 3);
538 test_stream_read(stream, S_OK, "defg", -1);
539
540 IStream_Release(stream);
541
542 hr = IMimeBody_GetData(body, IET_BASE64, &stream);
543 ok(hr == S_OK, "GetData failed %08lx\n", hr);
544
545 test_stream_read(stream, S_OK, " \t\r", 3);
546 IStream_Release(stream);
547
548 stream = create_stream_from_string(" =3d=3D\"one\" \t=\r\ntw= o=\nx3\n=34\r\n5");
549 hr = IMimeBody_SetData(body, IET_QP, "text", "plain", &IID_IStream, stream);
550 IStream_Release(stream);
551 ok(hr == S_OK, "SetData failed: %08lx\n", hr);
552
554
555 hr = IMimeBody_GetData(body, IET_BINARY, &stream);
556 ok(hr == S_OK, "GetData failed %08lx\n", hr);
557
558 test_stream_read(stream, S_OK, " ==\"one\" \ttw=o=3\n4\r\n5", -1);
559
560 IStream_Release(stream);
561
562 IMimeBody_Release(body);
563}
564
565static void test_Allocator(void)
566{
567 HRESULT hr;
568 IMimeAllocator *alloc;
569
571 ok(hr == S_OK, "ret %08lx\n", hr);
572 IMimeAllocator_Release(alloc);
573}
574
575static void test_CreateMessage(void)
576{
577 HRESULT hr;
580 LONG ref;
581 HBODY hbody, hbody2;
583 BODYOFFSETS offsets;
584 ULONG count;
585 FINDBODY find_struct;
586 HCHARSET hcs;
587 HBODY handle = NULL;
588
589 char text[] = "text";
590 HBODY *body_list;
591 PROPVARIANT prop;
592 static const char att_pritype[] = "att:pri-content-type";
593
595 ok(hr == S_OK, "ret %08lx\n", hr);
596
598
599 hr = IMimeMessage_Load(msg, stream);
600 ok(hr == S_OK, "ret %08lx\n", hr);
601
602 hr = IMimeMessage_CountBodies(msg, HBODY_ROOT, TRUE, &count);
603 ok(hr == S_OK, "ret %08lx\n", hr);
604 ok(count == 3, "got %ld\n", count);
605
606 hr = IMimeMessage_CountBodies(msg, HBODY_ROOT, FALSE, &count);
607 ok(hr == S_OK, "ret %08lx\n", hr);
608 ok(count == 3, "got %ld\n", count);
609
610 hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
611 ok(hr == S_OK, "ret %08lx\n", hr);
612 hr = IMimeBody_GetOffsets(body, &offsets);
613 ok(hr == S_OK, "ret %08lx\n", hr);
614 ok(offsets.cbBoundaryStart == 0, "got %ld\n", offsets.cbBoundaryStart);
615 ok(offsets.cbHeaderStart == 0, "got %ld\n", offsets.cbHeaderStart);
616 ok(offsets.cbBodyStart == 359, "got %ld\n", offsets.cbBodyStart);
617 ok(offsets.cbBodyEnd == 666, "got %ld\n", offsets.cbBodyEnd);
618 IMimeBody_Release(body);
619
620 hr = IMimeMessage_GetBody(msg, IBL_ROOT, NULL, &hbody);
621 ok(hr == S_OK, "ret %08lx\n", hr);
622
623 hr = IMimeBody_GetHandle(body, NULL);
624 ok(hr == E_INVALIDARG, "ret %08lx\n", hr);
625
626 hr = IMimeBody_GetHandle(body, &handle);
627 ok(hr == S_OK, "ret %08lx\n", hr);
628 ok(handle != NULL, "handle %p\n", handle);
629
630 hr = IMimeMessage_GetBody(msg, IBL_PARENT, hbody, NULL);
631 ok(hr == E_INVALIDARG, "ret %08lx\n", hr);
632
633 hbody2 = (HBODY)0xdeadbeef;
634 hr = IMimeMessage_GetBody(msg, IBL_PARENT, hbody, &hbody2);
635 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
636 ok(hbody2 == NULL, "hbody2 %p\n", hbody2);
637
638 PropVariantInit(&prop);
639 hr = IMimeMessage_GetBodyProp(msg, hbody, att_pritype, 0, &prop);
640 ok(hr == S_OK, "ret %08lx\n", hr);
641 ok(prop.vt == VT_LPSTR, "vt %08x\n", prop.vt);
642 ok(!strcasecmp(prop.pszVal, "multipart"), "got %s\n", prop.pszVal);
643 PropVariantClear(&prop);
644
645 hr = IMimeMessage_GetBody(msg, IBL_FIRST, hbody, &hbody);
646 ok(hr == S_OK, "ret %08lx\n", hr);
647 hr = IMimeMessage_BindToObject(msg, hbody, &IID_IMimeBody, (void**)&body);
648 ok(hr == S_OK, "ret %08lx\n", hr);
649
650 hr = IMimeBody_GetHandle(body, &handle);
651 ok(hr == S_OK, "ret %08lx\n", hr);
652 ok(handle == hbody, "handle %p\n", handle);
653
654 hr = IMimeBody_GetOffsets(body, &offsets);
655 ok(hr == S_OK, "ret %08lx\n", hr);
656 ok(offsets.cbBoundaryStart == 405, "got %ld\n", offsets.cbBoundaryStart);
657 ok(offsets.cbHeaderStart == 428, "got %ld\n", offsets.cbHeaderStart);
658 ok(offsets.cbBodyStart == 518, "got %ld\n", offsets.cbBodyStart);
659 ok(offsets.cbBodyEnd == 523, "got %ld\n", offsets.cbBodyEnd);
660
661 hr = IMimeBody_GetCharset(body, &hcs);
662 ok(hr == S_OK, "ret %08lx\n", hr);
664 {
665 ok(hcs != NULL, "Expected non-NULL charset\n");
666 }
667
668 IMimeBody_Release(body);
669
670 hr = IMimeMessage_GetBody(msg, IBL_NEXT, hbody, &hbody);
671 ok(hr == S_OK, "ret %08lx\n", hr);
672 hr = IMimeMessage_BindToObject(msg, hbody, &IID_IMimeBody, (void**)&body);
673 ok(hr == S_OK, "ret %08lx\n", hr);
674
675 hr = IMimeBody_GetHandle(body, &handle);
676 ok(hr == S_OK, "ret %08lx\n", hr);
677 ok(handle == hbody, "handle %p\n", handle);
678
679 hr = IMimeBody_GetOffsets(body, &offsets);
680 ok(hr == S_OK, "ret %08lx\n", hr);
681 ok(offsets.cbBoundaryStart == 525, "got %ld\n", offsets.cbBoundaryStart);
682 ok(offsets.cbHeaderStart == 548, "got %ld\n", offsets.cbHeaderStart);
683 ok(offsets.cbBodyStart == 629, "got %ld\n", offsets.cbBodyStart);
684 ok(offsets.cbBodyEnd == 639, "got %ld\n", offsets.cbBodyEnd);
685 IMimeBody_Release(body);
686
687 find_struct.pszPriType = text;
688 find_struct.pszSubType = NULL;
689
690 hr = IMimeMessage_FindFirst(msg, &find_struct, &hbody);
691 ok(hr == S_OK, "ret %08lx\n", hr);
692
693 hr = IMimeMessage_FindNext(msg, &find_struct, &hbody);
694 ok(hr == S_OK, "ret %08lx\n", hr);
695
696 hr = IMimeMessage_FindNext(msg, &find_struct, &hbody);
697 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
698
699 hr = IMimeMessage_GetAttachments(msg, &count, &body_list);
700 ok(hr == S_OK, "ret %08lx\n", hr);
701 ok(count == 2, "got %ld\n", count);
702 if(count == 2)
703 {
705 PROPVARIANT prop;
706
707 PropVariantInit(&prop);
708
709 hr = IMimeMessage_BindToObject(msg, body_list[0], &IID_IMimeBody, (void**)&attachment);
710 ok(hr == S_OK, "ret %08lx\n", hr);
711
712 hr = IMimeBody_IsContentType(attachment, "multipart", NULL);
713 ok(hr == S_FALSE, "ret %08lx\n", hr);
714
716
717 prop.vt = VT_LPSTR;
718 hr = IMimeBody_GetProp(attachment, "Content-Transfer-Encoding", 0, &prop);
719 ok(hr == S_OK, "ret %08lx\n", hr);
720
721 ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
722 ok(!strcmp(prop.pszVal, "8bit"), "got %s\n", prop.pszVal);
723 PropVariantClear(&prop);
724
725 hr = IMimeBody_IsType(attachment, IBT_ATTACHMENT);
726 todo_wine ok(hr == S_FALSE, "ret %08lx\n", hr);
727
728 IMimeBody_Release(attachment);
729
730 hr = IMimeMessage_BindToObject(msg, body_list[1], &IID_IMimeBody, (void**)&attachment);
731 ok(hr == S_OK, "ret %08lx\n", hr);
732
733 hr = IMimeBody_IsContentType(attachment, "multipart", NULL);
734 ok(hr == S_FALSE, "ret %08lx\n", hr);
735
737
738 prop.vt = VT_LPSTR;
739 hr = IMimeBody_GetProp(attachment, "Content-Transfer-Encoding", 0, &prop);
740 ok(hr == S_OK, "ret %08lx\n", hr);
741 ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
742 ok(!strcmp(prop.pszVal, "7bit"), "got %s\n", prop.pszVal);
743 PropVariantClear(&prop);
744
745 hr = IMimeBody_IsType(attachment, IBT_ATTACHMENT);
746 ok(hr == S_OK, "ret %08lx\n", hr);
747
748 IMimeBody_Release(attachment);
749 }
750 CoTaskMemFree(body_list);
751
752 hr = IMimeBody_GetCharset(body, &hcs);
753 ok(hr == S_OK, "ret %08lx\n", hr);
755 {
756 ok(hcs != NULL, "Expected non-NULL charset\n");
757 }
758
759 IMimeMessage_Release(msg);
760
761 ref = IStream_AddRef(stream);
762 ok(ref == 2 ||
763 broken(ref == 1), /* win95 */
764 "ref %ld\n", ref);
765 IStream_Release(stream);
766
767 IStream_Release(stream);
768}
769
770static void test_mhtml_message(void)
771{
772 IMimeMessage *mime_message;
773 IMimeBody *mime_body;
774 HBODY *body_list;
776 ULONG count;
778
779 hres = MimeOleCreateMessage(NULL, &mime_message);
780 ok(hres == S_OK, "MimeOleCreateMessage failed: %08lx\n", hres);
781
783 hres = IMimeMessage_Load(mime_message, stream);
784 IStream_Release(stream);
785 ok(hres == S_OK, "Load failed: %08lx\n", hres);
786
787 hres = IMimeMessage_CountBodies(mime_message, HBODY_ROOT, TRUE, &count);
788 ok(hres == S_OK, "CountBodies failed: %08lx\n", hres);
789 ok(count == 3, "got %ld\n", count);
790
791 hres = IMimeMessage_GetAttachments(mime_message, &count, &body_list);
792 ok(hres == S_OK, "GetAttachments failed: %08lx\n", hres);
793 ok(count == 2, "count = %lu\n", count);
794
795 hres = IMimeMessage_BindToObject(mime_message, body_list[0], &IID_IMimeBody, (void**)&mime_body);
796 ok(hres == S_OK, "BindToObject failed: %08lx\n", hres);
797
798 hres = IMimeBody_GetData(mime_body, IET_BINARY, &stream);
799 ok(hres == S_OK, "GetData failed: %08lx\n", hres);
800 test_stream_read(stream, S_OK, "<HTML></HTML>", -1);
801 IStream_Release(stream);
802
803 test_current_encoding(mime_body, IET_QP);
804
805 IMimeBody_Release(mime_body);
806
807 hres = IMimeMessage_BindToObject(mime_message, body_list[1], &IID_IMimeBody, (void**)&mime_body);
808 ok(hres == S_OK, "BindToObject failed: %08lx\n", hres);
809
810 test_current_encoding(mime_body, IET_BASE64);
811
812 hres = IMimeBody_GetData(mime_body, IET_BINARY, &stream);
813 ok(hres == S_OK, "GetData failed: %08lx\n", hres);
814 test_stream_read(stream, S_OK, "Test", -1);
815 IStream_Release(stream);
816
817 IMimeBody_Release(mime_body);
818
819 CoTaskMemFree(body_list);
820
821 IMimeMessage_Release(mime_message);
822}
823
824static void test_MessageSetProp(void)
825{
826 static const char topic[] = "wine topic";
827 HRESULT hr;
830 PROPVARIANT prop;
831
833 ok(hr == S_OK, "ret %08lx\n", hr);
834
835 PropVariantInit(&prop);
836
837 hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
838 ok(hr == S_OK, "ret %08lx\n", hr);
839
840 hr = IMimeBody_SetProp(body, NULL, 0, &prop);
841 ok(hr == E_INVALIDARG, "ret %08lx\n", hr);
842
843 hr = IMimeBody_SetProp(body, "Thread-Topic", 0, NULL);
844 ok(hr == E_INVALIDARG, "ret %08lx\n", hr);
845
846 prop.vt = VT_LPSTR;
847 prop.pszVal = CoTaskMemAlloc(strlen(topic)+1);
848 strcpy(prop.pszVal, topic);
849 hr = IMimeBody_SetProp(body, "Thread-Topic", 0, &prop);
850 ok(hr == S_OK, "ret %08lx\n", hr);
851 PropVariantClear(&prop);
852
853 hr = IMimeBody_GetProp(body, NULL, 0, &prop);
854 ok(hr == E_INVALIDARG, "ret %08lx\n", hr);
855
856 hr = IMimeBody_GetProp(body, "Thread-Topic", 0, NULL);
857 ok(hr == E_INVALIDARG, "ret %08lx\n", hr);
858
859 hr = IMimeBody_GetProp(body, "Wine-Topic", 0, &prop);
860 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
861
862 prop.vt = VT_LPSTR;
863 hr = IMimeBody_GetProp(body, "Thread-Topic", 0, &prop);
864 ok(hr == S_OK, "ret %08lx\n", hr);
865 if(hr == S_OK)
866 {
867 ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
868 ok(!strcmp(prop.pszVal, topic), "got %s\n", prop.pszVal);
869 PropVariantClear(&prop);
870 }
871
872 prop.vt = VT_LPSTR;
873 prop.pszVal = CoTaskMemAlloc(strlen(topic)+1);
874 strcpy(prop.pszVal, topic);
875 hr = IMimeBody_SetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
876 ok(hr == S_OK, "ret %08lx\n", hr);
877 PropVariantClear(&prop);
878
879 prop.vt = VT_LPSTR;
880 hr = IMimeBody_GetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
881 ok(hr == S_OK, "ret %08lx\n", hr);
882 if(hr == S_OK)
883 {
884 ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
885 ok(!strcmp(prop.pszVal, topic), "got %s\n", prop.pszVal);
886 PropVariantClear(&prop);
887 }
888
889 /* Using the name or PID returns the same result. */
890 prop.vt = VT_LPSTR;
891 hr = IMimeBody_GetProp(body, "Subject", 0, &prop);
892 ok(hr == S_OK, "ret %08lx\n", hr);
893 if(hr == S_OK)
894 {
895 ok(prop.vt == VT_LPSTR, "type %d\n", prop.vt);
896 ok(!strcmp(prop.pszVal, topic), "got %s\n", prop.pszVal);
897 PropVariantClear(&prop);
898 }
899
900 prop.vt = VT_LPWSTR;
901 hr = IMimeBody_GetProp(body, "Subject", 0, &prop);
902 ok(hr == S_OK, "ret %08lx\n", hr);
903 if(hr == S_OK)
904 {
905 ok(prop.vt == VT_LPWSTR, "type %d\n", prop.vt);
906 ok(!lstrcmpW(prop.pwszVal, L"wine topic"), "got %s\n", wine_dbgstr_w(prop.pwszVal));
907 PropVariantClear(&prop);
908 }
909
910 prop.vt = VT_LPSTR;
911 prop.pszVal = CoTaskMemAlloc(strlen(topic)+1);
912 strcpy(prop.pszVal, topic);
913 hr = IMimeBody_SetProp(body, PIDTOSTR(PID_HDR_TO), 0, &prop);
914 ok(hr == S_OK, "ret %08lx\n", hr);
915 PropVariantClear(&prop);
916
917 /* Out of Range PID */
918 prop.vt = VT_LPSTR;
919 prop.pszVal = CoTaskMemAlloc(strlen(topic)+1);
920 strcpy(prop.pszVal, topic);
921 hr = IMimeBody_SetProp(body, PIDTOSTR(124), 0, &prop);
922 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
923 PropVariantClear(&prop);
924
925 IMimeBody_Release(body);
926 IMimeMessage_Release(msg);
927}
928
929static void test_MessageGetPropInfo(void)
930{
931 static const char topic[] = "wine topic";
932 static const char subject[] = "wine testing";
933 HRESULT hr;
936 PROPVARIANT prop;
937 MIMEPROPINFO info;
938
940 ok(hr == S_OK, "ret %08lx\n", hr);
941
942 PropVariantInit(&prop);
943
944 hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
945 ok(hr == S_OK, "ret %08lx\n", hr);
946
947 prop.vt = VT_LPSTR;
948 prop.pszVal = CoTaskMemAlloc(strlen(topic)+1);
949 strcpy(prop.pszVal, topic);
950 hr = IMimeBody_SetProp(body, "Thread-Topic", 0, &prop);
951 ok(hr == S_OK, "ret %08lx\n", hr);
952 PropVariantClear(&prop);
953
954 prop.vt = VT_LPSTR;
955 prop.pszVal = CoTaskMemAlloc(strlen(subject)+1);
956 strcpy(prop.pszVal, subject);
957 hr = IMimeBody_SetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
958 ok(hr == S_OK, "ret %08lx\n", hr);
959 PropVariantClear(&prop);
960
961 memset(&info, 0, sizeof(info));
962 info.dwMask = PIM_ENCODINGTYPE | PIM_FLAGS | PIM_PROPID;
963 hr = IMimeBody_GetPropInfo(body, NULL, &info);
964 ok(hr == E_INVALIDARG, "ret %08lx\n", hr);
965
966 memset(&info, 0, sizeof(info));
967 info.dwMask = PIM_ENCODINGTYPE | PIM_FLAGS | PIM_PROPID;
968 hr = IMimeBody_GetPropInfo(body, "Subject", NULL);
969 ok(hr == E_INVALIDARG, "ret %08lx\n", hr);
970
971 memset(&info, 0xfe, sizeof(info));
972 info.dwMask = PIM_ENCODINGTYPE | PIM_FLAGS | PIM_PROPID;
973 hr = IMimeBody_GetPropInfo(body, "Subject", &info);
974 ok(hr == S_OK, "ret %08lx\n", hr);
975 if(hr == S_OK)
976 {
977 ok(info.dwMask & (PIM_ENCODINGTYPE | PIM_FLAGS| PIM_PROPID), "Invalid mask 0x%08lx\n", info.dwFlags);
978 todo_wine ok(info.dwFlags & 0x10000000, "Invalid flags 0x%08lx\n", info.dwFlags);
979 ok(info.ietEncoding == 0, "Invalid encoding %d\n", info.ietEncoding);
980 ok(info.dwPropId == PID_HDR_SUBJECT, "Invalid propid %ld\n", info.dwPropId);
981 ok(info.cValues == 0xfefefefe, "Invalid cValues %ld\n", info.cValues);
982 }
983
984 memset(&info, 0xfe, sizeof(info));
985 info.dwMask = 0;
986 hr = IMimeBody_GetPropInfo(body, "Subject", &info);
987 ok(hr == S_OK, "ret %08lx\n", hr);
988 if(hr == S_OK)
989 {
990 ok(info.dwMask == 0, "Invalid mask 0x%08lx\n", info.dwFlags);
991 ok(info.dwFlags == 0xfefefefe, "Invalid flags 0x%08lx\n", info.dwFlags);
992 ok(info.ietEncoding == -16843010, "Invalid encoding %d\n", info.ietEncoding);
993 ok(info.dwPropId == -16843010, "Invalid propid %ld\n", info.dwPropId);
994 }
995
996 memset(&info, 0xfe, sizeof(info));
997 info.dwMask = 0;
998 info.dwPropId = 1024;
999 info.ietEncoding = 99;
1000 hr = IMimeBody_GetPropInfo(body, "Subject", &info);
1001 ok(hr == S_OK, "ret %08lx\n", hr);
1002 if(hr == S_OK)
1003 {
1004 ok(info.dwMask == 0, "Invalid mask 0x%08lx\n", info.dwFlags);
1005 ok(info.dwFlags == 0xfefefefe, "Invalid flags 0x%08lx\n", info.dwFlags);
1006 ok(info.ietEncoding == 99, "Invalid encoding %d\n", info.ietEncoding);
1007 ok(info.dwPropId == 1024, "Invalid propid %ld\n", info.dwPropId);
1008 }
1009
1010 memset(&info, 0, sizeof(info));
1011 info.dwMask = PIM_ENCODINGTYPE | PIM_FLAGS | PIM_PROPID;
1012 hr = IMimeBody_GetPropInfo(body, "Invalid Property", &info);
1013 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
1014
1015 IMimeBody_Release(body);
1016 IMimeMessage_Release(msg);
1017}
1018
1019static void test_MessageOptions(void)
1020{
1021 static const char string[] = "XXXXX";
1022 static const char zero[] = "0";
1023 HRESULT hr;
1025 PROPVARIANT prop;
1026
1028 ok(hr == S_OK, "ret %08lx\n", hr);
1029
1030 PropVariantInit(&prop);
1031
1032 prop.vt = VT_BOOL;
1033 prop.boolVal = TRUE;
1034 hr = IMimeMessage_SetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1035 ok(hr == S_OK, "ret %08lx\n", hr);
1036 PropVariantClear(&prop);
1037
1038 hr = IMimeMessage_GetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1039 todo_wine ok(hr == S_OK, "ret %08lx\n", hr);
1040 todo_wine ok(prop.vt == VT_BOOL, "vt %08x\n", prop.vt);
1041 todo_wine ok(prop.boolVal == TRUE, "Hide Attachments got %d\n", prop.boolVal);
1042 PropVariantClear(&prop);
1043
1044 prop.vt = VT_LPSTR;
1045 prop.pszVal = CoTaskMemAlloc(strlen(string)+1);
1046 strcpy(prop.pszVal, string);
1047 hr = IMimeMessage_SetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1048 ok(hr == S_OK, "ret %08lx\n", hr);
1049 PropVariantClear(&prop);
1050
1051 hr = IMimeMessage_GetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1052 todo_wine ok(hr == S_OK, "ret %08lx\n", hr);
1053 todo_wine ok(prop.vt == VT_BOOL, "vt %08x\n", prop.vt);
1054 todo_wine ok(prop.boolVal == TRUE, "Hide Attachments got %d\n", prop.boolVal);
1055 PropVariantClear(&prop);
1056
1057 /* Invalid property type doesn't change the value */
1058 prop.vt = VT_LPSTR;
1059 prop.pszVal = CoTaskMemAlloc(strlen(zero)+1);
1060 strcpy(prop.pszVal, zero);
1061 hr = IMimeMessage_SetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1062 ok(hr == S_OK, "ret %08lx\n", hr);
1063 PropVariantClear(&prop);
1064
1065 hr = IMimeMessage_GetOption(msg, OID_HIDE_TNEF_ATTACHMENTS, &prop);
1066 todo_wine ok(hr == S_OK, "ret %08lx\n", hr);
1067 todo_wine ok(prop.vt == VT_BOOL, "vt %08x\n", prop.vt);
1068 todo_wine ok(prop.boolVal == TRUE, "Hide Attachments got %d\n", prop.boolVal);
1069 PropVariantClear(&prop);
1070
1071 /* Invalid OID */
1072 prop.vt = VT_BOOL;
1073 prop.boolVal = TRUE;
1074 hr = IMimeMessage_SetOption(msg, 0xff00000a, &prop);
1075 ok(hr == MIME_E_INVALID_OPTION_ID, "ret %08lx\n", hr);
1076 PropVariantClear(&prop);
1077
1078 /* Out of range before type. */
1079 prop.vt = VT_I4;
1080 prop.lVal = 1;
1081 hr = IMimeMessage_SetOption(msg, 0xff00000a, &prop);
1082 ok(hr == MIME_E_INVALID_OPTION_ID, "ret %08lx\n", hr);
1083 PropVariantClear(&prop);
1084
1085 IMimeMessage_Release(msg);
1086}
1087
1088static void test_BindToObject(void)
1089{
1090 HRESULT hr;
1092 IMimeBody *body;
1093 ULONG count;
1094
1096 ok(hr == S_OK, "ret %08lx\n", hr);
1097
1098 hr = IMimeMessage_CountBodies(msg, HBODY_ROOT, TRUE, &count);
1099 ok(hr == S_OK, "ret %08lx\n", hr);
1100 ok(count == 1, "got %ld\n", count);
1101
1102 hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
1103 ok(hr == S_OK, "ret %08lx\n", hr);
1104 IMimeBody_Release(body);
1105
1106 IMimeMessage_Release(msg);
1107}
1108
1109static void test_BodyDeleteProp(void)
1110{
1111 static const char topic[] = "wine topic";
1112 HRESULT hr;
1114 IMimeBody *body;
1115 PROPVARIANT prop;
1116
1118 ok(hr == S_OK, "ret %08lx\n", hr);
1119
1120 PropVariantInit(&prop);
1121
1122 hr = IMimeMessage_BindToObject(msg, HBODY_ROOT, &IID_IMimeBody, (void**)&body);
1123 ok(hr == S_OK, "ret %08lx\n", hr);
1124
1125 hr = IMimeBody_DeleteProp(body, "Subject");
1126 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
1127
1128 hr = IMimeBody_DeleteProp(body, PIDTOSTR(PID_HDR_SUBJECT));
1129 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
1130
1131 prop.vt = VT_LPSTR;
1132 prop.pszVal = CoTaskMemAlloc(strlen(topic)+1);
1133 strcpy(prop.pszVal, topic);
1134 hr = IMimeBody_SetProp(body, "Subject", 0, &prop);
1135 ok(hr == S_OK, "ret %08lx\n", hr);
1136 PropVariantClear(&prop);
1137
1138 hr = IMimeBody_DeleteProp(body, "Subject");
1139 ok(hr == S_OK, "ret %08lx\n", hr);
1140
1141 hr = IMimeBody_GetProp(body, "Subject", 0, &prop);
1142 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
1143
1144 prop.vt = VT_LPSTR;
1145 prop.pszVal = CoTaskMemAlloc(strlen(topic)+1);
1146 strcpy(prop.pszVal, topic);
1147 hr = IMimeBody_SetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
1148 ok(hr == S_OK, "ret %08lx\n", hr);
1149 PropVariantClear(&prop);
1150
1151 hr = IMimeBody_DeleteProp(body, PIDTOSTR(PID_HDR_SUBJECT));
1152 ok(hr == S_OK, "ret %08lx\n", hr);
1153
1154 hr = IMimeBody_GetProp(body, PIDTOSTR(PID_HDR_SUBJECT), 0, &prop);
1155 ok(hr == MIME_E_NOT_FOUND, "ret %08lx\n", hr);
1156
1157 IMimeBody_Release(body);
1158 IMimeMessage_Release(msg);
1159}
1160
1162{
1163 HRESULT hr;
1164 IMimePropertySchema *schema = NULL;
1165
1167 ok(hr == S_OK, "ret %08lx\n", hr);
1168
1169 IMimePropertySchema_Release(schema);
1170}
1171
1172typedef struct {
1173 const char *url;
1174 const char *content;
1175 const WCHAR *mime;
1176 const char *data;
1178
1180 {
1181 "mhtml:file://%s",
1183 L"text/html",
1184 "<HTML></HTML>"
1185 },
1186 {
1187 "mhtml:file://%s!http://winehq.org/mhtmltest.html",
1189 L"Image/Jpeg",
1190 "Test"
1191 }
1192};
1193
1196
1198{
1199 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1200 *ppv = iface;
1201 return S_OK;
1202 }
1203
1204 *ppv = NULL;
1205 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1206 return E_NOINTERFACE;
1207}
1208
1210{
1211 return 2;
1212}
1213
1215{
1216 return 1;
1217}
1218
1219static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1220{
1221 CHECK_EXPECT(GetBindInfo);
1222
1223 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1224 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1225 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %ld\n", pbindinfo->cbSize);
1226
1227 *grfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
1228 return S_OK;
1229}
1230
1231static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr,
1232 ULONG cEl, ULONG *pcElFetched)
1233{
1234 ok(0, "unexpected call\n");
1235 return E_NOTIMPL;
1236}
1237
1238static IInternetBindInfoVtbl InternetBindInfoVtbl = {
1244};
1245
1248};
1249
1251{
1252 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1253 *ppv = NULL;
1254 return E_NOINTERFACE;
1255}
1256
1258{
1259 return 2;
1260}
1261
1263{
1264 return 1;
1265}
1266
1268 REFIID riid, void **ppv)
1269{
1270 if(IsEqualGUID(&CLSID_MimeEdit, guidService)) {
1271 *ppv = NULL;
1272 return E_NOINTERFACE;
1273 }
1274
1275 ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
1276 return E_FAIL;
1277}
1278
1279static const IServiceProviderVtbl ServiceProviderVtbl = {
1284};
1285
1287
1289{
1290 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
1291 *ppv = iface;
1292 return S_OK;
1293 }
1294
1295 if(IsEqualGUID(&IID_IServiceProvider, riid)) {
1297 return S_OK;
1298 }
1299
1300 *ppv = NULL;
1301 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1302 return E_NOINTERFACE;
1303}
1304
1306{
1307 return 2;
1308}
1309
1311{
1312 return 1;
1313}
1314
1315static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1316{
1317 ok(0, "unexpected call\n");
1318 return E_NOTIMPL;
1319}
1320
1322 const WCHAR *szStatusText)
1323{
1324 switch(ulStatusCode) {
1325 case BINDSTATUS_MIMETYPEAVAILABLE:
1326 CHECK_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1327 ok(!lstrcmpW(szStatusText, current_binding_test->mime), "status text %s\n", wine_dbgstr_w(szStatusText));
1328 return S_OK;
1329 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
1330 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1331 return S_OK;
1332 default:
1333 ok(0, "unexpected call %lu %s\n", ulStatusCode, wine_dbgstr_w(szStatusText));
1334 }
1335
1336 return E_NOTIMPL;
1337}
1338
1340 ULONG ulProgressMax)
1341{
1342 char buf[1024];
1343 DWORD read;
1344 HRESULT hres;
1345
1346 CHECK_EXPECT(ReportData);
1347
1348 ok(!ulProgress, "ulProgress = %lu\n", ulProgress);
1349 ok(ulProgress == ulProgressMax, "ulProgress != ulProgressMax\n");
1350 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_INTERMEDIATEDATANOTIFICATION
1351 | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE | BSCF_AVAILABLEDATASIZEUNKNOWN),
1352 "grcf = %08lx\n", grfBSCF);
1353
1354 hres = IInternetProtocol_Read(current_binding_protocol, buf, sizeof(buf), &read);
1355 ok(hres == S_OK, "Read failed: %08lx\n", hres);
1356 buf[read] = 0;
1357 ok(!strcmp(buf, current_binding_test->data), "unexpected data: %s\n", buf);
1358
1359 hres = IInternetProtocol_Read(current_binding_protocol, buf, sizeof(buf), &read);
1360 ok(hres == S_FALSE, "Read failed: %08lx\n", hres);
1361 return S_OK;
1362}
1363
1365 LPCWSTR szResult)
1366{
1367 CHECK_EXPECT(ReportResult);
1368 ok(hrResult == S_OK, "hrResult = %08lx\n", hrResult);
1369 ok(!dwError, "dwError = %lu\n", dwError);
1370 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1371 return S_OK;
1372}
1373
1374static IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
1382};
1383
1385
1387{
1388 char file_name[MAX_PATH+32], *p, urla[INTERNET_MAX_URL_LENGTH];
1391 IUnknown *unk;
1392 HRESULT hres;
1393 HANDLE file;
1394 DWORD size;
1395 BOOL ret;
1396
1398 *p++ = '\\';
1399 strcpy(p, "winetest.mht");
1400
1403 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
1404
1405 WriteFile(file, test->content, strlen(test->content), &size, NULL);
1407
1408 sprintf(urla, test->url, file_name);
1410
1411 hres = CoCreateInstance(&CLSID_IMimeHtmlProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void**)&protocol);
1412 ok(hres == S_OK, "Could not create protocol handler: %08lx\n", hres);
1413
1414 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&unk);
1415 ok(hres == E_NOINTERFACE, "Could get IInternetProtocolEx\n");
1416
1419
1420 SET_EXPECT(GetBindInfo);
1421 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1422 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1423 SET_EXPECT(ReportData);
1424 SET_EXPECT(ReportResult);
1425 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
1426 ok(hres == S_OK, "Start failed: %08lx\n", hres);
1427 CHECK_CALLED(GetBindInfo);
1428 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1429 todo_wine CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1430 CHECK_CALLED(ReportData);
1431 CHECK_CALLED(ReportResult);
1432
1433 IInternetProtocol_Release(protocol);
1434 ret = DeleteFileA("winetest.mht");
1435 ok(ret, "DeleteFile failed: %lu\n", GetLastError());
1436}
1437
1438static const struct {
1443} combine_tests[] = {
1444 {
1445 L"mhtml:file:///c:/dir/test.mht", L"http://test.org",
1446 L"mhtml:file:///c:/dir/test.mht!x-usc:http://test.org"
1447 }, {
1448 L"mhtml:file:///c:/dir/test.mht", L"3D\"http://test.org\"",
1449 L"mhtml:file:///c:/dir/test.mht!x-usc:3D\"http://test.org\""
1450 }, {
1451 L"mhtml:file:///c:/dir/test.mht", L"123abc",
1452 L"mhtml:file:///c:/dir/test.mht!x-usc:123abc"
1453 }, {
1454 L"mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", L"123abc",
1455 L"mhtml:file:///c:/dir/test.mht!x-usc:123abc"
1456 }, {
1457 L"MhtMl:file:///c:/dir/test.mht!x-usc:http://test.org/dir/dir2/file.html", L"../..",
1458 L"mhtml:file:///c:/dir/test.mht!x-usc:../.."
1459 }, {
1460 L"mhtml:file:///c:/dir/test.mht!x-usc:file:///c:/dir/dir2/file.html", L"../..",
1461 L"mhtml:file:///c:/dir/test.mht!x-usc:../.."
1462 }, {
1463 L"mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", L"",
1464 L"mhtml:file:///c:/dir/test.mht"
1465 }, {
1466 L"mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", L"mhtml:file:///d:/file.html",
1467 L"file:///d:/file.html", TRUE
1468 }, {
1469 L"mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", L"mhtml:file:///c:/dir2/test.mht!x-usc:http://test.org",
1470 L"mhtml:file:///c:/dir2/test.mht!x-usc:http://test.org", TRUE
1471 }, {
1472 L"mhtml:file:///c:/dir/test.mht!http://test.org", L"123abc",
1473 L"mhtml:file:///c:/dir/test.mht!x-usc:123abc"
1474 }, {
1475 L"mhtml:file:///c:/dir/test.mht!http://test.org", L"",
1476 L"mhtml:file:///c:/dir/test.mht"
1477 }
1479
1481{
1484 DWORD combined_len;
1485 unsigned i, exlen;
1486 HRESULT hres;
1487
1488 hres = CoCreateInstance(&CLSID_IMimeHtmlProtocol, NULL, CLSCTX_INPROC_SERVER,
1489 &IID_IInternetProtocolInfo, (void**)&protocol_info);
1490 ok(hres == S_OK, "Could not create protocol info: %08lx\n", hres);
1491
1492 for(i = 0; i < ARRAY_SIZE(combine_tests); i++) {
1493 combined_len = 0xdeadbeef;
1494 hres = IInternetProtocolInfo_CombineUrl(protocol_info, combine_tests[i].base_url,
1496 combined_url, ARRAY_SIZE(combined_url), &combined_len, 0);
1498 ok(hres == S_OK, "[%u] CombineUrl failed: %08lx\n", i, hres);
1499 if(SUCCEEDED(hres)) {
1501 ok(combined_len == exlen, "[%u] combined len is %lu, expected %u\n", i, combined_len, exlen);
1502 ok(!lstrcmpW(combined_url, combine_tests[i].expected_result), "[%u] combined URL is %s, expected %s\n",
1504
1505 combined_len = 0xdeadbeef;
1506 hres = IInternetProtocolInfo_CombineUrl(protocol_info, combine_tests[i].base_url,
1508 combined_url, exlen, &combined_len, 0);
1509 ok(hres == E_FAIL, "[%u] CombineUrl returned: %08lx\n", i, hres);
1510 ok(!combined_len, "[%u] combined_len = %lu\n", i, combined_len);
1511 }
1512 }
1513
1514 hres = IInternetProtocolInfo_CombineUrl(protocol_info, L"http://test.org", L"http://test.org",
1516 &combined_len, 0);
1517 ok(hres == E_FAIL, "CombineUrl failed: %08lx\n", hres);
1518
1519 IInternetProtocolInfo_Release(protocol_info);
1520}
1521
1523{
1524 ok(0, "unexpected call\n");
1525 return E_NOINTERFACE;
1526}
1527
1529{
1530 return 2;
1531}
1532
1534{
1535 return 1;
1536}
1537
1538static const IUnknownVtbl outer_vtbl = {
1542};
1543
1545
1546static void test_mhtml_protocol(void)
1547{
1548 IUnknown outer = { &outer_vtbl };
1550 IUnknown *unk, *unk2;
1551 unsigned i;
1552 HRESULT hres;
1553
1554 /* test class factory */
1555 hres = CoGetClassObject(&CLSID_IMimeHtmlProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
1556 ok(hres == S_OK, "CoGetClassObject failed: %08lx\n", hres);
1557
1558 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&unk2);
1559 ok(hres == E_NOINTERFACE, "IInternetProtocolInfo supported\n");
1560
1561 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&class_factory);
1562 ok(hres == S_OK, "Could not get IClassFactory iface: %08lx\n", hres);
1563 IUnknown_Release(unk);
1564
1565 hres = IClassFactory_CreateInstance(class_factory, &outer, &IID_IUnknown, (void**)&unk);
1566 ok(hres == S_OK, "CreateInstance returned: %08lx\n", hres);
1567 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&unk2);
1568 ok(hres == S_OK, "Could not get IInternetProtocol iface: %08lx\n", hres);
1569 IUnknown_Release(unk2);
1570 IUnknown_Release(unk);
1571
1572 hres = IClassFactory_CreateInstance(class_factory, (IUnknown*)0xdeadbeef, &IID_IInternetProtocol, (void**)&unk2);
1573 ok(hres == CLASS_E_NOAGGREGATION, "CreateInstance returned: %08lx\n", hres);
1574
1575 IClassFactory_Release(class_factory);
1576
1579
1580 for(i = 0; i < ARRAY_SIZE(binding_tests); i++)
1582}
1583
1585{
1586 IMoniker *mon, *new_mon;
1587 WCHAR *mhtml_url;
1588 IBindCtx *bind_ctx;
1589 IUnknown *unk;
1590 unsigned i;
1591 HRESULT hres;
1592
1593 static const struct {
1594 const WCHAR *url;
1595 const WCHAR *mhtml_url;
1596 } tests[] = {
1597 {L"file:///x:\\dir\\file.mht", L"mhtml:file://x:\\dir\\file.mht"},
1598 {L"file:///x:/dir/file.mht", L"mhtml:file://x:\\dir\\file.mht"},
1599 {L"http://www.winehq.org/index.html?query#hash", L"mhtml:http://www.winehq.org/index.html?query#hash"},
1600 {L"../test.mht", L"mhtml:../test.mht"}
1601 };
1602
1603 for(i = 0; i < ARRAY_SIZE(tests); i++) {
1604 hres = CreateURLMoniker(NULL, tests[i].url, &mon);
1605 ok(hres == S_OK, "CreateURLMoniker failed: %08lx\n", hres);
1606
1607 hres = CreateBindCtx(0, &bind_ctx);
1608 ok(hres == S_OK, "CreateBindCtx failed: %08lx\n", hres);
1609
1610 hres = MimeOleObjectFromMoniker(0, mon, bind_ctx, &IID_IUnknown, (void**)&unk, &new_mon);
1611 ok(hres == S_OK || broken(!i && hres == INET_E_RESOURCE_NOT_FOUND), "MimeOleObjectFromMoniker failed: %08lx\n", hres);
1612 IBindCtx_Release(bind_ctx);
1613 if(hres == INET_E_RESOURCE_NOT_FOUND) { /* winxp */
1614 win_skip("Broken MHTML behaviour found. Skipping some tests.\n");
1616 return;
1617 }
1618
1619 hres = IMoniker_GetDisplayName(new_mon, NULL, NULL, &mhtml_url);
1620 ok(hres == S_OK, "GetDisplayName failed: %08lx\n", hres);
1621 ok(!lstrcmpW(mhtml_url, tests[i].mhtml_url), "[%d] unexpected mhtml URL: %s\n", i, wine_dbgstr_w(mhtml_url));
1622 CoTaskMemFree(mhtml_url);
1623
1624 IUnknown_Release(unk);
1625 IMoniker_Release(new_mon);
1626 IMoniker_Release(mon);
1627 }
1628}
1629
1631{
1636 test_SetData();
1649}
#define read
Definition: acwin.h:97
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#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:20
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
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: combase.c:709
HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(REFCLSID rclsid, DWORD clscontext, COSERVERINFO *server_info, REFIID riid, void **obj)
Definition: combase.c:1925
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
#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
#define lstrlenW
Definition: compat.h:750
HRESULT WINAPI MimeOleGetPropertySchema(IMimePropertySchema **schema)
Definition: mimeole.c:3626
static sub_stream_t * impl_from_IStream(IStream *iface)
Definition: mimeole.c:177
HRESULT WINAPI MimeOleObjectFromMoniker(BINDF bindf, IMoniker *moniker, IBindCtx *binding, REFIID riid, void **out, IMoniker **moniker_new)
Definition: mimeole.c:3679
HRESULT WINAPI MimeOleGetAllocator(IMimeAllocator **alloc)
Definition: mimeole.c:3513
HRESULT WINAPI MimeOleCreateVirtualStream(IStream **ppStream)
Definition: mimeole.c:3122
HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity)
Definition: mimeole.c:3314
HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessage)
Definition: mimeole.c:3104
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI WriteFile(_In_ HANDLE hFile, _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, _In_ DWORD nNumberOfBytesToWrite, _Out_opt_ LPDWORD lpNumberOfBytesWritten, _Inout_opt_ LPOVERLAPPED lpOverlapped)
Definition: rw.c:25
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2065
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
const WCHAR * text
Definition: package.c:1794
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:162
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:218
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#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 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
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
const WCHAR * schema
@ PID_HDR_SUBJECT
Definition: mimeole.idl:81
@ PID_HDR_TO
Definition: mimeole.idl:101
#define win_skip
Definition: minitest.h:67
#define todo_wine_if(is_todo)
Definition: minitest.h:81
#define todo_wine
Definition: minitest.h:80
#define CREATE_ALWAYS
Definition: disk.h:72
static struct test_info tests[]
#define sprintf
Definition: sprintf.c:45
static const WCHAR url[]
Definition: encode.c:1384
static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
Definition: mimeole.c:1267
#define SET_EXPECT(func)
Definition: mimeole.c:37
const WCHAR * base_url
Definition: mimeole.c:1439
static ULONG WINAPI Stream_AddRef(IStream *iface)
Definition: mimeole.c:302
const WCHAR * expected_result
Definition: mimeole.c:1441
static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
Definition: mimeole.c:1315
static void test_MimeOleObjectFromMoniker(void)
Definition: mimeole.c:1584
static const IUnknownVtbl outer_vtbl
Definition: mimeole.c:1538
static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
Definition: mimeole.c:1262
static void test_mhtml_protocol_info(void)
Definition: mimeole.c:1480
static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
Definition: mimeole.c:1214
static HRESULT WINAPI Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
Definition: mimeole.c:364
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: mimeole.c:1528
static HRESULT WINAPI Stream_Revert(IStream *iface)
Definition: mimeole.c:383
static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg, DWORD dwStatFlag)
Definition: mimeole.c:403
#define test_stream_read(a, b, c, d)
Definition: mimeole.c:443
static IInternetProtocolSinkVtbl InternetProtocolSinkVtbl
Definition: mimeole.c:1374
static void test_mhtml_message(void)
Definition: mimeole.c:770
static HRESULT WINAPI Stream_CopyTo(IStream *iface, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
Definition: mimeole.c:370
static void test_CreateSecurity(void)
Definition: mimeole.c:124
static IInternetProtocol * current_binding_protocol
Definition: mimeole.c:1195
#define CHECK_EXPECT(func)
Definition: mimeole.c:40
static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
Definition: mimeole.c:1310
static BOOL broken_mhtml_resolver
Definition: mimeole.c:1544
#define DEFINE_EXPECT(func)
Definition: mimeole.c:34
static void test_MessageGetPropInfo(void)
Definition: mimeole.c:929
static HRESULT WINAPI Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: mimeole.c:389
static IServiceProvider service_provider
Definition: mimeole.c:1286
static HRESULT WINAPI Stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
Definition: mimeole.c:290
static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1197
static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
Definition: mimeole.c:410
static const char mhtml_page1[]
Definition: mimeole.c:97
static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
Definition: mimeole.c:1219
static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1288
static IStream * create_stream_from_string(const char *data)
Definition: mimeole.c:135
static void test_MessageSetProp(void)
Definition: mimeole.c:824
static void test_MessageOptions(void)
Definition: mimeole.c:1019
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1522
static HRESULT WINAPI Stream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: mimeole.c:396
static void test_CreateVirtualStream(void)
Definition: mimeole.c:113
static const mhtml_binding_test_t * current_binding_test
Definition: mimeole.c:1194
static void test_mhtml_protocol(void)
Definition: mimeole.c:1546
static IInternetProtocolSink protocol_sink
Definition: mimeole.c:1384
static DWORD expect_seek_pos
Definition: mimeole.c:339
static const mhtml_binding_test_t binding_tests[]
Definition: mimeole.c:1179
static IStream * create_test_stream(void)
Definition: mimeole.c:433
BOOL todo
Definition: mimeole.c:1442
#define CHECK_CALLED(func)
Definition: mimeole.c:53
static const char msg1[]
Definition: mimeole.c:69
static void test_MimeOleGetPropertySchema(void)
Definition: mimeole.c:1161
static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
Definition: mimeole.c:1364
const WCHAR * relative_url
Definition: mimeole.c:1440
static ULONG WINAPI Stream_Release(IStream *iface)
Definition: mimeole.c:308
static const IStreamVtbl StreamVtbl
Definition: mimeole.c:416
static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
Definition: mimeole.c:377
static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: mimeole.c:341
static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: mimeole.c:333
static void test_mhtml_protocol_binding(const mhtml_binding_test_t *test)
Definition: mimeole.c:1386
static void test_BodyDeleteProp(void)
Definition: mimeole.c:1109
static void test_BindToObject(void)
Definition: mimeole.c:1088
static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
Definition: mimeole.c:1339
static HRESULT WINAPI Stream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: mimeole.c:319
static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
Definition: mimeole.c:1250
#define test_current_encoding(a, b)
Definition: mimeole.c:154
static const struct @1810 combine_tests[]
static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode, const WCHAR *szStatusText)
Definition: mimeole.c:1321
static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
Definition: mimeole.c:1257
static const IServiceProviderVtbl ServiceProviderVtbl
Definition: mimeole.c:1279
static IInternetBindInfoVtbl InternetBindInfoVtbl
Definition: mimeole.c:1238
static void test_CreateBody(void)
Definition: mimeole.c:165
static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
Definition: mimeole.c:1231
static void _test_current_encoding(unsigned line, IMimeBody *mime_body, ENCODINGTYPE encoding)
Definition: mimeole.c:155
static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
Definition: mimeole.c:1209
static IInternetBindInfo bind_info
Definition: mimeole.c:1246
static void test_CreateMessage(void)
Definition: mimeole.c:575
static void _test_stream_read(unsigned line, IStream *stream, HRESULT exhres, const char *exdata, unsigned read_size)
Definition: mimeole.c:444
static void test_Allocator(void)
Definition: mimeole.c:565
static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
Definition: mimeole.c:1305
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: mimeole.c:1533
static void test_SetData(void)
Definition: mimeole.c:460
HRESULT hres
Definition: protocol.c:465
const char * combined_url
Definition: protocol.c:466
static IUnknown * outer
Definition: compobj.c:82
static IInternetProtocolInfo protocol_info
Definition: misc.c:947
static LPCWSTR file_name
Definition: protocol.c:147
static const char test_url[]
Definition: urlcache.c:37
const CLSID * clsid
Definition: msctf.cpp:50
#define GENERIC_WRITE
Definition: nt_native.h:90
HRESULT WINAPI CreateBindCtx(DWORD reserved, IBindCtx **bind_context)
Definition: bindctx.c:491
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
static const char topic[]
Definition: propsys.c:45
#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
strcpy
Definition: string.h:131
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:171
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
LONG ref
Definition: mimeole.c:281
unsigned pos
Definition: mimeole.c:282
IStream IStream_iface
Definition: mimeole.c:280
Definition: scsiwmi.h:51
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: fci.c:127
Definition: parser.c:49
const char * url
Definition: mimeole.c:1173
const char * data
Definition: mimeole.c:1176
const WCHAR * mime
Definition: mimeole.c:1175
const char * content
Definition: mimeole.c:1174
Definition: send.c:48
Definition: parse.h:23
ULARGE_INTEGER pos
Definition: request.c:5735
IStream IStream_iface
Definition: request.c:5732
const uint16_t * LPCWSTR
Definition: typedefs.h:57
#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
ULONG LowPart
Definition: typedefs.h:106
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define INET_E_RESOURCE_NOT_FOUND
Definition: winerror.h:4655
#define ICU_BROWSER_MODE
Definition: winhttp.h:356
#define INTERNET_MAX_URL_LENGTH
Definition: wininet.h:51
unsigned char BYTE
Definition: xxhash.c:193