starting TextMessage implementation
authorVolker Birk <vb@pep-project.org>
Fri, 24 Apr 2015 17:19:41 +0200
changeset 86fe51215f252
parent 7 ccda23165d04
child 9 12c8f92de54e
starting TextMessage implementation
CpEpEngine.cpp
CpEpEngine.h
TextMessage.cpp
TextMessage.h
TextMessage.rgs
_ITextMessageEvents_CP.h
pEpCOMServerAdapter.idl
pEpCOMServerAdapter.vcxproj
pEpCOMServerAdapter.vcxproj.filters
pEpCOMServerAdapter_i.c
pEpCOMServerAdapter_i.h
pEp_identity_cpp.h
resource.h
stdafx.h
     1.1 --- a/CpEpEngine.cpp	Fri Apr 24 07:34:00 2015 +0200
     1.2 +++ b/CpEpEngine.cpp	Fri Apr 24 17:19:41 2015 +0200
     1.3 @@ -65,101 +65,8 @@
     1.4      return _stringlist;
     1.5  }
     1.6  
     1.7 -static ::pEp_identity *new_identity(const pEp_identity_s * ident)
     1.8 -{
     1.9 -    ::pEp_identity *_ident;
    1.10 -
    1.11 -    string _address;
    1.12 -    string _fpr;
    1.13 -    string _user_id;
    1.14 -    string _username;
    1.15 -
    1.16 -    if (ident->address)
    1.17 -        _address = utf8_string(ident->address);
    1.18 -    if (ident->fpr) {
    1.19 -        _fpr = utf8_string(ident->fpr);
    1.20 -        for (auto p = _fpr.begin(); p != _fpr.end(); ++p) {
    1.21 -            if (*p >= 'A' && *p <= 'Z')
    1.22 -                continue;
    1.23 -            if (*p >= '0' && *p <= '9')
    1.24 -                continue;
    1.25 -            throw invalid_argument("invalid hex digits in fingerprint");
    1.26 -        }
    1.27 -    }
    1.28 -    if (ident->user_id)
    1.29 -        _user_id = utf8_string(ident->user_id);
    1.30 -    if (ident->username)
    1.31 -        _username = utf8_string(ident->username);
    1.32 -
    1.33 -    _ident = ::new_identity(_address.c_str(), _fpr.c_str(), _user_id.c_str(), _username.c_str());
    1.34 -    assert(_ident);
    1.35 -    if (_ident == NULL)
    1.36 -        throw bad_alloc();
    1.37 -
    1.38 -    _ident->comm_type = (PEP_comm_type) ident->comm_type;
    1.39 -
    1.40 -    if (ident->lang) {
    1.41 -        string _lang = utf8_string(ident->lang);
    1.42 -        if (_lang.length() != 0) {
    1.43 -            if (_lang.length() != 2) {
    1.44 -                ::free_identity(_ident);
    1.45 -                throw invalid_argument("invalid language code");
    1.46 -            }
    1.47 -            if (_lang[0] < 'a' || _lang[0] > 'z') {
    1.48 -                ::free_identity(_ident);
    1.49 -                throw invalid_argument("invalid language code");
    1.50 -            }
    1.51 -            if (_lang[1] < 'a' || _lang[1] > 'z') {
    1.52 -                ::free_identity(_ident);
    1.53 -                throw invalid_argument("invalid language code");
    1.54 -            }
    1.55 -            _ident->lang[0] = _lang[0];
    1.56 -            _ident->lang[1] = _lang[1];
    1.57 -        }
    1.58 -    }
    1.59 -
    1.60 -    return _ident;
    1.61 -}
    1.62 -
    1.63 -static void copy_identity(pEp_identity_s * ident_s, const pEp_identity * ident)
    1.64 -{
    1.65 -    ::memset(ident_s, 0, sizeof(pEp_identity_s));
    1.66 -
    1.67 -    if (ident->address)
    1.68 -        ident_s->address = utf16_bstr(ident->address).Detach();
    1.69 -    if (ident->fpr)
    1.70 -        ident_s->fpr = utf16_bstr(ident->fpr).Detach();
    1.71 -    if (ident->user_id)
    1.72 -        ident_s->user_id = utf16_bstr(ident->user_id).Detach();
    1.73 -    if (ident->username)
    1.74 -        ident_s->username = utf16_bstr(ident->username).Detach();
    1.75 -    ident_s->comm_type = (pEp_comm_type) ident->comm_type;
    1.76 -    if (ident->lang)
    1.77 -        ident_s->lang = utf16_bstr(ident->lang).Detach();
    1.78 -}
    1.79 -
    1.80  // CpEpEngine
    1.81  
    1.82 -::pEp_identity *CpEpEngine::new_identity(const CpEpEngine::pEp_identity_cpp& ident)
    1.83 -{
    1.84 -    ::pEp_identity *_ident = ::new_identity(ident.address.c_str(), ident.fpr.c_str(), ident.user_id.c_str(), ident.username.c_str());
    1.85 -    assert(_ident);
    1.86 -    if (_ident == NULL)
    1.87 -        throw bad_alloc();
    1.88 -
    1.89 -    _ident->comm_type = (::PEP_comm_type) ident.comm_type;
    1.90 -    _ident->me = ident.me;
    1.91 -
    1.92 -    assert(ident.lang.size() == 0 || ident.lang.size() == 2);
    1.93 -
    1.94 -    if (ident.lang.size()) {
    1.95 -        _ident->lang[0] = ident.lang[0];
    1.96 -        _ident->lang[1] = ident.lang[1];
    1.97 -    }
    1.98 -
    1.99 -    return _ident;
   1.100 -}
   1.101 -
   1.102  STDMETHODIMP CpEpEngine::log(BSTR title, BSTR entity, BSTR description, BSTR comment)
   1.103  {
   1.104      string _title;
   1.105 @@ -929,7 +836,7 @@
   1.106      do /* poll queue */ {
   1.107          if (iq->size())
   1.108              break;
   1.109 -        ::Sleep(200);
   1.110 +        ::Sleep(100);
   1.111      } while (true);
   1.112  
   1.113      ::pEp_identity *_ident;
   1.114 @@ -940,7 +847,7 @@
   1.115          return NULL;
   1.116      }
   1.117  
   1.118 -    _ident = new_identity(ident);
   1.119 +    _ident = ident.to_pEp_identity();
   1.120      iq->pop_front();
   1.121  
   1.122      return _ident;
     2.1 --- a/CpEpEngine.h	Fri Apr 24 07:34:00 2015 +0200
     2.2 +++ b/CpEpEngine.h	Fri Apr 24 17:19:41 2015 +0200
     2.3 @@ -9,7 +9,7 @@
     2.4  #include "_IpEpEngineEvents_CP.h"
     2.5  #include "locked_queue.hh"
     2.6  #include "utf8_helper.h"
     2.7 -
     2.8 +#include "pEp_identity_cpp.h"
     2.9  
    2.10  
    2.11  #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
    2.12 @@ -80,57 +80,6 @@
    2.13  
    2.14  
    2.15  protected:
    2.16 -    struct pEp_identity_cpp {
    2.17 -        std::string address;
    2.18 -        std::string fpr;
    2.19 -        std::string user_id;
    2.20 -        std::string username;
    2.21 -        pEp_comm_type comm_type;
    2.22 -        std::string lang;
    2.23 -        bool me;
    2.24 -
    2.25 -        pEp_identity_cpp(
    2.26 -            std::string _address = std::string(),
    2.27 -            std::string _fpr = std::string(),
    2.28 -            std::string _user_id = std::string(),
    2.29 -            std::string _username = std::string(),
    2.30 -            pEp_comm_type _comm_type = pEp_ct_unknown,
    2.31 -            std::string _lang = std::string()
    2.32 -            ) : address(_address), fpr(_fpr), user_id(_user_id), username(_username), comm_type(_comm_type), lang(_lang), me(false)
    2.33 -        { }
    2.34 -
    2.35 -        pEp_identity_cpp(const ::pEp_identity *_ident)
    2.36 -            : me(false)
    2.37 -        {
    2.38 -            if (_ident->address)
    2.39 -                address = _ident->address;
    2.40 -            if (_ident->fpr)
    2.41 -                fpr = _ident->fpr;
    2.42 -            if (_ident->user_id)
    2.43 -                user_id = _ident->user_id;
    2.44 -            if (_ident->username)
    2.45 -                username = _ident->username;
    2.46 -            comm_type = (pEp_comm_type) _ident->comm_type;
    2.47 -            lang = _ident->lang;
    2.48 -        }
    2.49 -
    2.50 -        pEp_identity_cpp(const pEp_identity_s *_ident)
    2.51 -            : me(false)
    2.52 -        {
    2.53 -            if (_ident->address)
    2.54 -                address = utf8_string(_ident->address);
    2.55 -            if (_ident->fpr)
    2.56 -                fpr = utf8_string(_ident->fpr);
    2.57 -            if (_ident->user_id)
    2.58 -                user_id = utf8_string(_ident->user_id);
    2.59 -            if (_ident->username)
    2.60 -                username = utf8_string(_ident->username);
    2.61 -            comm_type = _ident->comm_type;
    2.62 -            if (_ident->lang)
    2.63 -                lang = utf8_string(_ident->lang);
    2.64 -        }
    2.65 -    };
    2.66 -
    2.67      class session
    2.68      {
    2.69      private:
    2.70 @@ -159,8 +108,6 @@
    2.71          return session(this);
    2.72      }
    2.73  
    2.74 -    static ::pEp_identity *new_identity(const pEp_identity_cpp&);
    2.75 -
    2.76      typedef locked_queue<pEp_identity_cpp> identity_queue_t;
    2.77      static ::pEp_identity * retrieve_next_identity(void *management);
    2.78      HRESULT error(_bstr_t msg);
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/TextMessage.cpp	Fri Apr 24 17:19:41 2015 +0200
     3.3 @@ -0,0 +1,59 @@
     3.4 +// TextMessage.cpp : Implementation of CTextMessage
     3.5 +
     3.6 +#include "stdafx.h"
     3.7 +#include "TextMessage.h"
     3.8 +
     3.9 +
    3.10 +// CTextMessage
    3.11 +
    3.12 +STDMETHODIMP CTextMessage::InterfaceSupportsErrorInfo(REFIID riid)
    3.13 +{
    3.14 +	static const IID* const arr[] = 
    3.15 +	{
    3.16 +		&IID_ITextMessage
    3.17 +	};
    3.18 +
    3.19 +	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
    3.20 +	{
    3.21 +		if (InlineIsEqualGUID(*arr[i],riid))
    3.22 +			return S_OK;
    3.23 +	}
    3.24 +	return S_FALSE;
    3.25 +}
    3.26 +
    3.27 +
    3.28 +STDMETHODIMP CTextMessage::get_from(pEp_identity_s* pVal)
    3.29 +{
    3.30 +    try {
    3.31 +        copy_identity(pVal, msg->from);
    3.32 +    }
    3.33 +    catch (bad_alloc& e) {
    3.34 +        return E_OUTOFMEMORY;
    3.35 +    }
    3.36 +    catch (exception& e) {
    3.37 +        return E_FAIL;
    3.38 +    }
    3.39 +
    3.40 +    return S_OK;
    3.41 +}
    3.42 +
    3.43 +
    3.44 +STDMETHODIMP CTextMessage::put_from(pEp_identity_s* newVal)
    3.45 +{
    3.46 +    ::pEp_identity *_from;
    3.47 +    
    3.48 +    try {
    3.49 +        _from = new_identity(newVal);
    3.50 +    }
    3.51 +    catch (bad_alloc& e) {
    3.52 +        return E_OUTOFMEMORY;
    3.53 +    }
    3.54 +    catch (exception& e)
    3.55 +    {
    3.56 +        return E_FAIL;
    3.57 +    }
    3.58 +
    3.59 +    ::free_identity(msg->from);
    3.60 +    msg->from = _from;
    3.61 +    return S_OK;
    3.62 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/TextMessage.h	Fri Apr 24 17:19:41 2015 +0200
     4.3 @@ -0,0 +1,98 @@
     4.4 +// TextMessage.h : Declaration of the CTextMessage
     4.5 +
     4.6 +#pragma once
     4.7 +#include "resource.h"       // main symbols
     4.8 +
     4.9 +
    4.10 +#include "pEpCOMServerAdapter_i.h"
    4.11 +#include "_ITextMessageEvents_CP.h"
    4.12 +
    4.13 +#include "pEp_identity_cpp.h"
    4.14 +
    4.15 +#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
    4.16 +#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
    4.17 +#endif
    4.18 +
    4.19 +using namespace ATL;
    4.20 +using namespace std;
    4.21 +
    4.22 +// CTextMessage
    4.23 +
    4.24 +class ATL_NO_VTABLE CTextMessage :
    4.25 +	public CComObjectRootEx<CComSingleThreadModel>,
    4.26 +	public CComCoClass<CTextMessage, &CLSID_TextMessage>,
    4.27 +	public ISupportErrorInfo,
    4.28 +	public IConnectionPointContainerImpl<CTextMessage>,
    4.29 +	public CProxy_ITextMessageEvents<CTextMessage>,
    4.30 +	public ITextMessage
    4.31 +{
    4.32 +private:
    4.33 +    ::message *msg;
    4.34 +
    4.35 +public:
    4.36 +	CTextMessage()
    4.37 +	{
    4.38 +        msg = (::message *) calloc(1, sizeof(::message));
    4.39 +        assert(msg);
    4.40 +        if (msg == NULL)
    4.41 +            throw bad_alloc();
    4.42 +	}
    4.43 +
    4.44 +    CTextMessage(const CTextMessage& second)
    4.45 +    {
    4.46 +        msg = ::message_dup(second.msg);
    4.47 +        assert(msg);
    4.48 +        if (msg == NULL)
    4.49 +            throw bad_alloc();
    4.50 +    }
    4.51 +
    4.52 +    CTextMessage(const ::message *second)
    4.53 +    {
    4.54 +        assert(second);
    4.55 +        msg = ::message_dup(second);
    4.56 +        assert(msg);
    4.57 +        if (msg == NULL)
    4.58 +            throw bad_alloc();
    4.59 +    }
    4.60 +
    4.61 +    virtual ~CTextMessage()
    4.62 +    {
    4.63 +        ::free_message(msg);
    4.64 +    }
    4.65 +
    4.66 +DECLARE_REGISTRY_RESOURCEID(IDR_TEXTMESSAGE)
    4.67 +
    4.68 +
    4.69 +BEGIN_COM_MAP(CTextMessage)
    4.70 +	COM_INTERFACE_ENTRY(ITextMessage)
    4.71 +	COM_INTERFACE_ENTRY(ISupportErrorInfo)
    4.72 +	COM_INTERFACE_ENTRY(IConnectionPointContainer)
    4.73 +END_COM_MAP()
    4.74 +
    4.75 +BEGIN_CONNECTION_POINT_MAP(CTextMessage)
    4.76 +	CONNECTION_POINT_ENTRY(__uuidof(_ITextMessageEvents))
    4.77 +END_CONNECTION_POINT_MAP()
    4.78 +// ISupportsErrorInfo
    4.79 +	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
    4.80 +
    4.81 +
    4.82 +	DECLARE_PROTECT_FINAL_CONSTRUCT()
    4.83 +
    4.84 +	HRESULT FinalConstruct()
    4.85 +	{
    4.86 +		return S_OK;
    4.87 +	}
    4.88 +
    4.89 +	void FinalRelease()
    4.90 +	{
    4.91 +	}
    4.92 +
    4.93 +public:
    4.94 +
    4.95 +
    4.96 +
    4.97 +    STDMETHOD(get_from)(pEp_identity_s* pVal);
    4.98 +    STDMETHOD(put_from)(pEp_identity_s* newVal);
    4.99 +};
   4.100 +
   4.101 +OBJECT_ENTRY_AUTO(__uuidof(TextMessage), CTextMessage)
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/TextMessage.rgs	Fri Apr 24 17:19:41 2015 +0200
     5.3 @@ -0,0 +1,15 @@
     5.4 +HKCR
     5.5 +{
     5.6 +	NoRemove CLSID
     5.7 +	{
     5.8 +		ForceRemove {B6CC444F-FE14-4DFE-8315-81E4EA16C1CC} = s 'TextMessage Class'
     5.9 +		{
    5.10 +			LocalServer32 = s '%MODULE%'
    5.11 +			{
    5.12 +				val ServerExecutable = s '%MODULE_RAW%'
    5.13 +			}
    5.14 +			TypeLib = s '{3EC2E1A4-40E8-48E4-A7B0-1876D34F9462}'
    5.15 +			Version = s '1.0'
    5.16 +		}
    5.17 +	}
    5.18 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/_ITextMessageEvents_CP.h	Fri Apr 24 17:19:41 2015 +0200
     6.3 @@ -0,0 +1,10 @@
     6.4 +#pragma once
     6.5 +
     6.6 +using namespace ATL;
     6.7 +
     6.8 +template <class T>
     6.9 +class CProxy_ITextMessageEvents : public IConnectionPointImpl<T, &__uuidof( _ITextMessageEvents ), CComDynamicUnkArray>
    6.10 +{
    6.11 +	// WARNING: This class may be regenerated by the wizard
    6.12 +public:
    6.13 +};
     7.1 --- a/pEpCOMServerAdapter.idl	Fri Apr 24 07:34:00 2015 +0200
     7.2 +++ b/pEpCOMServerAdapter.idl	Fri Apr 24 17:19:41 2015 +0200
     7.3 @@ -119,6 +119,7 @@
     7.4      HRESULT examine_myself([in] struct pEp_identity_s * myself);
     7.5      HRESULT myself([in] struct pEp_identity_s *ident, [out, retval] struct pEp_identity_s *result);
     7.6      HRESULT update_identity([in] struct pEp_identity_s *ident, [out, retval] struct pEp_identity_s *result);
     7.7 +    HRESULT key_compromized([in] BSTR fpr);
     7.8  };
     7.9  
    7.10  [
    7.11 @@ -153,8 +154,19 @@
    7.12          pEp_enc_PGP_MIME,                       // RFC3156
    7.13          pEp_enc_pEp                             // pEp encryption format
    7.14      } pEp_enc_format;
    7.15 +};
    7.16  
    7.17 -    HRESULT key_compromized([in] BSTR fpr);
    7.18 +[
    7.19 +	object,
    7.20 +	uuid(161538F9-53C8-4D9C-8BA4-0FB43AEC7106),
    7.21 +	oleautomation,
    7.22 +	nonextensible,
    7.23 +	pointer_default(unique)
    7.24 +]
    7.25 +interface ITextMessage : IUnknown {
    7.26 +
    7.27 +    [propget] HRESULT from([out, retval] struct pEp_identity_s* pVal);
    7.28 +    [propput] HRESULT from([in] struct pEp_identity_s *newVal);
    7.29  };
    7.30  
    7.31  [
    7.32 @@ -180,5 +192,21 @@
    7.33          [default, source] dispinterface _IpEpEngineEvents;
    7.34          interface IMessageAPI_Outlook;
    7.35      };
    7.36 +	[
    7.37 +		uuid(844B5363-4EF4-4A39-A030-16452783A6F7)		
    7.38 +	]
    7.39 +	dispinterface _ITextMessageEvents
    7.40 +	{
    7.41 +		properties:
    7.42 +		methods:
    7.43 +	};
    7.44 +	[
    7.45 +		uuid(B6CC444F-FE14-4DFE-8315-81E4EA16C1CC)		
    7.46 +	]
    7.47 +	coclass TextMessage
    7.48 +	{
    7.49 +		[default] interface ITextMessage;
    7.50 +		[default, source] dispinterface _ITextMessageEvents;
    7.51 +	};
    7.52  };
    7.53  
     8.1 --- a/pEpCOMServerAdapter.vcxproj	Fri Apr 24 07:34:00 2015 +0200
     8.2 +++ b/pEpCOMServerAdapter.vcxproj	Fri Apr 24 17:19:41 2015 +0200
     8.3 @@ -127,6 +127,7 @@
     8.4        <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
     8.5        <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
     8.6      </ClCompile>
     8.7 +    <ClCompile Include="TextMessage.cpp" />
     8.8      <ClCompile Include="utf8_helper.cpp" />
     8.9      <ClCompile Include="xdlldata.c">
    8.10        <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
    8.11 @@ -141,12 +142,15 @@
    8.12      <ClInclude Include="CpEpEngine.h" />
    8.13      <ClInclude Include="locked_queue.hh" />
    8.14      <ClInclude Include="pEpCOMServerAdapter_i.h" />
    8.15 +    <ClInclude Include="pEp_identity_cpp.h" />
    8.16      <ClInclude Include="Resource.h" />
    8.17      <ClInclude Include="stdafx.h" />
    8.18      <ClInclude Include="targetver.h" />
    8.19 +    <ClInclude Include="TextMessage.h" />
    8.20      <ClInclude Include="utf8_helper.h" />
    8.21      <ClInclude Include="xdlldata.h" />
    8.22      <ClInclude Include="_IpEpEngineEvents_CP.h" />
    8.23 +    <ClInclude Include="_ITextMessageEvents_CP.h" />
    8.24    </ItemGroup>
    8.25    <ItemGroup>
    8.26      <ResourceCompile Include="pEpCOMServerAdapter.rc" />
    8.27 @@ -157,6 +161,7 @@
    8.28    <ItemGroup>
    8.29      <None Include="pEpCOMServerAdapter.rgs" />
    8.30      <None Include="pEpEngine.rgs" />
    8.31 +    <None Include="TextMessage.rgs" />
    8.32    </ItemGroup>
    8.33    <ItemGroup>
    8.34      <Midl Include="pEpCOMServerAdapter.idl" />
     9.1 --- a/pEpCOMServerAdapter.vcxproj.filters	Fri Apr 24 07:34:00 2015 +0200
     9.2 +++ b/pEpCOMServerAdapter.vcxproj.filters	Fri Apr 24 17:19:41 2015 +0200
     9.3 @@ -37,6 +37,9 @@
     9.4      <ClCompile Include="utf8_helper.cpp">
     9.5        <Filter>Source Files</Filter>
     9.6      </ClCompile>
     9.7 +    <ClCompile Include="TextMessage.cpp">
     9.8 +      <Filter>Source Files</Filter>
     9.9 +    </ClCompile>
    9.10    </ItemGroup>
    9.11    <ItemGroup>
    9.12      <ClInclude Include="stdafx.h">
    9.13 @@ -66,6 +69,15 @@
    9.14      <ClInclude Include="_IpEpEngineEvents_CP.h">
    9.15        <Filter>Header Files</Filter>
    9.16      </ClInclude>
    9.17 +    <ClInclude Include="_ITextMessageEvents_CP.h">
    9.18 +      <Filter>Header Files</Filter>
    9.19 +    </ClInclude>
    9.20 +    <ClInclude Include="TextMessage.h">
    9.21 +      <Filter>Header Files</Filter>
    9.22 +    </ClInclude>
    9.23 +    <ClInclude Include="pEp_identity_cpp.h">
    9.24 +      <Filter>Header Files</Filter>
    9.25 +    </ClInclude>
    9.26    </ItemGroup>
    9.27    <ItemGroup>
    9.28      <ResourceCompile Include="pEpCOMServerAdapter.rc">
    9.29 @@ -82,6 +94,9 @@
    9.30      <None Include="pEpEngine.rgs">
    9.31        <Filter>Resource Files</Filter>
    9.32      </None>
    9.33 +    <None Include="TextMessage.rgs">
    9.34 +      <Filter>Resource Files</Filter>
    9.35 +    </None>
    9.36    </ItemGroup>
    9.37    <ItemGroup>
    9.38      <Midl Include="pEpCOMServerAdapter.idl">
    10.1 --- a/pEpCOMServerAdapter_i.c	Fri Apr 24 07:34:00 2015 +0200
    10.2 +++ b/pEpCOMServerAdapter_i.c	Fri Apr 24 17:19:41 2015 +0200
    10.3 @@ -6,7 +6,7 @@
    10.4  
    10.5  
    10.6   /* File created by MIDL compiler version 8.00.0603 */
    10.7 -/* at Thu Apr 23 23:53:02 2015
    10.8 +/* at Fri Apr 24 16:11:40 2015
    10.9   */
   10.10  /* Compiler settings for pEpCOMServerAdapter.idl:
   10.11      Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0603 
   10.12 @@ -73,6 +73,9 @@
   10.13  MIDL_DEFINE_GUID(IID, IID_IMessageAPI_Outlook,0xBC9AB54D,0x2CDA,0x47A5,0xAB,0x40,0x64,0x85,0x7B,0x9E,0x95,0x55);
   10.14  
   10.15  
   10.16 +MIDL_DEFINE_GUID(IID, IID_ITextMessage,0x161538F9,0x53C8,0x4D9C,0x8B,0xA4,0x0F,0xB4,0x3A,0xEC,0x71,0x06);
   10.17 +
   10.18 +
   10.19  MIDL_DEFINE_GUID(IID, LIBID_pEpCOMServerAdapterLib,0x3EC2E1A4,0x40E8,0x48E4,0xA7,0xB0,0x18,0x76,0xD3,0x4F,0x94,0x62);
   10.20  
   10.21  
   10.22 @@ -81,6 +84,12 @@
   10.23  
   10.24  MIDL_DEFINE_GUID(CLSID, CLSID_pEpEngine,0xEF1B073D,0x5058,0x4E0E,0x82,0x9E,0xB4,0xD2,0x2C,0xA2,0x1E,0xA2);
   10.25  
   10.26 +
   10.27 +MIDL_DEFINE_GUID(IID, DIID__ITextMessageEvents,0x844B5363,0x4EF4,0x4A39,0xA0,0x30,0x16,0x45,0x27,0x83,0xA6,0xF7);
   10.28 +
   10.29 +
   10.30 +MIDL_DEFINE_GUID(CLSID, CLSID_TextMessage,0xB6CC444F,0xFE14,0x4DFE,0x83,0x15,0x81,0xE4,0xEA,0x16,0xC1,0xCC);
   10.31 +
   10.32  #undef MIDL_DEFINE_GUID
   10.33  
   10.34  #ifdef __cplusplus
    11.1 --- a/pEpCOMServerAdapter_i.h	Fri Apr 24 07:34:00 2015 +0200
    11.2 +++ b/pEpCOMServerAdapter_i.h	Fri Apr 24 17:19:41 2015 +0200
    11.3 @@ -4,7 +4,7 @@
    11.4  
    11.5  
    11.6   /* File created by MIDL compiler version 8.00.0603 */
    11.7 -/* at Thu Apr 23 23:53:02 2015
    11.8 +/* at Fri Apr 24 16:11:40 2015
    11.9   */
   11.10  /* Compiler settings for pEpCOMServerAdapter.idl:
   11.11      Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0603 
   11.12 @@ -59,6 +59,13 @@
   11.13  #endif 	/* __IMessageAPI_Outlook_FWD_DEFINED__ */
   11.14  
   11.15  
   11.16 +#ifndef __ITextMessage_FWD_DEFINED__
   11.17 +#define __ITextMessage_FWD_DEFINED__
   11.18 +typedef interface ITextMessage ITextMessage;
   11.19 +
   11.20 +#endif 	/* __ITextMessage_FWD_DEFINED__ */
   11.21 +
   11.22 +
   11.23  #ifndef ___IpEpEngineEvents_FWD_DEFINED__
   11.24  #define ___IpEpEngineEvents_FWD_DEFINED__
   11.25  typedef interface _IpEpEngineEvents _IpEpEngineEvents;
   11.26 @@ -78,6 +85,25 @@
   11.27  #endif 	/* __pEpEngine_FWD_DEFINED__ */
   11.28  
   11.29  
   11.30 +#ifndef ___ITextMessageEvents_FWD_DEFINED__
   11.31 +#define ___ITextMessageEvents_FWD_DEFINED__
   11.32 +typedef interface _ITextMessageEvents _ITextMessageEvents;
   11.33 +
   11.34 +#endif 	/* ___ITextMessageEvents_FWD_DEFINED__ */
   11.35 +
   11.36 +
   11.37 +#ifndef __TextMessage_FWD_DEFINED__
   11.38 +#define __TextMessage_FWD_DEFINED__
   11.39 +
   11.40 +#ifdef __cplusplus
   11.41 +typedef class TextMessage TextMessage;
   11.42 +#else
   11.43 +typedef struct TextMessage TextMessage;
   11.44 +#endif /* __cplusplus */
   11.45 +
   11.46 +#endif 	/* __TextMessage_FWD_DEFINED__ */
   11.47 +
   11.48 +
   11.49  /* header files for imported files */
   11.50  #include "oaidl.h"
   11.51  #include "ocidl.h"
   11.52 @@ -265,6 +291,9 @@
   11.53              /* [in] */ struct pEp_identity_s *ident,
   11.54              /* [retval][out] */ struct pEp_identity_s *result) = 0;
   11.55          
   11.56 +        virtual HRESULT STDMETHODCALLTYPE key_compromized( 
   11.57 +            /* [in] */ BSTR fpr) = 0;
   11.58 +        
   11.59      };
   11.60      
   11.61      
   11.62 @@ -403,6 +432,10 @@
   11.63              /* [in] */ struct pEp_identity_s *ident,
   11.64              /* [retval][out] */ struct pEp_identity_s *result);
   11.65          
   11.66 +        HRESULT ( STDMETHODCALLTYPE *key_compromized )( 
   11.67 +            IpEpEngine * This,
   11.68 +            /* [in] */ BSTR fpr);
   11.69 +        
   11.70          END_INTERFACE
   11.71      } IpEpEngineVtbl;
   11.72  
   11.73 @@ -492,6 +525,9 @@
   11.74  #define IpEpEngine_update_identity(This,ident,result)	\
   11.75      ( (This)->lpVtbl -> update_identity(This,ident,result) ) 
   11.76  
   11.77 +#define IpEpEngine_key_compromized(This,fpr)	\
   11.78 +    ( (This)->lpVtbl -> key_compromized(This,fpr) ) 
   11.79 +
   11.80  #endif /* COBJMACROS */
   11.81  
   11.82  
   11.83 @@ -551,9 +587,6 @@
   11.84      IMessageAPI_Outlook : public IUnknown
   11.85      {
   11.86      public:
   11.87 -        virtual HRESULT STDMETHODCALLTYPE key_compromized( 
   11.88 -            /* [in] */ BSTR fpr) = 0;
   11.89 -        
   11.90      };
   11.91      
   11.92      
   11.93 @@ -575,10 +608,6 @@
   11.94          ULONG ( STDMETHODCALLTYPE *Release )( 
   11.95              IMessageAPI_Outlook * This);
   11.96          
   11.97 -        HRESULT ( STDMETHODCALLTYPE *key_compromized )( 
   11.98 -            IMessageAPI_Outlook * This,
   11.99 -            /* [in] */ BSTR fpr);
  11.100 -        
  11.101          END_INTERFACE
  11.102      } IMessageAPI_OutlookVtbl;
  11.103  
  11.104 @@ -602,8 +631,95 @@
  11.105      ( (This)->lpVtbl -> Release(This) ) 
  11.106  
  11.107  
  11.108 -#define IMessageAPI_Outlook_key_compromized(This,fpr)	\
  11.109 -    ( (This)->lpVtbl -> key_compromized(This,fpr) ) 
  11.110 +#endif /* COBJMACROS */
  11.111 +
  11.112 +
  11.113 +#endif 	/* C style interface */
  11.114 +
  11.115 +
  11.116 +
  11.117 +
  11.118 +#endif 	/* __IMessageAPI_Outlook_INTERFACE_DEFINED__ */
  11.119 +
  11.120 +
  11.121 +#ifndef __ITextMessage_INTERFACE_DEFINED__
  11.122 +#define __ITextMessage_INTERFACE_DEFINED__
  11.123 +
  11.124 +/* interface ITextMessage */
  11.125 +/* [unique][nonextensible][oleautomation][uuid][object] */ 
  11.126 +
  11.127 +
  11.128 +EXTERN_C const IID IID_ITextMessage;
  11.129 +
  11.130 +#if defined(__cplusplus) && !defined(CINTERFACE)
  11.131 +    
  11.132 +    MIDL_INTERFACE("161538F9-53C8-4D9C-8BA4-0FB43AEC7106")
  11.133 +    ITextMessage : public IUnknown
  11.134 +    {
  11.135 +    public:
  11.136 +        virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_from( 
  11.137 +            /* [retval][out] */ struct pEp_identity_s *pVal) = 0;
  11.138 +        
  11.139 +        virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_from( 
  11.140 +            /* [in] */ struct pEp_identity_s *newVal) = 0;
  11.141 +        
  11.142 +    };
  11.143 +    
  11.144 +    
  11.145 +#else 	/* C style interface */
  11.146 +
  11.147 +    typedef struct ITextMessageVtbl
  11.148 +    {
  11.149 +        BEGIN_INTERFACE
  11.150 +        
  11.151 +        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
  11.152 +            ITextMessage * This,
  11.153 +            /* [in] */ REFIID riid,
  11.154 +            /* [annotation][iid_is][out] */ 
  11.155 +            _COM_Outptr_  void **ppvObject);
  11.156 +        
  11.157 +        ULONG ( STDMETHODCALLTYPE *AddRef )( 
  11.158 +            ITextMessage * This);
  11.159 +        
  11.160 +        ULONG ( STDMETHODCALLTYPE *Release )( 
  11.161 +            ITextMessage * This);
  11.162 +        
  11.163 +        /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_from )( 
  11.164 +            ITextMessage * This,
  11.165 +            /* [retval][out] */ struct pEp_identity_s *pVal);
  11.166 +        
  11.167 +        /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_from )( 
  11.168 +            ITextMessage * This,
  11.169 +            /* [in] */ struct pEp_identity_s *newVal);
  11.170 +        
  11.171 +        END_INTERFACE
  11.172 +    } ITextMessageVtbl;
  11.173 +
  11.174 +    interface ITextMessage
  11.175 +    {
  11.176 +        CONST_VTBL struct ITextMessageVtbl *lpVtbl;
  11.177 +    };
  11.178 +
  11.179 +    
  11.180 +
  11.181 +#ifdef COBJMACROS
  11.182 +
  11.183 +
  11.184 +#define ITextMessage_QueryInterface(This,riid,ppvObject)	\
  11.185 +    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 
  11.186 +
  11.187 +#define ITextMessage_AddRef(This)	\
  11.188 +    ( (This)->lpVtbl -> AddRef(This) ) 
  11.189 +
  11.190 +#define ITextMessage_Release(This)	\
  11.191 +    ( (This)->lpVtbl -> Release(This) ) 
  11.192 +
  11.193 +
  11.194 +#define ITextMessage_get_from(This,pVal)	\
  11.195 +    ( (This)->lpVtbl -> get_from(This,pVal) ) 
  11.196 +
  11.197 +#define ITextMessage_put_from(This,newVal)	\
  11.198 +    ( (This)->lpVtbl -> put_from(This,newVal) ) 
  11.199  
  11.200  #endif /* COBJMACROS */
  11.201  
  11.202 @@ -613,7 +729,7 @@
  11.203  
  11.204  
  11.205  
  11.206 -#endif 	/* __IMessageAPI_Outlook_INTERFACE_DEFINED__ */
  11.207 +#endif 	/* __ITextMessage_INTERFACE_DEFINED__ */
  11.208  
  11.209  
  11.210  
  11.211 @@ -748,6 +864,129 @@
  11.212  class DECLSPEC_UUID("EF1B073D-5058-4E0E-829E-B4D22CA21EA2")
  11.213  pEpEngine;
  11.214  #endif
  11.215 +
  11.216 +#ifndef ___ITextMessageEvents_DISPINTERFACE_DEFINED__
  11.217 +#define ___ITextMessageEvents_DISPINTERFACE_DEFINED__
  11.218 +
  11.219 +/* dispinterface _ITextMessageEvents */
  11.220 +/* [uuid] */ 
  11.221 +
  11.222 +
  11.223 +EXTERN_C const IID DIID__ITextMessageEvents;
  11.224 +
  11.225 +#if defined(__cplusplus) && !defined(CINTERFACE)
  11.226 +
  11.227 +    MIDL_INTERFACE("844B5363-4EF4-4A39-A030-16452783A6F7")
  11.228 +    _ITextMessageEvents : public IDispatch
  11.229 +    {
  11.230 +    };
  11.231 +    
  11.232 +#else 	/* C style interface */
  11.233 +
  11.234 +    typedef struct _ITextMessageEventsVtbl
  11.235 +    {
  11.236 +        BEGIN_INTERFACE
  11.237 +        
  11.238 +        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
  11.239 +            _ITextMessageEvents * This,
  11.240 +            /* [in] */ REFIID riid,
  11.241 +            /* [annotation][iid_is][out] */ 
  11.242 +            _COM_Outptr_  void **ppvObject);
  11.243 +        
  11.244 +        ULONG ( STDMETHODCALLTYPE *AddRef )( 
  11.245 +            _ITextMessageEvents * This);
  11.246 +        
  11.247 +        ULONG ( STDMETHODCALLTYPE *Release )( 
  11.248 +            _ITextMessageEvents * This);
  11.249 +        
  11.250 +        HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( 
  11.251 +            _ITextMessageEvents * This,
  11.252 +            /* [out] */ UINT *pctinfo);
  11.253 +        
  11.254 +        HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( 
  11.255 +            _ITextMessageEvents * This,
  11.256 +            /* [in] */ UINT iTInfo,
  11.257 +            /* [in] */ LCID lcid,
  11.258 +            /* [out] */ ITypeInfo **ppTInfo);
  11.259 +        
  11.260 +        HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( 
  11.261 +            _ITextMessageEvents * This,
  11.262 +            /* [in] */ REFIID riid,
  11.263 +            /* [size_is][in] */ LPOLESTR *rgszNames,
  11.264 +            /* [range][in] */ UINT cNames,
  11.265 +            /* [in] */ LCID lcid,
  11.266 +            /* [size_is][out] */ DISPID *rgDispId);
  11.267 +        
  11.268 +        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( 
  11.269 +            _ITextMessageEvents * This,
  11.270 +            /* [annotation][in] */ 
  11.271 +            _In_  DISPID dispIdMember,
  11.272 +            /* [annotation][in] */ 
  11.273 +            _In_  REFIID riid,
  11.274 +            /* [annotation][in] */ 
  11.275 +            _In_  LCID lcid,
  11.276 +            /* [annotation][in] */ 
  11.277 +            _In_  WORD wFlags,
  11.278 +            /* [annotation][out][in] */ 
  11.279 +            _In_  DISPPARAMS *pDispParams,
  11.280 +            /* [annotation][out] */ 
  11.281 +            _Out_opt_  VARIANT *pVarResult,
  11.282 +            /* [annotation][out] */ 
  11.283 +            _Out_opt_  EXCEPINFO *pExcepInfo,
  11.284 +            /* [annotation][out] */ 
  11.285 +            _Out_opt_  UINT *puArgErr);
  11.286 +        
  11.287 +        END_INTERFACE
  11.288 +    } _ITextMessageEventsVtbl;
  11.289 +
  11.290 +    interface _ITextMessageEvents
  11.291 +    {
  11.292 +        CONST_VTBL struct _ITextMessageEventsVtbl *lpVtbl;
  11.293 +    };
  11.294 +
  11.295 +    
  11.296 +
  11.297 +#ifdef COBJMACROS
  11.298 +
  11.299 +
  11.300 +#define _ITextMessageEvents_QueryInterface(This,riid,ppvObject)	\
  11.301 +    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 
  11.302 +
  11.303 +#define _ITextMessageEvents_AddRef(This)	\
  11.304 +    ( (This)->lpVtbl -> AddRef(This) ) 
  11.305 +
  11.306 +#define _ITextMessageEvents_Release(This)	\
  11.307 +    ( (This)->lpVtbl -> Release(This) ) 
  11.308 +
  11.309 +
  11.310 +#define _ITextMessageEvents_GetTypeInfoCount(This,pctinfo)	\
  11.311 +    ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) 
  11.312 +
  11.313 +#define _ITextMessageEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo)	\
  11.314 +    ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) 
  11.315 +
  11.316 +#define _ITextMessageEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)	\
  11.317 +    ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) 
  11.318 +
  11.319 +#define _ITextMessageEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)	\
  11.320 +    ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) 
  11.321 +
  11.322 +#endif /* COBJMACROS */
  11.323 +
  11.324 +
  11.325 +#endif 	/* C style interface */
  11.326 +
  11.327 +
  11.328 +#endif 	/* ___ITextMessageEvents_DISPINTERFACE_DEFINED__ */
  11.329 +
  11.330 +
  11.331 +EXTERN_C const CLSID CLSID_TextMessage;
  11.332 +
  11.333 +#ifdef __cplusplus
  11.334 +
  11.335 +class DECLSPEC_UUID("B6CC444F-FE14-4DFE-8315-81E4EA16C1CC")
  11.336 +TextMessage;
  11.337 +#endif
  11.338  #endif /* __pEpCOMServerAdapterLib_LIBRARY_DEFINED__ */
  11.339  
  11.340  /* Additional Prototypes for ALL interfaces */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/pEp_identity_cpp.h	Fri Apr 24 17:19:41 2015 +0200
    12.3 @@ -0,0 +1,183 @@
    12.4 +#pragma once
    12.5 +
    12.6 +#include "stdafx.h"
    12.7 +#include "pEpComServerAdapter_i.h"
    12.8 +#include "utf8_helper.h"
    12.9 +
   12.10 +using namespace std;
   12.11 +
   12.12 +struct pEp_identity_cpp {
   12.13 +    string address;
   12.14 +    string fpr;
   12.15 +    string user_id;
   12.16 +    string username;
   12.17 +    pEp_comm_type comm_type;
   12.18 +    string lang;
   12.19 +    bool me;
   12.20 +
   12.21 +    pEp_identity_cpp(
   12.22 +        string _address = string(),
   12.23 +        string _fpr = string(),
   12.24 +        string _user_id = string(),
   12.25 +        string _username = string(),
   12.26 +        pEp_comm_type _comm_type = pEp_ct_unknown,
   12.27 +        string _lang = string()
   12.28 +        ) : address(_address), fpr(_fpr), user_id(_user_id), username(_username), comm_type(_comm_type), lang(_lang), me(false)
   12.29 +    { }
   12.30 +
   12.31 +    pEp_identity_cpp(const ::pEp_identity *_ident)
   12.32 +        : me(false)
   12.33 +    {
   12.34 +        if (_ident->address)
   12.35 +            address = _ident->address;
   12.36 +        if (_ident->fpr)
   12.37 +            fpr = _ident->fpr;
   12.38 +        if (_ident->user_id)
   12.39 +            user_id = _ident->user_id;
   12.40 +        if (_ident->username)
   12.41 +            username = _ident->username;
   12.42 +        comm_type = (pEp_comm_type) _ident->comm_type;
   12.43 +        lang = _ident->lang;
   12.44 +    }
   12.45 +
   12.46 +    pEp_identity_cpp(const pEp_identity_s *_ident)
   12.47 +        : me(false)
   12.48 +    {
   12.49 +        if (_ident->address)
   12.50 +            address = utf8_string(_ident->address);
   12.51 +        if (_ident->fpr)
   12.52 +            fpr = utf8_string(_ident->fpr);
   12.53 +        if (_ident->user_id)
   12.54 +            user_id = utf8_string(_ident->user_id);
   12.55 +        if (_ident->username)
   12.56 +            username = utf8_string(_ident->username);
   12.57 +        comm_type = _ident->comm_type;
   12.58 +        if (_ident->lang)
   12.59 +            lang = utf8_string(_ident->lang);
   12.60 +    }
   12.61 +
   12.62 +    pEp_identity * to_pEp_identity()
   12.63 +    {
   12.64 +        ::pEp_identity *_ident = ::new_identity(this->address.c_str(), this->fpr.c_str(), this->user_id.c_str(), this->username.c_str());
   12.65 +        assert(_ident);
   12.66 +        if (_ident == NULL)
   12.67 +            throw bad_alloc();
   12.68 +
   12.69 +        _ident->comm_type = (::PEP_comm_type) this->comm_type;
   12.70 +        _ident->me = this->me;
   12.71 +
   12.72 +        assert(this->lang.size() == 0 || this->lang.size() == 2);
   12.73 +
   12.74 +        if (this->lang.size()) {
   12.75 +            _ident->lang[0] = this->lang[0];
   12.76 +            _ident->lang[1] = this->lang[1];
   12.77 +        }
   12.78 +
   12.79 +        return _ident;
   12.80 +    }
   12.81 +
   12.82 +    pEp_identity_s * to_pEp_identity_s()
   12.83 +    {
   12.84 +        pEp_identity_s *_ident = (pEp_identity_s *) calloc(1, sizeof(pEp_identity_s));
   12.85 +        assert(_ident);
   12.86 +        if (_ident == NULL)
   12.87 +            throw bad_alloc();
   12.88 +
   12.89 +        _ident->address = utf16_bstr(this->address).Detach();
   12.90 +        _ident->comm_type = this->comm_type;
   12.91 +        _ident->fpr = utf16_bstr(this->fpr).Detach();
   12.92 +        _ident->lang = utf16_bstr(this->lang).Detach();
   12.93 +        _ident->username = utf16_bstr(this->username).Detach();
   12.94 +        _ident->user_id = utf16_bstr(this->user_id).Detach();
   12.95 +
   12.96 +        return _ident;
   12.97 +    }
   12.98 +};
   12.99 +
  12.100 +static void free_pEp_identity_s(pEp_identity_s *ident)
  12.101 +{
  12.102 +    if (ident) {
  12.103 +        SysFreeString(ident->address);
  12.104 +        SysFreeString(ident->fpr);
  12.105 +        SysFreeString(ident->lang);
  12.106 +        SysFreeString(ident->username);
  12.107 +        SysFreeString(ident->user_id);
  12.108 +        free(ident);
  12.109 +    }
  12.110 +}
  12.111 +
  12.112 +static void copy_identity(pEp_identity_s * ident_s, const pEp_identity * ident)
  12.113 +{
  12.114 +    assert(ident_s);
  12.115 +
  12.116 +    ::memset(ident_s, 0, sizeof(pEp_identity_s));
  12.117 +    if (ident) {
  12.118 +        if (ident->address)
  12.119 +            ident_s->address = utf16_bstr(ident->address).Detach();
  12.120 +        if (ident->fpr)
  12.121 +            ident_s->fpr = utf16_bstr(ident->fpr).Detach();
  12.122 +        if (ident->user_id)
  12.123 +            ident_s->user_id = utf16_bstr(ident->user_id).Detach();
  12.124 +        if (ident->username)
  12.125 +            ident_s->username = utf16_bstr(ident->username).Detach();
  12.126 +        ident_s->comm_type = (pEp_comm_type) ident->comm_type;
  12.127 +        if (ident->lang)
  12.128 +            ident_s->lang = utf16_bstr(ident->lang).Detach();
  12.129 +    }
  12.130 +}
  12.131 +
  12.132 +static ::pEp_identity *new_identity(const pEp_identity_s * ident)
  12.133 +{
  12.134 +    ::pEp_identity *_ident;
  12.135 +
  12.136 +    string _address;
  12.137 +    string _fpr;
  12.138 +    string _user_id;
  12.139 +    string _username;
  12.140 +
  12.141 +    if (ident->address)
  12.142 +        _address = utf8_string(ident->address);
  12.143 +    if (ident->fpr) {
  12.144 +        _fpr = utf8_string(ident->fpr);
  12.145 +        for (auto p = _fpr.begin(); p != _fpr.end(); ++p) {
  12.146 +            if (*p >= 'A' && *p <= 'Z')
  12.147 +                continue;
  12.148 +            if (*p >= '0' && *p <= '9')
  12.149 +                continue;
  12.150 +            throw invalid_argument("invalid hex digits in fingerprint");
  12.151 +        }
  12.152 +    }
  12.153 +    if (ident->user_id)
  12.154 +        _user_id = utf8_string(ident->user_id);
  12.155 +    if (ident->username)
  12.156 +        _username = utf8_string(ident->username);
  12.157 +
  12.158 +    _ident = ::new_identity(_address.c_str(), _fpr.c_str(), _user_id.c_str(), _username.c_str());
  12.159 +    assert(_ident);
  12.160 +    if (_ident == NULL)
  12.161 +        throw bad_alloc();
  12.162 +
  12.163 +    _ident->comm_type = (PEP_comm_type) ident->comm_type;
  12.164 +
  12.165 +    if (ident->lang) {
  12.166 +        string _lang = utf8_string(ident->lang);
  12.167 +        if (_lang.length() != 0) {
  12.168 +            if (_lang.length() != 2) {
  12.169 +                ::free_identity(_ident);
  12.170 +                throw invalid_argument("invalid language code");
  12.171 +            }
  12.172 +            if (_lang[0] < 'a' || _lang[0] > 'z') {
  12.173 +                ::free_identity(_ident);
  12.174 +                throw invalid_argument("invalid language code");
  12.175 +            }
  12.176 +            if (_lang[1] < 'a' || _lang[1] > 'z') {
  12.177 +                ::free_identity(_ident);
  12.178 +                throw invalid_argument("invalid language code");
  12.179 +            }
  12.180 +            _ident->lang[0] = _lang[0];
  12.181 +            _ident->lang[1] = _lang[1];
  12.182 +        }
  12.183 +    }
  12.184 +
  12.185 +    return _ident;
  12.186 +}
    13.1 Binary file resource.h has changed
    14.1 --- a/stdafx.h	Fri Apr 24 07:34:00 2015 +0200
    14.2 +++ b/stdafx.h	Fri Apr 24 17:19:41 2015 +0200
    14.3 @@ -39,3 +39,4 @@
    14.4  
    14.5  #include "../../pEpEngine/src/pEpEngine.h"
    14.6  #include "../../pEpEngine/src/keymanagement.h"
    14.7 +#include "../../pEpEngine/src/message_api.h"