Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
31297b6a
Commit
31297b6a
authored
Nov 26, 2007
by
Huw Davies
Committed by
Alexandre Julliard
Nov 27, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
inetcomm: Parse headers into a list.
parent
98dfca50
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
172 additions
and
1 deletion
+172
-1
mimeole.c
dlls/inetcomm/mimeole.c
+172
-1
No files found.
dlls/inetcomm/mimeole.c
View file @
31297b6a
...
...
@@ -31,18 +31,68 @@
#include "ole2.h"
#include "mimeole.h"
#include "wine/list.h"
#include "wine/debug.h"
#include "inetcomm_private.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
inetcomm
);
typedef
struct
{
LPCSTR
name
;
DWORD
id
;
DWORD
flags
;
/* MIMEPROPFLAGS */
VARTYPE
default_vt
;
}
property_t
;
typedef
struct
{
struct
list
entry
;
property_t
prop
;
}
property_list_entry_t
;
static
const
property_t
default_props
[]
=
{
{
"References"
,
PID_HDR_REFS
,
0
,
VT_LPSTR
},
{
"Subject"
,
PID_HDR_SUBJECT
,
0
,
VT_LPSTR
},
{
"From"
,
PID_HDR_FROM
,
MPF_ADDRESS
,
VT_LPSTR
},
{
"Message-ID"
,
PID_HDR_MESSAGEID
,
0
,
VT_LPSTR
},
{
"Return-Path"
,
PID_HDR_RETURNPATH
,
MPF_ADDRESS
,
VT_LPSTR
},
{
"Date"
,
PID_HDR_DATE
,
0
,
VT_LPSTR
},
{
"Received"
,
PID_HDR_RECEIVED
,
0
,
VT_LPSTR
},
{
"Reply-To"
,
PID_HDR_REPLYTO
,
MPF_ADDRESS
,
VT_LPSTR
},
{
"X-Mailer"
,
PID_HDR_XMAILER
,
0
,
VT_LPSTR
},
{
"Bcc"
,
PID_HDR_BCC
,
MPF_ADDRESS
,
VT_LPSTR
},
{
"MIME-Version"
,
PID_HDR_MIMEVER
,
MPF_MIME
,
VT_LPSTR
},
{
"Content-Type"
,
PID_HDR_CNTTYPE
,
MPF_MIME
|
MPF_HASPARAMS
,
VT_LPSTR
},
{
"Content-Transfer-Encoding"
,
PID_HDR_CNTXFER
,
MPF_MIME
,
VT_LPSTR
},
{
"Content-ID"
,
PID_HDR_CNTID
,
MPF_MIME
,
VT_LPSTR
},
{
"Content-Disposition"
,
PID_HDR_CNTDISP
,
MPF_MIME
,
VT_LPSTR
},
{
"To"
,
PID_HDR_TO
,
MPF_ADDRESS
,
VT_LPSTR
},
{
"Cc"
,
PID_HDR_CC
,
MPF_ADDRESS
,
VT_LPSTR
},
{
"Sender"
,
PID_HDR_SENDER
,
MPF_ADDRESS
,
VT_LPSTR
},
{
"In-Reply-To"
,
PID_HDR_INREPLYTO
,
0
,
VT_LPSTR
},
{
NULL
,
0
,
0
,
0
}
};
typedef
struct
{
struct
list
entry
;
const
property_t
*
prop
;
PROPVARIANT
value
;
}
header_t
;
typedef
struct
MimeBody
{
const
IMimeBodyVtbl
*
lpVtbl
;
LONG
refs
;
HBODY
handle
;
struct
list
headers
;
struct
list
new_props
;
/* FIXME: This should be in a PropertySchema */
DWORD
next_prop_id
;
}
MimeBody
;
static
inline
MimeBody
*
impl_from_IMimeBody
(
IMimeBody
*
iface
)
...
...
@@ -50,6 +100,15 @@ static inline MimeBody *impl_from_IMimeBody( IMimeBody *iface )
return
(
MimeBody
*
)((
char
*
)
iface
-
FIELD_OFFSET
(
MimeBody
,
lpVtbl
));
}
static
LPSTR
strdupA
(
LPCSTR
str
)
{
char
*
ret
;
int
len
=
strlen
(
str
);
ret
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
+
1
);
memcpy
(
ret
,
str
,
len
+
1
);
return
ret
;
}
#define PARSER_BUF_SIZE 1024
/*****************************************************
...
...
@@ -117,18 +176,122 @@ fail:
return
hr
;
}
static
header_t
*
read_prop
(
MimeBody
*
body
,
char
**
ptr
)
{
char
*
colon
=
strchr
(
*
ptr
,
':'
);
const
property_t
*
prop
;
header_t
*
ret
;
if
(
!
colon
)
return
NULL
;
*
colon
=
'\0'
;
for
(
prop
=
default_props
;
prop
->
name
;
prop
++
)
{
if
(
!
strcasecmp
(
*
ptr
,
prop
->
name
))
{
TRACE
(
"%s: found match with default property id %d
\n
"
,
*
ptr
,
prop
->
id
);
break
;
}
}
if
(
!
prop
->
name
)
{
property_list_entry_t
*
prop_entry
;
LIST_FOR_EACH_ENTRY
(
prop_entry
,
&
body
->
new_props
,
property_list_entry_t
,
entry
)
{
if
(
!
strcasecmp
(
*
ptr
,
prop_entry
->
prop
.
name
))
{
TRACE
(
"%s: found match with already added new property id %d
\n
"
,
*
ptr
,
prop_entry
->
prop
.
id
);
prop
=
&
prop_entry
->
prop
;
break
;
}
}
if
(
!
prop
->
name
)
{
prop_entry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
prop_entry
));
prop_entry
->
prop
.
name
=
strdupA
(
*
ptr
);
prop_entry
->
prop
.
id
=
body
->
next_prop_id
++
;
prop_entry
->
prop
.
flags
=
0
;
prop_entry
->
prop
.
default_vt
=
VT_LPSTR
;
list_add_tail
(
&
body
->
new_props
,
&
prop_entry
->
entry
);
prop
=
&
prop_entry
->
prop
;
TRACE
(
"%s: allocating new prop id %d
\n
"
,
*
ptr
,
prop_entry
->
prop
.
id
);
}
}
ret
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
ret
));
ret
->
prop
=
prop
;
PropVariantInit
(
&
ret
->
value
);
*
ptr
=
colon
+
1
;
return
ret
;
}
static
void
read_value
(
header_t
*
header
,
char
**
cur
)
{
char
*
end
=
*
cur
,
*
value
;
DWORD
len
;
do
{
end
=
strstr
(
end
,
"
\r\n
"
);
end
+=
2
;
}
while
(
*
end
==
' '
||
*
end
==
'\t'
);
len
=
end
-
*
cur
;
value
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
+
1
);
memcpy
(
value
,
*
cur
,
len
);
value
[
len
]
=
'\0'
;
header
->
value
.
vt
=
VT_LPSTR
;
header
->
value
.
pszVal
=
value
;
*
cur
=
end
;
}
static
HRESULT
parse_headers
(
MimeBody
*
body
,
IStream
*
stm
)
{
char
*
header_buf
;
char
*
header_buf
,
*
cur_header_ptr
;
HRESULT
hr
;
header_t
*
header
;
hr
=
copy_headers_to_buf
(
stm
,
&
header_buf
);
if
(
FAILED
(
hr
))
return
hr
;
cur_header_ptr
=
header_buf
;
while
((
header
=
read_prop
(
body
,
&
cur_header_ptr
)))
{
read_value
(
header
,
&
cur_header_ptr
);
list_add_tail
(
&
body
->
headers
,
&
header
->
entry
);
}
HeapFree
(
GetProcessHeap
(),
0
,
header_buf
);
return
hr
;
}
static
void
empty_header_list
(
struct
list
*
list
)
{
header_t
*
header
,
*
cursor2
;
LIST_FOR_EACH_ENTRY_SAFE
(
header
,
cursor2
,
list
,
header_t
,
entry
)
{
list_remove
(
&
header
->
entry
);
PropVariantClear
(
&
header
->
value
);
HeapFree
(
GetProcessHeap
(),
0
,
header
);
}
}
static
void
empty_new_prop_list
(
struct
list
*
list
)
{
property_list_entry_t
*
prop
,
*
cursor2
;
LIST_FOR_EACH_ENTRY_SAFE
(
prop
,
cursor2
,
list
,
property_list_entry_t
,
entry
)
{
list_remove
(
&
prop
->
entry
);
HeapFree
(
GetProcessHeap
(),
0
,
(
char
*
)
prop
->
prop
.
name
);
HeapFree
(
GetProcessHeap
(),
0
,
prop
);
}
}
static
HRESULT
WINAPI
MimeBody_QueryInterface
(
IMimeBody
*
iface
,
REFIID
riid
,
...
...
@@ -174,6 +337,9 @@ static ULONG WINAPI MimeBody_Release(IMimeBody* iface)
refs
=
InterlockedDecrement
(
&
This
->
refs
);
if
(
!
refs
)
{
empty_header_list
(
&
This
->
headers
);
empty_new_prop_list
(
&
This
->
new_props
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
...
...
@@ -582,6 +748,8 @@ static IMimeBodyVtbl body_vtbl =
MimeBody_GetHandle
};
#define FIRST_CUSTOM_PROP_ID 0x100
HRESULT
MimeBody_create
(
IUnknown
*
outer
,
void
**
obj
)
{
MimeBody
*
This
;
...
...
@@ -596,6 +764,9 @@ HRESULT MimeBody_create(IUnknown *outer, void **obj)
This
->
lpVtbl
=
&
body_vtbl
;
This
->
refs
=
1
;
This
->
handle
=
NULL
;
list_init
(
&
This
->
headers
);
list_init
(
&
This
->
new_props
);
This
->
next_prop_id
=
FIRST_CUSTOM_PROP_ID
;
*
obj
=
(
IMimeBody
*
)
&
This
->
lpVtbl
;
return
S_OK
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment