CpEpEngine.h
author Volker Birk <vb@pep.foundation>
Tue, 16 Oct 2018 01:24:16 +0200
branchsync
changeset 296 43d9e57b6561
parent 295 f55ec2fd694f
child 297 a48f0545e221
permissions -rw-r--r--
COM server adapter including sync
     1 // CpEpEngine.h : Declaration of the CpEpEngine
     2 
     3 #pragma once
     4 #include "resource.h"       // main symbols
     5 
     6 #include "pEpComServerAdapter_i.h"
     7 #include "..\libpEpAdapter\locked_queue.hh"
     8 #include "utf8_helper.h"
     9 #include "pEp_utility.h"
    10 #include "..\libpEpAdapter\Adapter.hh"
    11 #include <queue>
    12 #include <mutex>
    13 #include <vector>
    14 
    15 #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
    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."
    17 #endif
    18 
    19 using namespace ATL;
    20 using namespace utility;
    21 using namespace pEp::utility;
    22 using namespace pEp::Adapter;
    23 
    24 // CpEpEngine
    25 
    26 class ATL_NO_VTABLE CpEpEngine :
    27     public CComObjectRootEx<CComObjectThreadModel>,
    28     public CComCoClass<CpEpEngine, &CLSID_pEpEngine>,
    29     public ISupportErrorInfo,
    30     public IpEpEngine
    31 {
    32 
    33 protected:
    34     static int examine_identity(pEp_identity *ident, void *management);
    35 
    36 public:
    37     CpEpEngine() : keymanagement_thread(NULL), identity_queue(NULL), verbose_mode(false)
    38     {
    39         // See FinalConstruct() below for most initialization work, and an
    40         // explanation why it had to be moved there...
    41         ++count;
    42     }
    43 
    44     ~CpEpEngine()
    45     {
    46         --count;
    47         if (!count) {
    48             StopKeyserverLookup();
    49             ::log_event(session(), "Shutdown", "pEp COM Adapter", NULL, NULL);
    50             session(pEp::Adapter::release);
    51             shutdown();
    52         }
    53     }
    54 
    55     DECLARE_REGISTRY_RESOURCEID(IDR_PEPENGINE)
    56 
    57     DECLARE_NOT_AGGREGATABLE(CpEpEngine)
    58 
    59     BEGIN_COM_MAP(CpEpEngine)
    60         COM_INTERFACE_ENTRY(IpEpEngine)
    61         COM_INTERFACE_ENTRY(ISupportErrorInfo)
    62     END_COM_MAP()
    63 
    64     // ISupportsErrorInfo
    65     STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
    66 
    67     DECLARE_PROTECT_FINAL_CONSTRUCT()
    68 
    69     // Unfortunately, neither FAIL nor error() work in the constructor, as 
    70     // CreateErrorInfo/SetErrorInfo cannot work when the instance is not constructed.
    71     // AtlThrow works, but the exception is caught in CComCreator.CreateInstance, and
    72     // unconditionally turned into E_OUTOFMEMORY. Thus, we need to do most constructor
    73     // work in FinalConstruct. CreateErrorInfo/SetErrorInfo still won't work, but at least,
    74     // we can return a meaningful HRESULT. Thus, we pack our PEP_STATUS into a custom HRESULT.	
    75     HRESULT FinalConstruct()
    76     {
    77         std::lock_guard<std::mutex> lock(init_mutex);
    78         try {
    79             session();
    80         }
    81         catch (pEp::RuntimeError& e) {
    82             HRESULT res = MAKE_HRESULT(1, FACILITY_ITF, (0xFFFF & e.status));
    83             return res;
    84         }
    85 
    86         ::register_examine_function(session(), CpEpEngine::examine_identity, (void *)this);
    87         ::log_event(session(), "Startup", "pEp COM Adapter", NULL, NULL);
    88         startup(messageToSend, notifyHandshake);
    89         return S_OK;
    90     }
    91 
    92     void FinalRelease()
    93     {
    94     }
    95 
    96 
    97 protected:
    98     typedef locked_queue<pEp_identity_cpp> identity_queue_t;
    99     static ::pEp_identity * retrieve_next_identity(void *management);
   100     static PEP_STATUS messageToSend(message *msg);
   101     static PEP_STATUS notifyHandshake(pEp_identity *self, pEp_identity *partner, sync_handshake_signal signal);
   102 
   103     HRESULT error(_bstr_t msg);
   104     HRESULT error(_bstr_t msg, PEP_STATUS errorcode);
   105 
   106     void verbose(string text)
   107     {
   108         if (verbose_mode) {
   109             stringstream ss;
   110             ss << __FILE__ << ":" << __LINE__ << " " << text;
   111             ::log_event(session(), "verbose", "pEp COM Server Adapter", ss.str().c_str(), NULL);
   112         }
   113     }
   114 
   115 private:
   116     atomic< identity_queue_t * > identity_queue;
   117     thread *keymanagement_thread;
   118     bool verbose_mode;
   119 
   120     IpEpEngineCallbacks* client_callbacks = NULL;
   121     bool client_last_signalled_polling_state = true;
   122 
   123     static std::mutex init_mutex;
   124 
   125     static std::list< IpEpEngineCallbacks * > all_callbacks;
   126     static std::mutex callbacks_mutex;
   127 
   128     static atomic< int > count;
   129 
   130 public:
   131     // runtime config of the adapter
   132 
   133     STDMETHOD(VerboseLogging)(VARIANT_BOOL enable);
   134 
   135     // runtime config of the engine
   136 
   137     STDMETHOD(PassiveMode)(VARIANT_BOOL enable);
   138     STDMETHOD(UnencryptedSubject)(VARIANT_BOOL enable);
   139 
   140     // basic API
   141 
   142     STDMETHOD(ExportKey)(BSTR fpr, BSTR * keyData);
   143     STDMETHOD(Log)(BSTR title, BSTR entity, BSTR description, BSTR comment);
   144     STDMETHOD(Trustwords)(BSTR fpr, BSTR lang, LONG max_words, BSTR * words);
   145     STDMETHOD(GetTrustwords)(struct pEpIdentity *id1, struct pEpIdentity *id2, BSTR lang, VARIANT_BOOL full, BSTR *words);
   146     STDMETHOD(GetMessageTrustwords)(
   147         /* [in] */ struct TextMessage *msg,
   148         /* [in] */ struct pEpIdentity *receivedBy,
   149         /* [in] */ SAFEARRAY *keylist,
   150         /* [defaultvalue][in] */ BSTR lang,
   151         /* [defaultvalue][in] */ VARIANT_BOOL full,
   152         /* [retval][out] */ BSTR *words);
   153     STDMETHOD(GetCrashdumpLog)(LONG maxlines, BSTR * log);
   154     STDMETHOD(GetEngineVersion)(BSTR * engineVersion);
   155     STDMETHOD(GetLanguageList)(BSTR * languages);
   156     STDMETHOD(SetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
   157     STDMETHOD(UnsetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
   158 
   159     // keymanagement API
   160 
   161     STDMETHOD(StartKeyserverLookup)();
   162     STDMETHOD(StopKeyserverLookup)();
   163 
   164     STDMETHOD(Myself)(struct pEpIdentity *ident, struct pEpIdentity *result);
   165     STDMETHOD(UpdateIdentity)(struct pEpIdentity *ident, struct pEpIdentity *result);
   166     STDMETHOD(KeyMistrusted)(struct pEpIdentity *ident);
   167     STDMETHOD(KeyResetTrust)(struct pEpIdentity *ident);
   168     STDMETHOD(TrustPersonalKey)(struct pEpIdentity *ident, struct pEpIdentity *result);
   169     STDMETHOD(OwnIdentitiesRetrieve)(LPSAFEARRAY* ownIdentities);
   170 
   171     // STDMETHOD(UndoLastMistrust)(); 
   172     
   173     STDMETHOD(IspEpUser)(
   174         /* [in] */ struct pEpIdentity *ident,
   175         /* [retval][out] */ VARIANT_BOOL *ispEp);
   176 
   177     // Blacklist API
   178 
   179     STDMETHOD(BlacklistAdd)(BSTR fpr);
   180     STDMETHOD(BlacklistDelete)(BSTR fpr);
   181     STDMETHOD(BlacklistIsListed)(BSTR fpr, VARIANT_BOOL *listed);
   182     STDMETHOD(BlacklistRetrieve)(SAFEARRAY **blacklist);
   183 
   184     // Message API
   185 
   186     STDMETHOD(EncryptMessage)(
   187         /* [in] */ struct TextMessage *src,
   188         /* [out] */ struct TextMessage *dst,
   189         /* [in] */ SAFEARRAY * extra,
   190         /* [defaultvalue][in] */ pEpEncryptFlags flags = pEpEncryptFlagDefault,
   191         /* [defaultvalue][in] */ pEpEncFormat encFormat = pEpEncPep);
   192 
   193     STDMETHOD(EncryptMessageAndAddPrivKey)(
   194         /* [in] */ struct TextMessage *src,
   195         /* [out] */ struct TextMessage *dst,
   196         /* [in] */ BSTR to_fpr,
   197         /* [defaultvalue][in] */ pEpEncryptFlags flags = pEpEncryptFlagDefault,
   198         /* [defaultvalue][in] */ pEpEncFormat encFormat = pEpEncPep);
   199 
   200     STDMETHOD(DecryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY ** keylist, pEpDecryptFlags* flags, pEpRating *rating);
   201     STDMETHOD(ReEvaluateMessageRating)(TextMessage * msg, SAFEARRAY * x_KeyList, pEpRating x_EncStatus, pEpRating *rating);
   202 	STDMETHOD(OutgoingMessageRating)(TextMessage *msg, pEpRating * pVal);
   203 	STDMETHOD(OutgoingMessageRatingPreview)(TextMessage *msg, pEpRating * pVal);
   204     STDMETHOD(IdentityRating)(pEpIdentity * ident, pEpRating * pVal);
   205     STDMETHOD(ColorFromRating)(pEpRating rating, pEpColor * pVal);
   206 
   207     STDMETHOD(EncryptMessageForSelf)(
   208         pEpIdentity * targetId,
   209         TextMessage* src,
   210         /* [in] */ SAFEARRAY *extra,
   211         TextMessage *dst,
   212         pEpEncryptFlags flags
   213         );
   214 
   215     // Event callbacks
   216 
   217     STDMETHOD(RegisterCallbacks)(IpEpEngineCallbacks *new_callback);
   218     STDMETHOD(UnregisterCallbacks)();
   219 
   220     // PGP compatibility functions
   221     STDMETHOD(OpenPGPListKeyinfo)(BSTR search_pattern, LPSAFEARRAY* keyinfo_list);
   222 	STDMETHOD(SetOwnKey)(pEpIdentity * ident, BSTR fpr, struct pEpIdentity *result);
   223 
   224     // Trigger an immediate update
   225     STDMETHOD(UpdateNow)();
   226 };
   227 
   228 OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine)