Updater infrastructure
authorVolker Birk <vb@pep-project.org>
Sun, 19 Jun 2016 13:04:41 +0200
changeset 967c1816ce1dbd
parent 94 59e25c32911a
child 97 f4d2d5c35f94
Updater infrastructure
GateKeeper.cpp
GateKeeper.h
pEpCOMServerAdapter.cpp
     1.1 --- a/GateKeeper.cpp	Sun Jun 19 08:31:51 2016 +0200
     1.2 +++ b/GateKeeper.cpp	Sun Jun 19 13:04:41 2016 +0200
     1.3 @@ -4,64 +4,127 @@
     1.4  
     1.5  using namespace std;
     1.6  
     1.7 -const LPCTSTR GateKeeper::plugin_reg_path = _T("Software\\Microsoft\\Office\\Outlook\\Addins\\pEp");
     1.8 -const LPCTSTR GateKeeper::plugin_reg_value_name = _T("LoadBehavior");
     1.9 +namespace pEp {
    1.10  
    1.11 -const time_t GateKeeper::cycle = 7200;   // 7200 sec is 2 h
    1.12 -const DWORD GateKeeper::waiting = 10000; // 10000 ms is 10 sec
    1.13 +    const LPCTSTR GateKeeper::plugin_reg_path = _T("Software\\Microsoft\\Office\\Outlook\\Addins\\pEp");
    1.14 +    const LPCTSTR GateKeeper::plugin_reg_value_name = _T("LoadBehavior");
    1.15 +    const LPCTSTR GateKeeper::updater_reg_path = _T("Software\\pEp\\Updater";)
    1.16  
    1.17 -time_t GateKeeper::time_diff()
    1.18 -{
    1.19 -    try {
    1.20 -        static random_device rd;
    1.21 -        static mt19937 gen(rd());
    1.22 +    const time_t GateKeeper::cycle = 7200;   // 7200 sec is 2 h
    1.23 +    const DWORD GateKeeper::waiting = 10000; // 10000 ms is 10 sec
    1.24  
    1.25 -        uniform_int_distribution<time_t> dist(0, cycle);
    1.26 +    GateKeeper::GateKeeper(CpEpCOMServerAdapterModule * const self)
    1.27 +        : _self(self), now(time(NULL)), next(now + time_diff()), hkUpdater(NULL)
    1.28 +    {
    1.29 +        LONG lResult = RegOpenCurrentUser(KEY_READ, &cu);
    1.30 +        assert(lResult == ERROR_SUCCESS);
    1.31 +        if (lResult == ERROR_SUCCESS)
    1.32 +            cu_open = true;
    1.33 +        else
    1.34 +            cu_open = false;
    1.35  
    1.36 -        return dist(gen);
    1.37 +        if (cu_open) {
    1.38 +            LONG lResult = RegOpenKeyEx(cu, updater_reg_path, 0, KEY_READ, &hkUpdater);
    1.39 +            assert(lResult == ERROR_SUCCESS);
    1.40 +            if (lResult != ERROR_SUCCESS)
    1.41 +                return;
    1.42 +        }
    1.43      }
    1.44 -    catch (exception&) {
    1.45 -        assert(0);
    1.46 -        return 0;
    1.47 +    
    1.48 +    GateKeeper::~GateKeeper()
    1.49 +    {
    1.50 +        if (cu_open) {
    1.51 +            if (hkUpdater)
    1.52 +                RegCloseKey(hkUpdater);
    1.53 +            RegCloseKey(cu);
    1.54 +        }
    1.55      }
    1.56 -}
    1.57  
    1.58 -void GateKeeper::keep()
    1.59 -{
    1.60 -    while (1) {
    1.61 -        keep_plugin();
    1.62 +    time_t GateKeeper::time_diff()
    1.63 +    {
    1.64 +        try {
    1.65 +            static random_device rd;
    1.66 +            static mt19937 gen(rd());
    1.67  
    1.68 -        now = time(NULL);
    1.69 -        assert(now != -1);
    1.70 +            uniform_int_distribution<time_t> dist(0, cycle);
    1.71  
    1.72 -        if (now > next) {
    1.73 -            next = now + GateKeeper::cycle;
    1.74 -            keep_updated();
    1.75 +            return dist(gen);
    1.76 +        }
    1.77 +        catch (exception&) {
    1.78 +            assert(0);
    1.79 +            return 0;
    1.80 +        }
    1.81 +    }
    1.82 +
    1.83 +    void GateKeeper::keep()
    1.84 +    {
    1.85 +        if (!cu_open)
    1.86 +            return;
    1.87 +
    1.88 +        while (1) {
    1.89 +            keep_plugin();
    1.90 +
    1.91 +            now = time(NULL);
    1.92 +            assert(now != -1);
    1.93 +
    1.94 +            if (now > next) {
    1.95 +                next = now + GateKeeper::cycle;
    1.96 +                keep_updated();
    1.97 +            }
    1.98 +
    1.99 +            Sleep(waiting);
   1.100 +        }
   1.101 +    }
   1.102 +
   1.103 +    void GateKeeper::keep_plugin()
   1.104 +    {
   1.105 +        DWORD value;
   1.106 +        DWORD size;
   1.107 +
   1.108 +        LONG lResult = RegGetValue(cu, plugin_reg_path, plugin_reg_value_name, RRF_RT_REG_DWORD, NULL, &value, &size);
   1.109 +        if (lResult != ERROR_SUCCESS)
   1.110 +            return;
   1.111 +
   1.112 +        if (value != 3) {
   1.113 +            lResult = RegSetValue(cu, plugin_reg_path, RRF_RT_REG_DWORD, plugin_reg_value_name, 3);
   1.114 +            assert(lResult == ERROR_SUCCESS);
   1.115 +        }
   1.116 +    }
   1.117 +
   1.118 +    GateKeeper::product_list& GateKeeper::registered_products()
   1.119 +    {
   1.120 +        static product_list products;
   1.121 +
   1.122 +        // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724872(v=vs.85).aspx
   1.123 +        static TCHAR value_name[16384];
   1.124 +        DWORD value_name_size;
   1.125 +        static TCHAR value[L_MAX_URL_LENGTH + 1];
   1.126 +        DWORD value_size;
   1.127 +
   1.128 +        products.empty();
   1.129 +
   1.130 +        LONG lResult = ERROR_SUCCESS;
   1.131 +        for (DWORD i = 0; lResult == ERROR_SUCCESS; i++) {
   1.132 +            value_size = L_MAX_URL_LENGTH + 1;
   1.133 +            lResult = RegEnumValue(hkUpdater, 0, value_name, &value_name_size, NULL, NULL, (LPBYTE) value, &value_size);
   1.134 +            if (lResult == ERROR_SUCCESS)
   1.135 +                products.push_back({ value_name, value });
   1.136          }
   1.137  
   1.138 -        Sleep(waiting);
   1.139 +        return products;
   1.140      }
   1.141 -}
   1.142  
   1.143 -void GateKeeper::keep_plugin()
   1.144 -{
   1.145 -    if (!cu_open)
   1.146 -        return;
   1.147 +    void GateKeeper::update_product(product p)
   1.148 +    {
   1.149  
   1.150 -    DWORD value;
   1.151 -    DWORD size;
   1.152 +    }
   1.153  
   1.154 -    LONG lResult = RegGetValue(cu, plugin_reg_path, plugin_reg_value_name, RRF_RT_REG_DWORD, NULL, &value, &size);
   1.155 -    if (lResult != ERROR_SUCCESS)
   1.156 -        return;
   1.157 +    void GateKeeper::keep_updated()
   1.158 +    {
   1.159 +        product_list& products = registered_products();
   1.160 +        for (auto i = products.begin(); i != products.end(); i++) {
   1.161 +            update_product(*i);
   1.162 +        }
   1.163 +    }
   1.164  
   1.165 -    if (value != 3) {
   1.166 -        lResult = RegSetValue(cu, plugin_reg_path, RRF_RT_REG_DWORD, plugin_reg_value_name, 3);
   1.167 -        assert(lResult == ERROR_SUCCESS);
   1.168 -    }
   1.169 -}
   1.170 -
   1.171 -void GateKeeper::keep_updated()
   1.172 -{
   1.173 -
   1.174 -}
   1.175 +} // namespace pEp
     2.1 --- a/GateKeeper.h	Sun Jun 19 08:31:51 2016 +0200
     2.2 +++ b/GateKeeper.h	Sun Jun 19 13:04:41 2016 +0200
     2.3 @@ -1,45 +1,51 @@
     2.4  class CpEpCOMServerAdapterModule;
     2.5  
     2.6 -class GateKeeper {
     2.7 -public:
     2.8 -    GateKeeper(CpEpCOMServerAdapterModule * const self) : _self(self), now(time(NULL)), next(now + time_diff())
     2.9 -    {
    2.10 -        LONG lResult = RegOpenCurrentUser(KEY_READ, &cu);
    2.11 -        assert(lResult == ERROR_SUCCESS);
    2.12 -        if (lResult == ERROR_SUCCESS)
    2.13 -            cu_open = true;
    2.14 -        else
    2.15 -            cu_open = false;
    2.16 -    }
    2.17 +namespace pEp {
    2.18  
    2.19 -    ~GateKeeper()
    2.20 -    {
    2.21 -        if (cu_open)
    2.22 -            RegCloseKey(cu);
    2.23 -    }
    2.24 +#ifdef UNICODE
    2.25 +    typedef std::wstring tstring;
    2.26 +#else
    2.27 +    typedef std::string tstring;
    2.28 +#endif
    2.29  
    2.30 -    CpEpCOMServerAdapterModule * const module() const
    2.31 -    {
    2.32 -        return _self;
    2.33 -    }
    2.34 +    class GateKeeper {
    2.35 +    public:
    2.36 +        typedef std::pair<tstring, tstring> product;
    2.37 +        typedef std::vector< product > product_list;
    2.38  
    2.39 -    void keep();
    2.40 +        GateKeeper(CpEpCOMServerAdapterModule * const self);
    2.41 +        ~GateKeeper();
    2.42  
    2.43 -protected:
    2.44 -    static const LPCTSTR plugin_reg_path;
    2.45 -    static const LPCTSTR plugin_reg_value_name;
    2.46 -    static const time_t cycle;
    2.47 -    static const DWORD waiting;
    2.48 +        CpEpCOMServerAdapterModule * const module() const
    2.49 +        {
    2.50 +            return _self;
    2.51 +        }
    2.52  
    2.53 -    static time_t time_diff();
    2.54 -    void keep_plugin();
    2.55 -    void keep_updated();
    2.56 +        void keep();
    2.57  
    2.58 -private:
    2.59 -    time_t now;
    2.60 -    time_t next;
    2.61 -    bool cu_open;
    2.62 -    HKEY cu;
    2.63 +    protected:
    2.64 +        static const LPCTSTR plugin_reg_path;
    2.65 +        static const LPCTSTR plugin_reg_value_name;
    2.66 +        static const LPCTSTR updater_reg_path;
    2.67  
    2.68 -    CpEpCOMServerAdapterModule * const _self;
    2.69 -};
    2.70 +        static const time_t cycle;
    2.71 +        static const DWORD waiting;
    2.72 +
    2.73 +        static time_t time_diff();
    2.74 +
    2.75 +        void keep_plugin();
    2.76 +
    2.77 +        void update_product(product p);
    2.78 +        product_list& registered_products();
    2.79 +        void keep_updated();
    2.80 +
    2.81 +    private:
    2.82 +        time_t now;
    2.83 +        time_t next;
    2.84 +        bool cu_open;
    2.85 +        HKEY cu;
    2.86 +        HKEY hkUpdater;
    2.87 +
    2.88 +        CpEpCOMServerAdapterModule * const _self;
    2.89 +    };
    2.90 +}
     3.1 --- a/pEpCOMServerAdapter.cpp	Sun Jun 19 08:31:51 2016 +0200
     3.2 +++ b/pEpCOMServerAdapter.cpp	Sun Jun 19 13:04:41 2016 +0200
     3.3 @@ -37,7 +37,7 @@
     3.4  
     3.5  void CpEpCOMServerAdapterModule::gatekeeper(CpEpCOMServerAdapterModule * const self)
     3.6  {
     3.7 -    GateKeeper keeper(self);
     3.8 +    pEp::GateKeeper keeper(self);
     3.9      keeper.keep();
    3.10  }
    3.11