#include #include #include #include #include #include #include #include #include #include #include #include "ba1.h" #include "ba1103.h" #include "ba1500.h" #include "ba1600.h" #include "ba1700a.h" #include "ba1701.h" // definizioni delle colonne dello sheet #define C_MODULE 1 #define C_CODE 2 #define C_RELEASE 3 #define C_PATCH 4 #define C_DATAREL 5 #define C_CURRRELEASE 6 #define C_CURRPATCH 7 #define C_CURRDATAREL 8 #define C_ISPATCH 9 #define C_BASEPATCH 10 #define C_OEM 11 /////////////////////////////////////////////////////// // Metodi di utility /////////////////////////////////////////////////////// HIDDEN const TString& http_default_path() { int y,r,t,p; main_app().get_version_info(y, r, t, p); TString& site = get_tmp_string(); site.format("http://93.146.247.172/release%02d0/", r); return site; } HIDDEN int compare_version(const char* v1, int p1, const char* v2, int p2) { TString16 ver1(v1), ver2(v2); ver1.trim(); ver1.ltrim(ver1.len() == 4 ? 2 : 4); ver2.trim(); ver2.ltrim(ver2.len() == 4 ? 2 : 4); int res = ver1.compare(ver2, -1, TRUE); if (res == 0) res = p1 - p2; return res; } HIDDEN word version2year(const char* v) { TString16 ver(v); if (ver.len() == 4) ver.insert((v[0] == '9') ? "19" : "20", 0); ver.cut(4); return atoi(ver); } static int compare_modules(const TObject** o1, const TObject** o2) { TToken_string& ts1 = *(TToken_string*)(*o1); TToken_string& ts2 = *(TToken_string*)(*o2); int res = 0; for (int i = 2; i < 5 && res == 0; i++) { TString16 s1 = ts1.get(i); const char* s2 = ts2.get(i); res = s1.compare(s2); } return res; } bool is_internet_path(const TString& addr) { if (addr.starts_with("www.", true) || addr.starts_with("http:", true)) return true; int a1, a2, a3, a4; if (sscanf(addr, "%d.%d.%d.%d", &a1, &a2, &a3, &a4) == 4) return true; return false; } /////////////////////////////////////////////////////////// // Maschera principale /////////////////////////////////////////////////////////// class TInstaller_mask : public TArray_sheet { static TInstaller_mask* _curr_mask; int _station_type; //intero che definisce il tipo di installazione (1=std,2=server,3=client) bool _installed; // Flag per verificare se almeno un modulo e' stato installato bool _setup_run; //Flag che indica se e' stato lanciato il programma setup.exe enum { NONE=0, NEW_MENU=1, NEW_MENUPRG=2, NEW_INSTALLER=4, NEW_DLL=8, NEW_SYS=14, NEW_TRR=16 }; int _reboot_program; protected: // TSheet virtual bool on_key(KEY key); static bool tutti_handler(TMask_field& f, KEY k); int get_module_number(const TString& module) const; bool should_precheck_module(int modnumber) const; bool is_zip_file(const TFilename& n) const; bool copy_file(const TFilename& src, const TFilename& dst) const; bool copy_tree(const char* src_study, const char* dst_study) const; int test_station_type() const; protected: static bool path_handler(TMask_field& fld, KEY key); static bool web_handler(TMask_field& fld, KEY key); static bool sheet_notify(TSheet_field& s, int r, KEY k); static bool install_handler(TMask_field& fld, KEY key); static bool update_handler(TMask_field& f, KEY k); bool add_module(TConfig& ini, const TString& module, bool patch, int pos = -1); bool add_header(TConfig& ini, const TString& module); int precheck_modules(bool only_newer = true); void update_version(); void update_disk_and_web_path(); void kill_files(); int needs_reboot(const TFilename& file) const; bool move_file(const TFilename& src, const TFilename& dst) const; bool move_module(const TString& module, TInstall_ini& ini, bool update) const; bool can_install(const char* module, TInstall_ini& ini); void install_selection(); bool install_patches(const TString& module, const TString& lastrelease, int lastpatch , bool onlynew = true); KEY askdisk(TString& path, TFilename& cmdline, int d, int dischi, const char* modulo); bool do_process(TToken_string& commands) const; bool pre_process(TInstall_ini& ini, const char* module) const; bool post_process(TInstall_ini& ini, const char* module) const; bool get_patches_path(TFilename& path) const; void parse_internet_path(TString& http_server, TFilename& http_path) const; bool is_program_dir(const TFilename& path); bool is_visible_patch(TConfig& ini) const; bool check_customer() const; public: bool installed() const { return _installed;} bool setup_run() const { return _setup_run; } int station_type() const {return _station_type;} bool autoload(); bool install(const TString& module, int patch); void backup() const; bool run_conversion() const { return installed() && (_reboot_program & NEW_TRR) != 0; } TInstaller_mask(); virtual ~TInstaller_mask(); }; TInstaller_mask* TInstaller_mask::_curr_mask = NULL; bool TInstaller_mask::is_visible_patch(TConfig& ini) const { bool yes = true; TAuto_token_string oem = ini.get("OEM"); if (oem.full()) { const int my_oem = dongle().oem(); yes = oem.get_pos(my_oem) >= 0; if (!yes) { // Stando alla patch non sarei visibile ma devo controllare anche l'install.ini locale // in modo da permettere l'aggiunta e la rimozione di nuovi OEM alla lista const TString& module = ini.get_paragraph(); const TString& loc_oem = ini_get_string(CONFIG_GENERAL, module, "OEM"); if (loc_oem != oem) ini_set_string(CONFIG_GENERAL, module, "OEM", oem); } } return yes; } // Copia nello sheet i dati di un modulo prendendoli da un .ini bool TInstaller_mask::add_module(TConfig& ini, const TString& module, bool patch, int pos) { ini.write_protect(); if (!ini.set_paragraph(module)) return false; // Nasconde i moduli riservati da occhi indiscreti if (!is_visible_patch(ini)) return false; const int numpatch = ini.get_int("Patch"); TString4 strpatch; if (numpatch > 0) strpatch.format("%04d", numpatch); TToken_string row; row = " "; // Not selected row.add(ini.get("Descrizione")); row.add(module); row.add(ini.get("Versione")); row.add(strpatch); row.add(ini.get("Data")); row.add(patch ? "X" : " ", C_ISPATCH); row.add(ini.get("OEM"), C_OEM); if (pos < 0) add(row); else insert(row,pos); return true; } // Copia nello sheet l'intestazione di un modulo prendendola da un .ini bool TInstaller_mask::add_header(TConfig& ini, const TString& module) { ini.write_protect(); bool ok = ini.set_paragraph(module); if (ok) { TToken_string row; row = " "; // Not selected row.add(ini.get("Descrizione")); row.add(ini.get(" ")); enable_row(add(row),false); } return ok; } bool TInstaller_mask::should_precheck_module(int modnumber) const { bool ok = modnumber == BAAUT; if (!ok) { //se l'installazione è un server, prechecka tutti i moduli, a meno che non sia in funzione il server.. //..di chiavi; in questo caso infatti la chiave è unica, ha dunque sicuramente tutti i moduli comuni.. //..alle varie installazioni client, e quindi basta checkare i moduli sulla chiave come per qualsiasi.. //..altra installazione const TDongle& d = dongle(); if (station_type() == 2 && d.hardware() != _dongle_network) { //se sei un server hai tutti i moduli da installare ok = d.shown(modnumber); } else { //senno' sei sfigato e ti installa solo i moduli sulla chiave ok = d.active(modnumber); if (!ok) // Se non hai un modulo ... potresti avere un suo modulo sottinteso { switch (modnumber) { case CAAUT: ok = d.active(CMAUT); break; // Se non hai l'analitica ritenta con le commesse case TPAUT: ok = d.active(DCAUT); break; // Se non hai Pack ritenta con il CONAI default: break; } } } } return ok; } //che tipo di installazione e'? int TInstaller_mask::test_station_type() const { TConfig ini(CONFIG_INSTALL, "Main"); int type = ini.get_int("Type"); //se type non e' definito nei valori giusti (1=standard,2=server,3=client) if (type < 1 || type > 3) { const bool testdb = ini.get_bool("TestDatabase"); //const bool testprg = ini.get_bool("TestPrograms"); if (testdb) { if (dongle().hardware() == _dongle_network) //se usa un server di chiavi->server type = 2; else type = 1; } else type = 3; ini.set("Type", type); //cosi' lo definisce se non c'e' } return type; } int TInstaller_mask::precheck_modules(bool only_newer) { TString16 release, currrelease; TString4 cod_module; int patchlevel, modnumber, currpatch; bool check_enabled = true; _setup_run = false; //inizializzazione del flag di controllo di lancio di setup.exe const bool good_customer = check_customer(); TString_array& a = rows_array(); FOR_EACH_ARRAY_ROW(a, r, row) { TToken_string& rigar = *row; cod_module = rigar.get(C_CODE); modnumber = get_module_number(cod_module); release = rigar.get(C_RELEASE); patchlevel = rigar.get_int(C_PATCH); currrelease = rigar.get(C_CURRRELEASE); currpatch = rigar.get_int(C_CURRPATCH); if (modnumber >= BAAUT && should_precheck_module(modnumber) && release.full() && ((release > currrelease) || (release == currrelease && (only_newer ? patchlevel > currpatch : patchlevel >= currpatch) )) ) { // spunta il modulo o la patch se ho installata la stessa versione bool chk = rigar.get_char(C_ISPATCH) != 'X' || release == currrelease; // non spunta automaticamente il modulo server su installazioni che non siano server if (cod_module == "sr" && (test_station_type() != 2 || !xvt_sys_dongle_server_is_running())) { chk = false; disable_row(r); } if (chk && !good_customer && cod_module != "sy") chk = false; if (check_enabled) check(r, chk); if (chk && only_newer && (cod_module == "sy" || cod_module == "sr")) // se viene checkato il modulo sy (sistema) e/o sr (servers) { // deve togliere la possibilita' di installare altri moduli. for (int i = 0; i < a.items(); i++) { if (i != r) uncheck(i); // puo' succedere che il modulo sy o sr non sia il primo disable_row(i); // disabilita tutte le righe dello sheet (va fatto DOPO l'uncheck!!!) } disable(DLG_USER); check_enabled = false; //..ed uscire if (!run_as_admin()) warning_box("Per installare il modulo è necessario eseguire l'applicazione come amministratore."); } } //if(modnumber>=0... } //FOR_EACH_ARRAY_ROW... force_update(); // Indispensabile per vedere le righe aggiornate sullo sheet enable(F_INSTALL, good_customer); if (!good_customer) { send_campo_xml(); TString html; html << "" << "
Attenzione: chiave " << dongle().number() << " non riconosciuta.
\n" << "

Al fine di poter riattivare la chiave " << dongle().product().before(" ") << " in oggetto e poter quindi effettuare registrazioni, " << "La preghiamo di contattare Sirio informatica e sistemi ai seguenti riferimenti:


" << "" << ""; error_box(html); } return items(); } int TInstaller_mask::get_module_number(const TString& module) const { int aut = -1; bool ok = false; if (module.full()) { if (module == "ba" || module == "sy") //moduli base e sistema: deve ritornare 0; return BAAUT; aut = dongle().module_name2code(module); ok = aut < ENDAUT; } return ok ? aut : -1; } void TInstaller_mask::update_version() { TInstall_ini ini; TString_array& a = rows_array(); FOR_EACH_ARRAY_ROW_BACK(a, m, row) { if (*row->get(C_CODE) != ' ') { const TString4 module = row->get(C_CODE); ini.set_paragraph(module); const TString16 newver = row->get(C_RELEASE); const TString16 oldver = ini.get("Versione"); const int numpatch = ini.get_int("Patch"); TString4 strpatch; if (numpatch > 0) strpatch.format("%04d", numpatch); row->add(oldver, C_CURRRELEASE); row->add(strpatch, C_CURRPATCH); row->add(ini.get("Data"), C_CURRDATAREL); } } force_update(); } bool TInstaller_mask::check_customer() const { Tdninst dninst; return dninst.check_customer() == 0; } // Cerca nel percorso specificato sulla maschera tutti i possibili files .ini // utilizzabili per un'installazione e li inserisce nello spreadsheet bool TInstaller_mask::autoload() { TString_array& mask_rows = rows_array(); TString http_server; TFilename http_path, path, ininame; //controlla se si e' scelto un path di installazione internet o da disco const bool internet = get_patches_path(path); //se e' un aggiornamento via internet... if (internet) { if (!(xvt_net_get_status() & 0x4)) //la connessione web funziona?... return warning_box("Impossibile connettersi al sito con gli aggiornamenti\nVerificare che la connessione Internet sia attiva !"); parse_internet_path(http_server, http_path); //controlla il path internet scritto nel campo sulla maschera //se si ritrova dei vecchi file nella directory temporanea, la pulisce per evitare casini remove_files(path, true); ininame = path; ininame.add(TInstall_ini::default_name()); if (!ininame.exist()) { TFilename remote_ini = http_path; remote_ini << TInstall_ini::default_name(); if (remote_ini.full()) // dummy test { TTimerind contacting(30*1000, TR("Connessione al server HTTP..."), false, false); http_get(http_server, remote_ini, ininame); // Cerca di prelevare anche dninst.zip const char* const local_dninst = "setup/dninst.zip"; TFilename remote_dninst = http_path; remote_dninst << local_dninst; if (!http_get(http_server, remote_dninst, local_dninst)) { // Se non aggiorno da release riprovo con l'indirizzo dell'OEM remote_dninst = http_default_path(); remote_dninst << local_dninst; const int slash = remote_dninst.find('/'); if (slash > 0) http_get(remote_dninst.left(slash), remote_dninst.mid(slash), local_dninst); } } } } //if(internet... if (path.exist()) { ininame = path; ininame.add(TInstall_ini::default_name()); } else return error_box(TR("Specificare un percorso valido")); TWait_cursor hourglass; destroy(); force_update(); TString_array modules; //cerca sull'install.ini di origine se lo trova (ininame e' il path dell'install.ini remoto) if (ininame.exist()) { // Presente il file ini generale "install.ini" (moduli;immagine cd) TInstall_ini ini(ininame); ini.list_paragraphs(modules); //riempie modules con la lista dei paragrafi sul .ini *** FOR_EACH_ARRAY_ROW(modules, i, row) { const TString& module = *row; if (module[0] == '_' || module.len() == 2) { if (module[0] == '_') add_header(ini, module); else { TFilename mod_ini = ininame.path(); mod_ini.add(module); mod_ini << "inst.ini"; //controlla se esiste il pacco zippato del modulo attraverso l'esistenza del file.. //..XXinst.ini if (mod_ini.exist()) { TInstall_ini moduleini(mod_ini); add_module(moduleini, module, false); } else add_module(ini, module, false); } } //if(module[0]... } //FOR_EACH_ARRAY_ROW(... } else { // Presenti i singoli file .ini dei moduli (pacchi ma non patches!) ininame = path; ininame.add("??inst.ini"); list_files(ininame, modules); //ritorna la lista dei files presenti nel .ini della patch *** FOR_EACH_ARRAY_ROW(modules, m, row) { TString& ininame = *row; ininame.lower(); const int pos = ininame.find("inst.ini"); CHECKS(pos >= 2, "Invalid installation configuration: ", (const char*)ininame); const TString4 module = ininame.mid(pos-2, 2); TConfig ini(ininame, module); add_module(ini, module, false); } } modules.destroy(); if (internet) //internet patches { TProgress_monitor pi(1, TR("Controllo lista aggiornamenti"), false); // progind NON bloccabile: causa errore impossibile! http_dir(http_server, http_path, modules); pi.set_max(modules.items()); pi.set_text(TR("Download lista aggiornamenti")); for (int i = modules.last(); i >= 0; i--) { if (!pi.add_status()) break; TString& str = modules.row(i); if (str.ends_with("a.ini", true)) { /* Triste nescessita': si rischia di non caricare nessuna patch const TString& module = str.left(2); const int patch = atoi(str.mid(2, 4)); const int mypatch = ini_get_int(CONFIG_GENERAL, module, "Patch"); if (patch > 0 && patch < mypatch) { modules.destroy(i); continue; // Non fare il download delle patch inutili } */ TFilename remote = http_path; remote << str; ininame = path; ininame.add(str); if (!ininame.exist() && !http_get(http_server, remote, ininame)) { error_box(FR("Errore di trasferimento del file %s"), (const char*)remote); modules.destroy(i); } str = ininame; } else modules.destroy(i); } modules.pack(); } else //normal patches { ininame = path; ininame.add("??????a.ini"); list_files(ininame, modules); } if (modules.items() > 0) //ordina i moduli come sull'install.ini locale (per avere SY come primo { //modulo e via via gli altri) TInstall_ini installini; TString_array paragrafi; TFilename file; installini.list_paragraphs(paragrafi); // rimozione del produttore sull'install.ini locale ora obsoleto.. installini.remove("Producer"); FOR_EACH_ARRAY_ROW(modules, am, arow) { file = *arow; file = file.name(); int pos = paragrafi.find(file.left(2)); if (pos <= 0) pos = 10000+am; TString8 str; str.format("%05d", pos); //aggiunge un numero d'ordine sulla sinistra del nome del file.. arow->insert(str); } modules.sort(); //..cosi' che la sort (che ordina alfabeticamente) sistemi la lista moduli FOR_EACH_ARRAY_ROW(modules, bm, brow) //rimette i nomi dei moduli a posto (toglie il numero d'ordine) brow->ltrim(5); } //genera le righe dello sheet di installazione FOR_EACH_ARRAY_ROW(modules, am, arow) { TString& ininame = *arow; ininame.lower(); if (fsize(ininame) < 8) { xvt_fsys_remove_file(ininame); continue; } const int pos = ininame.find("a.ini"); CHECKS(pos >= 6, TR("Configurazione di installazione non valida: "), (const char*)ininame); const TString4 module = ininame.mid(pos-6, 2); TConfig ini(ininame, module); ini.write_protect(); int r; for (r = int(items()-1); r >= 0; r--) { if (module == row(r).get(C_CODE)) break; } if (r >= 0) { if (is_visible_patch(ini)) { const TString16 patchversion = ini.get("Versione"); const int patchlevel = ini.get_int("Patch"); TToken_string& row = mask_rows.row(r); const TString16 release(row.get(C_RELEASE)); if (patchversion.mid(4) == release.mid(4) && // se le versioni corrispondono ... patchlevel > row.get_int(C_PATCH)) // ..e il patchlevel è superiore { TString4 patch; patch.format("%04d", patchlevel); //aggiunge zeri per avere 3 cifre sempre row.add(patch, C_PATCH); // aggiorna il patchlevel mostrato per il modulo row.add(ini.get("Data"), C_DATAREL); // aggiorna data di rilascio if (row.get_char(C_ISPATCH)<=' ') // se era un modulo ... { row.add("+", C_ISPATCH); // .....setta la presenza di patches row.add(row.get(C_PATCH), C_BASEPATCH); // memorizza patch del modulo } if (release < patchversion) row.add(patchversion, C_RELEASE); row.add(ini.get("OEM"), C_OEM); } } else destroy(r); // Elimina patch di altri OEM erroneamente inserite } else add_module(ini, module, true); } update_version(); const bool ok = precheck_modules() > 0; if (!ok) error_box(FR("Non e' stato trovato nessun modulo da installare\nin %s"), (const char*)path); return ok; } bool TInstaller_mask::do_process(TToken_string& commands) const { bool ok = true; TFilename cmd; for (const char* c = commands.get(0); c && ok; c = commands.get()) { cmd = c; if (cmd.full()) { TWait_cursor hourglass; TExternal_app app(cmd); ok = app.run(false,3,true) == 0; } } return ok; } bool TInstaller_mask::pre_process(TInstall_ini& ini, const char* module) const { TAuto_token_string commands(ini.get("PreProcess", module)); bool ok = do_process(commands); return ok; } bool TInstaller_mask::post_process(TInstall_ini& ini, const char* module) const { TAuto_token_string commands(ini.get("PostProcess", module)); return do_process(commands); } bool TInstaller_mask::can_install(const char* module, TInstall_ini& ini) { ini.set_paragraph(module); if (!is_visible_patch(ini)) return false; const TString& version = ini.version(module); const word year = version2year(version); if (year < 2091) return error_box(FR("Il modulo '%s' non ha una versione valida."), module); if (!dongle().demo() && year > dongle().year_assist()) //devo aggiornare l'anno di assistenza? { if (!update_assistance_year()) //sono riuscito ad aggiornare l'anno di assistenza? return false; } TAuto_token_string altri(ini.get("Moduli", module)); if (xvt_str_compare_ignoring_case(module, "sy") != 0) //SY e' indipendente dagli altri moduli { if (xvt_str_compare_ignoring_case(module, "ba") != 0 && altri.get_pos("ba") < 0) altri.add("ba"); } bool ok = true; TString submodule; TInstall_ini curini; for (const char* mod = altri.get(0); mod && ok; mod = altri.get()) { submodule = mod; if (submodule.len() == 2) { if (curini.get("Versione", submodule).empty()) { TString msg; msg.format(FR("L'installazione del modulo %s richiede la presenza del modulo %s."), (const char*)module, (const char*)submodule); msg << '\n' << TR("Si desidera procedere alla sua installazione?"); ok = yesno_box(msg); if (ok) ok = install(submodule, 0); } } } return ok; } int TInstaller_mask::needs_reboot(const TFilename& file) const { char fname[_MAX_FNAME], ext[_MAX_EXT]; xvt_fsys_parse_pathname(file, NULL, NULL, fname, ext, NULL); int underscore = NONE; if (xvt_str_compare_ignoring_case(ext, "exe") == 0) { if (xvt_str_compare_ignoring_case(fname, "ba0") == 0) underscore = NEW_MENUPRG; else if (xvt_str_compare_ignoring_case(fname, "ba1") == 0) underscore = NEW_INSTALLER; } else if (xvt_str_compare_ignoring_case(ext, "dll") == 0) underscore = NEW_DLL; else if (xvt_str_compare_ignoring_case(ext, "men") == 0) underscore = NEW_MENU; else if (xvt_str_compare_ignoring_case(ext, "trr") == 0 || xvt_str_compare_ignoring_case(ext, "dir") == 0) underscore = NEW_TRR; return underscore; } // Controlla se un file puo' essere scompattato. // Attenzione: dninst.zip e' un falso zip bool TInstaller_mask::is_zip_file(const TFilename& n) const { bool yes = xvt_str_compare_ignoring_case(n.ext(), "zip") == 0 && xvt_str_compare_ignoring_case(n.name_only(), "dninst") != 0; return yes; } bool TInstaller_mask::copy_file(const TFilename& src, const TFilename& dst) const { // Crea la cartella di destinazione se necessario const char* dstdir = dst.path(); if (*dstdir && !xvt_fsys_mkdir(dstdir)) return error_box(FR("Impossibile creare la cartella %s"), dst.path()); // Copia veramente il file return ::fcopy(src, dst); } // sposta il file dal direttorio temporaneo a quello passato come destinazione bool TInstaller_mask::move_file(const TFilename& src, const TFilename& dst) const { TFilename dest = dst; const int reboot = needs_reboot(dest); if ((reboot & NEW_SYS)!=0 && dst.exist()) { dest.rtrim(1); dest << '_'; } const bool is_zip = is_zip_file(src); const long filesize = fsize(src) * (is_zip ? 4 : 1); if (xvt_fsys_test_disk_free_space(dest.path(), filesize) == 0) return error_box(TR("Lo spazio disponibile e' insufficiente!")); const bool write_ok = copy_file(src, dest); if (write_ok && is_zip) aga_unzip(src, dest.path()); if (write_ok) src.fremove(); if (write_ok) { (int&)_reboot_program |= reboot; // Skip const! } return write_ok; } bool TInstaller_mask::move_module(const TString& module, TInstall_ini& ini, bool update) const { bool ok = true; TFilename tempdir; tempdir.tempdir(); const TString& destdir = get(F_CURPATH); TString_array list; ini.build_list(module, list); FOR_EACH_ARRAY_ROW(list, f, file) { TFilename src = tempdir; src.add(file->get(0)); if (update) { TFilename dst = destdir; dst.add(file->get(0)); const bool move_ok = move_file(src, dst); if (!move_ok) ok = update = false; } if (!update) src.fremove(); } return ok; } bool TInstaller_mask::copy_tree(const char* src_study, const char* dst_study) const { xvt_fsys_save_dir(); TFilename mask(src_study); mask.add("*."); SLIST dlist = xvt_fsys_list_files(DIR_TYPE, mask, TRUE); xvt_fsys_restore_dir(); TProgress_monitor pd(xvt_slist_count(dlist), TR("Copia cartelle")); TString msg; // Messaggio di progresso bool go_on = true; for (SLIST_ELT d = xvt_slist_get_first(dlist); d && go_on; d = xvt_slist_get_next(dlist, d)) { if (!pd.add_status()) { go_on = false; break; } const TFilename dir = xvt_slist_get(dlist, d, NULL); TString name = dir.name(); name.lower(); if (name == "cesp") // Ignora la vetusta cartella Cespiti in FoxPro continue; msg.cut(0) << TR("Copia di ") << name; pd.set_text(msg); mask = dir; mask.add("*.*"); TString_array files; list_files(mask, files); TProgress_monitor pi(files.items(), TR("Copia file")); TFilename dst; FOR_EACH_ARRAY_ROW(files, i, f) { if (!pi.add_status()) { go_on = false; break; } TFilename src(*f); TString16 ext(src.ext()); ext.lower(); if (ext != "zip" && ext != "rar" && ext != "mdb" && ext != "inf") { msg.cut(0) << TR("Copia di ") << src; pi.set_text(msg); dst = dst_study; dst.add(name); dst.add(src.name()); copy_file(src, dst); } } } xvt_slist_destroy(dlist); return go_on; } void TInstaller_mask::backup() const { TFilename src = firm2dir(-1); if (!isalnum(src.right(1)[0])) src.rtrim(1); TFilename dst(src); dst << ' ' << TDate(TODAY).date2ansi(); // Lo spazio rende inutilizzabile lo studio TToken_string msg(256, '\n'); msg.add(TR("Si consiglia creare una copia dello studio ")); msg << src.name(); msg.add(TR("nella cartella ")); msg << dst; msg.add(TR("L'operazione potrebbe richiedere alcuni minuti.")); msg.add(""); msg.add(TR("Si desidera effetture la copia?")); if (yesno_box(msg)) copy_tree(src, dst); } KEY TInstaller_mask::askdisk(TString & path, TFilename & cmdline, int d, int dischi, const char * modulo) { TMask retry_mask(TR("Inserimento disco"),1,80,10); retry_mask.add_static((F_PATH==101 ? 102:101),0, format(FR("Inserire il disco %d di %d del modulo '%s' nell'unità"), d, dischi, modulo) ,2,2); retry_mask.add_static(F_PATH+3,0,TR("oppure indicare un percorso diverso"),2,3); retry_mask.add_string(F_PATH,0,"",2,5,48); retry_mask.add_button(DLG_OK,0,TR("Riprova"),-12,7,9,2); retry_mask.add_button(DLG_QUIT,0,"",-22,7,9,2); retry_mask.set(F_PATH,path); KEY k; do { if ((k=retry_mask.run())==K_QUIT ) break; if (!retry_mask.get(F_PATH).blank()) { if (fexist(retry_mask.get(F_PATH))) { TString16 tmpname(cmdline.name() ); cmdline= path = retry_mask.get(F_PATH); cmdline.add(tmpname); break; } else error_box(TR("Il percorso indicato non e' valido")); } } while (true); return k; } //rimozione da disco dei files da eliminare indicati nei paragrafi kill.. //..e successivo aggiornamento dell'install.ini in modo da non avere più tra i piedi i files killati void TInstaller_mask::kill_files() { //apre l'install.ini locale per effettuare l'aggiornamento TInstall_ini ini; //giro su tutti i sottomoduli di tipo 99 con l'elenco dei files da uccidere TString_array paragraph_names; ini.list_paragraphs(paragraph_names); FOR_EACH_ARRAY_ROW(paragraph_names, nriga, riga) { //interessano solo i paragrafi con le killer list if (riga->ends_with("99") && ini.set_paragraph(*riga)) { TString_array killed; TToken_string rigaini; TFilename filetokill; for (int k = 0;; k++) { rigaini = ini.get("Kill", NULL, k, ""); if (rigaini.empty()) break; filetokill = rigaini.get(0); if (filetokill.find('*') >= 0 || filetokill.find('?') >= 0) { TString_array filelist; list_files (filetokill, filelist); FOR_EACH_ARRAY_ROW(filelist, r, file) { filetokill = *file; if (filetokill.exist()) filetokill.fremove(); killed.add(filetokill); } } else { if (filetokill.exist()) filetokill.fremove(); killed.add(filetokill); } } //for(int k=0... for (int s = 0; s <= 9 && !killed.empty(); s++) { const TString4 mod = riga->left(2); const int cicli = mod == "ba" ? 2 : 1; for (int c = 1; c <= cicli; c++) { TString4 module = c == 1 ? mod : "sy"; module << s; TAssoc_array& vars = ini.list_variables(module); FOR_EACH_ASSOC_STRING(vars, hobj, key, str) { const int idx = killed.find(str); if (idx >= 0) { ini.remove(key); killed.destroy(idx, true); } } } } //for (int s... } //if (riga->ends_with... } //FOR_EACH_ARRAY_ROW(... } bool TInstaller_mask::install(const TString& module, int patchlevel) { bool cancelled = false; bool ok = false; TString msg; // stringa per i messaggi TString16 lastrelease; // release che sto installando int lastpatch = patchlevel; // patchlevel che sto installando TFilename path ; TString http_server; TFilename http_path; const bool internet = get_patches_path(path); if (internet) parse_internet_path(http_server,http_path ); const bool is_a_patch = (patchlevel > 0); //file .ini con le info di installazione (es. bainst.ini o ba0883.ini) TFilename remote_ininame = path; remote_ininame.add(module); //completa il nome del file .ini controllando se è una patch (es. ba0883a.ini) o se è un pacco (es. bainst.ini) if (is_a_patch) { TString16 name; name.format("%04da.ini", patchlevel); remote_ininame << name; } else remote_ininame << "inst.ini"; if (internet && !remote_ininame.exist()) { TFilename remote = remote_ininame.name(); remote.insert(http_path, 0); http_get(http_server, remote, remote_ininame); } if (remote_ininame.exist()) { // esiste un particolare .ini con formato XXinst.ini (moduli) o con XX9999a.ini (patch) //---------------------------------------------- // (INSTALLAZIONE DA DIRECTORY CON FILES .ZIP) //---------------------------------------------- //remote_ini è il file .ini con le info di installazione (es. ba0883a.ini, bainst.ini) TInstall_ini* remote_ini = new TInstall_ini(remote_ininame); remote_ini->write_protect(); lastpatch = remote_ini->get_int("Patch", module); lastrelease = remote_ini->get("Versione", module); //se non può installare il modulo chiude il remote_ini if (!can_install(module, *remote_ini)) { delete remote_ini; return false; } //antico controllo del numero di dischetti (ora sempre = 1) const int dischi = remote_ini->get_int("Dischi", module); ok = dischi > 0; if (!ok) return error_box(FR("Impossibile determinare il numero dei dischetti in %s"), remote_ininame.name()); else { if (patchlevel == 0) ok = pre_process(*remote_ini, module); if (!ok) { delete remote_ini; return false; } } // DECOMPRESSIONE // ---------------- // viene decompresso il file .zip collegato al file remote_ini (es. ba0883a1.zip, bainst.zip) TProgind* pi = NULL; if (dischi > 1) { msg = TR("Decompressione"); if (is_a_patch) msg << TR(" della patch ") << patchlevel ; msg << TR(" del modulo '") << module << TR("' in corso..."); pi = new TProgind(dischi, msg, false, true); } TFilename tempdir; tempdir.tempdir(); // File tottale dei vari sotto-zip TFilename totti = tempdir; totti.add(module); totti.ext("zip"); //si costruisce il nome dello zip for (int d = 1; d <= dischi && ok; d++) { TFilename chunk = path; chunk.add(module); if (patchlevel > 0) { TString8 name; name.format("%04da", patchlevel); chunk << name; } else chunk << "inst"; chunk << d << ".zip"; if (internet && !chunk.exist()) { TFilename remote = chunk.name(); remote.insert(http_path, 0); if (!http_get(http_server, remote, chunk)) error_box(FR("Errore di trasferimento del file '%s'"), (const char*)remote); } //antichi controlli in caso di multidischetto ok = chunk.exist(); if (!ok && !internet) // Chiedi cambio disco (solo se non sta scaricando da internet) { while (!ok) { if (askdisk(path, chunk, d, dischi, (const char*)remote_ini->get("Descrizione")) == K_QUIT) break; ok = chunk.exist(); if (!ok) message_box(FR("Impossibile trovare il file '%s'"), (const char*)chunk); } } if (ok) { const long required = fsize(chunk) * (dischi - d + 1) * 4; if (!xvt_fsys_test_disk_free_space(tempdir, required)) { ok = yesno_box(TR("Lo spazio su disco potrebbe essere insufficiente:\nSi desidera continuare ugualmente?")); } } if (ok) ::fcopy(chunk, totti, d > 1); // Somma il chunk al totale } if (pi != NULL) { delete pi; pi = NULL; } //scompattamento vero e proprio dello zip aga_unzip(totti, tempdir); // Scompatta il file totale zip totti.fremove(); // Elimina il file totale zip // TRASFERIMENTO // ----------------- if (ok) { // si assicura che sia leggibile il .ini del primo disco do { TFilename cmdline = path; cmdline.add(remote_ininame.name()); ok = cmdline.exist(); if (!ok) { if (askdisk(path, cmdline, 1, dischi, (const char*)remote_ini->get("Descrizione")) == K_QUIT) break; ok = fexist(cmdline); if (!ok) message_box(FR("Impossibile trovare %s\n"), (const char*)cmdline); else { delete remote_ini; remote_ini = new TInstall_ini (cmdline); } } } while (!ok); if (ok) { TWait_cursor hourglass; msg.cut(0); msg << TR("Aggiornamento del modulo '") << module << TR("' in corso..."); xvtil_statbar_set(msg); ok = move_module(module, *remote_ini, true); if (ok) { TAuto_token_string altri(remote_ini->get("Moduli", module)); FOR_EACH_TOKEN(altri, mod) { const TString16 submod = mod; if (submod.len() > 2) // sposta sottomoduli esterni { bool upd = ok; if (ok) { TInstall_ini local_cur_ini; const TString16 curver = local_cur_ini.version(submod); const int curpatch = local_cur_ini.patch(submod); const TString16 reqver = remote_ini->version(submod); const int reqpatch = remote_ini->patch(submod); int distance = compare_version(reqver, reqpatch, curver, curpatch); upd = distance > 0; } ok &= move_module(submod, *remote_ini, upd); if (upd && ok) // marca sull'install.ini di destinazione l'avvenuta installazione del sottomodulo "esterno" remote_ini->export_paragraph(submod, TInstall_ini::default_name(), !is_a_patch); } } } xvtil_statbar_set(""); } //if(ok).. } //if(ok).. if (ok) // marca sull'install.ini di destinazione l'avvenuta installazione del modulo remote_ini->export_module_paragraphs(module, TInstall_ini::default_name(), !is_a_patch); } // installazione da directory con zip else if (!is_a_patch) { // non c'e' il .ini del modulo ma un unico "install.ini" (es. aggiornamento client) //------------------------------------------------ // (INSTALLAZIONE DA DIRECTORY CON ESEGUIBILI) //------------------------------------------------ remote_ininame = path; remote_ininame.add(TInstall_ini::default_name()); ok = fexist(remote_ininame); if (ok) { TInstall_ini ini(remote_ininame); ini.write_protect(); lastpatch = ini.get_int("Patch", module); lastrelease = ini.get("Versione", module); if (!can_install(module, ini)) return false; TString_array list; const int files = ini.build_complete_list(module, list); if (files > 0) { if (patchlevel == 0) ok = pre_process(ini, module); if (ok) { msg.cut(0) << TR("Copia del modulo ") << module; TProgress_monitor pi(files, msg, false); TFilename src, dst; for (int f = 0; f < files && ok; f++) { if (!pi.add_status()) { cancelled = true; break; } dst = list.row(f).get(0); dst.lower(); src = path; src.add(dst); const int reboot = needs_reboot(dst); if ((reboot & NEW_SYS) != 0 && dst.exist()) { dst.rtrim(1); dst << '_'; } //copia il file dalla dir sorgenti ok = copy_file(src, dst); if (ok) { if (ok && is_zip_file(src)) aga_unzip(src, dst.path()); if (ok && reboot != NONE) _reboot_program |= reboot; } else //se non riesce chiede se proseguire ugualmente ok = yesno_box(TR("Continuare ugualmente ?")); } ok &= !cancelled; } if (ok) // marca sull'install.ini di destinazione l'avvenuta installazione del modulo ini.export_module_paragraphs(module, ini.default_name(), true); } // controllo esistenza lista di file non vuota per questo modulo } // controllo esistenza install.ini } // fine installazione da directory con eseguibili if (ok) { { TInstall_ini ini; ini.set("Data", TDate(TODAY), module); } // Non togliere le parentesi graffe soprastanti per permettere l'aggiornamento fisico del .ini (CON LA CHIAMATA DEL DISTRUTTORE) update_version(); } if (ok && patchlevel == 0) // Se installo un modulo pricipale ... { // ... installo DOPO tutte le patches successive install_patches(module, lastrelease, lastpatch); TInstall_ini ini; ok &= post_process(ini, module); } return ok; } bool TInstaller_mask::get_patches_path(TFilename& path) const { const TEdit_field& www = efield(F_WEB); path = www.get(); if (www.active() && path.full() && is_internet_path(path)) { path.tempdir(); path.add("www"); make_dir(path); //crea la directory temporanaea di installazione dove depositare e scompattare gli zip return true; } else { path = get(F_PATH); // Toglie l'eventual slash finale const char last = path.right(1)[0]; if (last == '/' || last == '\\') path.rtrim(1); } return false; } void TInstaller_mask::parse_internet_path(TString & http_server, TFilename &http_path) const { http_server = get(F_WEB); if (http_server.blank()) { http_server = http_default_path(); ((TMask*)this)->set(F_WEB, http_server); } if (http_server.starts_with("http://")) http_server.ltrim(7); const int slash = http_server.find('/'); if (slash > 0) { http_path = http_server.mid(slash); http_server.cut(slash); } //aggiunge lo slash finale se l'utonto l'ha omesso if (!http_path.ends_with("/")) http_path << '/'; //e' un server redirezionato? http_isredirected_server(http_server, http_path); } bool TInstaller_mask::install_patches(const TString& module, const TString& lastrelease, int lastpatch, bool only_newer) { bool ok = true; TString_array modules; TFilename ininame; get_patches_path(ininame); ininame.add(module); ininame << "????a.ini"; modules.destroy(); list_files(ininame, modules); modules.sort(); FOR_EACH_ARRAY_ROW(modules, am, arow) { TString& ininame = *arow; ininame.lower(); const int pos = ininame.find("a.ini"); CHECKS(pos >= 6, "Invalid installation configuration: ", (const char*)ininame); const TString4 patchmodule = ininame.mid(pos-6, 2); TConfig ini(ininame, patchmodule); const int patchlevel = ini.get_int("Patch"); const TString16 patchversion = ini.get("Versione"); if (ok && lastrelease.mid(4) == patchversion.mid(4) // installa solo le patch della stessa ver.. && (only_newer ? lastpatch < patchlevel : lastpatch <= patchlevel)) // ... e patch superiore o uguale (reinstalla l'ultima patch) ok = install(module, patchlevel); } return ok; } bool TInstaller_mask::update_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TInstaller_mask& m = (TInstaller_mask&)f.mask(); m.autoload(); } return true; } bool TInstaller_mask::path_handler(TMask_field& fld, KEY key) { bool ok = true; if (key == K_TAB && fld.focusdirty()) { TFilename path = fld.get(); if (path.not_empty()) { if (path.len() == 2 && isalpha(path[0]) && path[1] == ':') { path << SLASH; fld.set(path); } if (path.exist() || ::is_internet_path(path)) _curr_mask->autoload(); else ok = fld.error_box(TR("Specificare un percorso valido")); } } return ok; } bool TInstaller_mask::web_handler(TMask_field& fld, KEY key) { bool ok = true; if (key == K_TAB && fld.focusdirty()) { TFilename path = fld.get(); if (path.not_empty()) { if (!path.ends_with("/")) { path << '/'; fld.set(path); } ok = ::is_internet_path(path); if (!ok) ok = fld.error_box(TR("Specificare un indirizzo valido")); } } return ok; } // Aggiorna l'install.ini con eventuali modifiche dell'utente su dispath e/o webpath // Decisivo in caso di cambio path d'installazione // Serve a setup (deve essere chiamata in caso di esecuzioni passive di setup, tipo -uw, -uw) void TInstaller_mask::update_disk_and_web_path() { TInstall_ini ini; ini.set("DiskPath", get(F_PATH)); ini.set("WebPath", get(F_WEB)); } void TInstaller_mask::install_selection() { int nModules = 0; TString_array& arr = rows_array(); if (!arr.empty()) { FOR_EACH_ARRAY_ROW(arr, r, row) { if (checked(r)) nModules++; } } TProgress_monitor pi(nModules, TR("Installazione")); //deve poter tener conto del "No Tutti" in caso di installazione da area release bool no_to_all = false; FOR_EACH_ARRAY_ROW(arr, r, row) if (checked(r)) { if (!pi.add_status()) break; const TString newver = row->get(C_RELEASE); if (newver.blank()) { check(r, false); continue; } const TString4 modulo = row->get(C_CODE); const TString modesc = dongle().module_name2desc(modulo); const int newpatch = row->get_int(C_PATCH); const TString oldver = row->get(C_CURRRELEASE); const int oldpatch = row->get_int(C_CURRPATCH); pi.set_text(format(FR("Installazione modulo '%s'"), (const char*)modesc)); if (version2year(newver) < 2012) { error_box(FR("Il modulo '%s' non ha una versione valida."), (const char*)modesc); continue; } bool ok = true; bool is_patch = row->get_char(C_ISPATCH) == 'X'; bool has_patch = row->get_char(C_ISPATCH) == '+'; const int cmp = compare_version(oldver, oldpatch, newver, newpatch); //versione e patch coincidono if (cmp == 0) ok = noyes_box(FR("Si desidera reinstallare la versione %s.%d del modulo '%s' ?"), (const char*)newver, newpatch, (const char*)modesc); //ci sono ANCHE i pacchi if (!is_patch && cmp > 0) { TString256 msg; msg.format(FR("Si desidera ritornare alla versione %s.%d del modulo '%s' ?\nAttenzione: non è garantito il corretto\nfunzionamento di tutti i programmi!"), (const char*)newver, newpatch, (const char*)modesc); ok = noyes_box(msg); } //ci sono SOLO patch da installare if (ok && is_patch) { // installo le patch solo se esiste già un modulo installato della stessa versione if (!oldver.blank() ) { if (compare_version(oldver, 0, newver, 0)) //controlla SOLO la versione indipendentemente dall'anno! ok = error_box(FR("Il modulo '%s' installato ha versione %s:\nimpossibile installare le patch della versione %s"),(const char *)modulo,(const char *)oldver,(const char *)newver); } else if (newpatch < oldpatch) { TString256 msg; msg.format(FR("Si desidera ritornare alla patch %s.%d del modulo '%s' ?\nAttenzione: non e' garantito il corretto\nfunzionamento di tutti i programmi!"), (const char*)newver, newpatch, (const char*)modesc); ok = noyes_box(msg); } } //if(ok&&is_patch... if (ok) { if (has_patch) { if (newver == oldver && newpatch >= oldpatch) { const int basepatch = row->get_int(C_BASEPATCH); if (oldpatch >= basepatch) { if (!no_to_all) { const int key = yesnoall_box(FR("Si desidera reinstallare l'intero modulo '%s'?" "\nRispondendo NO verranno installate le sole patch"), (const char *)modesc); switch (key) { case K_YES: is_patch = true; break; case K_SPACE: //se risponde "No Tutti", non deve più chiederlo e prenderlo sempre per buono is_patch = true; no_to_all = true; break; default: is_patch = false; break; } } else { //se ha già deciso di NON reinstallare mai i pacchi ("no tutti") allora is_patch è sempre true.. //..in modo da installare le sole patch is_patch = true; } } else is_patch = false; // Quando la versione installata precede la patch base devo reinstallare il modulo! } } TFilename path; const bool internet = get_patches_path(path); //richiesto aggiornamento da disco del modulo SY o del modulo SR da manutenzione/installazione moduli! if (modulo == "sy" || modulo == "sr") { if (!run_as_admin()) { error_box("Per installare il modulo sistema è necessario eseguire l'applicazione come amministratore"); break; } if (!internet) { bool file_copied = false; //trova il path della directory setup che e' nell'area con gli zip del cd TFilename disk_path = path; disk_path.add("setup/"); TString_array ar; const int items = disk_path.exist() ? list_files(disk_path, ar) : 0; if (items > 0) { //copia la dir setup dal disco sovrascrivendo eventuali files gia' presenti make_dir("setup"); TFilename local_file, remote_file; //preserva l'OEM contenuto in oem.ini della directory setup const int old_oem = ini_get_int("setup/oem.ini", "MAIN", "OEM"); FOR_EACH_ARRAY_ROW(ar, r, row) { local_file = row->mid(path.len() + 1); remote_file = *row; file_copied = fcopy(remote_file, local_file); //occhio alle maiuscole!!!! } //riscrive il vecchio valore di oem in oem.ini ini_set_int("setup/oem.ini", "MAIN", "OEM", old_oem); } update_disk_and_web_path(); //aggiorna l'install.ini //lancia setup in modalita' aggiornamento da disco if (test_station_type() == 3) _setup_run = xvt_sys_execute("setup\\SetCmpUp.exe -uc", false, false) !=0; else _setup_run = xvt_sys_execute("setup\\SetCmpUp.exe -ud", false, false) !=0; } //richiesto aggiornamento via web del modulo SY da manutenzione/installazione moduli! else { bool file_copied = false; //trova l'indirizzo web completo TString http_server; TFilename http_path; parse_internet_path(http_server, http_path); //copia la dir setup dalla remote dir sovrascrivendo eventuali files gia' presenti http_path.add("setup/"); TString_array ar; http_dir(http_server, http_path, ar); if (ar.items() > 0) { make_dir("setup"); TFilename local_file, remote_file; FOR_EACH_ARRAY_ROW(ar, r, row) { local_file = "setup"; local_file.add(*row); remote_file = http_path; remote_file.add(*row); //via web NON deve copiare oem.ini perchè NON deve poter cambiare il reseller (solo via disco sarà.. //..possibile) const bool is_oem_ini = xvt_str_compare_ignoring_case(remote_file.name(), "oem.ini") == 0; if (is_oem_ini) { const int old_oem = xvt_sys_get_profile_int(local_file, "MAIN", "OEM", -1); file_copied = http_get(http_server, remote_file, local_file); //occhio alle maiuscole!!!! const int new_oem = xvt_sys_get_profile_int(local_file, "MAIN", "OEM", -1); if (new_oem != old_oem) { TString4 str_oem; str_oem << ' ' << old_oem; xvt_sys_set_profile_string(local_file, "MAIN", "OEM", str_oem); } } else file_copied = http_get(http_server, remote_file, local_file); //occhio alle maiuscole!!!! } } update_disk_and_web_path(); //aggiorna l'install.ini //lancia setup in modalita' aggiornamento web _setup_run = xvt_sys_execute("setup\\SetCmpUp.exe -uw", false, false) != 0; } if (_setup_run) //se riesce a lanciare setup.exe... { //si suicida...Banzai! uncheck(r); send_key(K_SPACE, DLG_QUIT); return; } } //installa solo le patch del modulo... if (is_patch) { ok = install_patches(modulo, oldver, oldpatch, false) ; // installa l'ultima patch if (!ok) message_box(TR("Impossibile installare le patch del modulo '%s'"),(const char *)modesc); } else //..installa anche il pacco del modulo { ok = install(modulo, 0); // installa il modulo } if (ok) { _installed = true; // Setta il flag di almeno un modulo installato uncheck(r); //finalmente unchecka i moduli installati } } //if(ok)... else uncheck(r); // se non ci sono patch o moduli -> uncheck } //FOR_EACH_ARRAY_ROW(arr... //aggiorna definitivamente i path su install.ini update_disk_and_web_path(); //accoppa i files nelle kill lists e aggiorna install.ini kill_files(); //serve per togliere il check al modulo 'sy' quando viene installato force_update(); } bool TInstaller_mask::install_handler(TMask_field& fld, KEY key) { if (key == K_SPACE) { if (_curr_mask->items() == 1) _curr_mask->check(0); const bool check_on = _curr_mask->check_enabled(); _curr_mask->enable_check(true); const bool some = _curr_mask->one_checked(); _curr_mask->enable_check(check_on); if (some) _curr_mask->install_selection(); else error_box(TR("Selezionare uno o più moduli da installare.")); } return true; } bool TInstaller_mask::tutti_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TInstaller_mask & m=(TInstaller_mask &) f.mask(); if (m.check_enabled()) { if (m.one_checked()) m.uncheck(-1); else m.precheck_modules(false); } } return true; } bool TInstaller_mask::on_key(KEY key) { bool ok = true; switch (key) { case K_F7: autoload(); break; case K_F8: field(DLG_USER).on_hit(); break; default : ok = TArray_sheet::on_key(key); break; } return ok; } //metodo per controllare se la directory indicata contiene una installazione buona di campo bool TInstaller_mask::is_program_dir(const TFilename& path) { //controlla l'esistenza di alcuni files chiave di campo const char* const essential[] = {"install.ini", "campo.ini", "campo.aut", "ba0.exe", "xvaga.dll", NULL }; bool ok = true; for (int i = 0; ok && essential[i]; i++) { TFilename work_path = path; work_path.add(essential[i]); ok = work_path.exist(); } return ok; } TInstaller_mask::TInstaller_mask() : TArray_sheet(0, 0, 0, 0, TR("Installazione"), HR("@1|Modulo@32|Cod.@3|Versione da\ninstallare@11|Liv.\nPatch@6|Data\nRilascio@10|Versione\nInstallata@10|Liv.\nPatch@6|Data\nInstallazione@13|Aggiornamento|Patch Base|OEM@10"), 0x18, 4) { add_button(F_INSTALL, TR("Installa"), '\0', TOOL_ELABORA); // NON mettere 'I' add_button(F_UPDATE, TR("Aggiorna Lista"), '\0', TOOL_CONVERT); add_button(DLG_NULL, "", '\0'); add_button(DLG_INFO, TR("Info"), K_F2, TOOL_INFO); add_button(DLG_HELP, TR("Help"), K_F1, TOOL_HELP); xvt_toolbar_set_last_tool(toolbar(), DLG_QUIT); _station_type = test_station_type(); _curr_mask = this; _installed = false; _reboot_program= NONE; //in base al tipo di installazione che rileva decide se puo' effettuare aggiornamenti via web (un client.. //..non puo' fare aggiornamenti da web!!!) TToken_string installada; installada.add(PR("Installa da disco")); installada.add(PR("Installa da web ")); TRadio_field& rf = add_radio(F_TYPE, 0, "", 0, 0, 23, "0|1", installada); *rf.message(0, true) = "DISABLE,207|ENABLE,201"; *rf.message(1, true) = "DISABLE,201|ENABLE,207"; add_string(F_PATH, 0, "", 23, 1, 256, "B", 56).set_selector('D', EMPTY_STRING); add_string(F_WEB, 0, "", 23, 2, 256, "", 56); set(F_TYPE, "0", 0x1); //deve conoscere i path adesso per poter testare se sono ok TInstall_ini ini; TFilename path = ini.get("DiskPath"); TFilename webpath = ini.get("WebPath"); //un client non puo' scegliere a caso da dove aggiornarsi! Solo dal suo server! if (_station_type == 3) { rf.disable(); bool ko = !is_program_dir(path); if (ko) warning_box(TR("La cartella origine dei programmi NON è valida!\nSelezionarne una valida e premere 'Invio'.")); enable(F_PATH, ko); } add_string(F_CURPATH, 0, PR("Installa in "), 1, 3, 80, "D", 56); set_handler(F_PATH, path_handler); set_handler(F_WEB, web_handler); set_handler(F_INSTALL, install_handler); set_handler(F_UPDATE, update_handler); set_handler(DLG_USER, tutti_handler); //se il webpath è vuoto o di test, propone quello in oem.ini; non ammette che possa essere proposto un path.. //..di tipo test per impedire all'utonto di aggiornarsi da test prima di essere passato da release if (webpath.empty() || webpath.find("test") > 0 || webpath.find("85.18.") >= 0) webpath = http_default_path(); set(F_PATH, path); set(F_WEB, webpath); //..fine costruzione maschera di installazione //decide quale e' il percorso di installazione //ha un cd o un disco di rete -> si aggiorna da questo... if (path.exist()) autoload(); else //senno' cerca su internet se trova un path internet completo e la connessione funzionante { if (_station_type != 3 && webpath.find("//") > 0) { set(F_TYPE, "1", 0x1); autoload(); } } DIRECTORY dir; xvt_fsys_get_dir(&dir); xvt_fsys_convert_dir_to_str(&dir, path.get_buffer(), path.size()); set(F_CURPATH, path); } TInstaller_mask::~TInstaller_mask() { _curr_mask = NULL; } /////////////////////////////////////////////////////////// // Programma principale /////////////////////////////////////////////////////////// class TInstaller : public TSkeleton_application { protected: TInstaller_mask* _m; protected: virtual bool create(); virtual bool use_files() const { return false; } virtual bool test_assistance_year() const; virtual void main_loop(); void convert_archives(); }; bool TInstaller::test_assistance_year() const { // Per il momento lascia continuare: ci pensa poi la create return true; } bool TInstaller::create() { if (!TApplication::test_assistance_year()) { TExternal_app attivazione("ba1 -4"); attivazione.run(); dongle().login(); // Rilegge anno assistenza } else update_dninst(false); // Aggiorna se necessario //crea la maschera di installazione _m = new TInstaller_mask(); //se e' un client if (_m->station_type() == 3) { _m->disable_check(); _m->disable(F_UPDATE); _m->disable(DLG_USER); } else //se e' standalone o server... { if (user() != ::dongle().administrator()) return error_box(TR("Solo l'utente amministratore puo' aggiornare questa postazione!")); } return TSkeleton_application::create(); } void TInstaller::convert_archives() { bool conv = true; if (is_power_station()) conv = yesno_box(TR("Si desidera convertire gli archivi ora?")); if (conv) { _m->backup(); // Lancia conversione: ba1 -0 -C -uADMIN TExternal_app conversion("ba1 -0 -C"); conversion.run(); } } void TInstaller::main_loop() { _m->run(); if (_m->run_conversion() && _m->station_type() < 3) // Almeno un trr installato e non e' client->conversione ammessa { convert_archives(); } //controlla se ha lanciato setup.exe prima di chiudersi; se non lo ha fatto -> e' a fine installazione.. //..normale (moduli non SY) e quindi lancia ba0.exe const bool setup_launched = _m->setup_run(); delete _m; _m = NULL; if (!setup_launched) { TExternal_app ba0("ba0.exe"); ba0.run(true, true, false); // run asynchronous and not iconized! } } int ba1700(int argc, char* argv[]) { TInstaller app; app.run(argc, argv, TR("Installazione moduli")); return 0; }