diff --git a/lib/EAPBase/include/Config.h b/lib/EAPBase/include/Config.h index be992d4..05241b8 100644 --- a/lib/EAPBase/include/Config.h +++ b/lib/EAPBase/include/Config.h @@ -86,8 +86,9 @@ namespace eapserial #include // Must include after #include -#include #include +#include +#include namespace eap @@ -326,12 +327,6 @@ namespace eap template class config_provider : public config { - public: - /// - /// Provider method configuration type - /// - typedef _Tmeth config_method_type; - public: /// /// Constructs configuration @@ -359,9 +354,10 @@ namespace eap m_lbl_alt_credential(other.m_lbl_alt_credential), m_lbl_alt_identity(other.m_lbl_alt_identity), m_lbl_alt_password(other.m_lbl_alt_password), - m_methods(other.m_methods), config(other) { + for (std::list >::const_iterator method = other.m_methods.cbegin(), method_end = other.m_methods.cend(); method != method_end; ++method) + m_methods.push_back(std::move(std::unique_ptr<_Tmeth>(*method ? (_Tmeth*)method->get()->clone() : nullptr))); } /// @@ -404,7 +400,10 @@ namespace eap m_lbl_alt_credential = other.m_lbl_alt_credential; m_lbl_alt_identity = other.m_lbl_alt_identity; m_lbl_alt_password = other.m_lbl_alt_password; - m_methods = other.m_methods; + + m_methods.clear(); + for (std::list >::const_iterator method = other.m_methods.cbegin(), method_end = other.m_methods.cend(); method != method_end; ++method) + m_methods.push_back(std::move(std::unique_ptr<_Tmeth>(*method ? (_Tmeth*)method->get()->clone() : nullptr))); } return *this; @@ -549,7 +548,7 @@ namespace eap return false; } - for (std::list<_Tmeth>::const_iterator method = m_methods.cbegin(), method_end = m_methods.cend(); method != method_end; ++method) { + for (std::list >::const_iterator method = m_methods.cbegin(), method_end = m_methods.cend(); method != method_end; ++method) { // winstd::com_obj pXmlElAuthenticationMethod; if ((dwResult = eapxml::create_element(pDoc, winstd::bstr(L"AuthenticationMethod"), bstrNamespace, &pXmlElAuthenticationMethod))) { @@ -558,7 +557,7 @@ namespace eap } // /... - if (!method->save(pDoc, pXmlElAuthenticationMethod, ppEapError)) + if (!method->get()->save(pDoc, pXmlElAuthenticationMethod, ppEapError)) return false; if (FAILED(hr = pXmlElAuthenticationMethods->appendChild(pXmlElAuthenticationMethod, NULL))) { @@ -662,19 +661,19 @@ namespace eap winstd::com_obj pXmlElMethod; pXmlListMethods->get_item(i, &pXmlElMethod); - _Tmeth cfg(m_module); + std::unique_ptr<_Tmeth> cfg(new _Tmeth(m_module)); // Check EAP method type (). DWORD dwMethodID; if (eapxml::get_element_value(pXmlElMethod, winstd::bstr(L"eap-metadata:EAPMethod"), &dwMethodID) == ERROR_SUCCESS) { - if ((type_t)dwMethodID != cfg.get_method_id()) { + if ((type_t)dwMethodID != cfg->get_method_id()) { // Wrong type. continue; } } // Load configuration. - if (!cfg.load(pXmlElMethod, ppEapError)) + if (!cfg->load(pXmlElMethod, ppEapError)) return false; // Add configuration to the list. @@ -751,28 +750,33 @@ namespace eap eapserial::unpack(cursor, m_lbl_alt_password ); std::list<_Tmeth>::size_type count; + bool is_nonnull; eapserial::unpack(cursor, count); m_methods.clear(); for (std::list<_Tmeth>::size_type i = 0; i < count; i++) { - _Tmeth el(m_module); - el.unpack(cursor); - m_methods.push_back(std::move(el)); + eapserial::unpack(cursor, is_nonnull); + if (is_nonnull) { + std::unique_ptr<_Tmeth> el(new _Tmeth(m_module)); + el->unpack(cursor); + m_methods.push_back(std::move(el)); + } else + m_methods.push_back(nullptr); } } /// @} public: - bool m_read_only; ///< Is profile read-only - std::wstring m_id; ///< Profile ID - winstd::tstring m_name; ///< Provider name - winstd::tstring m_help_email; ///< Helpdesk e-mail - winstd::tstring m_help_web; ///< Helpdesk website URL - winstd::tstring m_help_phone; ///< Helpdesk phone - winstd::tstring m_lbl_alt_credential; ///< Alternative label for credential prompt - winstd::tstring m_lbl_alt_identity; ///< Alternative label for identity prompt - winstd::tstring m_lbl_alt_password; ///< Alternative label for password prompt - std::list<_Tmeth> m_methods; ///< List of method configurations + bool m_read_only; ///< Is profile read-only + std::wstring m_id; ///< Profile ID + winstd::tstring m_name; ///< Provider name + winstd::tstring m_help_email; ///< Helpdesk e-mail + winstd::tstring m_help_web; ///< Helpdesk website URL + winstd::tstring m_help_phone; ///< Helpdesk phone + winstd::tstring m_lbl_alt_credential; ///< Alternative label for credential prompt + winstd::tstring m_lbl_alt_identity; ///< Alternative label for identity prompt + winstd::tstring m_lbl_alt_password; ///< Alternative label for password prompt + std::list > m_methods; ///< List of method configurations }; diff --git a/lib/EAPBase/include/EAPSerial.h b/lib/EAPBase/include/EAPSerial.h index 0a8c541..7b180b6 100644 --- a/lib/EAPBase/include/EAPSerial.h +++ b/lib/EAPBase/include/EAPSerial.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -230,6 +231,33 @@ namespace eapserial /// template inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ std::list<_Ty, _Ax> &val); + /// + /// Packs a std::unique_ptr + /// + /// \param[inout] cursor Memory cursor + /// \param[in] val std::unique_ptr to pack + /// + template inline void pack(_Inout_ unsigned char *&cursor, _In_ const std::unique_ptr<_Ty, _Dx> &val); + + /// + /// Returns packed size of a std::unique_ptr + /// + /// \param[in] val std::unique_ptr to pack + /// + /// \returns Size of data when packed (in bytes) + /// + template inline size_t get_pk_size(const std::unique_ptr<_Ty, _Dx> &val); + + ///// + ///// Unpacks a std::unique_ptr + ///// + ///// \note Not generally unpackable, since we do not know, how to create a new instance of unique_ptr. + ///// + ///// \param[inout] cursor Memory cursor + ///// \param[out] val std::unique_ptr to unpack to + ///// + //template inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ std::unique_ptr<_Ty, _Dx> &val); + /// /// Packs a certificate context /// @@ -486,6 +514,28 @@ namespace eapserial } + template + inline void pack(_Inout_ unsigned char *&cursor, _In_ const std::unique_ptr<_Ty, _Dx> &val) + { + if (val) { + pack(cursor, true); + pack(cursor, *val); + } else + pack(cursor, false); + } + + + template + inline size_t get_pk_size(const std::unique_ptr<_Ty, _Dx> &val) + { + return + val ? + get_pk_size(true) + + get_pk_size(*val) : + get_pk_size(false); + } + + inline void pack(_Inout_ unsigned char *&cursor, _In_ const winstd::cert_context &val) { if (val) { diff --git a/lib/EAPBase_UI/include/EAP_UI.h b/lib/EAPBase_UI/include/EAP_UI.h index 65fb5a5..7265f78 100644 --- a/lib/EAPBase_UI/include/EAP_UI.h +++ b/lib/EAPBase_UI/include/EAP_UI.h @@ -116,13 +116,13 @@ public: for (std::list<_Tprov>::iterator provider = m_cfg.m_providers.begin(), provider_end = m_cfg.m_providers.end(); provider != provider_end; ++provider) { bool is_single = provider->m_methods.size() == 1; - std::list<_Tmeth>::size_type count = 0; - std::list<_Tmeth>::iterator method = provider->m_methods.begin(), method_end = provider->m_methods.end(); + std::list >::size_type count = 0; + std::list >::iterator method = provider->m_methods.begin(), method_end = provider->m_methods.end(); for (; method != method_end; ++method, count++) m_providers->AddPage( new _wxT( *provider, - *method, + *method->get(), provider->m_id.c_str(), m_providers), is_single ? provider->m_id : winstd::tstring_printf(_T("%s (%u)"), provider->m_id.c_str(), count));