COM-50: Handshake Requests need to be decoupled.
authorMarkus Schaber <markus@pep-security.net>
Sat, 11 Feb 2017 17:49:02 +0100
changeset 234a3cc1847d197
parent 233 27848ed0067c
child 235 581e3f7a92f5
COM-50: Handshake Requests need to be decoupled.

First implementation, trying to decouple purely via the COM server. If this
does not work out (e. G. reentrancy problems in Outlook), we need to pass the
callback down to outlook, and open a pseudo-modal dialog there (which blocks
the main window, but does not block the code like ShowDialog()).
CpEpEngine.cpp
CpEpEngine.h
stdafx.h
     1.1 --- a/CpEpEngine.cpp	Fri Feb 03 21:30:26 2017 +0100
     1.2 +++ b/CpEpEngine.cpp	Sat Feb 11 17:49:02 2017 +0100
     1.3 @@ -10,18 +10,18 @@
     1.4  
     1.5  STDMETHODIMP CpEpEngine::InterfaceSupportsErrorInfo(REFIID riid)
     1.6  {
     1.7 -	static const IID* const arr[] =
     1.8 -	{
     1.9 -		&IID_IpEpEngine,
    1.10 +    static const IID* const arr[] =
    1.11 +    {
    1.12 +        &IID_IpEpEngine,
    1.13          &IID_IpEpEngine2,
    1.14 -	};
    1.15 +    };
    1.16  
    1.17 -	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
    1.18 -	{
    1.19 -		if (InlineIsEqualGUID(*arr[i], riid))
    1.20 -			return S_OK;
    1.21 -	}
    1.22 -	return S_FALSE;
    1.23 +    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
    1.24 +    {
    1.25 +        if (InlineIsEqualGUID(*arr[i], riid))
    1.26 +            return S_OK;
    1.27 +    }
    1.28 +    return S_FALSE;
    1.29  }
    1.30  
    1.31  // The second argument is optional, and currently supports PEP_STATUS.
    1.32 @@ -29,20 +29,20 @@
    1.33  
    1.34  STDMETHODIMP CpEpEngine::VerboseLogging(VARIANT_BOOL enable)
    1.35  {
    1.36 -	verbose_mode = enable != VARIANT_FALSE;
    1.37 -	return S_OK;
    1.38 +    verbose_mode = enable != VARIANT_FALSE;
    1.39 +    return S_OK;
    1.40  }
    1.41  
    1.42  STDMETHODIMP CpEpEngine::PassiveMode(VARIANT_BOOL enable)
    1.43  {
    1.44 -	::config_passive_mode(get_session(), enable != VARIANT_FALSE);
    1.45 -	return S_OK;
    1.46 +    ::config_passive_mode(get_session(), enable != VARIANT_FALSE);
    1.47 +    return S_OK;
    1.48  }
    1.49  
    1.50  STDMETHODIMP CpEpEngine::UnencryptedSubject(VARIANT_BOOL enable)
    1.51  {
    1.52 -	::config_unencrypted_subject(get_session(), enable != VARIANT_FALSE);
    1.53 -	return S_OK;
    1.54 +    ::config_unencrypted_subject(get_session(), enable != VARIANT_FALSE);
    1.55 +    return S_OK;
    1.56  }
    1.57  
    1.58  STDMETHODIMP CpEpEngine::ExportKey(BSTR fpr, BSTR * keyData)
    1.59 @@ -67,101 +67,101 @@
    1.60  
    1.61      _bstr_t b_key_data(utf16_string(_key_data).c_str());
    1.62      pEp_free(_key_data);
    1.63 -    * keyData = b_key_data.Detach();
    1.64 +    *keyData = b_key_data.Detach();
    1.65  
    1.66      return S_OK;
    1.67  }
    1.68  
    1.69  STDMETHODIMP CpEpEngine::Log(BSTR title, BSTR entity, BSTR description, BSTR comment)
    1.70  {
    1.71 -	string _title;
    1.72 -	string _entity;
    1.73 -	string _description;
    1.74 -	string _comment;
    1.75 -	HRESULT result = S_OK;
    1.76 +    string _title;
    1.77 +    string _entity;
    1.78 +    string _description;
    1.79 +    string _comment;
    1.80 +    HRESULT result = S_OK;
    1.81  
    1.82 -	assert(title);
    1.83 -	if (title)
    1.84 -		_title = utf8_string(title);
    1.85 -	else
    1.86 -		result = E_INVALIDARG;
    1.87 +    assert(title);
    1.88 +    if (title)
    1.89 +        _title = utf8_string(title);
    1.90 +    else
    1.91 +        result = E_INVALIDARG;
    1.92  
    1.93 -	assert(entity);
    1.94 -	if (entity)
    1.95 -		_entity = utf8_string(entity);
    1.96 -	else
    1.97 -		result = E_INVALIDARG;
    1.98 +    assert(entity);
    1.99 +    if (entity)
   1.100 +        _entity = utf8_string(entity);
   1.101 +    else
   1.102 +        result = E_INVALIDARG;
   1.103  
   1.104 -	if (description)
   1.105 -		_description = utf8_string(description);
   1.106 +    if (description)
   1.107 +        _description = utf8_string(description);
   1.108  
   1.109 -	if (comment)
   1.110 -		_comment = utf8_string(comment);
   1.111 +    if (comment)
   1.112 +        _comment = utf8_string(comment);
   1.113  
   1.114 -	if (result != S_OK)
   1.115 -		return result;
   1.116 +    if (result != S_OK)
   1.117 +        return result;
   1.118  
   1.119 -	PEP_STATUS _status = ::log_event(get_session(), _title.c_str(), _entity.c_str(), _description.c_str(), _comment.c_str());
   1.120 -	assert(_status == PEP_STATUS_OK);
   1.121 -	if (_status != PEP_STATUS_OK)
   1.122 -		return FAIL(L"log_event", _status);
   1.123 -	else
   1.124 -		return S_OK;
   1.125 +    PEP_STATUS _status = ::log_event(get_session(), _title.c_str(), _entity.c_str(), _description.c_str(), _comment.c_str());
   1.126 +    assert(_status == PEP_STATUS_OK);
   1.127 +    if (_status != PEP_STATUS_OK)
   1.128 +        return FAIL(L"log_event", _status);
   1.129 +    else
   1.130 +        return S_OK;
   1.131  }
   1.132  
   1.133  STDMETHODIMP CpEpEngine::Trustwords(BSTR fpr, BSTR lang, LONG max_words, BSTR * words)
   1.134  {
   1.135 -	assert(fpr);
   1.136 -	assert(max_words >= 0);
   1.137 -	assert(words);
   1.138 +    assert(fpr);
   1.139 +    assert(max_words >= 0);
   1.140 +    assert(words);
   1.141  
   1.142 -	HRESULT result = S_OK;
   1.143 +    HRESULT result = S_OK;
   1.144  
   1.145 -	string _fpr;
   1.146 -	if (fpr)
   1.147 -		_fpr = utf8_string(fpr);
   1.148 -	else
   1.149 -		result = E_INVALIDARG;
   1.150 +    string _fpr;
   1.151 +    if (fpr)
   1.152 +        _fpr = utf8_string(fpr);
   1.153 +    else
   1.154 +        result = E_INVALIDARG;
   1.155  
   1.156 -	string _lang;
   1.157 -	if (lang) {
   1.158 -		_lang = utf8_string(lang);
   1.159 -		if (_lang.length()) {
   1.160 -			if (_lang.length() != 2)
   1.161 -				result = E_INVALIDARG;
   1.162 -		}
   1.163 -		else
   1.164 -			_lang = "en";
   1.165 -	}
   1.166 -	else
   1.167 -		_lang = "en";
   1.168 +    string _lang;
   1.169 +    if (lang) {
   1.170 +        _lang = utf8_string(lang);
   1.171 +        if (_lang.length()) {
   1.172 +            if (_lang.length() != 2)
   1.173 +                result = E_INVALIDARG;
   1.174 +        }
   1.175 +        else
   1.176 +            _lang = "en";
   1.177 +    }
   1.178 +    else
   1.179 +        _lang = "en";
   1.180  
   1.181 -	if (max_words < 0)
   1.182 -		result = E_INVALIDARG;
   1.183 +    if (max_words < 0)
   1.184 +        result = E_INVALIDARG;
   1.185  
   1.186 -	if (words == NULL)
   1.187 -		result = E_INVALIDARG;
   1.188 +    if (words == NULL)
   1.189 +        result = E_INVALIDARG;
   1.190  
   1.191 -	if (result != S_OK)
   1.192 -		return result;
   1.193 +    if (result != S_OK)
   1.194 +        return result;
   1.195  
   1.196 -	char *_words = NULL;
   1.197 -	size_t _wsize = 0;
   1.198 +    char *_words = NULL;
   1.199 +    size_t _wsize = 0;
   1.200  
   1.201 -	PEP_STATUS status = ::trustwords(get_session(), _fpr.c_str(), _lang.c_str(), &_words, &_wsize, max_words);
   1.202 -	assert(status != PEP_OUT_OF_MEMORY);
   1.203 -	if (status == PEP_OUT_OF_MEMORY)
   1.204 -		return E_OUTOFMEMORY;
   1.205 +    PEP_STATUS status = ::trustwords(get_session(), _fpr.c_str(), _lang.c_str(), &_words, &_wsize, max_words);
   1.206 +    assert(status != PEP_OUT_OF_MEMORY);
   1.207 +    if (status == PEP_OUT_OF_MEMORY)
   1.208 +        return E_OUTOFMEMORY;
   1.209  
   1.210 -	if (_words == NULL) {
   1.211 -		*words = NULL;
   1.212 -		return FAIL(L"Trustwords: _words == NULL", status);
   1.213 -	}
   1.214 -	else {
   1.215 -		*words = utf16_bstr(_words);
   1.216 -		pEp_free(_words);
   1.217 -		return S_OK;
   1.218 -	}
   1.219 +    if (_words == NULL) {
   1.220 +        *words = NULL;
   1.221 +        return FAIL(L"Trustwords: _words == NULL", status);
   1.222 +    }
   1.223 +    else {
   1.224 +        *words = utf16_bstr(_words);
   1.225 +        pEp_free(_words);
   1.226 +        return S_OK;
   1.227 +    }
   1.228  }
   1.229  
   1.230  STDMETHODIMP CpEpEngine::GetTrustwords(struct pEpIdentity *id1, struct pEpIdentity *id2, BSTR lang, VARIANT_BOOL full, BSTR *words)
   1.231 @@ -190,15 +190,19 @@
   1.232              _lang = utf8_string(lang);
   1.233              if (_lang.length() == 0) {
   1.234                  _lang = "en";
   1.235 -            } else if (_lang.length() != 2) {
   1.236 +            }
   1.237 +            else if (_lang.length() != 2) {
   1.238                  result = E_INVALIDARG;
   1.239              }
   1.240 -        } else {
   1.241 +        }
   1.242 +        else {
   1.243              _lang = "en";
   1.244          }
   1.245 -    } catch (bad_alloc&) {
   1.246 +    }
   1.247 +    catch (bad_alloc&) {
   1.248          result = E_OUTOFMEMORY;
   1.249 -    } catch (exception& ex) {
   1.250 +    }
   1.251 +    catch (exception& ex) {
   1.252          result = FAIL(ex.what());
   1.253      }
   1.254  
   1.255 @@ -315,509 +319,484 @@
   1.256  
   1.257  STDMETHODIMP CpEpEngine::GetCrashdumpLog(LONG maxlines, BSTR * log)
   1.258  {
   1.259 -	// COM-18: Currently, long == int on windows, so the check
   1.260 -	// for INT_MAX is not strictly necessary. However, the code
   1.261 -	// might get copy-pasted to other adapters in the future,
   1.262 -	// so safety first...
   1.263 -	assert(maxlines >= 0 && maxlines <= INT_MAX);
   1.264 -	assert(log);
   1.265 +    // COM-18: Currently, long == int on windows, so the check
   1.266 +    // for INT_MAX is not strictly necessary. However, the code
   1.267 +    // might get copy-pasted to other adapters in the future,
   1.268 +    // so safety first...
   1.269 +    assert(maxlines >= 0 && maxlines <= INT_MAX);
   1.270 +    assert(log);
   1.271  
   1.272 -	if (!(maxlines >= 0 && maxlines <= INT_MAX && log))
   1.273 -		return E_INVALIDARG;
   1.274 +    if (!(maxlines >= 0 && maxlines <= INT_MAX && log))
   1.275 +        return E_INVALIDARG;
   1.276  
   1.277 -	char *_log;
   1.278 -	PEP_STATUS status = ::get_crashdump_log(get_session(), (int)maxlines, &_log);
   1.279 -	assert(status == PEP_STATUS_OK);
   1.280 -	if (status == PEP_OUT_OF_MEMORY)
   1.281 -		return E_OUTOFMEMORY;
   1.282 -	if (status != PEP_STATUS_OK)
   1.283 -		return FAIL(L"GetCrashdumpLog", status);
   1.284 +    char *_log;
   1.285 +    PEP_STATUS status = ::get_crashdump_log(get_session(), (int)maxlines, &_log);
   1.286 +    assert(status == PEP_STATUS_OK);
   1.287 +    if (status == PEP_OUT_OF_MEMORY)
   1.288 +        return E_OUTOFMEMORY;
   1.289 +    if (status != PEP_STATUS_OK)
   1.290 +        return FAIL(L"GetCrashdumpLog", status);
   1.291      if (_log == NULL)
   1.292          return FAIL(L"GetCrashdumpLog: _log == NULL");
   1.293  
   1.294 -	*log = utf16_bstr(_log);
   1.295 -	pEp_free(_log);
   1.296 -	return S_OK;
   1.297 +    *log = utf16_bstr(_log);
   1.298 +    pEp_free(_log);
   1.299 +    return S_OK;
   1.300  }
   1.301  
   1.302  STDMETHODIMP CpEpEngine::GetEngineVersion(BSTR * engine_version)
   1.303  {
   1.304 -	assert(engine_version);
   1.305 +    assert(engine_version);
   1.306  
   1.307 -	if (!engine_version)
   1.308 -		return E_INVALIDARG;
   1.309 +    if (!engine_version)
   1.310 +        return E_INVALIDARG;
   1.311  
   1.312 -	const char *_engine_version = ::get_engine_version();
   1.313 +    const char *_engine_version = ::get_engine_version();
   1.314  
   1.315 -	if (_engine_version == NULL)
   1.316 -		return FAIL(L"GetEngineVersion: _engine_version == NULL");
   1.317 +    if (_engine_version == NULL)
   1.318 +        return FAIL(L"GetEngineVersion: _engine_version == NULL");
   1.319  
   1.320 -	*engine_version = utf16_bstr(_engine_version);
   1.321 +    *engine_version = utf16_bstr(_engine_version);
   1.322  
   1.323 -	return S_OK;
   1.324 +    return S_OK;
   1.325  }
   1.326  
   1.327  STDMETHODIMP CpEpEngine::GetLanguageList(BSTR * languages)
   1.328  {
   1.329 -	assert(languages);
   1.330 +    assert(languages);
   1.331  
   1.332 -	if (!languages)
   1.333 -		return E_INVALIDARG;
   1.334 +    if (!languages)
   1.335 +        return E_INVALIDARG;
   1.336  
   1.337 -	char *_languages;
   1.338 -	PEP_STATUS status = ::get_languagelist(get_session(), &_languages);
   1.339 -	assert(status == PEP_STATUS_OK);
   1.340 -	if (status == PEP_OUT_OF_MEMORY)
   1.341 -		return E_OUTOFMEMORY;
   1.342 +    char *_languages;
   1.343 +    PEP_STATUS status = ::get_languagelist(get_session(), &_languages);
   1.344 +    assert(status == PEP_STATUS_OK);
   1.345 +    if (status == PEP_OUT_OF_MEMORY)
   1.346 +        return E_OUTOFMEMORY;
   1.347      if (status != PEP_STATUS_OK)
   1.348          return FAIL(L"GetLanguageList", status);
   1.349 -	if (_languages == NULL)
   1.350 -		return FAIL(L"GetLanguageList: _languages == NULL");
   1.351 +    if (_languages == NULL)
   1.352 +        return FAIL(L"GetLanguageList: _languages == NULL");
   1.353  
   1.354 -	*languages = utf16_bstr(_languages);
   1.355 -	pEp_free(_languages);
   1.356 -	return S_OK;
   1.357 +    *languages = utf16_bstr(_languages);
   1.358 +    pEp_free(_languages);
   1.359 +    return S_OK;
   1.360  }
   1.361  
   1.362  STDMETHODIMP CpEpEngine::SetIdentityFlags(struct pEpIdentity *identity, pEpIdentityFlags flags)
   1.363  {
   1.364 -	assert(identity);
   1.365 -	if (!identity)
   1.366 -		return E_INVALIDARG;
   1.367 +    assert(identity);
   1.368 +    if (!identity)
   1.369 +        return E_INVALIDARG;
   1.370  
   1.371 -	::pEp_identity *_ident = nullptr;
   1.372 +    ::pEp_identity *_ident = nullptr;
   1.373  
   1.374 -	try {
   1.375 -		_ident = new_identity(identity);
   1.376 -		assert(_ident);
   1.377 -		if (_ident == NULL)
   1.378 -			return E_OUTOFMEMORY;
   1.379 -	}
   1.380 -	catch (bad_alloc&) {
   1.381 -		return E_OUTOFMEMORY;
   1.382 -	}
   1.383 -	catch (exception& ex) {
   1.384 -		return FAIL(ex.what());;
   1.385 -	}
   1.386 +    try {
   1.387 +        _ident = new_identity(identity);
   1.388 +        assert(_ident);
   1.389 +        if (_ident == NULL)
   1.390 +            return E_OUTOFMEMORY;
   1.391 +    }
   1.392 +    catch (bad_alloc&) {
   1.393 +        return E_OUTOFMEMORY;
   1.394 +    }
   1.395 +    catch (exception& ex) {
   1.396 +        return FAIL(ex.what());;
   1.397 +    }
   1.398  
   1.399 -	PEP_STATUS status = ::set_identity_flags(get_session(), _ident, (identity_flags_t)flags);
   1.400 -	::free_identity(_ident);
   1.401 -	if (status != PEP_STATUS_OK)
   1.402 -		return FAIL(_T("SetIdentityFlags"), status);
   1.403 +    PEP_STATUS status = ::set_identity_flags(get_session(), _ident, (identity_flags_t)flags);
   1.404 +    ::free_identity(_ident);
   1.405 +    if (status != PEP_STATUS_OK)
   1.406 +        return FAIL(_T("SetIdentityFlags"), status);
   1.407  
   1.408 -	return S_OK;
   1.409 +    return S_OK;
   1.410  }
   1.411  
   1.412  STDMETHODIMP CpEpEngine::UnsetIdentityFlags(struct pEpIdentity *identity, pEpIdentityFlags flags)
   1.413  {
   1.414 -	assert(identity);
   1.415 -	if (!identity)
   1.416 -		return E_INVALIDARG;
   1.417 +    assert(identity);
   1.418 +    if (!identity)
   1.419 +        return E_INVALIDARG;
   1.420  
   1.421 -	::pEp_identity *_ident = nullptr;
   1.422 +    ::pEp_identity *_ident = nullptr;
   1.423  
   1.424 -	try {
   1.425 -		_ident = new_identity(identity);
   1.426 -		assert(_ident);
   1.427 -		if (_ident == NULL)
   1.428 -			return E_OUTOFMEMORY;
   1.429 -	}
   1.430 -	catch (bad_alloc&) {
   1.431 -		return E_OUTOFMEMORY;
   1.432 -	}
   1.433 -	catch (exception& ex) {
   1.434 -		return FAIL(ex.what());;
   1.435 -	}
   1.436 +    try {
   1.437 +        _ident = new_identity(identity);
   1.438 +        assert(_ident);
   1.439 +        if (_ident == NULL)
   1.440 +            return E_OUTOFMEMORY;
   1.441 +    }
   1.442 +    catch (bad_alloc&) {
   1.443 +        return E_OUTOFMEMORY;
   1.444 +    }
   1.445 +    catch (exception& ex) {
   1.446 +        return FAIL(ex.what());;
   1.447 +    }
   1.448  
   1.449 -	PEP_STATUS status = ::unset_identity_flags(get_session(), _ident, (identity_flags_t)flags);
   1.450 -	::free_identity(_ident);
   1.451 -	if (status != PEP_STATUS_OK)
   1.452 -		return FAIL(_T("UnsetIdentityFlags"), status);
   1.453 +    PEP_STATUS status = ::unset_identity_flags(get_session(), _ident, (identity_flags_t)flags);
   1.454 +    ::free_identity(_ident);
   1.455 +    if (status != PEP_STATUS_OK)
   1.456 +        return FAIL(_T("UnsetIdentityFlags"), status);
   1.457  
   1.458 -	return S_OK;
   1.459 +    return S_OK;
   1.460  }
   1.461  
   1.462  STDMETHODIMP CpEpEngine::StartKeyserverLookup()
   1.463  {
   1.464 -	if (identity_queue.load())
   1.465 -		return S_OK;
   1.466 +    if (identity_queue.load())
   1.467 +        return S_OK;
   1.468  
   1.469 -	identity_queue.store(new identity_queue_t());
   1.470 -	keymanagement_thread = new thread(::do_keymanagement, retrieve_next_identity, (void *)identity_queue.load());
   1.471 +    identity_queue.store(new identity_queue_t());
   1.472 +    keymanagement_thread = new thread(::do_keymanagement, retrieve_next_identity, (void *)identity_queue.load());
   1.473  
   1.474 -	return S_OK;
   1.475 +    return S_OK;
   1.476  }
   1.477  
   1.478  STDMETHODIMP CpEpEngine::StopKeyserverLookup()
   1.479  {
   1.480 -	if (identity_queue.load() == NULL)
   1.481 -		return S_OK;
   1.482 +    if (identity_queue.load() == NULL)
   1.483 +        return S_OK;
   1.484  
   1.485 -	identity_queue_t *_iq = identity_queue.load();
   1.486 -	identity_queue.store(NULL);
   1.487 +    identity_queue_t *_iq = identity_queue.load();
   1.488 +    identity_queue.store(NULL);
   1.489  
   1.490 -	pEp_identity_cpp shutdown;
   1.491 -	_iq->push_front(shutdown);
   1.492 +    pEp_identity_cpp shutdown;
   1.493 +    _iq->push_front(shutdown);
   1.494  
   1.495 -	keymanagement_thread->join();
   1.496 -	delete keymanagement_thread;
   1.497 -	keymanagement_thread = NULL;
   1.498 +    keymanagement_thread->join();
   1.499 +    delete keymanagement_thread;
   1.500 +    keymanagement_thread = NULL;
   1.501  
   1.502 -	delete _iq;
   1.503 +    delete _iq;
   1.504  
   1.505 -	return S_OK;
   1.506 +    return S_OK;
   1.507  }
   1.508  
   1.509  STDMETHODIMP CpEpEngine::Myself(struct pEpIdentity *ident, struct pEpIdentity *result)
   1.510  {
   1.511 -	assert(ident);
   1.512 -	assert(result);
   1.513 +    assert(ident);
   1.514 +    assert(result);
   1.515  
   1.516 -	if (!(ident && result))
   1.517 -		return E_INVALIDARG;
   1.518 +    if (!(ident && result))
   1.519 +        return E_INVALIDARG;
   1.520  
   1.521 -	::pEp_identity *_ident = 0;
   1.522 -	
   1.523 -	try {
   1.524 -		_ident = new_identity(ident);
   1.525 -		assert(_ident);
   1.526 -		if (_ident == NULL)
   1.527 -			return E_OUTOFMEMORY;
   1.528 -	}
   1.529 -	catch (bad_alloc&) {
   1.530 -		return E_OUTOFMEMORY;
   1.531 -	}
   1.532 -	catch (exception& ex) {
   1.533 -		return FAIL(ex.what());;
   1.534 -	}
   1.535 +    ::pEp_identity *_ident = 0;
   1.536  
   1.537 +    try {
   1.538 +        _ident = new_identity(ident);
   1.539 +        assert(_ident);
   1.540 +        if (_ident == NULL)
   1.541 +            return E_OUTOFMEMORY;
   1.542 +    }
   1.543 +    catch (bad_alloc&) {
   1.544 +        return E_OUTOFMEMORY;
   1.545 +    }
   1.546 +    catch (exception& ex) {
   1.547 +        return FAIL(ex.what());;
   1.548 +    }
   1.549  
   1.550 -	// DEBUG CODE - REMOVE BEFORE RELEASE!
   1.551 -	// SyncHandshakeResult handshakeResult;
   1.552 -	//
   1.553 -	// HRESULT res = Fire_NotifyHandshake(ident, result, signal, &handshakeResult);
   1.554 -	// 
   1.555 -	// HRESULT res2 = Fire_TestEvent(15, _bstr_t( "hallo"));
   1.556  
   1.557 -	PEP_STATUS status = ::myself(get_session(), _ident);
   1.558 +    // DEBUG CODE - REMOVE BEFORE RELEASE!
   1.559 +    // SyncHandshakeResult handshakeResult;
   1.560 +    //
   1.561 +    // HRESULT res = Fire_NotifyHandshake(ident, result, signal, &handshakeResult);
   1.562 +    // 
   1.563 +    // HRESULT res2 = Fire_TestEvent(15, _bstr_t( "hallo"));
   1.564  
   1.565 -	if (status == PEP_STATUS_OK) {
   1.566 -		assert(_ident->fpr);
   1.567 -		copy_identity(result, _ident);
   1.568 -		::free_identity(_ident);
   1.569 -		return S_OK;
   1.570 -	}
   1.571 -	else {
   1.572 -		::free_identity(_ident);
   1.573 -		if (status == PEP_OUT_OF_MEMORY)
   1.574 -			return E_OUTOFMEMORY;
   1.575 -		else
   1.576 -			return FAIL(L"myself", status);
   1.577 -	}
   1.578 +    PEP_STATUS status = ::myself(get_session(), _ident);
   1.579 +
   1.580 +    if (status == PEP_STATUS_OK) {
   1.581 +        assert(_ident->fpr);
   1.582 +        copy_identity(result, _ident);
   1.583 +        ::free_identity(_ident);
   1.584 +        return S_OK;
   1.585 +    }
   1.586 +    else {
   1.587 +        ::free_identity(_ident);
   1.588 +        if (status == PEP_OUT_OF_MEMORY)
   1.589 +            return E_OUTOFMEMORY;
   1.590 +        else
   1.591 +            return FAIL(L"myself", status);
   1.592 +    }
   1.593  }
   1.594  
   1.595  STDMETHODIMP CpEpEngine::UpdateIdentity(struct pEpIdentity *ident, struct pEpIdentity *result)
   1.596  {
   1.597 -	assert(ident);
   1.598 -	assert(result);
   1.599 +    assert(ident);
   1.600 +    assert(result);
   1.601  
   1.602 -	if (!(ident && result))
   1.603 -		return E_INVALIDARG;
   1.604 +    if (!(ident && result))
   1.605 +        return E_INVALIDARG;
   1.606  
   1.607 -	::pEp_identity *_ident;
   1.608 -	try {
   1.609 -		_ident = new_identity(ident);
   1.610 -	}
   1.611 -	catch (bad_alloc&) {
   1.612 -		return E_OUTOFMEMORY;
   1.613 -	}
   1.614 -	catch (exception& ex) {
   1.615 -		return FAIL(ex.what());
   1.616 -	}
   1.617 +    ::pEp_identity *_ident;
   1.618 +    try {
   1.619 +        _ident = new_identity(ident);
   1.620 +    }
   1.621 +    catch (bad_alloc&) {
   1.622 +        return E_OUTOFMEMORY;
   1.623 +    }
   1.624 +    catch (exception& ex) {
   1.625 +        return FAIL(ex.what());
   1.626 +    }
   1.627  
   1.628 -	assert(_ident);
   1.629 -	if (_ident == NULL)
   1.630 -		return E_OUTOFMEMORY;
   1.631 +    assert(_ident);
   1.632 +    if (_ident == NULL)
   1.633 +        return E_OUTOFMEMORY;
   1.634  
   1.635 -	PEP_STATUS status = ::update_identity(get_session(), _ident);
   1.636 +    PEP_STATUS status = ::update_identity(get_session(), _ident);
   1.637  
   1.638 -	if (status == PEP_STATUS_OK) {
   1.639 -		assert(_ident->fpr); // Guaranteed not NULL, but possibly empty string.
   1.640 -		copy_identity(result, _ident);
   1.641 -		::free_identity(_ident);
   1.642 -		return S_OK;
   1.643 -	}
   1.644 -	else if (status == PEP_GET_KEY_FAILED) {
   1.645 -		if (_ident->fpr) {
   1.646 -			pEp_free(_ident->fpr);
   1.647 -			_ident->fpr = NULL;
   1.648 -		}
   1.649 -		copy_identity(result, _ident);
   1.650 -		result->Fpr = NULL;
   1.651 -		::free_identity(_ident);
   1.652 -		return S_OK;
   1.653 -	}
   1.654 -	else {
   1.655 -		::free_identity(_ident);
   1.656 -		if (status == PEP_OUT_OF_MEMORY)
   1.657 -			return E_OUTOFMEMORY;
   1.658 -		else
   1.659 -			return FAIL(L"UpdateIdentity", status);
   1.660 -	}
   1.661 +    if (status == PEP_STATUS_OK) {
   1.662 +        assert(_ident->fpr); // Guaranteed not NULL, but possibly empty string.
   1.663 +        copy_identity(result, _ident);
   1.664 +        ::free_identity(_ident);
   1.665 +        return S_OK;
   1.666 +    }
   1.667 +    else if (status == PEP_GET_KEY_FAILED) {
   1.668 +        if (_ident->fpr) {
   1.669 +            pEp_free(_ident->fpr);
   1.670 +            _ident->fpr = NULL;
   1.671 +        }
   1.672 +        copy_identity(result, _ident);
   1.673 +        result->Fpr = NULL;
   1.674 +        ::free_identity(_ident);
   1.675 +        return S_OK;
   1.676 +    }
   1.677 +    else {
   1.678 +        ::free_identity(_ident);
   1.679 +        if (status == PEP_OUT_OF_MEMORY)
   1.680 +            return E_OUTOFMEMORY;
   1.681 +        else
   1.682 +            return FAIL(L"UpdateIdentity", status);
   1.683 +    }
   1.684  }
   1.685  
   1.686  STDMETHODIMP CpEpEngine::KeyMistrusted(struct pEpIdentity *ident)
   1.687  {
   1.688 -	::pEp_identity *_ident;
   1.689 +    ::pEp_identity *_ident;
   1.690  
   1.691 -	assert(ident);
   1.692 -	if (!ident)
   1.693 -		return E_INVALIDARG;
   1.694 +    assert(ident);
   1.695 +    if (!ident)
   1.696 +        return E_INVALIDARG;
   1.697  
   1.698 -	try {
   1.699 -		_ident = new_identity(ident);
   1.700 -	}
   1.701 -	catch (bad_alloc&) {
   1.702 -		return E_OUTOFMEMORY;
   1.703 -	}
   1.704 -	catch (exception& ex) {
   1.705 -		return FAIL(ex.what());;
   1.706 -	}
   1.707 +    try {
   1.708 +        _ident = new_identity(ident);
   1.709 +    }
   1.710 +    catch (bad_alloc&) {
   1.711 +        return E_OUTOFMEMORY;
   1.712 +    }
   1.713 +    catch (exception& ex) {
   1.714 +        return FAIL(ex.what());;
   1.715 +    }
   1.716  
   1.717 -	PEP_STATUS status = ::key_mistrusted(get_session(), _ident);
   1.718 -	free_identity(_ident);
   1.719 +    PEP_STATUS status = ::key_mistrusted(get_session(), _ident);
   1.720 +    free_identity(_ident);
   1.721  
   1.722 -	if (status == PEP_OUT_OF_MEMORY)
   1.723 -		return E_OUTOFMEMORY;
   1.724 +    if (status == PEP_OUT_OF_MEMORY)
   1.725 +        return E_OUTOFMEMORY;
   1.726  
   1.727 -	if (status == PEP_KEY_NOT_FOUND)
   1.728 -		return FAIL(L"key not found");
   1.729 +    if (status == PEP_KEY_NOT_FOUND)
   1.730 +        return FAIL(L"key not found");
   1.731  
   1.732 -	if (status != ::PEP_STATUS_OK)
   1.733 -		return FAIL(L"cannot revoke compromized key", status);
   1.734 +    if (status != ::PEP_STATUS_OK)
   1.735 +        return FAIL(L"cannot revoke compromized key", status);
   1.736  
   1.737 -	return S_OK;
   1.738 +    return S_OK;
   1.739  }
   1.740  
   1.741  STDMETHODIMP CpEpEngine::KeyResetTrust(struct pEpIdentity *ident)
   1.742  {
   1.743 -	::pEp_identity *_ident;
   1.744 +    ::pEp_identity *_ident;
   1.745  
   1.746 -	assert(ident); 
   1.747 -	
   1.748 -	if (!ident)
   1.749 -		return E_INVALIDARG;
   1.750 +    assert(ident);
   1.751  
   1.752 -	try {
   1.753 -		_ident = new_identity(ident);
   1.754 -	}
   1.755 -	catch (bad_alloc&) {
   1.756 -		return E_OUTOFMEMORY;
   1.757 -	}
   1.758 -	catch (exception& ex) {
   1.759 -		return FAIL(ex.what());;
   1.760 -	}
   1.761 +    if (!ident)
   1.762 +        return E_INVALIDARG;
   1.763  
   1.764 -	PEP_STATUS status = ::key_reset_trust(get_session(), _ident);
   1.765 -	free_identity(_ident);
   1.766 +    try {
   1.767 +        _ident = new_identity(ident);
   1.768 +    }
   1.769 +    catch (bad_alloc&) {
   1.770 +        return E_OUTOFMEMORY;
   1.771 +    }
   1.772 +    catch (exception& ex) {
   1.773 +        return FAIL(ex.what());;
   1.774 +    }
   1.775  
   1.776 -	if (status == PEP_OUT_OF_MEMORY)
   1.777 -		return E_OUTOFMEMORY;
   1.778 +    PEP_STATUS status = ::key_reset_trust(get_session(), _ident);
   1.779 +    free_identity(_ident);
   1.780  
   1.781 -	if (status == PEP_KEY_NOT_FOUND)
   1.782 -		return FAIL(L"key not found");
   1.783 +    if (status == PEP_OUT_OF_MEMORY)
   1.784 +        return E_OUTOFMEMORY;
   1.785  
   1.786 -	if (status != ::PEP_STATUS_OK)
   1.787 -		return FAIL(L"cannot reset trust", status);
   1.788 +    if (status == PEP_KEY_NOT_FOUND)
   1.789 +        return FAIL(L"key not found");
   1.790  
   1.791 -	return S_OK;
   1.792 +    if (status != ::PEP_STATUS_OK)
   1.793 +        return FAIL(L"cannot reset trust", status);
   1.794 +
   1.795 +    return S_OK;
   1.796  }
   1.797  
   1.798  int CpEpEngine::examine_identity(pEp_identity *ident, void *management)
   1.799  {
   1.800 -	assert(ident);
   1.801 -	assert(management);
   1.802 -	if (!(ident && management))
   1.803 -		return -1;
   1.804 +    assert(ident);
   1.805 +    assert(management);
   1.806 +    if (!(ident && management))
   1.807 +        return -1;
   1.808  
   1.809 -	CpEpEngine *me = (CpEpEngine *)management;
   1.810 +    CpEpEngine *me = (CpEpEngine *)management;
   1.811  
   1.812 -	if (me->identity_queue.load() == NULL)
   1.813 -		return 0;
   1.814 +    if (me->identity_queue.load() == NULL)
   1.815 +        return 0;
   1.816  
   1.817 -	try {
   1.818 -		me->identity_queue.load()->push_back(ident);
   1.819 -	}
   1.820 -	catch (exception&) {
   1.821 -		return -1;
   1.822 -	}
   1.823 +    try {
   1.824 +        me->identity_queue.load()->push_back(ident);
   1.825 +    }
   1.826 +    catch (exception&) {
   1.827 +        return -1;
   1.828 +    }
   1.829  
   1.830 -	return 0;
   1.831 +    return 0;
   1.832  }
   1.833  
   1.834  ::pEp_identity * CpEpEngine::retrieve_next_identity(void *management)
   1.835  {
   1.836 -	assert(management);
   1.837 -	if (!management)
   1.838 -		return NULL;
   1.839 +    assert(management);
   1.840 +    if (!management)
   1.841 +        return NULL;
   1.842  
   1.843 -	identity_queue_t *iq = (identity_queue_t *)management;
   1.844 +    identity_queue_t *iq = (identity_queue_t *)management;
   1.845  
   1.846 -	do /* poll queue */ {
   1.847 -		if (iq->size())
   1.848 -			break;
   1.849 -		::Sleep(100);
   1.850 -	} while (true);
   1.851 +    do /* poll queue */ {
   1.852 +        if (iq->size())
   1.853 +            break;
   1.854 +        ::Sleep(100);
   1.855 +    } while (true);
   1.856  
   1.857 -	::pEp_identity *_ident;
   1.858 -	pEp_identity_cpp& ident = iq->front();
   1.859 +    ::pEp_identity *_ident;
   1.860 +    pEp_identity_cpp& ident = iq->front();
   1.861  
   1.862 -	if (ident.address.size() == 0)
   1.863 -		return NULL;
   1.864 +    if (ident.address.size() == 0)
   1.865 +        return NULL;
   1.866  
   1.867 -	_ident = ident.to_pEp_identity();
   1.868 -	iq->pop_front();
   1.869 +    _ident = ident.to_pEp_identity();
   1.870 +    iq->pop_front();
   1.871  
   1.872 -	return _ident;
   1.873 +    return _ident;
   1.874  }
   1.875  
   1.876  PEP_STATUS CpEpEngine::messageToSend(void * obj, message *msg)
   1.877  {
   1.878 -	assert(msg);
   1.879 -	assert(obj);
   1.880 -	if (!(msg && obj))
   1.881 -		return PEP_ILLEGAL_VALUE;
   1.882 +    assert(msg);
   1.883 +    assert(obj);
   1.884 +    if (!(msg && obj))
   1.885 +        return PEP_ILLEGAL_VALUE;
   1.886  
   1.887 -	TextMessage _msg;
   1.888 -	memset(&_msg, 0, sizeof(TextMessage));
   1.889 +    TextMessage _msg;
   1.890 +    memset(&_msg, 0, sizeof(TextMessage));
   1.891  
   1.892 -	text_message_from_C(&_msg, msg);
   1.893 -	CpEpEngine *me = (CpEpEngine *)obj;
   1.894 -	HRESULT r = me->Fire_MessageToSend(&_msg);
   1.895 -	assert(r == S_OK);
   1.896 -	clear_text_message(&_msg);
   1.897 -	if (r == E_OUTOFMEMORY)
   1.898 -		return PEP_OUT_OF_MEMORY;
   1.899 -	if (r != S_OK)
   1.900 -		return PEP_UNKNOWN_ERROR;
   1.901 +    text_message_from_C(&_msg, msg);
   1.902 +    CpEpEngine *me = (CpEpEngine *)obj;
   1.903 +    HRESULT r = me->Fire_MessageToSend(&_msg);
   1.904 +    assert(r == S_OK);
   1.905 +    clear_text_message(&_msg);
   1.906 +    if (r == E_OUTOFMEMORY)
   1.907 +        return PEP_OUT_OF_MEMORY;
   1.908 +    if (r != S_OK)
   1.909 +        return PEP_UNKNOWN_ERROR;
   1.910  
   1.911 -	return PEP_STATUS_OK;
   1.912 -}
   1.913 -
   1.914 -PEP_STATUS CpEpEngine::notifyHandshake(void * obj, pEp_identity *self, pEp_identity *partner, sync_handshake_signal signal)
   1.915 -{
   1.916 -	assert(self && partner);
   1.917 -	if (!(self && partner))
   1.918 -		return PEP_ILLEGAL_VALUE;
   1.919 -
   1.920 -	pEpIdentity _self;
   1.921 -	copy_identity(&_self, self);
   1.922 -	pEpIdentity _partner;
   1.923 -	copy_identity(&_partner, partner);
   1.924 -	CpEpEngine *me = (CpEpEngine *)obj;
   1.925 -	SyncHandshakeResult _result;
   1.926 -	HRESULT r = me->Fire_NotifyHandshake(&_self, &_partner, (SyncHandshakeSignal)(int)signal, &_result);
   1.927 -	assert(r == S_OK);
   1.928 -	clear_identity_s(_self);
   1.929 -	clear_identity_s(_partner);
   1.930 -	if (r == E_OUTOFMEMORY)
   1.931 -		return PEP_OUT_OF_MEMORY;
   1.932 -	if (r != S_OK)
   1.933 -		return PEP_UNKNOWN_ERROR;
   1.934 -
   1.935 -	PEP_STATUS status = deliverHandshakeResult(me->get_session(), partner, (sync_handshake_result)(int)_result);
   1.936 -	return status;
   1.937 +    return PEP_STATUS_OK;
   1.938  }
   1.939  
   1.940  STDMETHODIMP CpEpEngine::BlacklistAdd(BSTR fpr)
   1.941  {
   1.942 -	assert(fpr);
   1.943 -	if (!fpr)
   1.944 -		return E_INVALIDARG;
   1.945 +    assert(fpr);
   1.946 +    if (!fpr)
   1.947 +        return E_INVALIDARG;
   1.948  
   1.949 -	string _fpr = utf8_string(fpr);
   1.950 -	PEP_STATUS status = ::blacklist_add(get_session(), _fpr.c_str());
   1.951 -	assert(status == PEP_STATUS_OK);
   1.952 -	if (status != PEP_STATUS_OK)
   1.953 -		return FAIL(L"blacklist_add failed in pEp engine", status);
   1.954 +    string _fpr = utf8_string(fpr);
   1.955 +    PEP_STATUS status = ::blacklist_add(get_session(), _fpr.c_str());
   1.956 +    assert(status == PEP_STATUS_OK);
   1.957 +    if (status != PEP_STATUS_OK)
   1.958 +        return FAIL(L"blacklist_add failed in pEp engine", status);
   1.959  
   1.960 -	return S_OK;
   1.961 +    return S_OK;
   1.962  }
   1.963  
   1.964  STDMETHODIMP CpEpEngine::BlacklistDelete(BSTR fpr)
   1.965  {
   1.966 -	assert(fpr);
   1.967 -	if (!fpr)
   1.968 -		return E_INVALIDARG;
   1.969 +    assert(fpr);
   1.970 +    if (!fpr)
   1.971 +        return E_INVALIDARG;
   1.972  
   1.973 -	string _fpr = utf8_string(fpr);
   1.974 -	PEP_STATUS status = ::blacklist_delete(get_session(), _fpr.c_str());
   1.975 -	assert(status == PEP_STATUS_OK);
   1.976 -	if (status != PEP_STATUS_OK)
   1.977 -		return FAIL(L"blacklist_delete failed in pEp engine", status);
   1.978 +    string _fpr = utf8_string(fpr);
   1.979 +    PEP_STATUS status = ::blacklist_delete(get_session(), _fpr.c_str());
   1.980 +    assert(status == PEP_STATUS_OK);
   1.981 +    if (status != PEP_STATUS_OK)
   1.982 +        return FAIL(L"blacklist_delete failed in pEp engine", status);
   1.983  
   1.984 -	return S_OK;
   1.985 +    return S_OK;
   1.986  }
   1.987  
   1.988  STDMETHODIMP CpEpEngine::BlacklistIsListed(BSTR fpr, VARIANT_BOOL *listed)
   1.989  {
   1.990 -	assert(fpr);
   1.991 -	assert(listed);
   1.992 +    assert(fpr);
   1.993 +    assert(listed);
   1.994  
   1.995 -	if (!(fpr && listed))
   1.996 -		return E_INVALIDARG;
   1.997 +    if (!(fpr && listed))
   1.998 +        return E_INVALIDARG;
   1.999  
  1.1000 -	string _fpr = utf8_string(fpr);
  1.1001 -	bool result;
  1.1002 -	PEP_STATUS status = ::blacklist_is_listed(get_session(), _fpr.c_str(), &result);
  1.1003 -	assert(status == PEP_STATUS_OK);
  1.1004 -	if (status != PEP_STATUS_OK)
  1.1005 -		return FAIL(L"blacklist_is_listed failed in pEp engine", status);
  1.1006 +    string _fpr = utf8_string(fpr);
  1.1007 +    bool result;
  1.1008 +    PEP_STATUS status = ::blacklist_is_listed(get_session(), _fpr.c_str(), &result);
  1.1009 +    assert(status == PEP_STATUS_OK);
  1.1010 +    if (status != PEP_STATUS_OK)
  1.1011 +        return FAIL(L"blacklist_is_listed failed in pEp engine", status);
  1.1012  
  1.1013 -	*listed = result ? VARIANT_TRUE : VARIANT_FALSE;
  1.1014 -	return S_OK;
  1.1015 +    *listed = result ? VARIANT_TRUE : VARIANT_FALSE;
  1.1016 +    return S_OK;
  1.1017  }
  1.1018  
  1.1019  STDMETHODIMP CpEpEngine::BlacklistRetrieve(SAFEARRAY **blacklist)
  1.1020  {
  1.1021 -	assert(blacklist);
  1.1022 +    assert(blacklist);
  1.1023  
  1.1024 -	if (!blacklist)
  1.1025 -		return E_INVALIDARG;
  1.1026 +    if (!blacklist)
  1.1027 +        return E_INVALIDARG;
  1.1028  
  1.1029 -	::stringlist_t *_blacklist = NULL;
  1.1030 -	PEP_STATUS status = ::blacklist_retrieve(get_session(), &_blacklist);
  1.1031 -	assert(status == PEP_STATUS_OK);
  1.1032 -	if (status != PEP_STATUS_OK)
  1.1033 -		return FAIL(L"blacklist_retrieve failed in pEp engine", status);
  1.1034 -	assert(_blacklist);
  1.1035 +    ::stringlist_t *_blacklist = NULL;
  1.1036 +    PEP_STATUS status = ::blacklist_retrieve(get_session(), &_blacklist);
  1.1037 +    assert(status == PEP_STATUS_OK);
  1.1038 +    if (status != PEP_STATUS_OK)
  1.1039 +        return FAIL(L"blacklist_retrieve failed in pEp engine", status);
  1.1040 +    assert(_blacklist);
  1.1041  
  1.1042 -	*blacklist = string_array(_blacklist);
  1.1043 -	::free_stringlist(_blacklist);
  1.1044 -	return S_OK;
  1.1045 +    *blacklist = string_array(_blacklist);
  1.1046 +    ::free_stringlist(_blacklist);
  1.1047 +    return S_OK;
  1.1048  }
  1.1049  
  1.1050  HRESULT CpEpEngine::error(_bstr_t msg)
  1.1051  {
  1.1052 -	_bstr_t helpFile = L"";
  1.1053 -	_bstr_t source = L"pEp COM Adapter";
  1.1054 +    _bstr_t helpFile = L"";
  1.1055 +    _bstr_t source = L"pEp COM Adapter";
  1.1056  
  1.1057 -	ICreateErrorInfo *cei;
  1.1058 -	if (SUCCEEDED(CreateErrorInfo(&cei))) {
  1.1059 -		cei->SetDescription(msg);
  1.1060 -		cei->SetGUID(__uuidof(IpEpEngine));
  1.1061 -		cei->SetHelpContext(0);
  1.1062 -		cei->SetHelpFile(helpFile);
  1.1063 -		cei->SetSource(source);
  1.1064 +    ICreateErrorInfo *cei;
  1.1065 +    if (SUCCEEDED(CreateErrorInfo(&cei))) {
  1.1066 +        cei->SetDescription(msg);
  1.1067 +        cei->SetGUID(__uuidof(IpEpEngine));
  1.1068 +        cei->SetHelpContext(0);
  1.1069 +        cei->SetHelpFile(helpFile);
  1.1070 +        cei->SetSource(source);
  1.1071  
  1.1072 -		IErrorInfo *errinfo;
  1.1073 -		if (SUCCEEDED(cei->QueryInterface(IID_IErrorInfo, (LPVOID FAR*) &errinfo))) {
  1.1074 -			SetErrorInfo(0, errinfo);
  1.1075 -			errinfo->Release();
  1.1076 -		}
  1.1077 -		cei->Release();
  1.1078 -	}
  1.1079 -	return E_FAIL;
  1.1080 +        IErrorInfo *errinfo;
  1.1081 +        if (SUCCEEDED(cei->QueryInterface(IID_IErrorInfo, (LPVOID FAR*) &errinfo))) {
  1.1082 +            SetErrorInfo(0, errinfo);
  1.1083 +            errinfo->Release();
  1.1084 +        }
  1.1085 +        cei->Release();
  1.1086 +    }
  1.1087 +    return E_FAIL;
  1.1088  }
  1.1089  
  1.1090  HRESULT CpEpEngine::error(_bstr_t msg, PEP_STATUS status)
  1.1091 @@ -826,7 +805,7 @@
  1.1092      stream << msg;
  1.1093      stream << ": ";
  1.1094      stream << std::hex << status;
  1.1095 -    
  1.1096 +
  1.1097      error(stream.str().c_str());
  1.1098  
  1.1099      if (status == ::PEP_OUT_OF_MEMORY)
  1.1100 @@ -837,269 +816,269 @@
  1.1101  
  1.1102  STDMETHODIMP CpEpEngine::EncryptMessage(TextMessage * src, TextMessage * dst, SAFEARRAY * extra, pEpEncryptFlags flags)
  1.1103  {
  1.1104 -	assert(src);
  1.1105 -	assert(dst);
  1.1106 +    assert(src);
  1.1107 +    assert(dst);
  1.1108  
  1.1109 -	if (!(src && dst))
  1.1110 -		return E_INVALIDARG;
  1.1111 +    if (!(src && dst))
  1.1112 +        return E_INVALIDARG;
  1.1113  
  1.1114 -	::message *_src = text_message_to_C(src);
  1.1115 +    ::message *_src = text_message_to_C(src);
  1.1116  
  1.1117 -	// COM-19: Initialize msg_dst to NULL, or we end up calling
  1.1118 -	// free_message() below with a pointer to random garbage in
  1.1119 -	// case of an error in encrypt_message().
  1.1120 -	::message *msg_dst = NULL;
  1.1121 -	::stringlist_t *_extra = new_stringlist(extra); // can cope with NULL
  1.1122 +    // COM-19: Initialize msg_dst to NULL, or we end up calling
  1.1123 +    // free_message() below with a pointer to random garbage in
  1.1124 +    // case of an error in encrypt_message().
  1.1125 +    ::message *msg_dst = NULL;
  1.1126 +    ::stringlist_t *_extra = new_stringlist(extra); // can cope with NULL
  1.1127  
  1.1128 -	// _PEP_enc_format is intentionally hardcoded to PEP_enc_PEP:
  1.1129 -	// 2016-10-02 14:10 < fdik> schabi: actually, all adapters now must use PEP_enc_PEP
  1.1130 -	PEP_encrypt_flags_t engineFlags = (PEP_encrypt_flags_t) flags;
  1.1131 -	PEP_STATUS status = ::encrypt_message(get_session(), _src, _extra, &msg_dst, PEP_enc_PEP, engineFlags);
  1.1132 -	::free_stringlist(_extra);
  1.1133 +    // _PEP_enc_format is intentionally hardcoded to PEP_enc_PEP:
  1.1134 +    // 2016-10-02 14:10 < fdik> schabi: actually, all adapters now must use PEP_enc_PEP
  1.1135 +    PEP_encrypt_flags_t engineFlags = (PEP_encrypt_flags_t)flags;
  1.1136 +    PEP_STATUS status = ::encrypt_message(get_session(), _src, _extra, &msg_dst, PEP_enc_PEP, engineFlags);
  1.1137 +    ::free_stringlist(_extra);
  1.1138  
  1.1139 -	if (status == PEP_STATUS_OK)
  1.1140 -		text_message_from_C(dst, msg_dst);
  1.1141 -	else
  1.1142 -		text_message_from_C(dst, _src);
  1.1143 +    if (status == PEP_STATUS_OK)
  1.1144 +        text_message_from_C(dst, msg_dst);
  1.1145 +    else
  1.1146 +        text_message_from_C(dst, _src);
  1.1147  
  1.1148 -	::free_message(msg_dst);
  1.1149 -	::free_message(_src);
  1.1150 +    ::free_message(msg_dst);
  1.1151 +    ::free_message(_src);
  1.1152  
  1.1153 -	if (status == PEP_OUT_OF_MEMORY)
  1.1154 -		return E_OUTOFMEMORY;
  1.1155 +    if (status == PEP_OUT_OF_MEMORY)
  1.1156 +        return E_OUTOFMEMORY;
  1.1157  
  1.1158 -	// COM-41: Enhanced PEP status handling
  1.1159 -	if ((status != PEP_STATUS_OK) && (status < PEP_UNENCRYPTED || status >= PEP_TRUSTWORD_NOT_FOUND))
  1.1160 -		return FAIL("Failure to encrypt message", status);
  1.1161 +    // COM-41: Enhanced PEP status handling
  1.1162 +    if ((status != PEP_STATUS_OK) && (status < PEP_UNENCRYPTED || status >= PEP_TRUSTWORD_NOT_FOUND))
  1.1163 +        return FAIL("Failure to encrypt message", status);
  1.1164  
  1.1165 -	// Statii like PEP_UNENCRYPTED due to no private key
  1.1166 -	// should not be a catastrophic failure here. Using S_FALSE
  1.1167 -	// still allows clients to differentiate with S_OK,
  1.1168 -	// although this does not work out of the box with
  1.1169 -	// the standard .NET mapping of COM.
  1.1170 -	if (status != PEP_STATUS_OK)
  1.1171 -		return S_FALSE;
  1.1172 +    // Statii like PEP_UNENCRYPTED due to no private key
  1.1173 +    // should not be a catastrophic failure here. Using S_FALSE
  1.1174 +    // still allows clients to differentiate with S_OK,
  1.1175 +    // although this does not work out of the box with
  1.1176 +    // the standard .NET mapping of COM.
  1.1177 +    if (status != PEP_STATUS_OK)
  1.1178 +        return S_FALSE;
  1.1179  
  1.1180 -	return S_OK;
  1.1181 +    return S_OK;
  1.1182  }
  1.1183  
  1.1184  STDMETHODIMP CpEpEngine::DecryptMessage(TextMessage * src, TextMessage * dst, SAFEARRAY ** keylist, pEpDecryptFlags *flags, pEpRating *rating)
  1.1185  {
  1.1186 -	assert(src);
  1.1187 -	assert(dst);
  1.1188 -	assert(keylist);
  1.1189 -	assert(flags);
  1.1190 -	assert(rating);
  1.1191 +    assert(src);
  1.1192 +    assert(dst);
  1.1193 +    assert(keylist);
  1.1194 +    assert(flags);
  1.1195 +    assert(rating);
  1.1196  
  1.1197 -	if (!(src && dst && keylist && flags && rating))
  1.1198 -		return E_INVALIDARG;
  1.1199 +    if (!(src && dst && keylist && flags && rating))
  1.1200 +        return E_INVALIDARG;
  1.1201  
  1.1202 -	*keylist = NULL;
  1.1203 -	*rating = pEpRatingUndefined;
  1.1204 +    *keylist = NULL;
  1.1205 +    *rating = pEpRatingUndefined;
  1.1206  
  1.1207 -	::message *_src = text_message_to_C(src);
  1.1208 -	::message *msg_dst = NULL;
  1.1209 -	::stringlist_t *_keylist = NULL;
  1.1210 -	::PEP_rating _rating;
  1.1211 +    ::message *_src = text_message_to_C(src);
  1.1212 +    ::message *msg_dst = NULL;
  1.1213 +    ::stringlist_t *_keylist = NULL;
  1.1214 +    ::PEP_rating _rating;
  1.1215  
  1.1216 -	PEP_decrypt_flags_t engineflags = 0;
  1.1217 -	PEP_STATUS status = ::decrypt_message(get_session(), _src, &msg_dst, &_keylist, &_rating, &engineflags);
  1.1218 +    PEP_decrypt_flags_t engineflags = 0;
  1.1219 +    PEP_STATUS status = ::decrypt_message(get_session(), _src, &msg_dst, &_keylist, &_rating, &engineflags);
  1.1220  
  1.1221 -	*flags = (pEpDecryptFlags)engineflags;
  1.1222 +    *flags = (pEpDecryptFlags)engineflags;
  1.1223  
  1.1224 -	if (msg_dst)
  1.1225 -		text_message_from_C(dst, msg_dst);
  1.1226 +    if (msg_dst)
  1.1227 +        text_message_from_C(dst, msg_dst);
  1.1228  
  1.1229 -	::free_message(_src);
  1.1230 -	::free_message(msg_dst);
  1.1231 +    ::free_message(_src);
  1.1232 +    ::free_message(msg_dst);
  1.1233  
  1.1234 -	if (_keylist) {
  1.1235 -		*keylist = string_array(_keylist);
  1.1236 -		free_stringlist(_keylist);
  1.1237 -	}
  1.1238 +    if (_keylist) {
  1.1239 +        *keylist = string_array(_keylist);
  1.1240 +        free_stringlist(_keylist);
  1.1241 +    }
  1.1242  
  1.1243 -	*rating = (pEpRating)_rating;
  1.1244 +    *rating = (pEpRating)_rating;
  1.1245  
  1.1246 -	return S_OK;
  1.1247 +    return S_OK;
  1.1248  }
  1.1249  
  1.1250  STDMETHODIMP CpEpEngine::OutgoingMessageRating(TextMessage *msg, pEpRating * pVal)
  1.1251  {
  1.1252 -	assert(msg);
  1.1253 -	assert(pVal);
  1.1254 +    assert(msg);
  1.1255 +    assert(pVal);
  1.1256  
  1.1257 -	if (!(msg  && pVal))
  1.1258 -		return E_INVALIDARG;
  1.1259 +    if (!(msg  && pVal))
  1.1260 +        return E_INVALIDARG;
  1.1261  
  1.1262 -	::message *_msg = text_message_to_C(msg);
  1.1263 +    ::message *_msg = text_message_to_C(msg);
  1.1264  
  1.1265 -	PEP_rating _rating;
  1.1266 -	PEP_STATUS status = ::outgoing_message_rating(get_session(), _msg, &_rating);
  1.1267 -	if (status != PEP_STATUS_OK)
  1.1268 -		return FAIL(L"cannot get message rating", status);
  1.1269 +    PEP_rating _rating;
  1.1270 +    PEP_STATUS status = ::outgoing_message_rating(get_session(), _msg, &_rating);
  1.1271 +    if (status != PEP_STATUS_OK)
  1.1272 +        return FAIL(L"cannot get message rating", status);
  1.1273  
  1.1274 -	*pVal = (pEpRating)_rating;
  1.1275 -	return S_OK;
  1.1276 +    *pVal = (pEpRating)_rating;
  1.1277 +    return S_OK;
  1.1278  }
  1.1279  
  1.1280  STDMETHODIMP CpEpEngine::IdentityRating(struct pEpIdentity *ident, pEpRating * pVal)
  1.1281  {
  1.1282 -	::pEp_identity *_ident;
  1.1283 +    ::pEp_identity *_ident;
  1.1284  
  1.1285 -	assert(ident);
  1.1286 -	assert(pVal);
  1.1287 +    assert(ident);
  1.1288 +    assert(pVal);
  1.1289  
  1.1290 -	if (!(ident  && pVal))
  1.1291 -		return E_INVALIDARG;
  1.1292 +    if (!(ident  && pVal))
  1.1293 +        return E_INVALIDARG;
  1.1294  
  1.1295 -	try {
  1.1296 -		_ident = new_identity(ident);
  1.1297 -	}
  1.1298 -	catch (bad_alloc&) {
  1.1299 -		return E_OUTOFMEMORY;
  1.1300 -	}
  1.1301 -	catch (exception& ex) {
  1.1302 -		return FAIL(ex.what());;
  1.1303 -	}
  1.1304 +    try {
  1.1305 +        _ident = new_identity(ident);
  1.1306 +    }
  1.1307 +    catch (bad_alloc&) {
  1.1308 +        return E_OUTOFMEMORY;
  1.1309 +    }
  1.1310 +    catch (exception& ex) {
  1.1311 +        return FAIL(ex.what());;
  1.1312 +    }
  1.1313  
  1.1314 -	PEP_rating _rating;
  1.1315 -	PEP_STATUS status = ::identity_rating(get_session(), _ident, &_rating);
  1.1316 -	free_identity(_ident);
  1.1317 +    PEP_rating _rating;
  1.1318 +    PEP_STATUS status = ::identity_rating(get_session(), _ident, &_rating);
  1.1319 +    free_identity(_ident);
  1.1320  
  1.1321 -	if (status != PEP_STATUS_OK)
  1.1322 -		return FAIL(L"cannot get message color", status);
  1.1323 +    if (status != PEP_STATUS_OK)
  1.1324 +        return FAIL(L"cannot get message color", status);
  1.1325  
  1.1326 -	*pVal = (pEpRating)_rating;
  1.1327 -	return S_OK;
  1.1328 +    *pVal = (pEpRating)_rating;
  1.1329 +    return S_OK;
  1.1330  }
  1.1331  
  1.1332  STDMETHODIMP CpEpEngine::ColorFromRating(pEpRating rating, pEpColor * pVal)
  1.1333  {
  1.1334 -	assert(pVal);
  1.1335 +    assert(pVal);
  1.1336  
  1.1337 -	if (!pVal)
  1.1338 -		return E_INVALIDARG;
  1.1339 +    if (!pVal)
  1.1340 +        return E_INVALIDARG;
  1.1341  
  1.1342 -	PEP_rating engineRating = (PEP_rating)rating;
  1.1343 -	PEP_color _color = ::color_from_rating(engineRating);
  1.1344 +    PEP_rating engineRating = (PEP_rating)rating;
  1.1345 +    PEP_color _color = ::color_from_rating(engineRating);
  1.1346  
  1.1347 -	*pVal = (pEpColor)_color;
  1.1348 +    *pVal = (pEpColor)_color;
  1.1349  
  1.1350 -	return S_OK;
  1.1351 +    return S_OK;
  1.1352  }
  1.1353  
  1.1354  STDMETHODIMP CpEpEngine::OwnIdentitiesRetrieve(LPSAFEARRAY* own_identities)
  1.1355  {
  1.1356 -	assert(own_identities);
  1.1357 -	if (!own_identities)
  1.1358 -		return E_INVALIDARG;
  1.1359 +    assert(own_identities);
  1.1360 +    if (!own_identities)
  1.1361 +        return E_INVALIDARG;
  1.1362  
  1.1363 -	*own_identities = nullptr;
  1.1364 +    *own_identities = nullptr;
  1.1365  
  1.1366 -	::identity_list *il = nullptr;
  1.1367 -	PEP_STATUS status = ::own_identities_retrieve(get_session(), &il);
  1.1368 -	if (status == PEP_OUT_OF_MEMORY) {
  1.1369 -		return E_OUTOFMEMORY;
  1.1370 -	}
  1.1371 -	else if (status != PEP_STATUS_OK)
  1.1372 -	{
  1.1373 -		return FAIL(_T("OwnIdentitiesRetrieve"), status);
  1.1374 -	}
  1.1375 +    ::identity_list *il = nullptr;
  1.1376 +    PEP_STATUS status = ::own_identities_retrieve(get_session(), &il);
  1.1377 +    if (status == PEP_OUT_OF_MEMORY) {
  1.1378 +        return E_OUTOFMEMORY;
  1.1379 +    }
  1.1380 +    else if (status != PEP_STATUS_OK)
  1.1381 +    {
  1.1382 +        return FAIL(_T("OwnIdentitiesRetrieve"), status);
  1.1383 +    }
  1.1384  
  1.1385 -	SAFEARRAY * _own_identities = nullptr;
  1.1386 -	try {
  1.1387 -		_own_identities = array_from_C<pEpIdentity, identity_list>(il);
  1.1388 -	}
  1.1389 -	catch (exception& ex)
  1.1390 -	{
  1.1391 -		::free_identity_list(il);
  1.1392 -		try {
  1.1393 -			dynamic_cast<bad_alloc&>(ex);
  1.1394 -		}
  1.1395 -		catch (bad_cast&)
  1.1396 -		{
  1.1397 -			return FAIL(ex.what());
  1.1398 -		}
  1.1399 -		return E_OUTOFMEMORY;
  1.1400 -	}
  1.1401 -	free_identity_list(il);
  1.1402 +    SAFEARRAY * _own_identities = nullptr;
  1.1403 +    try {
  1.1404 +        _own_identities = array_from_C<pEpIdentity, identity_list>(il);
  1.1405 +    }
  1.1406 +    catch (exception& ex)
  1.1407 +    {
  1.1408 +        ::free_identity_list(il);
  1.1409 +        try {
  1.1410 +            dynamic_cast<bad_alloc&>(ex);
  1.1411 +        }
  1.1412 +        catch (bad_cast&)
  1.1413 +        {
  1.1414 +            return FAIL(ex.what());
  1.1415 +        }
  1.1416 +        return E_OUTOFMEMORY;
  1.1417 +    }
  1.1418 +    free_identity_list(il);
  1.1419  
  1.1420 -	*own_identities = _own_identities;
  1.1421 -	return S_OK;
  1.1422 +    *own_identities = _own_identities;
  1.1423 +    return S_OK;
  1.1424  }
  1.1425  
  1.1426  STDMETHODIMP CpEpEngine::TrustPersonalKey(struct pEpIdentity *ident, struct pEpIdentity *result)
  1.1427  {
  1.1428 -	::pEp_identity *_ident;
  1.1429 +    ::pEp_identity *_ident;
  1.1430  
  1.1431 -	assert(ident);
  1.1432 -	assert(result);
  1.1433 +    assert(ident);
  1.1434 +    assert(result);
  1.1435  
  1.1436 -	if (!ident || !result)
  1.1437 -		return E_INVALIDARG;
  1.1438 +    if (!ident || !result)
  1.1439 +        return E_INVALIDARG;
  1.1440  
  1.1441 -	try {
  1.1442 -		_ident = new_identity(ident);
  1.1443 -	}
  1.1444 -	catch (bad_alloc&) {
  1.1445 -		return E_OUTOFMEMORY;
  1.1446 -	}
  1.1447 -	catch (exception& ex) {
  1.1448 -		return FAIL(ex.what());;
  1.1449 -	}
  1.1450 +    try {
  1.1451 +        _ident = new_identity(ident);
  1.1452 +    }
  1.1453 +    catch (bad_alloc&) {
  1.1454 +        return E_OUTOFMEMORY;
  1.1455 +    }
  1.1456 +    catch (exception& ex) {
  1.1457 +        return FAIL(ex.what());;
  1.1458 +    }
  1.1459  
  1.1460 -	if (verbose_mode) {
  1.1461 -		stringstream ss;
  1.1462 -		ss << "TrustPersonalKey called with ";
  1.1463 -		ss << utf8_string(ident->Address);
  1.1464 -		ss << L": ";
  1.1465 -		ss << ident->CommType;
  1.1466 -		verbose(ss.str());
  1.1467 -	}
  1.1468 +    if (verbose_mode) {
  1.1469 +        stringstream ss;
  1.1470 +        ss << "TrustPersonalKey called with ";
  1.1471 +        ss << utf8_string(ident->Address);
  1.1472 +        ss << L": ";
  1.1473 +        ss << ident->CommType;
  1.1474 +        verbose(ss.str());
  1.1475 +    }
  1.1476  
  1.1477 -	PEP_STATUS status = ::trust_personal_key(get_session(), _ident);
  1.1478 +    PEP_STATUS status = ::trust_personal_key(get_session(), _ident);
  1.1479  
  1.1480 -	if (verbose_mode) {
  1.1481 -		stringstream ss;
  1.1482 -		ss << "result ";
  1.1483 -		ss << status;
  1.1484 -		ss << " for ";
  1.1485 -		ss << _ident->address;
  1.1486 -		ss << L": ";
  1.1487 -		ss << _ident->comm_type;
  1.1488 -		verbose(ss.str());
  1.1489 -	}
  1.1490 +    if (verbose_mode) {
  1.1491 +        stringstream ss;
  1.1492 +        ss << "result ";
  1.1493 +        ss << status;
  1.1494 +        ss << " for ";
  1.1495 +        ss << _ident->address;
  1.1496 +        ss << L": ";
  1.1497 +        ss << _ident->comm_type;
  1.1498 +        verbose(ss.str());
  1.1499 +    }
  1.1500  
  1.1501 -	if (status == PEP_STATUS_OK)
  1.1502 -		copy_identity(result, _ident);
  1.1503 +    if (status == PEP_STATUS_OK)
  1.1504 +        copy_identity(result, _ident);
  1.1505  
  1.1506 -	free_identity(_ident);
  1.1507 -	if (status == PEP_OUT_OF_MEMORY)
  1.1508 -		return E_OUTOFMEMORY;
  1.1509 -	else if (status != PEP_STATUS_OK)
  1.1510 -		return FAIL(L"failure while executing TrustPersonalKey()", status);
  1.1511 +    free_identity(_ident);
  1.1512 +    if (status == PEP_OUT_OF_MEMORY)
  1.1513 +        return E_OUTOFMEMORY;
  1.1514 +    else if (status != PEP_STATUS_OK)
  1.1515 +        return FAIL(L"failure while executing TrustPersonalKey()", status);
  1.1516  
  1.1517 -	return S_OK;
  1.1518 +    return S_OK;
  1.1519  }
  1.1520  
  1.1521  // keysync api
  1.1522  
  1.1523  void CpEpEngine::start_keysync()
  1.1524  {
  1.1525 -	// acquire the lock
  1.1526 -	std::unique_lock<std::mutex> lock(keysync_mutex);
  1.1527 +    // acquire the lock
  1.1528 +    std::unique_lock<std::mutex> lock(keysync_mutex);
  1.1529  
  1.1530 -	// Assert if we're not already running.
  1.1531 +    // Assert if we're not already running.
  1.1532      assert(!this->keysync_thread);
  1.1533  
  1.1534 -	// Ensure we are not aborting the new thread due to a
  1.1535 -	// left over flag.
  1.1536 -	keysync_abort_requested = false;
  1.1537 +    // Ensure we are not aborting the new thread due to a
  1.1538 +    // left over flag.
  1.1539 +    keysync_abort_requested = false;
  1.1540  
  1.1541 -	// Init our keysync session
  1.1542 -	PEP_STATUS status = ::init(&keysync_session);
  1.1543 -	::register_sync_callbacks(keysync_session, (void*)this, messageToSend, notifyHandshake, inject_sync_msg, retrieve_next_sync_msg);
  1.1544 -	assert(status == PEP_STATUS_OK);
  1.1545 +    // Init our keysync session
  1.1546 +    PEP_STATUS status = ::init(&keysync_session);
  1.1547 +    ::register_sync_callbacks(keysync_session, (void*)this, messageToSend, notifyHandshake, inject_sync_msg, retrieve_next_sync_msg);
  1.1548 +    assert(status == PEP_STATUS_OK);
  1.1549  
  1.1550      attach_sync_session(get_session(), keysync_session);
  1.1551  
  1.1552 @@ -1109,14 +1088,14 @@
  1.1553      auto result = CoMarshalInterThreadInterfaceInStream(IID_IpEpEngineCallbacks, client_callbacks, &marshaled_callbacks);
  1.1554      assert(result == S_OK);
  1.1555  
  1.1556 -	// Star the keysync thread
  1.1557 -	keysync_thread = new thread(do_keysync_in_thread, this, marshaled_callbacks);
  1.1558 +    // Star the keysync thread
  1.1559 +    keysync_thread = new thread(do_keysync_in_thread, this, marshaled_callbacks);
  1.1560  }
  1.1561  
  1.1562 -void CpEpEngine::do_keysync_in_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks) 
  1.1563 +void CpEpEngine::do_keysync_in_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks)
  1.1564  {
  1.1565      assert(self);
  1.1566 -	assert(marshaled_callbacks);
  1.1567 +    assert(marshaled_callbacks);
  1.1568  
  1.1569      // We need to initialize COM here for successfull delivery of the callbacks.
  1.1570      // As we don't create any COM instances in our thread, the COMINIT value is
  1.1571 @@ -1152,73 +1131,73 @@
  1.1572  
  1.1573  void CpEpEngine::stop_keysync()
  1.1574  {
  1.1575 -	// acquire the lock
  1.1576 -	std::unique_lock<std::mutex> lock(keysync_mutex);
  1.1577 +    // acquire the lock
  1.1578 +    std::unique_lock<std::mutex> lock(keysync_mutex);
  1.1579  
  1.1580      // Do nothing if keysync is not running.
  1.1581      if (!keysync_thread)
  1.1582          return;
  1.1583  
  1.1584      assert(!keysync_abort_requested);
  1.1585 -	// signal that we're gonna abort
  1.1586 -	keysync_abort_requested = true;
  1.1587 +    // signal that we're gonna abort
  1.1588 +    keysync_abort_requested = true;
  1.1589  
  1.1590 -	// Notify the keysync thread
  1.1591 -	keysync_condition.notify_all();
  1.1592 +    // Notify the keysync thread
  1.1593 +    keysync_condition.notify_all();
  1.1594  
  1.1595 -	// Wait for the other thread to finish and clean up
  1.1596 -	while (keysync_abort_requested)
  1.1597 -		keysync_condition.wait(lock);
  1.1598 +    // Wait for the other thread to finish and clean up
  1.1599 +    while (keysync_abort_requested)
  1.1600 +        keysync_condition.wait(lock);
  1.1601  
  1.1602 -	// collect the child thread for the thread to end
  1.1603 -	keysync_thread->join();
  1.1604 +    // collect the child thread for the thread to end
  1.1605 +    keysync_thread->join();
  1.1606  
  1.1607 -	// clean up
  1.1608 -	delete keysync_thread;
  1.1609 -	keysync_thread = NULL;
  1.1610 +    // clean up
  1.1611 +    delete keysync_thread;
  1.1612 +    keysync_thread = NULL;
  1.1613  
  1.1614      ::detach_sync_session(get_session());
  1.1615 -	::unregister_sync_callbacks(keysync_session);
  1.1616 -	release(keysync_session);
  1.1617 +    ::unregister_sync_callbacks(keysync_session);
  1.1618 +    release(keysync_session);
  1.1619      keysync_session = NULL;
  1.1620  }
  1.1621  
  1.1622  int CpEpEngine::inject_sync_msg(void * msg, void * management)
  1.1623  {
  1.1624 -	assert(msg);
  1.1625 -	assert(management);
  1.1626 -	// check argument
  1.1627 -	if (!msg)
  1.1628 -		return E_INVALIDARG;
  1.1629 -	if (!management)
  1.1630 -		return ERROR_INVALID_HANDLE;
  1.1631 +    assert(msg);
  1.1632 +    assert(management);
  1.1633 +    // check argument
  1.1634 +    if (!msg)
  1.1635 +        return E_INVALIDARG;
  1.1636 +    if (!management)
  1.1637 +        return ERROR_INVALID_HANDLE;
  1.1638  
  1.1639 -	CpEpEngine* me = (CpEpEngine*)management;
  1.1640 +    CpEpEngine* me = (CpEpEngine*)management;
  1.1641  
  1.1642 -	// acquire the lock
  1.1643 -	std::unique_lock<std::mutex> lock(me->keysync_mutex);
  1.1644 +    // acquire the lock
  1.1645 +    std::unique_lock<std::mutex> lock(me->keysync_mutex);
  1.1646  
  1.1647 -	// check whether we're in a valid state running:
  1.1648 -	if (!me->keysync_thread)
  1.1649 -		return E_ASYNC_OPERATION_NOT_STARTED;
  1.1650 +    // check whether we're in a valid state running:
  1.1651 +    if (!me->keysync_thread)
  1.1652 +        return E_ASYNC_OPERATION_NOT_STARTED;
  1.1653  
  1.1654 -	// queue the message
  1.1655 -	me->keysync_queue.push(msg);
  1.1656 +    // queue the message
  1.1657 +    me->keysync_queue.push(msg);
  1.1658  
  1.1659 -	// notify the receivers
  1.1660 -	me->keysync_condition.notify_all();
  1.1661 +    // notify the receivers
  1.1662 +    me->keysync_condition.notify_all();
  1.1663  
  1.1664      return S_OK;
  1.1665  }
  1.1666  
  1.1667  void * CpEpEngine::retrieve_next_sync_msg(void * management, time_t *timeout)
  1.1668  {
  1.1669 -	// sanity check
  1.1670 -	assert(management);
  1.1671 -	if (!(management))
  1.1672 -		return NULL;
  1.1673 +    // sanity check
  1.1674 +    assert(management);
  1.1675 +    if (!(management))
  1.1676 +        return NULL;
  1.1677  
  1.1678 -	CpEpEngine* me = (CpEpEngine*)management;
  1.1679 +    CpEpEngine* me = (CpEpEngine*)management;
  1.1680  
  1.1681      if ((timeout && *timeout)
  1.1682          && me->client_callbacks2_on_sync_thread
  1.1683 @@ -1235,9 +1214,12 @@
  1.1684          me->client_last_signalled_polling_state = false;
  1.1685      }
  1.1686  
  1.1687 -	// acquire the lock
  1.1688 -	std::unique_lock<std::mutex> lock(me->keysync_mutex);
  1.1689 -    
  1.1690 +    // acquire the lock
  1.1691 +    std::unique_lock<std::mutex> lock(me->keysync_mutex);
  1.1692 +
  1.1693 +    if (me->notify_handshake_finished)
  1.1694 +        me->notify_handshake_deliver_result();
  1.1695 +
  1.1696      if (timeout && *timeout) {
  1.1697          auto end_time = std::chrono::steady_clock::now()
  1.1698              + std::chrono::seconds(*timeout);
  1.1699 @@ -1246,18 +1228,24 @@
  1.1700          {
  1.1701              auto status = me->keysync_condition.wait_until(lock, end_time);
  1.1702  
  1.1703 +            if (me->notify_handshake_finished)
  1.1704 +                me->notify_handshake_deliver_result();
  1.1705 +
  1.1706              if (status == std::cv_status::timeout)
  1.1707              {
  1.1708                  *timeout = 1; // Signal timeout
  1.1709                  return NULL;
  1.1710 -            }            
  1.1711 +            }
  1.1712          }
  1.1713      }
  1.1714 -    else 
  1.1715 +    else
  1.1716      {
  1.1717          while (me->keysync_queue.empty() && !me->keysync_abort_requested)
  1.1718          {
  1.1719              me->keysync_condition.wait(lock);
  1.1720 +
  1.1721 +            if (me->notify_handshake_finished)
  1.1722 +                me->notify_handshake_deliver_result();
  1.1723          }
  1.1724      }
  1.1725  
  1.1726 @@ -1275,15 +1263,15 @@
  1.1727          return NULL;
  1.1728      }
  1.1729  
  1.1730 -    assert(!me->keysync_queue.empty());	
  1.1731 +    assert(!me->keysync_queue.empty());
  1.1732  
  1.1733 -	// Pop the message and return it.
  1.1734 -	void* msg = me->keysync_queue.front();
  1.1735 -	assert(msg);
  1.1736 +    // Pop the message and return it.
  1.1737 +    void* msg = me->keysync_queue.front();
  1.1738 +    assert(msg);
  1.1739  
  1.1740 -	me->keysync_queue.pop();
  1.1741 +    me->keysync_queue.pop();
  1.1742  
  1.1743 -	return msg;
  1.1744 +    return msg;
  1.1745  }
  1.1746  
  1.1747  
  1.1748 @@ -1302,9 +1290,9 @@
  1.1749      this->client_callbacks = new_callbacks;
  1.1750      new_callbacks->AddRef();
  1.1751  
  1.1752 -	start_keysync();
  1.1753 +    start_keysync();
  1.1754  
  1.1755 -	return S_OK;
  1.1756 +    return S_OK;
  1.1757  }
  1.1758  
  1.1759  STDMETHODIMP CpEpEngine::UnregisterCallbacks()
  1.1760 @@ -1324,66 +1312,197 @@
  1.1761  }
  1.1762  
  1.1763  STDMETHODIMP CpEpEngine::OpenPGPListKeyinfo(BSTR search_pattern, LPSAFEARRAY* keyinfo_list) {
  1.1764 -	assert(keyinfo_list);
  1.1765 +    assert(keyinfo_list);
  1.1766  
  1.1767 -	if (keyinfo_list == NULL)
  1.1768 -		return E_INVALIDARG;
  1.1769 +    if (keyinfo_list == NULL)
  1.1770 +        return E_INVALIDARG;
  1.1771  
  1.1772 -	string _pattern = "";
  1.1773 -	if (search_pattern)
  1.1774 -		_pattern = utf8_string(search_pattern);
  1.1775 -	::stringpair_list_t* _keyinfo_list = NULL;
  1.1776 +    string _pattern = "";
  1.1777 +    if (search_pattern)
  1.1778 +        _pattern = utf8_string(search_pattern);
  1.1779 +    ::stringpair_list_t* _keyinfo_list = NULL;
  1.1780  
  1.1781 -	PEP_STATUS status = ::OpenPGP_list_keyinfo(get_session(), _pattern.c_str(), &_keyinfo_list);
  1.1782 -	assert(status != PEP_OUT_OF_MEMORY);
  1.1783 -	if (status == PEP_OUT_OF_MEMORY)
  1.1784 -		return E_OUTOFMEMORY;
  1.1785 +    PEP_STATUS status = ::OpenPGP_list_keyinfo(get_session(), _pattern.c_str(), &_keyinfo_list);
  1.1786 +    assert(status != PEP_OUT_OF_MEMORY);
  1.1787 +    if (status == PEP_OUT_OF_MEMORY)
  1.1788 +        return E_OUTOFMEMORY;
  1.1789  
  1.1790 -	if (status != ::PEP_STATUS_OK)
  1.1791 -		return FAIL(L"OpenPGP_list_keyinfo", status);
  1.1792 +    if (status != ::PEP_STATUS_OK)
  1.1793 +        return FAIL(L"OpenPGP_list_keyinfo", status);
  1.1794  
  1.1795 -	if (_keyinfo_list && _keyinfo_list->value) {
  1.1796 -		::opt_field_array_from_C(_keyinfo_list, keyinfo_list);
  1.1797 -	}
  1.1798 -	else {
  1.1799 -		::free_stringpair_list(_keyinfo_list);
  1.1800 -		return FAIL(L"OpenPGP_list_keyinfo: no keys found");
  1.1801 -	}
  1.1802 +    if (_keyinfo_list && _keyinfo_list->value) {
  1.1803 +        ::opt_field_array_from_C(_keyinfo_list, keyinfo_list);
  1.1804 +    }
  1.1805 +    else {
  1.1806 +        ::free_stringpair_list(_keyinfo_list);
  1.1807 +        return FAIL(L"OpenPGP_list_keyinfo: no keys found");
  1.1808 +    }
  1.1809  
  1.1810 -	::free_stringpair_list(_keyinfo_list);
  1.1811 -	return S_OK;
  1.1812 +    ::free_stringpair_list(_keyinfo_list);
  1.1813 +    return S_OK;
  1.1814  
  1.1815  }
  1.1816  
  1.1817  HRESULT CpEpEngine::Fire_MessageToSend(TextMessage * msg)
  1.1818  {
  1.1819 -	assert(msg);
  1.1820 +    assert(msg);
  1.1821      assert(this->client_callbacks_on_sync_thread);
  1.1822  
  1.1823 -	if (!msg)
  1.1824 -		return E_INVALIDARG;
  1.1825 +    if (!msg)
  1.1826 +        return E_INVALIDARG;
  1.1827  
  1.1828 -	if (!this->client_callbacks_on_sync_thread)
  1.1829 -		return E_ILLEGAL_METHOD_CALL;
  1.1830 +    if (!this->client_callbacks_on_sync_thread)
  1.1831 +        return E_ILLEGAL_METHOD_CALL;
  1.1832  
  1.1833      auto result = this->client_callbacks_on_sync_thread->MessageToSend(msg);
  1.1834  
  1.1835 -	return result;
  1.1836 +    return result;
  1.1837  }
  1.1838  
  1.1839 -HRESULT CpEpEngine::Fire_NotifyHandshake(pEpIdentity * self, pEpIdentity * partner, SyncHandshakeSignal signal, SyncHandshakeResult * result)
  1.1840 +// This method is called from the keysync thread, and dispatches
  1.1841 +// the handshake asynchroneously to a background thread,
  1.1842 +// so the engine can continue working.
  1.1843 +PEP_STATUS CpEpEngine::notifyHandshake(void * obj, pEp_identity *self, pEp_identity *partner, sync_handshake_signal signal)
  1.1844  {
  1.1845 -	assert(self);
  1.1846 -	assert(partner);
  1.1847 -	assert(result);
  1.1848 -    assert(this->client_callbacks_on_sync_thread);
  1.1849 +    assert(self && partner);
  1.1850 +    if (!(self && partner))
  1.1851 +        return PEP_ILLEGAL_VALUE;
  1.1852  
  1.1853 -	if (!(self && partner && result))
  1.1854 -		return E_INVALIDARG;
  1.1855 -	if (!this->client_callbacks_on_sync_thread)
  1.1856 -		return E_ILLEGAL_METHOD_CALL;
  1.1857 -    	
  1.1858 -	auto res = this->client_callbacks_on_sync_thread->NotifyHandshake(self, partner, signal, result);
  1.1859 -		
  1.1860 -	return res;	
  1.1861 +    CpEpEngine *me = (CpEpEngine *)obj;
  1.1862 +
  1.1863 +    if (me->notify_handshake_active) {
  1.1864 +        // We don't support concurrent handshakes currently...
  1.1865 +        me->FAIL("Reentrant notify_handshake call!");
  1.1866 +        return PEP_UNKNOWN_ERROR;
  1.1867 +    }
  1.1868 +
  1.1869 +    assert(!(me->notify_handshake_active
  1.1870 +        || me->notify_handshake_finished
  1.1871 +        || me->notify_handshake_thread));
  1.1872 +
  1.1873 +    me->notify_handshake_active = true;
  1.1874 +
  1.1875 +    copy_identity(&me->notify_handshake_self, self);
  1.1876 +    copy_identity(&me->notify_handshake_partner, partner);
  1.1877 +    me->notify_handshake_signal = (SyncHandshakeSignal)signal;
  1.1878 +
  1.1879 +    // We need to marshal the callbacks to the keysync thread
  1.1880 +    LPSTREAM marshaled_callbacks;
  1.1881 +
  1.1882 +    auto result = CoMarshalInterThreadInterfaceInStream(IID_IpEpEngineCallbacks, me->client_callbacks_on_sync_thread, &marshaled_callbacks);
  1.1883 +    assert(result == S_OK);
  1.1884 +
  1.1885 +    me->notify_handshake_thread = new thread(notify_handshake_background_thread, me, marshaled_callbacks);
  1.1886 +
  1.1887 +    return PEP_STATUS_OK;
  1.1888  }
  1.1889 +
  1.1890 +// This method also runs in the keysync thread, called by
  1.1891 +// retrieve_next_sync_msg() to deliver back the results
  1.1892 +// of the sync into the engine.
  1.1893 +void CpEpEngine::notify_handshake_deliver_result()
  1.1894 +{
  1.1895 +    assert(notify_handshake_active
  1.1896 +        && notify_handshake_finished);
  1.1897 +    if (!(notify_handshake_active
  1.1898 +        && notify_handshake_finished))
  1.1899 +        return;
  1.1900 +
  1.1901 +    notify_handshake_thread->join();
  1.1902 +    notify_handshake_thread = NULL;
  1.1903 +
  1.1904 +    Identity partner = new_identity(&notify_handshake_partner);
  1.1905 +
  1.1906 +    if (FAILED(notify_handshake_error))
  1.1907 +    {
  1.1908 +        IErrorInfo *errorInfo = NULL;
  1.1909 +
  1.1910 +        if (notify_handshake_error_info) {
  1.1911 +            LPVOID lp = NULL;
  1.1912 +            auto res = CoGetInterfaceAndReleaseStream(notify_handshake_error_info, IID_IErrorInfo, &lp);
  1.1913 +
  1.1914 +            if (SUCCEEDED(res) && lp)
  1.1915 +                errorInfo = static_cast<IErrorInfo*>(lp);
  1.1916 +        }
  1.1917 +
  1.1918 +        // The _com_error takes ownership of the errorInfo
  1.1919 +        // and will Release() it. It can also cope with
  1.1920 +        // NULL errorInfos.
  1.1921 +        _com_error error(notify_handshake_error, errorInfo);
  1.1922 +
  1.1923 +        string _description = utf8_string(
  1.1924 +            error.ErrorMessage());
  1.1925 +
  1.1926 +        string _comment = utf8_string(error.Description());
  1.1927 +
  1.1928 +        auto source = error.Source();
  1.1929 +        if (source.length() > 0) {
  1.1930 +            _comment += "\r\nSource: ";
  1.1931 +            _comment += utf8_string(source);
  1.1932 +        }
  1.1933 +
  1.1934 +        ::log_event(keysync_session,
  1.1935 +            "Notify Handshake Failed!",
  1.1936 +            "pEp COM Adapter",
  1.1937 +            _description.c_str(),
  1.1938 +            _comment.c_str());
  1.1939 +
  1.1940 +        ::deliverHandshakeResult(keysync_session, partner, SYNC_HANDSHAKE_CANCEL);
  1.1941 +    }
  1.1942 +    else {
  1.1943 +        ::deliverHandshakeResult(
  1.1944 +            keysync_session,
  1.1945 +            partner,
  1.1946 +            (sync_handshake_result)notify_handshake_result);
  1.1947 +    }
  1.1948 +    notify_handshake_error_info = NULL;
  1.1949 +
  1.1950 +    notify_handshake_active = false;
  1.1951 +    notify_handshake_finished = false;
  1.1952 +}
  1.1953 +
  1.1954 +// Method on the background thread, calling into Outlook to
  1.1955 +// trigger the Handshake notification, and then scheduling
  1.1956 +// the result back to the main thread.
  1.1957 +void CpEpEngine::notify_handshake_background_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks)
  1.1958 +{
  1.1959 +    assert(self);
  1.1960 +
  1.1961 +    // We need to initialize COM here for successfull delivery of the callbacks.
  1.1962 +    // As we don't create any COM instances in our thread, the COMINIT value is
  1.1963 +    // currently irrelevant, so we go with the safest value.
  1.1964 +    auto res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  1.1965 +    assert(res == S_OK);
  1.1966 +
  1.1967 +    LPVOID vp;
  1.1968 +
  1.1969 +    res = CoGetInterfaceAndReleaseStream(marshaled_callbacks, IID_IpEpEngineCallbacks, &vp);
  1.1970 +    assert(SUCCEEDED(res));
  1.1971 +
  1.1972 +    auto client_callbacks_on_sync_thread = static_cast<IpEpEngineCallbacks*>(vp);
  1.1973 +
  1.1974 +    self->notify_handshake_error = client_callbacks_on_sync_thread->NotifyHandshake(
  1.1975 +        &self->notify_handshake_self,
  1.1976 +        &self->notify_handshake_partner,
  1.1977 +        self->notify_handshake_signal,
  1.1978 +        &self->notify_handshake_result);
  1.1979 +
  1.1980 +    if (FAILED(self->notify_handshake_error)) {
  1.1981 +        IErrorInfo* errorInfo = NULL;
  1.1982 +
  1.1983 +        res = GetErrorInfo(0, &errorInfo);
  1.1984 +
  1.1985 +        if (res = S_OK && errorInfo != NULL) {
  1.1986 +            res = CoMarshalInterThreadInterfaceInStream(
  1.1987 +                IID_IErrorInfo,
  1.1988 +                errorInfo,
  1.1989 +                &self->notify_handshake_error_info);
  1.1990 +
  1.1991 +            errorInfo->Release();
  1.1992 +        }
  1.1993 +    }
  1.1994 +
  1.1995 +    // notify the keysync thread.
  1.1996 +    self->notify_handshake_finished = true;
  1.1997 +    self->keysync_condition.notify_all();
  1.1998 +}
  1.1999 \ No newline at end of file
     2.1 --- a/CpEpEngine.h	Fri Feb 03 21:30:26 2017 +0100
     2.2 +++ b/CpEpEngine.h	Sat Feb 11 17:49:02 2017 +0100
     2.3 @@ -145,6 +145,19 @@
     2.4      bool keysync_abort_requested = false;
     2.5      PEP_SESSION keysync_session;
     2.6  
     2.7 +    // Members used for handshake notification dispatch to the background thread.
     2.8 +    static void notify_handshake_background_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks);
     2.9 +    void notify_handshake_deliver_result();
    2.10 +    bool notify_handshake_active = false;
    2.11 +    bool notify_handshake_finished = false;
    2.12 +    std::thread *notify_handshake_thread = NULL;
    2.13 +    pEpIdentity notify_handshake_self;
    2.14 +    pEpIdentity notify_handshake_partner;
    2.15 +    SyncHandshakeSignal notify_handshake_signal;
    2.16 +    SyncHandshakeResult notify_handshake_result;
    2.17 +    LPSTREAM notify_handshake_error_info = NULL;
    2.18 +    HRESULT notify_handshake_error;
    2.19 +
    2.20  public:
    2.21      // runtime config of the adapter
    2.22  
     3.1 --- a/stdafx.h	Fri Feb 03 21:30:26 2017 +0100
     3.2 +++ b/stdafx.h	Sat Feb 11 17:49:02 2017 +0100
     3.3 @@ -26,6 +26,7 @@
     3.4  #include <atlsafe.h>
     3.5  
     3.6  #include <comutil.h>
     3.7 +#include <comdef.h>
     3.8  
     3.9  #include <Wininet.h>
    3.10  #include <intsafe.h>