Commit ed3ca136 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

inetcomm: Implement IMimeInternational_FindCharset.

parent 0c590201
......@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = inetcomm.dll
IMPORTLIB = inetcomm
IMPORTS = uuid ole32 ws2_32 user32 advapi32 kernel32
IMPORTS = uuid oleaut32 ole32 ws2_32 user32 advapi32 kernel32
C_SRCS = \
inetcomm_main.c \
......
......@@ -31,6 +31,7 @@
#include "objbase.h"
#include "ole2.h"
#include "mimeole.h"
#include "mlang.h"
#include "wine/list.h"
#include "wine/debug.h"
......@@ -41,8 +42,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);
typedef struct
{
struct list entry;
INETCSETINFO cs_info;
} charset_entry;
typedef struct
{
const IMimeInternationalVtbl *lpVtbl;
LONG refs;
CRITICAL_SECTION cs;
struct list charsets;
LONG next_charset_handle;
} internat;
static inline internat *impl_from_IMimeInternational( IMimeInternational *iface )
......@@ -50,6 +61,12 @@ static inline internat *impl_from_IMimeInternational( IMimeInternational *iface
return (internat *)((char*)iface - FIELD_OFFSET(internat, lpVtbl));
}
static inline HRESULT get_mlang(IMultiLanguage **ml)
{
return CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
&IID_IMultiLanguage, (void **)ml);
}
static HRESULT WINAPI MimeInternat_QueryInterface( IMimeInternational *iface, REFIID riid, LPVOID *ppobj )
{
if (IsEqualGUID(riid, &IID_IUnknown) ||
......@@ -78,6 +95,13 @@ static ULONG WINAPI MimeInternat_Release( IMimeInternational *iface )
refs = InterlockedDecrement(&This->refs);
if (!refs)
{
charset_entry *charset, *cursor2;
LIST_FOR_EACH_ENTRY_SAFE(charset, cursor2, &This->charsets, charset_entry, entry)
{
list_remove(&charset->entry);
HeapFree(GetProcessHeap(), 0, charset);
}
HeapFree(GetProcessHeap(), 0, This);
}
......@@ -104,11 +128,80 @@ static HRESULT WINAPI MimeInternat_GetCodePageCharset(IMimeInternational *iface,
return E_NOTIMPL;
}
static HRESULT mlang_getcsetinfo(const char *charset, MIMECSETINFO *mlang_info)
{
DWORD len = MultiByteToWideChar(CP_ACP, 0, charset, -1, NULL, 0);
BSTR bstr = SysAllocStringLen(NULL, len - 1);
HRESULT hr;
IMultiLanguage *ml;
MultiByteToWideChar(CP_ACP, 0, charset, -1, bstr, len);
hr = get_mlang(&ml);
if(SUCCEEDED(hr))
{
hr = IMultiLanguage_GetCharsetInfo(ml, bstr, mlang_info);
IMultiLanguage_Release(ml);
}
SysFreeString(bstr);
if(FAILED(hr)) hr = MIME_E_NOT_FOUND;
return hr;
}
static HCHARSET add_charset(struct list *list, MIMECSETINFO *mlang_info, HCHARSET handle)
{
charset_entry *charset = HeapAlloc(GetProcessHeap(), 0, sizeof(*charset));
WideCharToMultiByte(CP_ACP, 0, mlang_info->wszCharset, -1,
charset->cs_info.szName, sizeof(charset->cs_info.szName), NULL, NULL);
charset->cs_info.cpiWindows = mlang_info->uiCodePage;
charset->cs_info.cpiInternet = mlang_info->uiInternetEncoding;
charset->cs_info.hCharset = handle;
charset->cs_info.dwReserved1 = 0;
list_add_head(list, &charset->entry);
return charset->cs_info.hCharset;
}
static HRESULT WINAPI MimeInternat_FindCharset(IMimeInternational *iface, LPCSTR pszCharset,
LPHCHARSET phCharset)
{
FIXME("stub\n");
return E_NOTIMPL;
internat *This = impl_from_IMimeInternational( iface );
HRESULT hr = MIME_E_NOT_FOUND;
charset_entry *charset;
TRACE("(%p)->(%s, %p)\n", iface, debugstr_a(pszCharset), phCharset);
*phCharset = NULL;
EnterCriticalSection(&This->cs);
LIST_FOR_EACH_ENTRY(charset, &This->charsets, charset_entry, entry)
{
if(!strcmp(charset->cs_info.szName, pszCharset))
{
*phCharset = charset->cs_info.hCharset;
hr = S_OK;
break;
}
}
if(hr == MIME_E_NOT_FOUND)
{
MIMECSETINFO mlang_info;
LeaveCriticalSection(&This->cs);
hr = mlang_getcsetinfo(pszCharset, &mlang_info);
EnterCriticalSection(&This->cs);
if(SUCCEEDED(hr))
*phCharset = add_charset(&This->charsets, &mlang_info,
(HCHARSET)InterlockedIncrement(&This->next_charset_handle));
}
LeaveCriticalSection(&This->cs);
return hr;
}
static HRESULT WINAPI MimeInternat_GetCharsetInfo(IMimeInternational *iface, HCHARSET hCharset,
......@@ -224,6 +317,10 @@ HRESULT MimeInternational_Construct(IMimeInternational **internat)
global_internat = HeapAlloc(GetProcessHeap(), 0, sizeof(*global_internat));
global_internat->lpVtbl = &mime_internat_vtbl;
global_internat->refs = 0;
InitializeCriticalSection(&global_internat->cs);
list_init(&global_internat->charsets);
global_internat->next_charset_handle = 0;
*internat = (IMimeInternational*)&global_internat->lpVtbl;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment