inetcomm: Copy RFC822 headers into a memory block for later parsing.
This commit is contained in:
parent
c2f0697763
commit
98dfca50bb
|
@ -2,6 +2,7 @@
|
||||||
* MIME OLE Interfaces
|
* MIME OLE Interfaces
|
||||||
*
|
*
|
||||||
* Copyright 2006 Robert Shearman for CodeWeavers
|
* Copyright 2006 Robert Shearman for CodeWeavers
|
||||||
|
* Copyright 2007 Huw Davies for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -49,6 +50,86 @@ static inline MimeBody *impl_from_IMimeBody( IMimeBody *iface )
|
||||||
return (MimeBody *)((char*)iface - FIELD_OFFSET(MimeBody, lpVtbl));
|
return (MimeBody *)((char*)iface - FIELD_OFFSET(MimeBody, lpVtbl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PARSER_BUF_SIZE 1024
|
||||||
|
|
||||||
|
/*****************************************************
|
||||||
|
* copy_headers_to_buf [internal]
|
||||||
|
*
|
||||||
|
* Copies the headers into a '\0' terminated memory block and leave
|
||||||
|
* the stream's current position set to after the blank line.
|
||||||
|
*/
|
||||||
|
static HRESULT copy_headers_to_buf(IStream *stm, char **ptr)
|
||||||
|
{
|
||||||
|
char *buf = NULL;
|
||||||
|
DWORD size = PARSER_BUF_SIZE, offset = 0, last_end = 0;
|
||||||
|
HRESULT hr;
|
||||||
|
int done = 0;
|
||||||
|
|
||||||
|
*ptr = NULL;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
DWORD read;
|
||||||
|
|
||||||
|
if(!buf)
|
||||||
|
buf = HeapAlloc(GetProcessHeap(), 0, size + 1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size *= 2;
|
||||||
|
buf = HeapReAlloc(GetProcessHeap(), 0, buf, size + 1);
|
||||||
|
}
|
||||||
|
if(!buf)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IStream_Read(stm, buf + offset, size - offset, &read);
|
||||||
|
if(FAILED(hr)) goto fail;
|
||||||
|
|
||||||
|
offset += read;
|
||||||
|
buf[offset] = '\0';
|
||||||
|
|
||||||
|
if(read == 0) done = 1;
|
||||||
|
|
||||||
|
while(!done && (end = strstr(buf + last_end, "\r\n")))
|
||||||
|
{
|
||||||
|
DWORD new_end = end - buf + 2;
|
||||||
|
if(new_end - last_end == 2)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER off;
|
||||||
|
off.QuadPart = new_end;
|
||||||
|
IStream_Seek(stm, off, STREAM_SEEK_SET, NULL);
|
||||||
|
buf[new_end] = '\0';
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
last_end = new_end;
|
||||||
|
}
|
||||||
|
} while(!done);
|
||||||
|
|
||||||
|
*ptr = buf;
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
HeapFree(GetProcessHeap(), 0, buf);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT parse_headers(MimeBody *body, IStream *stm)
|
||||||
|
{
|
||||||
|
char *header_buf;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = copy_headers_to_buf(stm, &header_buf);
|
||||||
|
if(FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, header_buf);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static HRESULT WINAPI MimeBody_QueryInterface(IMimeBody* iface,
|
static HRESULT WINAPI MimeBody_QueryInterface(IMimeBody* iface,
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
void** ppvObject)
|
void** ppvObject)
|
||||||
|
@ -119,8 +200,9 @@ static HRESULT WINAPI MimeBody_Load(
|
||||||
IMimeBody* iface,
|
IMimeBody* iface,
|
||||||
LPSTREAM pStm)
|
LPSTREAM pStm)
|
||||||
{
|
{
|
||||||
FIXME("(%p)->(%p): stub\n", iface, pStm);
|
MimeBody *This = impl_from_IMimeBody(iface);
|
||||||
return E_NOTIMPL;
|
TRACE("(%p)->(%p)\n", iface, pStm);
|
||||||
|
return parse_headers(This, pStm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI MimeBody_Save(
|
static HRESULT WINAPI MimeBody_Save(
|
||||||
|
@ -143,8 +225,8 @@ static HRESULT WINAPI MimeBody_GetSizeMax(
|
||||||
static HRESULT WINAPI MimeBody_InitNew(
|
static HRESULT WINAPI MimeBody_InitNew(
|
||||||
IMimeBody* iface)
|
IMimeBody* iface)
|
||||||
{
|
{
|
||||||
FIXME("stub\n");
|
TRACE("%p->()\n", iface);
|
||||||
return E_NOTIMPL;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI MimeBody_GetPropInfo(
|
static HRESULT WINAPI MimeBody_GetPropInfo(
|
||||||
|
|
|
@ -32,6 +32,32 @@
|
||||||
|
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
static char msg1[] =
|
||||||
|
"MIME-Version: 1.0\r\n"
|
||||||
|
"Content-Type: multipart/mixed;\r\n"
|
||||||
|
" boundary=\"------------1.5.0.6\";\r\n"
|
||||||
|
" stuff=\"du;nno\"\r\n"
|
||||||
|
"foo: bar\r\n"
|
||||||
|
"From: Huw Davies <huw@codeweavers.com>\r\n"
|
||||||
|
"From: Me <xxx@codeweavers.com>\r\n"
|
||||||
|
"To: wine-patches <wine-patches@winehq.org>\r\n"
|
||||||
|
"Cc: Huw Davies <huw@codeweavers.com>,\r\n"
|
||||||
|
" \"Fred Bloggs\" <fred@bloggs.com>\r\n"
|
||||||
|
"foo: baz\r\n"
|
||||||
|
"bar: fum\r\n"
|
||||||
|
"\r\n"
|
||||||
|
"This is a multi-part message in MIME format.\r\n"
|
||||||
|
"--------------1.5.0.6\r\n"
|
||||||
|
"Content-Type: text/plain; format=fixed; charset=UTF-8\r\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\r\n"
|
||||||
|
"\r\n"
|
||||||
|
"Stuff\r\n"
|
||||||
|
"--------------1.5.0.6\r\n"
|
||||||
|
"Content-Type: text/plain; charset=\"us-ascii\"\r\n"
|
||||||
|
"Content-Transfer-Encoding: 7bit\r\n"
|
||||||
|
"\r\n"
|
||||||
|
"More stuff\r\n"
|
||||||
|
"--------------1.5.0.6--\r\n";
|
||||||
|
|
||||||
static void test_CreateVirtualStream(void)
|
static void test_CreateVirtualStream(void)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +86,9 @@ static void test_CreateBody(void)
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IMimeBody *body;
|
IMimeBody *body;
|
||||||
HBODY handle = (void *)0xdeadbeef;
|
HBODY handle = (void *)0xdeadbeef;
|
||||||
|
IStream *in;
|
||||||
|
LARGE_INTEGER off;
|
||||||
|
ULARGE_INTEGER pos;
|
||||||
|
|
||||||
hr = CoCreateInstance(&CLSID_IMimeBody, NULL, CLSCTX_INPROC_SERVER, &IID_IMimeBody, (void**)&body);
|
hr = CoCreateInstance(&CLSID_IMimeBody, NULL, CLSCTX_INPROC_SERVER, &IID_IMimeBody, (void**)&body);
|
||||||
ok(hr == S_OK, "ret %08x\n", hr);
|
ok(hr == S_OK, "ret %08x\n", hr);
|
||||||
|
@ -68,6 +97,22 @@ static void test_CreateBody(void)
|
||||||
ok(hr == MIME_E_NO_DATA, "ret %08x\n", hr);
|
ok(hr == MIME_E_NO_DATA, "ret %08x\n", hr);
|
||||||
ok(handle == NULL, "handle %p\n", handle);
|
ok(handle == NULL, "handle %p\n", handle);
|
||||||
|
|
||||||
|
hr = CreateStreamOnHGlobal(NULL, TRUE, &in);
|
||||||
|
ok(hr == S_OK, "ret %08x\n", hr);
|
||||||
|
IStream_Write(in, msg1, sizeof(msg1) - 1, NULL);
|
||||||
|
off.QuadPart = 0;
|
||||||
|
IStream_Seek(in, off, STREAM_SEEK_SET, NULL);
|
||||||
|
|
||||||
|
/* Need to call InitNew before Load otherwise Load crashes with native inetcomm */
|
||||||
|
hr = IMimeBody_InitNew(body);
|
||||||
|
ok(hr == S_OK, "ret %08x\n", hr);
|
||||||
|
|
||||||
|
hr = IMimeBody_Load(body, in);
|
||||||
|
ok(hr == S_OK, "ret %08x\n", hr);
|
||||||
|
off.QuadPart = 0;
|
||||||
|
IStream_Seek(in, off, STREAM_SEEK_CUR, &pos);
|
||||||
|
ok(pos.LowPart == 328, "pos %u\n", pos.LowPart);
|
||||||
|
|
||||||
IMimeBody_Release(body);
|
IMimeBody_Release(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue