#include "SelectRestoreWindowsComponents.h" #include "checked.xpm" #include "unchecked.xpm" #include #include #include #include "stringtools.h" #include "SelectWindowsComponents.h" #include "json/json.h" #include "RestoreWindowsComponents.h" extern wxString res_path; extern wxString ico_ext; extern wxBitmapType ico_type; extern std::string g_res_path; RetrieveComponentBackups::RetrieveComponentBackups() : wxThread(wxTHREAD_JOINABLE), success(false) { } RetrieveComponentBackups::~RetrieveComponentBackups() { } wxThread::ExitCode RetrieveComponentBackups::Entry() { filelist = Connector::getFileList("windows_components_config", access_error); if (Connector::hasError()) { return NULL; } success = true; return NULL; } SelectRestoreComponents::SelectRestoreComponents(wxWindow * parent) : GUISelectRestoreComponents(parent), canSelectBackup(false), retrievingBackupConfig(false), backupid(0) { retrieveComponentBackups.Run(); Start(200); m_listBox1->Append(_("Loading...")); wxIcon icons[2]; icons[0] = wxIcon(unchecked_xpm); icons[1] = wxIcon(checked_xpm); int icon_width = icons[0].GetWidth(); int icon_height = icons[0].GetHeight(); selectList = new wxImageList(icon_width, icon_height, true); iconList = new wxImageList(icon_width, icon_height, true); for (size_t i = 0; i < WXSIZEOF(icons); i++) selectList->Add(icons[i]); m_treeCtrl1->AssignStateImageList(selectList); m_treeCtrl1->AddRoot(_("Loading...")); } void SelectRestoreComponents::Notify(void) { if (!retrieveComponentBackups.IsAlive() && !canSelectBackup) { retrieveComponentBackups.Wait(); canSelectBackup = true; if (!retrieveComponentBackups.hasSuccess()) { Stop(); wxMessageBox(_("Error retrieving Windows component backups: ") + accessErrorToString(retrieveComponentBackups.getAccessError()), wxT("UrBackup"), wxOK | wxICON_ERROR); Start(200); return; } m_listBox1->Clear(); for (size_t i = 0; i < retrieveComponentBackups.getFileList().size(); ++i) { wxDateTime logtime_dt((wxLongLong)(retrieveComponentBackups.getFileList()[i].backuptime * 1000)); m_listBox1->Append(logtime_dt.Format()); } if (!retrieveComponentBackups.getFileList().empty()) { m_listBox1->Select(0); wxCommandEvent evt; onListBoxSelected(evt); } } if (retrievingBackupConfig && retrieveComponentConfig.get() && !retrieveComponentConfig->IsAlive()) { retrieveComponentConfig->Wait(); retrievingBackupConfig = false; if (!retrieveComponentConfig->hasSuccess()) { wxString errmsg = accessErrorToString(retrieveComponentConfig->getAccessError()); if (!retrieveComponentConfig->getErrMsg().empty()) { errmsg = retrieveComponentConfig->getErrMsg(); } Stop(); wxMessageBox(_("Error retrieving Windows component configuration: ") + errmsg, wxT("UrBackup"), wxOK | wxICON_ERROR); Start(200); retrieveComponentConfig.reset(); return; } m_treeCtrl1->Delete(m_treeCtrl1->GetRootItem()); wxTreeItemId rootId = m_treeCtrl1->AddRoot(_("Windows components")); m_treeCtrl1->SetItemState(rootId, 0); SComponent* root = retrieveComponentConfig->getRoot(); tree_components[rootId] = root; tree_items[root] = rootId; SelectWindowsComponents::addComponents(m_treeCtrl1, iconList, rootId, root, tree_components, tree_items, icon_width, icon_height); m_treeCtrl1->SetImageList(iconList); SelectWindowsComponents::selectTreeItems(m_treeCtrl1, tree_items, retrieveComponentConfig->getRoot(), retrieveComponentConfig->getRoot(), true); for (std::map::iterator it = tree_items.begin(); it != tree_items.end(); ++it) { m_treeCtrl1->Toggle(it->second); } backupid = retrieveComponentConfig->getBackupid(); componentConfigDir = retrieveComponentConfig->getComponentConfigDir(); } } void SelectRestoreComponents::onListBoxSelected(wxCommandEvent & event) { if (!canSelectBackup) { return; } int sel = m_listBox1->GetSelection(); if (sel >= 0) { while (retrievingBackupConfig && retrieveComponentConfig.get() && retrieveComponentConfig->IsAlive() ) { Sleep(100); wxTheApp->SafeYield(NULL, false); } m_treeCtrl1->DeleteAllItems(); tree_components.clear(); tree_items.clear(); m_treeCtrl1->SetImageList(NULL); iconList->RemoveAll(); m_treeCtrl1->AddRoot(_("Loading...")); retrieveComponentConfig.reset(new RetrieveComponentConfig); retrieveComponentConfig->reset(retrieveComponentBackups.getFileList()[sel].backupid); retrieveComponentConfig->Run(); retrievingBackupConfig = true; } } void SelectRestoreComponents::onStartRestore(wxCommandEvent & event) { if (backupid == 0) { wxMessageBox(_("No backup was selected"), wxT("UrBackup"), wxOK | wxICON_ERROR); return; } std::vector selected_components; for (std::map::iterator it = tree_items.begin(); it != tree_items.end(); ++it) { if (!it->first->is_root) { int state = m_treeCtrl1->GetItemState(it->second); if (state == 1) { selected_components.push_back(*it->first); } } } if (selected_components.empty()) { wxMessageBox(_("No components selected"), wxT("UrBackup"), wxOK | wxICON_ERROR); return; } Close(); RestoreWindowsComponents* rwc = new RestoreWindowsComponents(NULL, backupid, selected_components, componentConfigDir); wxTheApp->SetTopWindow(rwc); rwc->ShowModal(); rwc->Destroy(); } void SelectRestoreComponents::evtOnTreeStateImageClick(wxTreeEvent & event) { SComponent* component = tree_components[event.GetItem()]; if (component == NULL || retrieveComponentConfig.get()==NULL) { return; } bool select = m_treeCtrl1->GetItemState(event.GetItem()) == 0; SelectWindowsComponents::selectTreeItems(m_treeCtrl1, tree_items, retrieveComponentConfig->getRoot(), component, select); } void SelectRestoreComponents::onCancel(wxCommandEvent & event) { Close(); } RetrieveComponentConfig::RetrieveComponentConfig() : wxThread(wxTHREAD_JOINABLE), success(false) { root.is_root = true; } RetrieveComponentConfig::~RetrieveComponentConfig() { for (size_t i = 0; i < components.size(); ++i) { delete components[i]; } if (!componentConfigDir.empty()) { wxFileName::Rmdir(componentConfigDir, wxPATH_RMDIR_RECURSIVE); } } wxThread::ExitCode RetrieveComponentConfig::Entry() { wxMilliClock_t now = wxGetLocalTimeMillis(); std::random_device rd; componentConfigDir = wxFileName::GetTempDir().Append(wxString::Format(wxT("\\urb_win_comps_%llu_%lu"), now, rd())); if (!wxFileName::Mkdir(componentConfigDir)) { componentConfigDir.clear(); return NULL; } SPathMap path_map; path_map.source = "C:\\windows_components_config"; path_map.target = componentConfigDir.ToStdString(); std::vector path_maps; path_maps.push_back(path_map); SStartRestore restore_info = Connector::startRestore("windows_components_config", backupid, path_maps, access_error, false, true, false, 0); if (!restore_info.ok) { return NULL; } SConnection connection; bool restore_finished = false; while (!restore_finished) { Sleep(100); SStatusDetails status = Connector::getStatusDetails(&connection); if (status.ok) { for (size_t i = 0; i < status.finished_processes.size(); ++i) { if (status.finished_processes[i].id == restore_info.process_id) { restore_finished = true; break; } } } else { return NULL; } } std::string data = getFile((componentConfigDir + wxT("\\backupcom.xml")).ToStdWstring()); if (data.empty()) { return NULL; } std::string info = getFile((componentConfigDir + wxT("\\info.json")).ToStdWstring()); if (info.empty()) { return NULL; } wxDir dir(componentConfigDir); if (!dir.IsOpened()) { return NULL; } std::vector componentXmls; wxString filename; bool cont = dir.GetFirst(&filename); while (cont) { if ( filename != "backupcom.xml" && filename != "info.json" ) { componentXmls.push_back(getFile((componentConfigDir + wxT("\\") + filename).ToStdWstring())); } cont = dir.GetNext(&filename); } Json::Value info_root; Json::Reader reader; if (!reader.parse(info, info_root, false)) { return NULL; }; std::vector filter_except; try { Json::Value selected_components = info_root["selected_components"]; for (Json::ArrayIndex i = 0; i < selected_components.size(); ++i) { Json::Value compInfo = selected_components[i]; SComponent comp; HRESULT hr = IIDFromString(ConvertToUnicode(compInfo["writerId"].asString()).c_str(), &comp.writerId); comp.logicalPath = compInfo["logicalPath"].asString(); comp.name = compInfo["componentName"].asString(); filter_except.push_back(comp); } } catch (std::runtime_error&) { return NULL; } if (!WindowsComponentReader::readComponents(data, componentXmls, filter_except, root, components, errmsg)) { return NULL; } success = true; return ExitCode(); } wxString accessErrorToString(Connector::EAccessError access_error) { switch (access_error) { case Connector::EAccessError_Ok: return _("Unknown access error"); case Connector::EAccessError_NoServer: return _("Currently not connected to a backup server. No backup server found."); case Connector::EAccessError_NoTokens: return _("No file backup access tokens found. Did you run a file backup yet?"); } assert(false); return wxT("UNDEF"); }