2 * MIME OLE International interface
4 * Copyright 2008 Huw Davies for CodeWeavers
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.
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.
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
22 #define NONAMELESSUNION
36 #include "wine/list.h"
37 #include "wine/debug.h"
39 #include "inetcomm_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(inetcomm
);
51 const IMimeInternationalVtbl
*lpVtbl
;
56 LONG next_charset_handle
;
59 static inline internat
*impl_from_IMimeInternational( IMimeInternational
*iface
)
61 return (internat
*)((char*)iface
- FIELD_OFFSET(internat
, lpVtbl
));
64 static inline HRESULT
get_mlang(IMultiLanguage
**ml
)
66 return CoCreateInstance(&CLSID_CMultiLanguage
, NULL
, CLSCTX_INPROC_SERVER
| CLSCTX_INPROC_HANDLER
,
67 &IID_IMultiLanguage
, (void **)ml
);
70 static HRESULT WINAPI
MimeInternat_QueryInterface( IMimeInternational
*iface
, REFIID riid
, LPVOID
*ppobj
)
72 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
73 IsEqualGUID(riid
, &IID_IMimeInternational
))
75 IMimeInternational_AddRef( iface
);
80 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
84 static ULONG WINAPI
MimeInternat_AddRef( IMimeInternational
*iface
)
86 internat
*This
= impl_from_IMimeInternational( iface
);
87 return InterlockedIncrement(&This
->refs
);
90 static ULONG WINAPI
MimeInternat_Release( IMimeInternational
*iface
)
92 internat
*This
= impl_from_IMimeInternational( iface
);
95 refs
= InterlockedDecrement(&This
->refs
);
98 charset_entry
*charset
, *cursor2
;
100 LIST_FOR_EACH_ENTRY_SAFE(charset
, cursor2
, &This
->charsets
, charset_entry
, entry
)
102 list_remove(&charset
->entry
);
103 HeapFree(GetProcessHeap(), 0, charset
);
105 HeapFree(GetProcessHeap(), 0, This
);
111 static HRESULT WINAPI
MimeInternat_SetDefaultCharset(IMimeInternational
*iface
, HCHARSET hCharset
)
117 static HRESULT WINAPI
MimeInternat_GetDefaultCharset(IMimeInternational
*iface
, LPHCHARSET phCharset
)
123 static HRESULT WINAPI
MimeInternat_GetCodePageCharset(IMimeInternational
*iface
, CODEPAGEID cpiCodePage
,
124 CHARSETTYPE ctCsetType
,
125 LPHCHARSET phCharset
)
131 static HRESULT
mlang_getcsetinfo(const char *charset
, MIMECSETINFO
*mlang_info
)
133 DWORD len
= MultiByteToWideChar(CP_ACP
, 0, charset
, -1, NULL
, 0);
134 BSTR bstr
= SysAllocStringLen(NULL
, len
- 1);
138 MultiByteToWideChar(CP_ACP
, 0, charset
, -1, bstr
, len
);
144 hr
= IMultiLanguage_GetCharsetInfo(ml
, bstr
, mlang_info
);
145 IMultiLanguage_Release(ml
);
148 if(FAILED(hr
)) hr
= MIME_E_NOT_FOUND
;
152 static HCHARSET
add_charset(struct list
*list
, MIMECSETINFO
*mlang_info
, HCHARSET handle
)
154 charset_entry
*charset
= HeapAlloc(GetProcessHeap(), 0, sizeof(*charset
));
156 WideCharToMultiByte(CP_ACP
, 0, mlang_info
->wszCharset
, -1,
157 charset
->cs_info
.szName
, sizeof(charset
->cs_info
.szName
), NULL
, NULL
);
158 charset
->cs_info
.cpiWindows
= mlang_info
->uiCodePage
;
159 charset
->cs_info
.cpiInternet
= mlang_info
->uiInternetEncoding
;
160 charset
->cs_info
.hCharset
= handle
;
161 charset
->cs_info
.dwReserved1
= 0;
162 list_add_head(list
, &charset
->entry
);
164 return charset
->cs_info
.hCharset
;
167 static HRESULT WINAPI
MimeInternat_FindCharset(IMimeInternational
*iface
, LPCSTR pszCharset
,
168 LPHCHARSET phCharset
)
170 internat
*This
= impl_from_IMimeInternational( iface
);
171 HRESULT hr
= MIME_E_NOT_FOUND
;
172 charset_entry
*charset
;
174 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_a(pszCharset
), phCharset
);
178 EnterCriticalSection(&This
->cs
);
180 LIST_FOR_EACH_ENTRY(charset
, &This
->charsets
, charset_entry
, entry
)
182 if(!strcmp(charset
->cs_info
.szName
, pszCharset
))
184 *phCharset
= charset
->cs_info
.hCharset
;
190 if(hr
== MIME_E_NOT_FOUND
)
192 MIMECSETINFO mlang_info
;
194 LeaveCriticalSection(&This
->cs
);
195 hr
= mlang_getcsetinfo(pszCharset
, &mlang_info
);
196 EnterCriticalSection(&This
->cs
);
199 *phCharset
= add_charset(&This
->charsets
, &mlang_info
,
200 (HCHARSET
)InterlockedIncrement(&This
->next_charset_handle
));
203 LeaveCriticalSection(&This
->cs
);
207 static HRESULT WINAPI
MimeInternat_GetCharsetInfo(IMimeInternational
*iface
, HCHARSET hCharset
,
208 LPINETCSETINFO pCsetInfo
)
210 internat
*This
= impl_from_IMimeInternational( iface
);
211 HRESULT hr
= MIME_E_INVALID_HANDLE
;
212 charset_entry
*charset
;
214 TRACE("(%p)->(%p, %p)\n", iface
, hCharset
, pCsetInfo
);
216 EnterCriticalSection(&This
->cs
);
218 LIST_FOR_EACH_ENTRY(charset
, &This
->charsets
, charset_entry
, entry
)
220 if(charset
->cs_info
.hCharset
== hCharset
)
222 *pCsetInfo
= charset
->cs_info
;
228 LeaveCriticalSection(&This
->cs
);
233 static HRESULT WINAPI
MimeInternat_GetCodePageInfo(IMimeInternational
*iface
, CODEPAGEID cpiCodePage
,
234 LPCODEPAGEINFO pCodePageInfo
)
240 static HRESULT WINAPI
MimeInternat_DecodeHeader(IMimeInternational
*iface
, HCHARSET hCharset
,
242 LPPROPVARIANT pDecoded
,
243 LPRFC1522INFO pRfc1522Info
)
249 static HRESULT WINAPI
MimeInternat_EncodeHeader(IMimeInternational
*iface
, HCHARSET hCharset
,
252 LPRFC1522INFO pRfc1522Info
)
258 static HRESULT WINAPI
MimeInternat_ConvertBuffer(IMimeInternational
*iface
, CODEPAGEID cpiSource
,
268 static HRESULT WINAPI
MimeInternat_ConvertString(IMimeInternational
*iface
, CODEPAGEID cpiSource
,
277 static HRESULT WINAPI
MimeInternat_MLANG_ConvertInetReset(IMimeInternational
*iface
)
283 static HRESULT WINAPI
MimeInternat_MLANG_ConvertInetString(IMimeInternational
*iface
, CODEPAGEID cpiSource
,
294 static HRESULT WINAPI
MimeInternat_Rfc1522Decode(IMimeInternational
*iface
, LPCSTR pszValue
,
303 static HRESULT WINAPI
MimeInternat_Rfc1522Encode(IMimeInternational
*iface
, LPCSTR pszValue
,
311 static IMimeInternationalVtbl mime_internat_vtbl
=
313 MimeInternat_QueryInterface
,
315 MimeInternat_Release
,
316 MimeInternat_SetDefaultCharset
,
317 MimeInternat_GetDefaultCharset
,
318 MimeInternat_GetCodePageCharset
,
319 MimeInternat_FindCharset
,
320 MimeInternat_GetCharsetInfo
,
321 MimeInternat_GetCodePageInfo
,
322 MimeInternat_DecodeHeader
,
323 MimeInternat_EncodeHeader
,
324 MimeInternat_ConvertBuffer
,
325 MimeInternat_ConvertString
,
326 MimeInternat_MLANG_ConvertInetReset
,
327 MimeInternat_MLANG_ConvertInetString
,
328 MimeInternat_Rfc1522Decode
,
329 MimeInternat_Rfc1522Encode
332 static internat
*global_internat
;
334 HRESULT
MimeInternational_Construct(IMimeInternational
**internat
)
336 global_internat
= HeapAlloc(GetProcessHeap(), 0, sizeof(*global_internat
));
337 global_internat
->lpVtbl
= &mime_internat_vtbl
;
338 global_internat
->refs
= 0;
339 InitializeCriticalSection(&global_internat
->cs
);
341 list_init(&global_internat
->charsets
);
342 global_internat
->next_charset_handle
= 0;
344 *internat
= (IMimeInternational
*)&global_internat
->lpVtbl
;
346 IMimeInternational_AddRef(*internat
);
350 HRESULT WINAPI
MimeOleGetInternat(IMimeInternational
**internat
)
352 TRACE("(%p)\n", internat
);
354 *internat
= (IMimeInternational
*)&global_internat
->lpVtbl
;
355 IMimeInternational_AddRef(*internat
);